ASIS CTF 2022 pwn - babyscan 1 & babyscan 2
Author: 堇姬Naup
babyscan_1
source code
1 |
|
首先讓你輸入一個size
並且alloca size + 1大小的在stack上(與 malloc 不同,alloca 分配的記憶體會在函數返回時自動釋放,不需要使用 free)
並且通過snprintf來構建fmt
https://www.runoob.com/cprogramming/c-function-snprintf.html
他長這樣
1 | int snprintf ( char * str, size_t size, const char * format, ... ); |
單一一個%會被認為是fmt,所以使用%%來表示他是個str
之後%s表示size
所以是%%<size>s
第一個是轉義所以放到scanf內就是scanf("%<size>s", buf)
分析
看一下保護
1 | pwndbg> checksec |
沒PIE跟canary
這題很巧妙
首先是isdigit
https://www.runoob.com/python/att-string-isdigit.html
他會去檢查字串內是否有非數字
然而他寫爛了,通過*size
的方式只會判斷該char array第一個是否為數字
因此通過構造2$之類的fmt來嘗試做任意寫
最終可以構造出
%1$s 這樣就可以對 buf寫上任意長度了
https://ctf-wiki.org/pwn/linux/user-mode/fmtstr/fmtstr-intro/#_4
1 | sla(b'size: ',b'1$s') |
這樣就控到rip了,好ㄟ

接下來就寫ROPchain leaklibc
跳回main在overflow一次
通過libc的gadget打ROP開個shell
exploit
我不知道為啥我的libc system address寫不上去stack,所以堆syscall
1 | from pwn import * |
babyscan_2
source code
1 |
|
基本上跟上一題一樣,只是變成了malloc
代表沒有辦法簡單的通過overflow buf來打ROP
並且最後的return 0改成了exit
分析
他有給libc,把他patch上去
這邊用我CTFlib的patchelf bash script
1 |
|
接下來檢查保護
1 | pwndbg> checksec |
跟上一題一樣
既然沒辦法寫第一個參數,也就是buf,因為在heap overflow沒辦法控rip
這邊就可以嘗試overflow在其他參數
嘗試送這段payload可以發現b'10$s'+b'aaaa'+b'b'*0x20
可以發現他在rsp + 0x18的地方會填上我們輸入的b

rsp + 0x18 是 9$
故可以通過這個來任意寫
現在得到了任意寫了然後要leaklibc
這裡就是這題的難點(雖然也算老梗了)
簡單來說,第一步我們先把exit改成main
這樣可以獲得無限的任意寫
這邊有蠻多小細節的
像是size只接收15個byte
然後送main address時要記的少送一個byte,讓0xa不要蓋到重要資訊
他會卡在scanf裡面rsi+0x68引用到no access address
接下來關注到setbuf stdin stdout stderr
把setbuf GOT改成puts plt
stderr GOT改成其他function GOT
這樣就可以把libc印出來了
另外還有個坑點就是scanf會過濾\x20也就是空白,因此0x404020需要往前一個byte
這樣才不會被過濾
之後再把exit 改回start,讓他重跑一次setbuf那
就會把libc印出來了
PS: 變成了puts(atoi_got)來印libc
之後就把exit改成onegadget就行了
這條在跳進去exit時是符合的
1 | 0xe3b01 execve("/bin/sh", r15, rdx) |
這樣就getshell成功
exploit
1 | from pwn import * |
after all
突然看到感覺蠻有趣的就寫了一下
結果第二題我打了快一小時,原因是我一直看錯,導致我算出來的libcbase是錯的www