DEFCON 24 CTF參賽記

照例每年寫遊記。原本以爲去年的DEFCON 23 CTF是最後一次。

每一張貼紙承載了一段故事,畢業前後的境遇對比。想當年,金戈鐵馬……

畢業前 畢業後

……

感謝組織今年又帶上了我,達成了醬油喵的第四次DEFCON CTF之行。本次blue-lotus戰隊和0ops戰隊聯合成爲b1o0p,由兩位隊長kelwin和slipper分別帶隊,slipper在長亭科技實習,於是關係錯綜複雜。兩支隊伍的贊助是獨立的,blue-lotus由原安全寶,現已被百度收購的百度安全XXX的贊助;0ops由騰訊贊助。

好多隊員都有實習或工作,投入時間有限,也能看出大家並沒有特別準備這個比賽。我大概7月28日纔開始瞭解DEF CON CTF決賽採用的Cyber Grand Challenge平臺。給0ops的隊友們點贊,他們做了很多準備。

Cyber Grand Challenge

本次DEF CON 24 CTF用了Cyber Grand Challenge(CGC)的比賽平臺,因此先介紹一下CGC。這是Defense Advanced Research Projects Agency(DARPA)發起的機器自動網絡攻防的計劃,可以與之做比較的是圍棋界的AlphaGo。CGC讓機器來尋找漏洞、修補漏洞、防火牆規則保護漏洞、利用漏洞。分爲兩輪,2015年7月3日的CGC Qualifying Event(CQE)和2016年8月4日的CGC Finals Event(CFE)。28支隊伍參加了CQE,24小時內讓機器自動分析約一百個可執行文件裏的漏洞。

最終有7支隊伍晉級CFEhttps://repo.cybergrandchallenge.com/cqe_results/

  • ForAllSecure, CMU教授David Brumley和兩個學生Thanassis Avgerinos和Alex Rebert發起的startup。
  • Shellphish,主要來自University of California, Santa Barbara,還有blue-lotus的老朋友王若愚。
  • Codejitsu, BERKELEY, CA/LAUSANNE, SWI/SYRACUSE, NY
  • CSDS,Dr. Jia Song和Dr. Jim Alves-Foss
  • DeepRed,Raytheon
  • disekt,Michael Contreras, Robert Lee Harrison, Yeongjin Jang, Taesoo Kim, Kang Li, Byoungyoung Lee, Chengyu Song, Kevin J. Warrick, Insu Yun
  • TechXicians,GrammaTech, Inc和University of Virginia

CFE在Paris Las Vegas Hotel舉行,隊伍介紹和比賽規則參見https://s3.amazonaws.com/cgcdist/cfe/cgc-final_event-cfe-brochure.pdf。運行Cyber Reasoning systems(CRS)的7組機器據說每組造價70萬美元,不同隊伍的機箱閃爍着不同顏色,引入注目。觀賞效果極佳,可視化效果構思巧妙,並非一味注重觀賞效果而忽視展示的信息量和清晰度。解說的功力也很強,現場採訪參賽選手,還能實時配上採訪選手的名字、隸屬機構。

ForAllSecure的Mayhem第一,Techxicians第二,Shellphish第三。Mayhem作爲機器選手參加接下來三天的DEF CON 24 CTF Finals。

DECREE環境

爲了便於評分、減少競爭條件、減少CTF attack and defense類比賽中不確定因素(後門、系統管理、難以自動化的瑣碎規則等)、增加確定性,CGC修改Linux源碼,採用基於x86-32的受限平臺。

內核改動

修改了Unix System V Release 4的ELF實現,把ELF文件頭從ELF改成CGC創建了一種新的可執行文件格式。不支持dynamic linking,只能static linking。

爲CGC可執行文件創建了personality,設置了ADDR_NO_RANDOMIZE禁用了地址空間隨機化,設置了STICKY_TIMEOUTS防止fdwait syscall修改時間戳參數。

