之前我沒打過 Pwn,對它的瞭解只有從 OS 學到的知識去融會貫通。所以先從比較簡單的 Pwn 看起。
這一題的說明是:
nc pwn.ctf.tamu.edu 4321
(真的只有一行)
(但偵查階段好像直接到行動階段了)
$ file ./pwn1
./pwn1: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=50e68bf77076eb3487d3478631c1659cade5a1bc, not stripped
拿到檔案後直接用 file
檢查,所以我們可以知道,這個檔案是在 Linux 下執行,執行環境爲 32bit。
拿到之後,就先試試看這二進制檔會發生啥事。
$ chmod +x ./pwn1
$ ./pwn1
-bash: ./pwn1: No such file or directory
一開始還懷疑是拿到壞的(或有問題)的二進制檔,但仔細看了一下 file
的輸出...
Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2,
我的執行環境是 x86_64,而且根本沒這檔案阿。
$ ls /lib/ld*
ls: cannot access '/lib/ld*': No such file or directory
$ dnf provides 'ld-linux.so.2'
Last metadata expiration check: 7 days, 6:47:26 ago on Fri 12 Oct 2018 02:16:44 PM CST.
glibc-2.27-32.fc28.i686 : The GNU libc libraries
Repo : @System
Matched from:
Provide : ld-linux.so.2
glibc-2.27-32.fc28.i686 : The GNU libc libraries
Repo : updates
Matched from:
Provide : ld-linux.so.2
glibc-2.27-8.fc28.i686 : The GNU libc libraries
Repo : fedora
Matched from:
Provide : ld-linux.so.2
裝了 glibc.i686
後,就可以正常執行了。
$ ./pwn1
This is a super secret program
Noone is allowed through except for those who know the secret!
What is my secret?
secret
That is not the secret word!
看起來我們有個程式,會把的輸入和某個數值比對,若符合則吐出它的數值。
若我們用 gdb ./pwn1
,下斷點在 main()
,執行後執行 d9sassemble main
時,會看到:
箭頭的地方是目前 PC (Program Counter) 所在的位置。
因為我們知道程式會拿輸入去做比對,相對應的 ASM 爲 cmp
。這份程式碼中,+107
的部分就有一個 cmp
。
往回看的話,會發現程式依順序作這些事情:
ebp-0x23
的數值移動到 eax
上 x86 LEA
eax
的數值推到 Stack 上 x86 PUSH
gets()
(拿輸入的數值)ebp-0xc
的數值和 0xf007ba11
逐字比較jne
,回到 main+123
。如果通過,呼叫 print_flag
由於 gets()
執行時會把 stack 上最後的數值當作第一個參數,並將內容寫到該數值所指的位置上,故我們想辦法把 ebp-0xc
蓋成 f007ba11
,此時 cmp
就可以通過了。
gets()
的目標是在 ebp-0x23
,而我們需要覆蓋的數值在 ebp-0xc
上。兩個位置相減爲十六進位的 0x17
,爲十進位 17。
故我們輸入:
AAAAAAAAAAAAAAAAAAAAAAA11ba07f0
時,應該會可以通過 jmp
。
(註:因為是 little-endian,故數值是反過來的)
執行結果大概會像這樣:(扣除 crash 的部分)
Intro to Pwn – Aneesh Dogra’s Blog
Endianness - Wikipedia