2009年6月12日 星期五

Defcon17 Wargame Crypto_Badness 400 解題過程

接續上一篇 Defcon 17 Wargame 競賽解題心得,這次分享的是 Crypto_Badness 400 的題目解題過程。

此題提供下載一個檔案,題目說明表示,此程式正在 pwn11.ddtek.biz 主機上執行,該程式為一 FreeBSD 的可執行檔,執行時會開 TCP Port 7852。直接用工具 nc 連向 pwn11.ddtek.biz 7852,即出現詢問 Password。所以按照慣例,先來個 strings 指令,觀察檔案內容。



其中有個字串,”chickenfingers” 應該就是該 Password 要問的答案了。當 Password: 提示出現時,輸入 chickenfingers,出現 What is your name? 時,隨便亂輸入 1234567890,最後出現如下圖:


要求解出該加密過的字串,該加密字串的每一字元用 16 進制表示。
接下來就不知要幹嘛,只好把原來的 FreeBSD執行檔,再來作分析,這一次改用工具 objdump 作反組譯(Disassemble)以及逆向工程(Reverse Engineering),分析結果如下:

  • 為一對稱式加密法,先取得五個亂數數值,每個亂數值為 0~255 (0x00~0xff) 之間,再建立一個 256 字元的陣列,陣列中每個值介於 0 至255。利用此五個亂數數值為亂數種子,擴充成 256 個亂數數值,存於此陣列中。
  • 利用簡單的 XOR 運算來加密,從明文中逐一取得字元,再從前面擴充成 256 個亂數陣列中,取一數值,來和明文的該字元 XOR,當明文的每一字元完成 XOR 後,即為密文。每次從 256 個亂數陣列中取值的方式則和明文字元的位置有關。
  • 由於 XOR 的特性,若是把密文的每個字元和 Key 的每個字元作 XOR 就可以反解成明文。透過程式的逆向工程,可以知道加密演算法,甚至可以直接取用相關計算函式。如此一來,我們只要猜測一開始亂數取得的五個亂數字元,就可以把 256 字元的亂數陣列值計算出來。
  • 不過,若是嘗試寫程式用暴力法計算,五個亂數數值全部猜測,就要計算 256 的 5 次方,而且,如何判斷該亂數值是否猜測正確呢?
  • 由於明文是從純文字檔內讀取 32 個字元,所以假設明文都是可顯示之字元(包含大小寫英文、符號及空白字元),那就可以在暴力法每回解出明文時,掃瞄一次明文字元是否都為可顯示之字元,若是,就假設為明文字串,全部顯示出來。
這下就可以寫程式,計算 256 的 5 次方,求解明文了!但是這樣跑程式實在太慢了,就算試著用一些最佳化或分散運算的方式,仍然要等上很久。


回過頭來重新檢視之前的輸入輸出。當 Password: 提示出現時,輸入 chickenfingers,出現 What is your name? 時,則輸入 1234567890,最後出現如下圖:



奇怪,1234567890 字串到 ? 字元出現的中間有一段空白,改用 hexedit 編輯看看:



這樣就看清楚了,在 1234567890 字串後面,接了 6 個空白字元(0x20),然後一個字元(0xCE),再一個 : (0x3A)字元。這個 0xCE 字元,即為一開始取五個亂數值中的第一個數值。
五個亂數值中,第一個數值已知,如此一來,就可以動手寫暴力破解程式,計算 256 的 4 次方,即可找出\x5f\x92\x84\xbc\xe\x16\xab\x2a\x92\x97\x63\x78\x06\x5f\xa1\x3a\xa3\xee\xa9\xc3\xee\x49\xea\xea\x92\x1a\x36\x2e\xa8\x7c\x28\x0cf 的明文。

透過分散數台電腦來分批執行暴力破解程式,但仍然很慢,花了數個小時仍找不出明文字串。這時想到,原來的程式中,輸出的函式有兩組,另一組會輸出兩倍長度的字元。假若我可以改變程式流程,跳躍至另一組輸出函式,也許可以輸出五個亂數值中的前兩個數值,這樣就可以跑計算次數降為 256 的 3 次方。

