看雪CTF.TSRC 2018 團隊賽 第十一題『伊甸園』 解題思路

Editor發表於2018-12-23

看雪CTF.TSRC 2018 團隊賽 第十一題『伊甸園』 解題思路


第十一題《伊甸園》在今天(12月23日)中午12:00 結束攻擊!僅4支團隊攻擊成功,其中,金左手 以48489s 攻速奪得本題第一名!


本題結束後,防守團隊排行榜如下:


看雪CTF.TSRC 2018 團隊賽 第十一題『伊甸園』 解題思路



最新賽況戰況一覽


第十一題之後,攻擊方最新排名情況如下:


看雪CTF.TSRC 2018 團隊賽 第十一題『伊甸園』 解題思路


中午放題搬磚狗哭哭 依然在Top 10 的首席座位,AceHub下降一名至第五名,萌新隊上升一名至第四名,其他排名不變。


距離比賽結束,僅剩4題,潛力團隊是時候登場了!來“hack"這個局勢吧!


第十一題 點評


crownless:

“伊甸園”此題涉及到了數學中的微分和積分知識,但不完全是單純的微積分,還要求破解者利用數學基礎知識對反編譯程式碼化繁為簡,並結合Base62編碼求出最終答案。



第十一題 出題團隊簡介


出題團隊: CR_Reborn 


夏娃吃了蘋果後,發現吃虧了,於是想報復蛇

她摘了一個蘋果,掰開蛇的口,硬塞了進去

蛇開始發生蛻變

蘋果經過之處,或延長,或縮短,或複製,或變異,或新生,或消失

......

一切過去之後,一具受到懲罰的蛇屍擺在了伊甸園裡

它原本長什麼樣?已經變得印象模糊了

夏娃害怕了後悔了,但已無力挽回

這時亞當說,能把蛇復原的,唯有上帝的神力


看雪CTF.TSRC 2018 團隊賽 第十一題『伊甸園』 解題思路



第十一題 設計思路


由看雪論壇ElssZion 原創


看雪CTF.TSRC 2018 團隊賽 第十一題『伊甸園』 解題思路


題目答案:


BpLDc1LExvZywqLC0sUG9A3ZXJfYXgsMjMsLSxQb3dlcl9A4YSwrLExvZyxQb3dlcl9AheCw5MCxMb2c


這道題的設計思路,取自《孫子兵法·謀攻》


孫子曰:夫用兵之法,全軍為上,破軍次之。是故百戰百勝,非善之善也;不戰而屈人之兵,善之善者也。故善用兵者,屈人之兵而非戰也,此謀攻之法。知可以戰與不可以戰者勝,識眾寡之用者勝。此知勝之道也。


我們的程式裡儲存著一個殘缺的數學函式 f,還有一個數學函式 g;


破解者輸入的資料會用於補全 f;


如果 f 的微分結果 與 g 相匹配,解題成功,這時程式會輸出字串,告知破解者已破解成功。


下面,我們給出正確的積分過程和每個步驟所應用的數學公式:


《恢復輔助項》和《積分步驟》這2個檔案詳細描述了從 g 推匯出 f 的過程。


其中,每個步驟所使用到的數學公式 被記錄在了《恢復依據公式》和《積分依據公式》2個檔案中。


正確的積分結果 f 記錄在《公式》中。


f 經過 base62 編碼的結果儲存在 《編碼後公式》 中。


為了補齊 f 所需的正確輸入序列號 記錄在 《key》 中。


祝大家破解順利!



原文連結:

https://bbs.pediy.com/thread-248030.htm



第十一題  伊甸園 解題思路


本題解析由看雪論壇 kkHAIKE原創。


看雪CTF.TSRC 2018 團隊賽 第十一題『伊甸園』 解題思路


程式流程


用 IDA 分析程式,流程如下


全域性類初始化表部分:

1、以 10000 位元組為分割初始化了7段表示式,最後匯成最終表示式 F;

2、初始化三段字串 enc0(1000) enc1(8000) enc2(8335)。


主函式部分:

1、讀入輸入 ipt,合成 enc = enc0 + ipt + enc1 + enc2,校驗長度 17415;

2、用 Base62[^1x] 解碼,得到表示式 f,校驗長度 12715;