執行CGC可執行文件時內核檢查命令行參數,解析seed=skiprng=max_transmit=等參數,影響隨機數、調度器和兩個I/O系統調用的最大傳輸字節數。

CGC可執行文件啓動時內核自動在0x4347c000分配一頁,填充隨機值稱爲magic page,代替了傳統attack-and-defense CTF中的flag文件。命令行參數seed=skiprng=用於決定magic page的內容,把flag的生成確定化。

設置了7種系統調用,x86-32的其他系統調用均不可用:

  • allocatemmap的包裝
  • deallocatemunmap的包裝
  • fdwaitselect的包裝
  • random,獲取隨機數
  • receiveread的包裝
  • terminateexit的包裝
  • transmitwrite的包裝

Signal的處理,SIGPIPE默認行爲SIG_IGNSIGSEGVSIGILLSIGBUS爲coredump,其他爲退出,返回值爲signal值。SEGSEGV時printk通用寄存器的值。

設置CPU的CR4寄存器禁用performance monitoring center。

修改了out-of-memory killer的行爲,優先殺死CGC可執行文件格式的進程。

工具鏈

cgc2elf把CGC executable的magic改成ELF。

strace可以顯示CGC內核的系統調用名。

clangld編譯鏈接生成CGC object file和executable,修改的部分很少,似乎只能靜態鏈接。

比賽規則

參賽選手不再控制單獨的機器。

輸入:

  • 原始可執行文件challenge binary(CB)
  • 每輪其他隊伍上傳的CB、intrusion detection system(IDS)
  • 每輪己方各CB執行時是否收到SIGSEGV等signal異常退出過
  • 指定IP和UDP端口接收packet captures,是己方CB執行時的stdin、stdout,用connection id區分不同進程

輸出:

  • 是否上傳CB、IDS,不上傳則沿用上一輪的;上傳則該輪該題得分爲0
  • 攻擊不同隊伍使用的proof of vulnerability(POV),即自動與CB交互的client程序

除了UDP端口接收的packet captures,輸入均通過HTTP API獲取。輸出也通過HTTP API提交。

比賽分爲若干輪,每一輪5分鐘。平臺會做如下事情:

1
2
3
4
5
6
for team T
for challenge C
run poller against CB(round, T, C) # service level agreement
for team T'
run POV(round, T', C) against CB(round, T, C)
# stdin/stdout are recorded and sent to 10.$id.5.2 1999/udp

然後計算每支隊伍每一道題的得分。

下面解釋CB、POV、IDS、poller。

Challenge binary

題目所用的可執行文件,原始可執行文件會特意放置一些漏洞。

平臺設置了檢測CB正確性和性能的poller generator,檢查CB的各項功能是否滿足原CB的預期行爲,否則選手可以無節制地刪除功能來移除vulnerability。Poller generator採用了類似QuickCheck的方式,構造finite state automaton表示CB執行時所處的階段,比如未登錄、已登錄、等待輸入X等,使用規則描述每個階段應產生什麼樣的I/O,隨機產生輸入餵給CB,把CB的輸出保存在變量中通過字串slice或正則表達式構造新的輸入等,判斷CB的輸出是否滿足要求。

這種checker在以往的attack-and-defense CTF中稱爲service level agreement(SLA)。CGC明確提出finte state automaton是一大進步。CGC要求poller generator至少要能產生1000000種不同的輸出,太少容易被選手檢測出特徵,寫出針對poller,剛好能實現poller檢測的功能,但本質上不正確的challenge binary。

Proof of vulnerability

每個題目,對於不同隊伍可以上傳不同的POV,並指定攻擊次數(最大爲10)。

POV是一個CGC executable,使用與CB一樣的辦法編譯鏈接。平臺會在幾個file descriptors上創建管道與其他隊伍CB進行交互。POV要與平臺進行challenge response,宣稱自己能產生Type-1或Type-2的vulnerability,平臺會給出challenge,之後與CB進行交互,如果CB如challenge崩潰或偷取到magic page即算攻擊成功,可以獲得Evaluation分數(見評分標準)。

https://github.com/CyberGrandChallenge/cgc-release-documentation/blob/master/walk-throughs/understanding-cfe-povs.md描述了proof of vulnerability。

Type 1 vulnerability:可以控制EIP寄存器的20個bits與另一個general purpose register的20個bits,與平臺協商時指出能控制哪20個bits,平臺會給出這20個bits的應有取值(challenge),讓CB崩潰後兩個寄存器的指定20 bits與平臺給出的challenge一致即攻擊成功。

Type 2 vulnerability:與平臺協商時平臺指定要讀取magic page區間的連續若干字節。與CB交互時偷取這些字節(flag)想平臺報告即攻擊成功。

Intrusion detection system

除了CB和POV外,選手還可以提交intrusion detection system規則(簡稱爲IDS),使用一種類似snort的domain-specific language描述防火牆規則,過濾CB接收的流量。

評分標準

每輪某題如果上傳CB或IDS,不得分;否則根據以下三個要素加分:

  • Security,有1和2種取值,無法被其他隊伍POV攻擊取1,被任意一個隊伍攻擊則取2。突出了防守的重要性,而以往attach-and-defense CTF中防守相對來說沒有那麼重要。
  • Availability,取0到1,通過poller的比例和內存時間開銷算分。
  • Evaluation,取1到2,爲1+可攻擊隊伍數/對手數

每道題加分爲,一輪加分爲所有題目的加分之和。當前分數爲之前所有輪的加分之和。

其他規則及策略

平臺會提供各個CB的packet captures:poller或POV兩類clients和自己的CB產生的交互。可以從流量中輔助理解CB的邏輯,揣摩vulnerability所在及POV攻擊自己的方式。

所有隊伍的CB和IDS公開。可以分析其他CRS的CB和IDS來針對性攻擊。修補CB時可以加入自己的後門:自己知道如何攻擊的漏洞,其他隊伍若抄襲,則自己可以攻破,但其他隊伍可能較難發現這一漏洞。

上傳CB會丟失當輪分數,一道題可能會更改多次CB,因此很多CRS解出一道題後選擇不上傳修補後的CB,當有其他CRS解出題後再進行修補。

修補CB可以使用通用的防禦手段,也可以發現漏洞後針對性修補。另外還可以使用別人修補的CB,照抄後還可以略作修改。

參考實現

https://github.com/CyberGrandChallenge帶有比賽採用的很多組件的源碼。

  • libcgc。類似於glibc中的syscall wrapper,也實現了部分math.h功能。
  • libpov。CFE使用C編譯、靜態鏈接成的可執行文件作爲POV。
  • network-appliance
    • cb-proxy。一個TCP proxy服務,帶有IDS的實現,可以過濾輸入。另外可以用一種自定義格式描述客戶端與challenge binary交互產生的TCP流量中的主要部分:challenge binary名稱、連接號、序列號、方向、載荷,發送到指定UDP端口。
    • cb-packet-log。把cb-proxy發送的UDP包記錄成libpcap savefile format
  • service-launcher
    • cb-server。TCP server,爲每個連接創建challenge binary進程與之交互。支持多challenge binary的多進程形式,此時會創建若干對socketpair用於進程間通信。cb-server做一些資源限制和隔離,進一步增強安全性。
  • cb-testing
    • cb-replay。使用XML格式或CGC可執行文件格式的兩類POV自動交互challenge binary。
    • cb-test。在service-launcher和cb-replay外套了層殼,讓這兩個東西交互。
  • poll-generator。

其他工具:

  • binutils
  • cgcef-verify
  • strace
  • cgc2elf
  • pov-xml2c

DEF CON 24 CTF Finals

主辦方Legitimate Business Syndicate自行實現了平臺部分模塊。

14支人類隊伍晉級決賽,CGC CFE中勝出的Mayhem作爲第15支隊伍。

  • Mayhem
  • DEFKOR
  • ESPR
  • b1o0p
  • pasten
  • HITCON
  • LCBC
  • PPP
  • Samurai
  • 9447
  • KaisHackGoN
  • binja
  • Shellphish
  • DragonSector
  • SpamAndHex

每支隊伍得到8塊badge,即只有8人能去現場,想要同時去更多人就得買badge。儘管今年現場嘈雜情況比往年改善了一些,大家還是喜歡待在酒店幹活。

以下流水帳有很多腦補成分,畢竟時日已遠。

8月2日

Riatre、firesun、我從上海出發,在Seattle轉機去Las Vegas,在Seattle遇到了blue-lotus的其他人。本次終於知道要在國內提前買好當地電話卡和附帶的流量,可惜比較晚只買到lycamobile的,信號不好,北京也租了幾個提供WiFi熱點的移動設備。

第一程長達12個小時,沒有意識到飛機上有電源插座,寫了約兩小時代碼,試圖重寫去年使用的PCAP搜索引擎中由fqj1994實現的部分:把PCAP規整爲便於檢索的形式,以及爲檢索到的內容提供多種展示類型爲漏洞利用的隊友提供便利。

今年DEF CON仍舊在Bally's Las Vegas Hotel,到達酒店後大家都很疲憊,都去休息了,想到任務在身,繼續重寫。

天有不測風雲,BrieflyX的電腦壞了。禍不單行,Riatre的筆記本電腦屏幕無法顯示,只得熟悉使用攜帶的一臺MacBook。

8月3日

libmaru和Riatre去吃Hash a Go Go。firesun和我去附近的7-11買了水,我順便去買早飯,很快不適,yuf4n隨身帶藥真厲害。

晚上大家聚在套房討論比賽分工;小花椒準備了大量二進制文件相關工具,寫了一個流量分析、重放工具;azure準備了IDA Pro使用的CGC可執行文件的IDA Pro loader(可能來自http://idabook.com/cgc/),和一些C函數庫的F.L.I.R.T signatures;neoni準備了zynamics公司出品的BinDiff,找出各隊伍上傳的challenge binary與原版的差異等,firesun把它搬到服務器rr上,hen準備了反彙編工具。

我們攜帶了一款RT-AC68U Dual Band 802.11ac Gigabit Router,放在套房內。比賽現場的網絡環境是主辦方Legitimate Business Syndicate提供的,和Bally's酒店WiFi不同,另外還需要考慮連回國內。libmaru是網管,制定了方案。酒店和國內要用CERNET2才能達到幾十Mbps的帶寬,酒店網絡沒有IPv6因此找一臺帶IPv6,兩邊帶寬延遲都不差的VPS中轉,幾經測試選擇了RamNode的Los Angeles機房。國內CERNET2選用的是浙江大學的機器,因爲沒有公網IP因此和北京長亭科技的連接通過Amazon AWS北京機房中轉。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
   (1.1.2.0/24)                    (1.1.1.0/24)
Room 898 @ Bally's CTF Room @ Paris -------- 10.?.?.? (CTF Network)
| |
Cox @ Las Vegas ??? @ Las Vegas
| |
+---------------+---------------+
|
v
VPS @ Los Angeles (OpenVPN Server)
^
| IPv6 CERNET 2 (~25 Mbps)
|
Zhejiang University
|
| China Telecom (TCP)
|
+---------------+---------------+
| |
Amazon AWS @ Beijing TBD
|
Chaitin

各種服務運行在rr上,一個去年pandada8購置的小服務器。

firesun、劉一噸yu4fn、BrieflyX等基於HTTP API開發更好用的team interface。

照例,晚上百度安全部邀請一些同行、我們吃飯。之後原來打算給我們表演無人機,後因下雨取消。

8月4日

PCAP搜索引擎重構工作完成了一部分,但根據UDP/TCP stream重組PCAP不好做,以及怕出現bug,放棄。開始寫把UDP端口接收的流量根據CB id、connection id、sequence ID重組爲IP/UDP的PCAP、PCAP轉XML格式POV等工具。

libmaru在rr上配置OpenVPN dial-in clients、systemd-networkd,我把我需要啓動的服務弄成systemd service,塞到defcon.target裏,這樣啓動就方便了。後來向lilydjwg學到一招,systemctl --user status \*.service可以查看所有服務狀態。

下午Riatre去參觀Cyber Grand Challenge final event,18:30其他人多人也去參觀,19:20 blue-lotus的人和slipper去一家自助餐廳吃飯,8人以上需要加收服務費。

8月5日

Riatre用HDMI線把筆記本電腦接到電視上操作,給我們直播逆向。

HTTP API不方便使用,主辦方另外提供了網頁版,在http://10.3.1.21/u/。爲了讓參賽隊伍熟悉環境,10:00測試賽開始,放出測試題LEGIT_00010,即https://github.com/CyberGrandChallenge/cgc-release-documentation/blob/master/walk-throughs/building-a-cb.md提到的LUNGE_00001。

我們的隊伍編號爲4,分配到一根網線,內含native VLAN與VLAN id 99。native VLAN爲比賽平臺內網,每支隊伍分配到一個10.5.id.2:1999/udp。VLAN id 99則爲外網,可以用DHCP client得到172.19.192.0/24段的IP。

我們的服務器rr連接這根網線,VLAN id 99對外配置爲10.5.4.2,連接交換機後給現場隊友的電腦作爲連接外網的路由器。使用packet-log把1999/UDP上的包整理成方便查看的IP/UDP pcap。爲防程序出錯,用iptables的NFLOG記錄原始的UDP包:

1
2
iptables -I INPUT -p udp --dport 1999 -j NFLOG --nflog-group 1
dumpcap -i nflog:1 -b filesize:102400 -b duration:300 -w a.pcapng

libmaru配置路由後很長一段時間沒有收到UDP流量,後來發現了兩個問題:配錯了iptables、沒考慮reverse path filter。

正式比賽爲15:00到20:00,期望5分鐘一輪,但主辦方的機器比較差,到第三天近10分鐘才能結束一輪。最早放出測試題LEGIT_00008,一些保護後大致執行了如下代碼:char a[32] = {}, b[256] = {}, c[256] = {}; read(0, a, 31); read(0, b, 255); sprintf(c, "%s %s", b, a);會buffer overflow覆蓋saved EBP和return address。

Round 5 DEFKOR修補了LEGIT_00008。太快了!很像是lokihardt的手筆。考慮到LEGIT_00008只輸出一次,把交互函數 epilogue恢復棧幀的指令換成push 1; push 0; jmp 0x08093f0b,0x08093f0b會設置EAX指定syscall號碼後調用int 0x80,起到強制terminate(1)的效果。

Round 7 Shellphish修補了LEGIT_00008,大意是把b讀入的最大字節數減小到222。他們修復的方式看上去像是反編譯後再重新編譯的,比原始CB多出了符號表,另外原來CB末尾附帶的PDF被移除了。

Round 9我們換上修補過的LEGIT_00008,把交互函數的棧幀調大320字節(prologue處sub esp, 0x2fc增大320),再修復幾處引用局部變量的指令。

Round 9 PPP修補了LEGIT_00008,至少做了這些事:

  • 移除了PDF
  • 合併了program header中的LOAD segments
  • 移除了section header
  • 移除了冗餘函數
  • 調整了函數的位置
  • 生成隨機canary:entry point把棧最後一個word 0xbaaaaffc的值設置爲magic page前兩個word的XOR。在函數prologue/epilogue處retaddr ^= *(int*)0xbaaaaffc;,使得難以控制EIP,保護Type 1 vulnerability
  • 可執行文件大小爲358956字節,比原始的434312字節小。

程序依然受到buffer overflow影響,但攻擊者難以獲取0xbaaaaffc的值控制return address。

Round 9 HITCON修補了LEGIT_00008。.text, .rodata所在的segment 1在CB中放置在.data .bss所在的segment 2前面。CB文件中一個page的內容同時映射給segment 1的最後一個page與segment 2的第一個page:

1
2
3
4
5
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x08048034 0x08048034 0x00060 0x00060 R 0x4
LOAD 0x000000 0x08048000 0x08048000 0x55c2f 0x55c2f R E 0x1000
LOAD 0x055bf4 0x0809ebf4 0x0809ebf4 0x1432f 0x15000 RW 0x1000

在這個page放修改過的prologue與epilogue:

1
2
3
4
5
6
7
8
9
10
11
12
13
LOAD:0809DC00                 push    ebp
LOAD:0809DC01 sub esp, 100h
LOAD:0809DC07 mov ebp, esp
LOAD:0809DC09 push ebx
LOAD:0809DC0A push edi
LOAD:0809DC0B jmp loc_80480C5

LOAD:0809DC10 pop esi
LOAD:0809DC11 pop edi
LOAD:0809DC12 pop ebx
LOAD:0809DC13 add esp, 100h
LOAD:0809DC19 pop ebp
LOAD:0809DC1A retn

在這個文件中被共享的page添上代碼,會影響segment 2,好在.data開頭的若干字節是庫函數用的,程序並沒有調用這些庫函數,這麼做不會影響正確性。HITCON在交互函數入口處jmp 0x0809dc00,在0x0809dc00(文件中被共享的page)處把棧幀增大,之後再跳轉回原函數,buffer overflow時就不會影響saved EBP和return address了。

Mayhem在Round 47修補了LEGIT_00008,和PPP的修補很像(可以理解,Mayhem開發人員與PPP隊員有交集),帶有0xbaaaaffc的canary,但是做的改動更爲激進:

  • entry point被完全重寫,添加了很多不會執行到的混淆指令;用magic page產生隨機數alloca改變ESP
  • 移除了section header:.e_shentsize = 20300, .e_shnum = 65356, .e_shstrndx = 0,內核可以執行,但binutils無法識別

Spam And Hex用的方法則是在文件末尾添加一個新的LOAD segment放置代碼,調用sprintf前檢查兩個變量ab的長度和。

15:25發現新題LEGIT_00003,是個有JIT和interpreter兩種執行模式的IBM PowerPC Gekko模擬器,azure發現是根據gekko-gc-emu修改的。

kelwin每題都會先用American fuzzy lop試試,讓我把流量中的stdin提取出來便於replay attack。

出現新題LEGIT_00007,是一個用default,base,next,check四個數組實現的Trie解析輸入,之後再用字節碼switch-threaded dispatch的計算器。帶字符串運算功能。

1
2
3
4
5
6
7
8
a:="test"
a.upper
a
<string> TEST
a:="a\tb"
a.expandtab
a
<string> a b
至少有兩處bug:

  • 0x0804cb9a處expandtab會buffer overflow
  • 形如a[i] := "A"的修改操作,0x0804c48b處下標和長度的比較使用有符號比較,指定大於等於0x80000000的下標可以越界寫任意字節,可以修改前一個變量的字串指針指向magic page,讀取該變量即可

第27輪LEGIT_00008又有SIGSEGV了,沒搞懂爲什麼會SIGSEGV(應該是平臺的隨機事件)第49輪換上了類似於DEFKOR的新補丁。

15:42 jackyxty搞出了expandtab的Type 1 POV。小花椒弄了a[i] := "A"的Type 2 POV,kelwin之後也弄了一個很複雜的POV。

18:10 slipper寫了一個LEGIT_00003 POV。

Round 9升到了第2名,但後來又跌到第5名,Round 19又上升到第4名一段時間,之後穩定在第5名。下午kelwin老馬失蹄,修補時把POV提交成CB了。

20:00第一天比賽結束,Round 59。kelwin的學弟陳羽北給我們準備了晚飯。感謝他幾天來給我們的後勤支援。0ops好多隊友先躺着睡了一會兒,隔了幾個小時後相繼爬起來繼續分析。

8月6日

slipper在弄LEGIT_00003的POV。azure用coverity分析了gekko-gc-emu,xky準備了用流量測試CB的工具。6:00之後kelwin、小花椒、jackyxty、memeda弄了LEGIT_00007幾個版本的POV。

主辦方昨日平臺有問題,似乎每一輪都要上傳POV,而不會複用上一輪的。今天根據昨天的數據重新演算了各隊分數,我們變成了第四名。開賽時主辦方沒調試好,rollback到Round 58,hotfix,沒改好,又rollback數次。照往年慣例,今天只顯示排名。

10:00開賽後分析各隊上傳的CB,針對性地選擇合適的POV。很快我們升到了第3名。

Round 65約11:10發現新題LEGIT_00004,內存中的文件系統,參看https://blog.forallsecure.com/2016/08/10/case-study-legit_00004/,通過buffer overflow修改棧上保存的EBP,進而修改返回地址。

12:08 xky發現了有人用LEGIT_00004的明顯的Type 2 vulnerability攻擊我們:新建文件系統初始化文件時會讀取magic page,makefs命令後接list就能讀取,jackyxty 12:16把流量轉成了POV。

13:00發現我們修補的LEGIT_00007 overhead很高,研究其他隊伍的patch。Riatre說DEFKOR一直在上傳新的patch。後來發現PPP的patch在用損壞功能的方式patch,針對它寫POV。

LEGIT_00007都能攻擊全場,LEGIT_00003能打10多支隊伍。

libmaru做了一個Slack bot,檢測dashboard網頁變化,當有隊伍修補CB時進行提示。於是我也開始弄關於分數變化的bot,把分數以外的其他數據也抓取下來。

TODO 13:52 samurai free条件。 注意到PPP的CB不能用a[0] := "A",扣功能分但是不会被攻击。

Round 94(約14:16)關閉了LEGIT_00008。

14:51發現新題LEGIT_00006,是個實現C部分功能的編譯器。binja 約round 101迅速修補。PPP Round 119上傳了CB,一如既往,打亂了函數位置,很難分析。DEFKOR Round 119也上傳了一個NOP掉函數的CB,Round 123我們採納了,後來改爲修改棧幀大小。这是libmaru把LEGIT_00004的文件系统结构题逆向得差不多了。

Round 127終於重新回到第2名。

快結束時出現新題LEGIT_00001,四個進程的網絡協議題。Round 134(約19:01)就發現有SIGSEGV。

Round 136(約19:20)後關閉了LEGIT_00007。

jackyxty、memeda在找隨機C程序生成工具,riatre在逆向,16:00多就發現有Type 2 POV,之後發現DEFKOR的patch抄了過來,18:00多又發現DEFKOR的patch擋不了新的攻擊。pidgenx也加入進來分析。

20:00第二天比賽結束。第二天比賽只有4小時,套房裏瀰漫着通宵的氣氛。

8月7日

Las Vegas 3點鐘

好多人都在做LEGIT_00006。Riatre回房睡了很久,2:00多衝進套房說“睡覺真耽誤時間”然後開始逆向LEGIT_00006。僞隨機數生成、singly-linked list、仿stringstream、詞法分析直接調用的一些函數,逆向難度非常大。 libmaru在寫LEGIT_00001的POV。

小花椒睡到兩三點起來,因爲負責各種CB的修補,責任重大:“椒哥你現在睡了我們就完了。”

我把之前給kelwin提供的單向stdin改了改,把stdin/stdout都提取出來了。另外寫了個ptrace檢測部分Type 1/2 vulnerability。這個東西應該早點做的,因爲多數題目都沒用到隨機數。

6:00多小花椒修補了LEGIT_00004,之後我用已有流量測試了一下,似乎沒問題。

8:00 kelwin說LEGIT_00006是堆溢出。

10:00比賽開始,照例今天不顯示積分榜。每個Round的時間顯著增長。

Round 139,memeda試了4個POV,發現9447、Shellphish、DEFKOR都打不了,似乎是修補了。比賽最後4小時,大家把更多的注意力放到replay attack上面。這時候各種工具總算齊備了,可惜LEGIT_00006還是不知道怎麼做。發現了一種POV可以replay,但是成功率低於10%。

12:00小花椒把LEGIT_00004翻新了。

LEGIT_00001的POV發現只能打三四支隊伍,後來又換libmaru的 約10:26出現新題LEGIT_00009,是一個CD和tracks管理程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
for(;;)
switch (read_int()) {
case 0: // show the flag magic hash and exit
case 1: // add a track
case 2: // list tracks
case 3: // unknow command
case 4: // feedback
case 5: // play cd
case 6: // show the flag magic hash
case 7: // fix the cd's real name
case 8: // fix the track's real name
case 9: // destory cd
}

hen指出destory cd之後還能fix the track's real name,可能有use after free。

0x08052150到0x0805f7ed有個54941字節的巨大函數。seabreeze指出增大sub esp棧幀大小後可以用Hex-Rays Decompiler反編譯,生成12158行C。

10:40 kelwin用American fuzzy lop構造出了可以讓程序SIGSEGV的輸入,但沒找到利用方式,給強隊throw了假POV產生SIGSEGV混淆。

12:00關閉了我們具有巨大優勢的LEGIT_00003。

12:10出現新題LEGIT_00002,memeda和jackyxty在搞,很快發現POV流量,0x08048f89處似乎有sprintf buffer overflow。Round 157 Shellphish在prologue/epilogue把return address XOR一個值修復buffer overflow。

13:26左右我們試圖修LEGIT_00002,增大棧幀。引用變量的地方有兩處lea ecx, [ebp-0x45],佔3個字節,偏移調大超過int8_t範圍後需要5字節,改壞了。

14:00比賽結束,定格在Round 163。我們最後第2名,參見https://blog.legitbs.net/2016/09/2016-def-con-ctf-final-scores.html

Team Final Score
PPP 113555
b1o0p 98891
DEFKOR 97468
HITCON 93539
KaisHack GoN 91331
LC↯BC 84412
Eat Sleep Pwn Repeat 80859
binja 80812
pasten 78518
Shellphish 78044
9447 77722
Dragon Sector 75320
!SpamAndHex 73993
73368
Mayhem 72047

其他

明年DEFCON CTF將採用custom architecture和custom operating system了。

機器選手Mayhem有些可惜,比賽前兩天他們收到的流量似乎都有問題。後來才發現DEF CON CTF Finals用的平臺和CGC CFE不同,第三天收到流量,據說9個CB找出了7個exploit、修補了6個。如果來場公平的較量也許能碾壓人類。

可以去Reddit /r/IAmA圍觀Mayhem:https://www.reddit.com/r/IAmA/comments/4x9yn3/iama_mayhem_the_hacking_machine_that_won_darpas/

  • symbolic execution
    • fine-tuned process-based instrumentation and taint analysis
    • access to an extensive set of tested x86 semantics
    • several years of performance tuning for solvers (expression rewriting, caches, etc)
    • path merging

共享CB給比賽帶來了新的玩法,像PPP就給自己的CB都塞了後門。從前不知道大家怎麼修補executable的,今年是個好機會,學到了很多招數。

Shellphish把他們用的很多東西開源了:https://github.com/shellphish

我在現場寫的一些代碼:https://github.com/MaskRay/DEFCON24CTFFinalsAdmin

8月8日

遭遇Delta Air系統故障,滯留在Las Vegas一天半,其他隊友也滯留0~2天不等,Las Vegas algorithm:最終我們都能離開,但消耗的資源不確定。10日3:00多才離開機場T_T。感謝各位高中同學、大學同學、學長,之後一路蹭吃蹭住在San Francisco Bay Area、New York City、Boston、Cambridge、Jersey City輾轉混了十幾天。

參考