將所附的程式碼再重新反組譯,可以觀察出程式中有一個變數可以控制字元輸出的長度。該變數位在 -0x25(%ebp),此變數值是由 -0x29(%ebp) 和 1 作 AND 運算後的結果,若此變數 -0x25(%ebp) 的值為 1 是,則會輸出兩倍長度的字元。



當 Password: 提示出現時,輸入 chickenfingersa (故意多打一個字元,造成 one byte 溢出),出現 What is your name? 時,則輸入 ABCDEFGHIJKLMNOABCDEFGHIJKLMNO,最後出現如下圖:





在 ABCDEFGHIJKLMNOABCDEFGHIJKLMNO 字串後面,接了 2 個換行字元(0x0A),然後三個字元(0xD9、0xE2、0x00),再接一個 : (0x3A)字元。其中 0xD9、0xE2 字元,即為一開始取五個亂數值中的前兩個數值。這樣一來跑暴力破解程式實在快多了,不到十秒就出現一組明文。



不過這明文怎麼看都不像啊!讓暴力破解程式繼續執行,很快地,又發現第二組明文啦。

賓果! 解出明文了!

註:
暴力破解程式的解密函式是直接從原程式作逆向工程後取用,變數處理要注意 signed/unsigned 的問題,否則從亂數陣列取值時會計算不正確。


2009年6月10日 星期三

Defcon 17 Wargame 競賽解題心得

上週末剛好是美國知名駭客大會 Defcon 17 的 Wargame 外圍競賽期間。和往年一樣,這一次大夥又一塊聚在一起解題目,各展長才,不論是卡關卡的很痛苦、解謎解的快抓狂,或是終於解出答案的喜悅,總之我喜歡這樣的感覺。

經過兩天的努力,成績差強人意,雖然還是未能打進前十名,但應該也有二十多名,在全球兩三百個團隊競賽下,也不算太差吧!這兩日我共解了兩題,一題 100 分,另一題 400 分,我打算把解法寫出來,和大家分享交流。

這題是屬於 Binary_L33tness 的 100 分題目,題目很簡單,給一個檔案然後 "Find the key",如圖:


下載完檔案,第一步當然用 Linux 的 file 指令來判斷檔案型態囉!

[timhsu@localhost 100]$ file 100.file
100.file: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, stripped

此 100.file 檔為 Linux 的靜態執行檔,而且被 strip 過。不要怕,直接執行看看。

[timhsu@localhost 100]$ ./100.file
What is the password? 123
I smack you down. Step off bitch.

看來是要猜密碼耶。可以猜想一下,這個題目應該是密碼字串就在 Binary 執行檔裡,只要把檔案用 strings 指令來找這個字串,應該就是答案了。

有這麼容易嗎? 哦!若是直接用 strings 指令,大概找不出什麼像答案的字串吧!來用 hexdump 把檔頭資料印出來瞧瞧。