3、解析 f,得到由 CTreeNode 組成的 tree(PS:後文有類似解析程式碼);

4、執行了某種運算,再準備硬啃時,經過隊友 新手慢慢來 提點,推斷出應該是 微分(求導)、化簡 過程。


看雪CTF.TSRC 2018 團隊賽 第十一題『伊甸園』 解題思路

5、將微分結果輸出成字首表示式 f_,與 F 對比;

6、用 StrCheck 校驗 enc(PS:不影響解題,可能是為了確保唯一解加的)。


長度分析:

1、enc0 + enc1 + enc2 長度 17335,所以 ipt 長度 17415 - 17335 = 80;

2、enc0 直接解 b62 會報 pad 錯誤,多餘 2 位元組,令 dec0 = b62dec(enc0[:-2]),長度 726;

3、根據多餘的 2 位元組分析,接下來應該是 ',x,' 或 ',pi,';

4、enc1_2 多餘第一位元組,令 dec2 = b62dec(enc1_2[1:]),長度 11929;

5、根據多餘的 1 位元組分析,前面是 ',',從內容看也是;

6、所以剩下 12715 - 726 - 11929 = 60,令這一部分為 code,其以 ',x,' 或 ',pi,' 開頭,以 ',' 結尾。

[^1x]: Base62:網上沒有標準,是一種為了 URL 而存在的 Base64 改進型,替換了 URL 敏感的 '+' '/' 符號,本實現具體為 '+'->'9B' '/'->'9C' '='->'9D' '9'->'9A'



字首解析


先上解析程式碼


with open("yidian.exe", "rb") as f:

f.seek(0x3cc18)

func = f.read(10000)

f.seek(0x3f330)

func += f.read(10000)

f.seek(0x41A60)

func += f.read(10000)

f.seek(0x44188)

func += f.read(10000)

f.seek(0x468a8)

func += f.read(10000)

f.seek(0x48fc8)

func += f.read(10000)

f.seek(0x4b6e0)

func += f.read(4875)

f.seek(0x4c9f0)

enc0 = f.read(1000)

f.seek(0x4cdf8)

enc1_2 = f.read(8000) # 組合 enc1 + enc2

f.seek(0x4ed40)

enc1_2 += f.read(8335)

class Node:

def __init__(self, s):

self.left = self.right = None

self.val = s

if s in ["+", "-", "*", "/", "Power_xa", "Power_ax", "Log", "Sin", "Cos"]:

# 運算子

self.type = 1

elif s in ["x", "e", "pi"]:

# 未知數和常數

self.type = 2

else:

# 立即數

self.type = 0

# 運算子求目

def opernum(self):

if self.type != 1:

raise Exception("not oper")

if self.val in ["Sin", "Cos"]:

return 1

return 2

# 轉字首表示式

# 最後的結果要去除最尾逗號

def __str__(self):

if self.type == 1:

if self.opernum() > 1:

s = "{},{}{}".format(self.val, self.left, self.right)

else:

s = "{},{}".format(self.val, self.left)

else:

s = self.val + ","

return s

# 轉中間表示式

def mid(self, n, m):

# 深度限制

if n == m:

return "j"

if self.type == 1:

if self.val in ["+", "-", "*", "/"]:

s = "{} {} {}".format(self.left.mid(n+1, m), self.val, self.right.mid(n+1, m))

elif self.val in ["Power_xa", "Power_ax"]:

s = "{} ^ {}".format(self.left.mid(n+1, m), self.right.mid(n+1, m))

elif self.val == "Log":

s = "log({}, {})".format(self.left.mid(n+1, m), self.right.mid(n+1, m))

else:

s = "{}{}".format(self.val.lower(), self.left.mid(n+1, m))

else:

s = self.val

return "(" + s +")"

pfunc = func

def parseinit(s):

global pfunc

pfunc = s

def parse(parent):

global pfunc

if pfunc is None:

return

idx = pfunc.find(",")

if idx != -1:

x = pfunc[:idx]

pfunc = pfunc[idx + 1:]

else:

x = pfunc

pfunc = None

n = Node(x)

if n.type == 1:

# 若是運算子則遞迴解析

parse(n)

if parent is not None:

if parent.left is not None:

if parent.right is not None:

raise Exception("must die")

else:

parent.right = n

else:

parent.left = n

if parent.type == 1 and parent.opernum() > 1:

# 雙目則繼續右邊

parse(parent)

return n

import base64

def b62dec(b):

b = b.replace("9D", "=").replace("9C", "/").replace("9B", "+").replace("9A", "9")

return base64.b64decode(b)

def b62enc(b):

b = base64.b64encode(b)

return b.replace("9", "9A").replace("+", "9B").replace("/", "9C").replace("=", "9D")


微積分


從流程上看,好像關鍵就是求這個 微分 的逆轉了,好像對 F 求積不就拿到 f 了嗎?


其實這是作者故意給出的陷阱,不過同時,作者也給出了糖果:


1、仔細分析表示式 f 以及 F,發現第一位元組(最外層運算子)均為 ‘/’(除法);

2、令 f = u / v;

3、結合除法的求導公式;

看雪CTF.TSRC 2018 團隊賽 第十一題『伊甸園』 解題思路

4、你會發現其實 f_(也就是 F)中,是包含原 f 組成部分 u v 的;

5、使用程式碼驗證設想並輸出原始 u v。


def check_uv():

tree = parse(None)

# 先輸出至多 3 級表示式

print tree.mid(0, 3)

# 輸出

# (((j * j) - (j * j)) / ((j * j) ^ (2)))

# 滿足求導公式

# 進一步驗證滿足條件,分子中的 v 與分母中的 v 相等

assert str(tree.left.left.right) == str(tree.right.left)

u = tree.left.right.left

v = tree.right.left

# 輸出 u v

print str(u)[:-1]

print str(v)[:-1]


這麼一來,微積分到此結束。


化簡求繁


從上一章看,好像提取出 u v 就能直接得出 f 了,其實不行,具體就是從原始的 dec2 中搜不到 v


那麼,定義上章獲得的為 u_ v_


從 dec0(以原 u 開頭) 和 u_ 對比來看,發現 dec0 到 u_ 進行了一種化簡(還好 dec0 短,全手動),具體如下:


1、*,Log,x,x, log(x,x) 為 1,所以這一段可以直接搜尋全刪;

2、剩下的Log,x,x替換為 1;

3、+,g(x),g(x) 化簡為 *,g(x),2;

4、*,g(x),g(x) 化簡為Power_xa,g(x),2。


將得到的 dec0_ 與 u_ 對比,得到 code 的開頭處,為 ',pi,' 與之前的推理一致。


將 dec2 替換*,Log,x,x,,分析 dec2 與 code 開頭處部分(關鍵字 38,故意調整了對齊)。


看雪CTF.TSRC 2018 團隊賽 第十一題『伊甸園』 解題思路


得到要補充的部分,剛好 60 位元組

code = ",pi,75,Log,*,-,Power_ax,23,-,Power_xa,+,Log,Power_ax,90,Log,"


使用程式碼求得 ipt

print b62enc(b62dec(enc0[:-2]) + code + b62dec(enc1_2[1:]))[1000: 1080]


原文連結:

https://bbs.pediy.com/thread-248585.htm



第十二題【移動迷宮】正在火熱進行中

第12題/共15題

《 移動迷宮》將於 12月25 日中午 12:00 結束

趕緊參與進來吧~!


看雪CTF.TSRC 2018 團隊賽 第十一題『伊甸園』 解題思路

騰訊安全應急響應中心 

TSRC,騰訊安全的先頭兵,肩負騰訊公司安全漏洞、駭客入侵的發現和處理工作。這是個沒有硝煙的戰場,我們與兩萬多名安全專家並肩而行,捍衛全球億萬使用者的資訊、財產安全。一直以來,我們懷揣感恩之心,努力構建開放的TSRC交流平臺,回饋安全社群。未來,我們將繼續攜手安全行業精英,探索網際網路安全新方向,建設網際網路生態安全,共鑄“網際網路+”新時代。

看雪CTF.TSRC 2018 團隊賽 第十一題『伊甸園』 解題思路

看雪CTF.TSRC 2018 團隊賽 第十一題『伊甸園』 解題思路



轉載請註明:轉自看雪學院



看雪CTF.TSRC 2018 團隊賽 解題思路彙總: 












相關文章