XCTF 進階 RE notsequence
直接進入正題,下載下傳檔案,無殼,直接使用ida打開找到關鍵函數:
程式過程很簡單,有兩個檢查,一個if判斷
首先檢視第一個檢查函數:
要求我們return v5,不能return -1
為了讓我們的邏輯更加清楚,粗略寫了一下C語言的代碼:
int sub_80486CD(int a1){
v5 = 0;
for(int i = 0; i <= 1024 && a1[i]; i = v5 * (v5 + 1) / 2){
v3 = 0;
for(int j = 0;j <= v5; ++j)
v3 += a1[i+j]
if(1 << v5 != v3)
return -1;
++v5;
}
return v5;
}
a1就是我們的輸入,分析一下這個函數:
首先i=0,1,3,6,10,15,
v3表示從a1[i]開始加v5個的和:
a1[0]
a1[1] + a1[2]
a1[3] + a1[4] + a1[5]
a1[6] + a1[7] + a1[8] + a1[9]
v5左移一位等于v3即可!!!
可以列出幾個例子:
a1[0] = 1
a1[1] + a1[2] = 2
a1[3] + a1[4] + a1[5] = 4
a1[6] + a1[7] + a1[8] + a1[9] = 8
接下來進入第二個函數:
這裡也粗略寫了一下C語言的代碼:
int sub_8048783(int a1 , int a2){
v6 = 0;
for(int i = 1;i < a2; ++i ){
v4 = 0;
v3 = i - 1;
if( !a1[i] )
return 0;
while(a2 - 1 > v3){
v4 += a1[v3 * (v3 + 1) / 2 + v6];
v3++;
}
if(a1[v3 * (v3 + 1) / 2 + i] != v4)
return 0;
++v6;
}
return 1;
}
題目的要求是讓我們傳回1,也就是說要我們把這個函數執行完成,這裡存在兩個參數
第一個自然是我們的輸入,第二個類似于上面舉例子的層數
由于這裡的a2沒變,而且後面的if條件需要我們将這個類似的層數等于20
是以我們現在就可以認為a2=20,接下來繼續分析這個函數
首先a1裡面的每個數都不能為0,由于程式有點複雜
我們可以将下标列印出來看一下結果,編寫python:
v6 = v3 = 1 # 因為v3未變化前 v6=v3
a2 = 20 # 表示層數
i = 1
while a2 - 1 > v3:
print(int(v3 * (v3 + 1) / 2 + v6))
v3 += 1
print(v3 * (v3 + 1) / 2 + i)
由于20太大了,是以我就調小了層數,一點點嘗試,得到結果:
a1[2] = a1[0] = 1
a1[4] = a1[0] + a1[1] = 2
a1[5] = a1[2] = 1
a1[7] = a1[0] + a1[1] + a1[3] = 3
a1[8] = a1[2] + a1[4] = 3
a1[11] = a1[0] + a1[1] + a1[3] + a1[6] = 4
a1[12] = a1[2] + a1[4] + a1[7] = 6
a1[13] = a1[5] + a1[8] = 4
再結合上一個函數得出的結論,可以推出前幾層的數:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
… … … …
這裡就很顯然了,學過C語言的應該都敲過,楊輝三角嘛~~
是以這裡應該是讓我們輸入一個20層的楊輝三角!!
然後根據最後答案的提示:
去掉空格和換行進行MD5值加密,裹上RCTF{}送出即可
接下來就是編寫python腳本了,附上解題腳本:
a = []
for i in range(0,20):
b = []
for j in range(0,i + 1):
b.append(1)
a.append(b)
print(a)
for i in range(1,20):
for j in range(1,i):
a[i][j] = a[i - 1][j] + a[i - 1][j - 1]
print(a)
flag = ""
for i in range(0,len(a)):
for j in range(0,len(a[i])):
flag += str(a[i][j])
print(flag)
運作結果:
md5加密得到:
得到flag:RCTF{37894beff1c632010dd6d524aa9604db}