[timhsu@localhost 100]$ hexdump -C 100.file -n 256
00000000 7f 45 4c 46 01 01 01 03 00 00 00 00 00 00 00 00 |.ELF............|
00000010 02 00 03 00 01 00 00 00 e8 83 c0 00 34 00 00 00 |............4...|
00000020 00 00 00 00 00 00 00 00 34 00 20 00 02 00 28 00 |........4. ...(.|
00000030 00 00 00 00 01 00 00 00 00 00 00 00 00 10 c0 00 |................|
00000040 00 10 c0 00 d0 7b 00 00 d0 7b 00 00 05 00 00 00 |.....{...{......|
00000050 00 10 00 00 01 00 00 00 1c 0e 00 00 1c 0e 05 08 |................|
00000060 1c 0e 05 08 00 00 00 00 00 00 00 00 06 00 00 00 |................|
00000070 00 10 00 00 01 99 69 2e 55 50 58 21 e6 07 0d 0c |......i.UPX!....|
00000080 00 00 00 00 a6 03 01 00 a6 03 01 00 14 01 00 00 |................|
00000090 9a 00 00 00 02 00 00 00 63 3f 64 f9 7f 45 46 46 |........c?d..EFF|
000000a0 01 00 02 00 03 00 0d 92 ff b7 d9 ee 04 08 34 06 |..............4.|
000000b0 2c e5 17 0b 20 00 07 00 28 00 26 00 23 00 cf 3d |,... ...(.&.#..=|
000000c0 77 b1 06 0f 03 80 04 08 e0 0b 03 5a b3 69 9a 05 |w..........Z.i..|
000000d0 04 03 14 01 81 1b 05 1b ac fb 03 13 0f 13 1b 01 |................|
000000e0 03 ef b5 9f 8b 00 3b 03 a4 5b 0a 03 3f cf b9 b1 |......;..[..?...|
000000f0 d9 00 10 1f 13 eb 1b 03 50 d7 75 5f ec 78 22 00 |........P.u_.x".|

檔頭裡發現關鍵字串 "UPX",為一加殼程式,也就是說這個 Linux 執行檔被 UPX 加殼過,真正的檔案內容要在執行期間才會解開執行。直接用 upx 工具來作解殼動作,還原檔案內容。

[timhsu@localhost 100]$ upx -vvv -d 100.file
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2008
UPX 3.03 Markus Oberhumer, Laszlo Molnar & John Reiser Apr 27th 2008

File size Ratio Format Name
-------------------- ------ ----------- -----------
upx: 100.file: Exception: checksum error

Unpacked 1 file: 0 ok, 1 error.

失敗!upx 工具的解殼動作出現 checksum error,所以無法解開。
好吧,換個思維想想,既然加殼程式在執行期間會在記憶體還原原檔案內容,所以我們就可以試著在檔案執行時,把記憶體內容傾印出來。

試著建立 CoreDump 檔。

[timhsu@localhost 100]$ ulimit -c unlimited
[timhsu@localhost 100]$ ./100.file &
What is the password? [1] 22488

[1]+ Stopped ./100.file
[timhsu@localhost 100]$ kill -11 22488
[timhsu@localhost 100]$ ls
100.file*
[timhsu@localhost 100]$ ps
PID TTY TIME CMD
22408 pts/4 00:00:00 bash
22488 pts/4 00:00:00 100.file
22490 pts/4 00:00:00 ps
[timhsu@localhost 100]$ bg
[1]+ ./100.file &
[1]+ Segmentation fault (core dumped) ./100.file

CoreDump 建立成功!馬上用 strings 指令瞧瞧檔案內容。

[timhsu@localhost 100]$ strings core.22488 | more
...<略>...
,[^_]
[^_]
What is the password?
visilooksgoodinhotpants
, %d byte packets
CWR ECN
...<略>...
/lib/i686
libc.so.6
What is the password?
rotection after relocation
apic
mtrr
...<略>...
[timhsu@localhost 100]$

有兩組可能的密碼,試一下就知道。

[timhsu@localhost 100]$ ./100.file
What is the password? visilooksgoodinhotpants
You're my daddy! See you at the hacker swinger's club next week.

成功!這樣看來很簡單是吧?
事實上,當時我是用幾年前自己寫的小工具 dump2bin 來傾印執行檔,後來才想到不必寫程式的 DumpCore 方法,也許有其它方法,大家可以動動腦筋。

下回我將分享 Crypto_Badness 400 分的解題心得。

2009年6月3日 星期三

大陸 DNS 暴風門事件

上個月,在中國地區有個驚人的網路消息爆發,在 5/19 日時,大陸的 DNS 發生大規模的故障: 後來稱作 「暴風門」事件。

「5月19日晚間訊息,來自廣州、杭州等地中國電信客服人員向新浪科技證實,這些地區的網路出現故障,致使用戶無法上網。從晚間九點開始,陸續有多位網友反映稱,包括廣州、山西網通、上海、浙江等地均出現了不同程度的DNS癱瘓故障。」--- 節錄自: http://4i4u.com/blog/dns-baofeng-dnspod/

當時事件發生時,有網友猜測是 DNS 伺服器被黑客大規模 DDoS 攻擊,但這影響層面廣大是前所未聞。後來經過這陣子的調查,大家才了解事情的始末。

在 5/18 日時,著名 DNS 服務廠商 DNSPod 的 6 台伺服器受到 DDoS 的攻擊,直到 5/19 日,DNSPod 承受不了如此大流量攻擊下,被迫停止 DNS 服務。但為何這樣幾台 DNS 伺服器下線,就會造成大規模的網路異常呢?

這是因為,大陸地區最盛名的影音播放軟體 - 暴風影音,該公司的 DNS 服務就是由 DNS Pod 所提供的。因此,暴風影音播放器的用戶端無法解析出伺服器的 IP,開始不斷向網路供應商的 DNS 伺服器發送解析請求,造成 DNS 伺服器堵塞。據說,暴風影音的 1.5 億的客户端,其中約一半的客户端解析不到域名,令人詬病的是,暴風影音軟體會啟動自動連線程式,約每 15 秒連線暴風影音,若 DNS 查詢失敗則會不斷重試,因此,各地的客户端不停地發送 DNS Query (UDP 封包),各地 ISP 的 DNS 伺服器也就連帶著被暴風影音的用戶 DDoS 了。

相關消息及資料整理如下:

1. 5月19日大陸DNS發生大規模故障
2. 暴风影音DNS故障追踪:由24岁站长引发的蝴蝶效应
3.暴风长老, 请收了神通吧!
4.大陸出現罕見網絡大癱瘓 網民不滿
5.大陸DNS大規模故障始末:網域服務商遭DDOS攻擊
6.“5·19网络大瘫痪案”告破
7.暴风召回1.2亿播放软件 称损失应由黑客赔偿

當中也可以發現由於黑客地下經濟的興盛,從木馬程式開發、販售、「肉雞」養成,到提供各項網路攻擊,只要有錢,就可以胡作非為。

這些文章中也提到了 2006 年 12 月時,台灣發生地震,波及海底光纜,造成台灣對外如大陸地區、東南亞和澳洲等無法正常連線。事實上,當時台灣網路對外連線困難的影響,還意外地讓大家注意到了中華電信(hinet)偉大的 DNS 伺服器: 168.95.1.1。

我們可以在網路上找到許多網路教學或設定的文件,幾乎都是教人設定 DNS 伺服設定為: 168.95.1.1。還不止這樣,google://168.95.1.1 把範圍縮小到網路設備手冊,不論中文還是各國語言,也可以看到熟悉的 IP: 168.95.1.1!當然,台灣這幾年來在網通設備上的開發,出廠預設值的 DNS 伺服器,自然也是 168.95.1.1!

這也就是台灣 2006 年 12 月的地震,衝擊了世界上其它地區數以萬計的網友無法正常上網。真好奇 168.95.1.1 這台的 DNS Query 流量如何,而有多少 DNS Query 來自非台灣地區? :-)

DNS 的重要性看來很明顯,直到去年,都還有 DNS 伺服器的問題被爆出來 (Multiple Vendors DNS Spoofing Vulnerability) ,或許還有些我們不知道的問題在未來會發生,像這次「暴風門」事件,除了期望 ISP 固好 DNS 外,我們能試著改變一些習慣?
例如,DNS 的設定上除了 168.95.1.1 我們還可以設定其它 ISP 提供的 DNS 作為 Secondary。

不久前,有位友人和我打趣地說,若是 168.95.1.1 不回應 ICMP 的話會如何? 我說,大概很多人都以為網路對外不通吧!