i春秋試驗場 CTF奪旗賽(第三季)RE 整型數列
emmmm,這次比賽比較簡單,沒啥好說的,,,
關鍵記錄一下這個逆向題目,,,,,
ida直接打開進行靜態分析:
看英語好像是說可以自動跑出來,需要一些時間,,,,
直接上kali進行運行,,,等了很久沒出來,直接放棄
開始分析函數,進入check(),沒有發現什麼問題,進入loadQuestion()查看,發現這裏是主要的函數:
很顯然嘛,有匹配,還有四個函數,進入查看貌似就是斐波拉契數組,,,,
這裏我用了python進行轉化,看得更清楚:
def func1(x):
if x <= 2:
return x
s = func1(x-1)
return s + func1(x-2)
def func2(x):
if x <= 3:
return x
s = func2(x-1)
s1 = s + func2(x-2)
return s1 + func2(x-3)
def func3(x):
if x <= 4:
return x
s = func3(x-1)
s1 = s + func3(x-2)
s2 = s1 + func3(x-3)
return s2 + func3(x-4)
def func4(x):
if x <= 5:
return x
s = func4(x-1)
s1 = s + func4(x-2)
s2 = s1 + func4(x-3)
s3 = s2 + func4(x-4)
return s3 + func4(x-5)
四個函數都用了遞歸,查看一下v6等於的那個函數發現:
八個數字,還是大數,貌似邏輯已經清楚了,,,,,
就是看這八個數在這幾個函數生成的結果(可以看成數組)中的第多少個(位),,,
顯然,如果我們直接運行程序等待的話,那麼我們可能會等一年,,,
畢竟第四個函數調用了多層遞歸,,,,
我們可以轉換思路,直接先初始化,把數組給存起來,這樣就快多了,,,,
利用python編寫腳本:
a = [3736710778780434371, 14787220707439219840,
10155230078262535612,6284562052556236687,
6463547837513153369, 4771310769738115795,
14436565591186214307, 4379970031970910517]
a1 = [0] * 100
a1[0] = 1
a1[1] = 2
for i in range(2,100):
a1[i] = a1[i-1] + a1[i-2]
print(a1)
a2 = [0] * 100
a2[0] = 1
a2[1] = 2
a2[2] = 3
for i in range(3,100):
a2[i] = a2[i-1] + a2[i-2] + a2[i-3]
print(a2)
a3 = [0] * 100
a3[0] = 1
a3[1] = 2
a3[2] = 3
a3[3] = 4
for i in range(4,100):
a3[i] = a3[i-1] + a3[i-2] + a3[i-3] +a3[i-4]
print(a3)
a4 = [0] * 100
a4[0] = 1
a4[1] = 2
a4[2] = 3
a4[3] = 4
a4[4] = 5
for i in range(5,100):
a4[i] = a4[i-1] + a4[i-2] + a4[i-3] +a4[i-4] + a4[i-5]
print(a4)
for i in range(0,8):
for k in range(0,100):
if(a[i] == a1[k]):
print(k + 1)
break
for i in range(0,8):
for k in range(0,100):
if(a[i] == a2[k]):
print(k + 1)
break
for i in range(0,8):
for k in range(0,100):
if(a[i] == a3[k]):
print(k + 1)
break
for i in range(0,8):
for k in range(0,100):
if(a[i] == a4[k]):
print(k + 1)
break
運行無果,,,,
經過分析得知,python與C語言不一樣,C語言最大的數爲2^64,然而python卻沒有這個限制,,,,
直接編寫C語言腳本進行解題,,,,,
最後解題腳本(C語言):
#include<stdio.h>
using namespace std;
__int64 a1[100],a2[100],a3[100],a4[100];
int main(){
__int64 a[8] = {3736710778780434371, 14787220707439219840,10155230078262535612,6284562052556236687,6463547837513153369, 4771310769738115795,14436565591186214307, 4379970031970910517};
a1[0] = 1;
a1[1] = 2;
for(int i=2;i<=99;i++)
a1[i] = a1[i-1] + a1[i-2];
a2[0] = 1;
a2[1] = 2;
a2[2] = 3;
for(int i=3;i<=99;i++)
a2[i] = a2[i-1] + a2[i-2] + a2[i-3];
a3[0] = 1;
a3[1] = 2;
a3[2] = 3;
a3[3] = 4;
for(int i=4;i<=99;i++)
a3[i] = a3[i-1] + a3[i-2] + a3[i-3] +a3[i-4];
a4[0] = 1;
a4[1] = 2;
a4[2] = 3;
a4[3] = 4;
a4[4] = 5;
for(int i=5;i<=99;i++)
a4[i] = a4[i-1] + a4[i-2] + a4[i-3] +a4[i-4] + a4[i-5];
printf("flag{");
for(int i=0;i<8;i++)
for(int k=10;k<=99;k++)
if(a[i] == a1[k]){
printf("%d_",k+1);
break;
}
for(int i=0;i<8;i++)
for(int k=10;k<=99;k++)
if(a[i] == a2[k]){
printf("%d_",k+1);
break;
}
for(int i=0;i<8;i++)
for(int k=10;k<=99;k++)
if(a[i] == a3[k]){
printf("%d_",k+1);
break;
}
int f = 1;
for(int i=0;i<8;i++)
for(int k=10;k<=99;k++)
if(a[i] == a4[k] && f == 1){
printf("%d_",k+1);
f = 0;
break;
}else if(a[i] == a4[k]){
printf("%d",k+1);
break;
}
printf("}\n");
return 0;
}
秒出結果:
這題還要結合C語言的特性去搞,,,,
有點難頂~~