看雪CTF 2017 比賽進行至第十五題
截止至今天中午12點,第十五題破解人數為 9 人!
防守方 hsadkhk 依然位居首位~
今天是最後一題,攻擊方風間仁![看雪.WiFi萬能鑰匙 CTF 2017第十五題 點評及解題思路](https://i.iter01.com/images/458eb697cbefc6713fade299b4a378d68d6c3c0f681287fd5fb7333deb70d9f1.png)
處於第一位~,kkHAIKE位列第二位。
![看雪.WiFi萬能鑰匙 CTF 2017第十五題 點評及解題思路](https://i.iter01.com/images/49a07351fc6a3bef865879db09f99336a87715954e7cea9e6fb92c4382a6adc8.png)
比賽至此告一段落了,
比賽的最終結果,請大家持續關注!
接下來我們來回顧一下第十五題
看看 看雪評委和出題者是怎麼說的ヾ(๑╹◡╹)ノ"。
題目中的VM是作者設計的一個全新的VM,體積雖小,五臟俱全。VM功能包括反除錯、反虛擬機器、反 API 斷點、匯入表保護、OEP 抽取,程式碼虛擬化、程式碼亂序、程式碼拆分、程式碼混淆;攻方需瞭解vm的基本知識,識別出各條handler,然後根據各handler序列分析出整個流程;作者同時採用lua指令碼來進行程式碼保護,攻方還需掌握lua反編譯知識;在演算法上採用了簡單的異或演算法。此題重在考察選手VM分析能力和LUA反編譯能力。
一、設計思路
一個專業實用的保護系統應該不僅能防 keygen 還應該能防爆破防程式碼分析
縱觀當前市面上最好的幾款保護,使用的技術皆為 RSA 演算法+程式碼虛擬化保護,這是當前最流行,最強的軟體保護技術。
題目設計主要考察分析vm的能力,所以不使用複雜的演算法,只進行了簡單的異或。
根據去年CTF時各位大牛寫的分析文章,對VM的弱點進行了修補,增強了VM的強度。
吸收去年CTF其它守護方的設計思路,結合lua指令碼,實現雙虛擬機器保護。
二、設計亮點
1、一個體積雖小,五臟俱全的新VM,非市面上已經被N多人分析過的VM,需要攻擊者重新分析,考察分析VM的基本功。
vm實現的功能:反除錯、反虛擬機器、反 API 斷點、匯入表保護、OEP 抽取,程式碼虛擬化、程式碼亂序、程式碼拆分、程式碼混淆。
2、結合 lua 指令碼,使用自寫虛擬機器+lua虛擬機器,實現雙虛擬機器保護。
考察攻擊者的 lua 反編譯知識。
3、不用使複雜演算法,避免演算法分析。
三、破解思路
1、由於本題只是對輸入進行了簡單的異或判斷,所以無需費力氣分析演算法,只要把 vm 流程,各個 handler 分析清楚,找到異或的 key 即可。目前殼處理的指令還比較少,混淆模式也比較簡單,所以要理清楚並不難,只是由於大家都第一次接觸到此 VM,所以可能需要花點時間。
2、本題演算法較簡單,主要難點在分析VM和反編譯lua指令碼上
3、分析vm要求大家瞭解vm的基本知識,vm的整體框架,流程,然後區分出花掉令和正常的指令,去掉花指令,保留正常指令,識別出各條handler,然後根據各handler序列分析出整個流程
4、反編譯lua需要找到lua位元組碼並儲存下來,然後使用網上的方法,進行反編譯,這裡的難點在於找到 lua_loadbuffer的地址,在此函式裡把位元組碼dump下來即可
四、其它說明
1、CrackMe使用vs2008編譯,已在xp,win7 32、 win7 64系統上測試功能正常
2、CrackMe使用自己實現的虛擬機器BBProtect加密,之前未曾發在網上,複合題目要求
3、BBProtect 程式在已放到 BBProtect目錄裡
4、由於加了vm,所以殺軟軟體可能會報毒,cm沒有任何惡意功能,可放心執行
使用工具:IDA6.8(反彙編分析) python(程式設計解碼) OD(動態除錯)
步 驟:
一、定位關鍵程式碼
該程式有加殼,但對主要流程影響不大,難點在於分析luajit程式碼,定位主要流程。只要流程清晰了,該題沒有難度,只是簡單異或運算。
(1)脫殼
其實也不算真正脫殼,其實就是等程式執行起來後,dump記憶體映象。
這樣在IDA中可以分析解密後的函式和解密後的字串,如下圖
(2)定位關鍵點
從IDA的字串視窗可以看到該程式使用了LuaJIT 2.1.0-beta3 且Lua版本號為Lua 5.1。
通過“main”(呼叫Lua的main函式)關鍵字在IDA中定位到如下位置。
其上面從0040103D開始的一大段mov指令實際是在棧中生成了一個luajit的bytecode。
二、解密
function randomFunction by (INPUT_VAR_0_,INPUT_VAR_1_)
var_0_4 = INPUT_VAR_0_
var_0_5 = INPUT_VAR_1_
var_0_6 = INPUT_VAR_1_
string.byte( string.sub(var_0_4, var_0_5, var_0_6) )
end
function randomFunction main (INPUT_VAR_0_)
var_1_2 = INPUT_VAR_0_
var_1_1 = string.len(var_1_2)
if var_1_1 ~= 0 then
--jump to 0009 (if previous if statement is false) --0009 JMP-JMP
var_1_1 = 0 --var_1_1 NUMBER-NUMBER
return var_1_1
end
var_1_3 = INPUT_VAR_0_ key[0]
var_1_4 = 1 --var_1_4 NUMBER-NUMBER
var_1_2 = by(var_1_3, var_1_4) key[1]
var_1_3 = 112 --var_1_3 NUMBER-NUMBER
var_1_1 = bit.bxor(var_1_2, var_1_3) key[1]^112
var_1_4 = INPUT_VAR_0_
var_1_5 = 2 --var_1_5 NUMBER-NUMBER
var_1_3 = by(var_1_4, var_1_5) key[2]
var_1_4 = 101 --var_1_4 NUMBER-NUMBER
var_1_2 = bit.bxor(var_1_3, var_1_4) key[2]^101
var_1_5 = INPUT_VAR_0_
var_1_6 = 3 --var_1_6 NUMBER-NUMBER
var_1_4 = by(var_1_5, var_1_6) key[3]
var_1_5 = 100 --var_1_5 NUMBER-NUMBER
var_1_3 = bit.bxor(var_1_4, var_1_5) key[3]^100
var_1_6 = INPUT_VAR_0_
var_1_7 = 4 --var_1_7 NUMBER-NUMBER
var_1_5 = by(var_1_6, var_1_7) key[4]
var_1_6 = 105 --var_1_6 NUMBER-NUMBER
var_1_4 = bit.bxor(var_1_5, var_1_6) key[4]^105
var_1_7 = INPUT_VAR_0_
var_1_8 = 5 --var_1_8 NUMBER-NUMBER
var_1_6 = by(var_1_7, var_1_8) key[5]
var_1_7 = 121 --var_1_7 NUMBER-NUMBER
var_1_5 = bit.bxor(var_1_6, var_1_7) key[5]^121
var_1_8 = INPUT_VAR_0_
var_1_9 = 6 --var_1_9 NUMBER-NUMBER
var_1_7 = by(var_1_8, var_1_9) key[6]
var_1_8 = 49 --var_1_8 NUMBER-NUMBER
var_1_6 = bit.bxor(var_1_7, var_1_8) key[6]^49
var_1_9 = INPUT_VAR_0_
var_1_10 = 7 --var_1_10 NUMBER-NUMBER
var_1_8 = by(var_1_9, var_1_10) key[7]
var_1_9 = 50 --var_1_9 NUMBER-NUMBER
var_1_7 = bit.bxor(var_1_8, var_1_9) key[7]^50
var_1_10 = INPUT_VAR_0_
var_1_11 = 8 --var_1_11 NUMBER-NUMBER
var_1_9 = by(var_1_10, var_1_11) key[8]
var_1_10 = 7 --var_1_10 NUMBER-NUMBER
var_1_8 = by(var_1_9, var_1_10) key[8]^51
var_1_11 = INPUT_VAR_0_
var_1_12 = 9 --var_1_12 NUMBER-NUMBER
var_1_10 = by(var_1_11, var_1_12) key[9]
var_1_11 = 52 --var_1_11 NUMBER-NUMBER
var_1_9 = bit.bxor(var_1_10, var_1_11) key[9]^52
var_1_12 = INPUT_VAR_0_
var_1_13 = 10 --var_1_13 NUMBER-NUMBER
var_1_11 = by(var_1_12, var_1_13) key[10]
var_1_12 = 53 --var_1_12 NUMBER-NUMBER
var_1_10 = bit.bxor(var_1_11, var_1_12) key[10]^53
var_1_13 = INPUT_VAR_0_
var_1_14 = 11 --var_1_14 NUMBER-NUMBER
var_1_12 = by(var_1_13, var_1_14) key[11]
var_1_13 = 54 --var_1_13 NUMBER-NUMBER
var_1_11 = bit.bxor(var_1_12, var_1_13) key[11]^54
var_1_14 = INPUT_VAR_0_
var_1_15 = 12 --var_1_15 NUMBER-NUMBER
var_1_13 = by(var_1_14, var_1_15) key[12]
var_1_14 = 55 --var_1_14 NUMBER-NUMBER
var_1_12 = bit.bxor(var_1_13, var_1_14) key[12]^55
var_1_13 = var_1_1
var_1_14 = var_1_2
var_1_15 = var_1_3
var_1_16 = var_1_4
var_1_17 = var_1_5
var_1_18 = var_1_6
var_1_19 = var_1_7
var_1_20 = var_1_8
var_1_21 = var_1_9
var_1_22 = var_1_10
var_1_23 = var_1_11
var_1_24 = var_1_12
return var_1_13, var_1_14, var_1_15, var_1_16, var_1_17, var_1_18, var_1_19, var_1_20, var_1_21, var_1_22, var_1_23, var_1_24
end
function someFunc2()
require("bit")
local randomFunction0 = function() end -- starts at test.lua:0
by = randomFunction0
local randomFunction1 = function() end -- starts at test.lua:0
main = randomFunction1
return
end
我們主要關注其中的main函式,上面已經用c語法註釋出來。其實就是對輸入分別與下面這一串異或,返回結果。
[112,101,100,105,121,49,50,51,52,53,54,55]
接下來0040222C處的程式碼取得lua輸出的每一個值分別與下面這一串值異或。
[0x5,0x12,0xa,0x29,0x42,0x41,0x75,0x61,0x35,0x83,0x55,0x94]
接下來004022F0處,異或後的值分別與下面著串值比較,相等則註冊成功。
[0x18,0x16,0x1e,0x2f,0x48,0x11,0x21,0x37,0x33,0x86,0x52,0x94]
那麼python編寫如下程式碼,即可得到真正註冊碼“maposafe2017”。
a = '000000000000'
b = [112,101,100,105,121,49,50,51,52,53,54,55]
c = [0x5,0x12,0xa,0x29,0x42,0x41,0x75,0x61,0x35,0x83,0x55,0x94]
d = [0x18,0x16,0x1e,0x2f,0x48,0x11,0x21,0x37,0x33,0x86,0x52,0x94]
al = len(a)
a1 = list(a)
for i in range(al):
a1[i] = chr(b[i]^c[i]^d[i])
print ''.join(a1)
全文完,註冊碼“maposafe2017”。
最後感謝 WiFi 萬能鑰匙安全應急響應中心的贊助支援,
接下來的比賽大家一定要使出洪荒之力哦!↖(^ω^)↗
比心 ❤
上海連尚網路科技有限公司成立於 2013 年,是一家專注於提供免費上網和內容服務的移動網際網路企業。連尚網路自主研發的核心產品 WiFi 萬能鑰匙,以分享經濟的模式,通過雲端計算和大資料技術,利用熱點主人分享的閒置WiFi資源,為使用者提供免費、穩定、安全的上網服務,以幫助更多的人上網,找到屬於他們的機會,改變自己的命運。
往期熱門內容推薦
更多比賽詳情,長按下方二維碼,“關注看雪學院公眾號”檢視!
![看雪.WiFi萬能鑰匙 CTF 2017第十五題 點評及解題思路](https://i.iter01.com/images/3e8e8c349f028d9f099d1b7c27c71110b2804204b3d63f4b7139838b23728501.jpg)