加入我們,一起探討ctf比賽的樂趣!
CTF大賽
最近,京東安全與安全界的“黃埔軍校”看雪論壇合作舉辦了一場線上CTF大賽,吸引了近3萬人參與。其中,參與解答“京東ai CTF大挑戰特別題”的選手有1435人,最終僅有2人成功破解。
解題報告一這是一道非常有趣的題目,成功激發了我的興趣。盡管我的解法可能不一定是最佳的,但仍希望與大家分享。
一、審題下載附件,解壓文件,仔細審題。
1、題目
題目給出了一系列二進制序列的十進制數,共200個數。要求使用機器學習模型判斷這些數是否為函數入口,如果是則標記為1。然而,目前模型輸出的全是0,缺少唯一的一個1。
2、h5文件
這是keras的模型文件,可以通過load_model加載。
2、x32dbg調試器
3、Anaconda3
4、Keras(在Windows下通過pip安裝Keras主體沒有問題,但可視化部分有缺陷,暫不使用)
5、vscode編輯器
三、手工分析數據題目說明了兩百個樣本點是“二進制代碼”,但數據經過處理,數值在1到256之間。特別是多次出現的256,不在正常的0x00到0xff范圍內,因此推測手工分析數據時應全部減1。
處理數據后,輸出為可復制粘貼的格式:
結果:
將處理后的數據復制到x32dbg中查看:
發現代碼已經可讀,位置40(從0開始計數)對應于sub esp,C的指令,符合題目對函數入口的要求。相比其他ret片段,前幾段較短且不涉及esp(0x83)的代碼不在題目要求范圍內,后幾段只有add esp的代碼顯然不是正常函數。
推測:題目要求的“函數入口”需要局部變量的堆棧平衡操作,特征以0x83為主。
四、模型分析
模型包含三層網絡,最后輸出200*2的結果。將題目樣本輸入模型,查看結果:
其中0.999999是我在觀察輸出后選擇的閾值,因為大多數值都接近1。
可以看到,只有位置40的概率相對較高,但未超過0.5。另外注意到,0x31對應xor指令,0xb8對應mov指令。
五、目標推測可以看出模型的問題在于1的置信度不足,也就是說,原始樣本中的0太多,需要更多1的樣例來確定這是“函數入口”。
因此,基于原始樣本改造訓練樣本的思路就形成了。在訓練集中增加符合題意的1,我在位置168添加了一個函數入口:
轉換回數據后進行訓練:
這次對原始樣本的預測結果:
結果滿足要求,只有一個位置的概率大于50%,并且是正確的位置。
至此,題目按我的理解應該通過了。
六、優化1、構造的數據集可以有更多組合來避免一些誤判,如調換add和sub的順序,降低mov的命中概率等;
2、優化器完全是默認的,還沒有進行觀察和改造。這部分就不深入研究了。
解題報告二前段時間我也在思考能否將熱門的AI技術與CTF比賽結合起來,沒想到就發現了這道題,感覺非常有趣。
一、題目解析首先,仔細閱讀題目。發現模型使用深度學習來檢測一段二進制代碼中是否存在函數入口,如果存在則將入口點標記為1,否則為0。題目要求我們對模型進行微調,使其能夠識別出一段不能識別的二進制代碼的入口點。簡單來說,我們需要構造一些樣本,重新訓練模型,使其能夠識別給定樣本的函數入口點,同時保證非入口點也能正確識別。題目提供了模型文件和樣本點兩個數據。
接著,我們需要查看模型是使用什么框架生成的,檢查模型文件的二進制代碼,發現是hdf文件:
使用Python的h5py工具解析,發現模型是基于Theano工具的Keras框架生成的,使用的是rnn算法:
代碼:
之后使用Keras自帶的模型繪制接口,將模型結構圖打印出來:
代碼:
知道了模型使用的框架,之后重新訓練模型就非常方便了。
再來看看樣本點:觀察發現,一段正常的二進制代碼應該存在很多個0,而樣本點存在很多個1且沒有0,同時單字節存在幾個256(單字節最大應該只有255),所以這里的二進制代碼是經過加1運算后的代碼,我們通過減1再進行反匯編,看看函數的入口特征:
題目提示說,這一段代碼的函數入口點是在下標為40的點,也就是上面所示的0048E028地址的sub esp,0xC這一句。函數的入口點模型無法識別,這個函數反編譯后的結果其實是一個switch結構,類似如下:
題目解析到這里,接下來說說如何解答。
二、解題方法首先,我們將樣本點輸入到模型中,看模型預測的結果,發現每個點輸出一個包含2個元素的向量,第1個表示不是入口點的概率,第2個表示是入口點的概率。
從輸出的結果可以看出,除去第40個點的概率是[0.722,0.278],其他基本都是[1,0],說明模型差一點就能識別出函數的入口點,而其它的點也沒有識別錯誤。
模型預測的結果:
那么,最簡單的辦法就是將樣本點隨便改改,然后輸入到模型重新訓練,應該就能識別。(這里題目沒有要求模型需要保證在原始的樣本中保持某一個準確度)
我這里將樣本點的第0個點50改成49,也就是將第一句的xor eax,eax改成xor al,al,作為模型的一個訓練樣本,使用SGD作為優化方法,參數學習率lr=0.0001,動量momentum=0.9,使用了10次迭代,并且凍結除RNN的其他層,再重新訓練,結果如下:
代碼如下:
>>>> 三、結束語感覺這道題的逆向要求不是很高,然后深度學習算法的要求也不是很高,但是兩者結合起來感覺挺有意思的。不過,沒有其他限制的話,模型是可以過擬合的(只識別一個提供的樣本點),為了避免模型過擬合,主辦方其實可以提供一些樣本,要求新的模型在這些樣本下也能夠保持準確度。