工具
IDA+虛擬機(kali)
思路展開
1.查殼,無殼,64位,放到虛擬機運行
靈魂三連問
2.iDA(64-bit)啓動
先從下往上找,找關鍵比較,再從上往下,找用戶輸入與函數關係
找關鍵函數的原則:用戶的輸入變量,第一個過程判斷輸入符合條件,第二個過程實現算法(輸入字符串+算法=結果字符串)
stringMod關鍵函數
__int64 __fastcall stringMod(__int64 *a1)
{
__int64 len; // r9
__int64 c_str; // r10
__int64 i; // rcx
signed int v4; // er8
int *temp_2; // rdi
int *temp_3; // rsi
signed int t; // ecx
signed int j; // er9
int g; // er10
unsigned int h; // eax
int sign; // esi
int v12; // esi
int temp[24]; // [rsp+0h] [rbp-60h]
memset(temp, 0, 0x48uLL);
len = a1[1];
if ( len )
{
c_str = *a1;
i = 0LL;
v4 = 0;
do
{
v12 = *(char *)(c_str + i);
temp[i] = v12; // temp=a1
if ( 3 * ((unsigned int)i / 3) == (_DWORD)i && v12 != firstchar[(unsigned int)i / 3] )// 當i是3的倍數時,str=first[i/3]
v4 = -1;
++i;
}
while ( i != len );
}
else
{
v4 = 0;
} // 將正確的a1賦值給temp
temp_2 = temp;
temp_3 = temp;
t = 666;
do
{ // 將temp裏的每個字符與v7異或,v7變化
*temp_3 = t ^ *(unsigned __int8 *)temp_3;
t += t % 5;
++temp_3;
}
while ( &temp[18] != temp_3 );
j = 1;
g = 0;
h = 1;
sign = 0;
do
{
if ( sign == 2 )
{
if ( *temp_2 != thirdchar[g] ) // 2 5 8 11 15 17
v4 = -1;
if ( h % *temp_2 != masterArray[g] ) // 1 4 7 10 14 16
v4 = -1;
++g;
h = 1;
sign = 0;
}
else
{
h *= *temp_2;
if ( ++sign == 3 )
sign = 0;
}
++j;
++temp_2;
}
while ( j != 19 );
return (unsigned int)(t * v4);
}
看了一圈,函數分三層,第一層賦值操作,當i是3的倍數時,對字符有規定(確定0 3 6 9 12 15 18六個字符),第二層異或操作,異或的值變化,第三層對異或後的值循環,0 1 2 三個爲一組
3.腳本
firstchar=[65, 105, 110, 69, 111, 97]
thirdchar=[751, 708, 732, 711, 734, 764]
masterArray=[471, 12, 580, 606, 147, 108 ]
t=[]
x=666
for i in range(18):
t.append(x)
x+=x%5
flag=[0 for i in range(18)]
index=0
for i in range(0,18,3):
flag[i]=firstchar[index] #0,3,6,9,12,15
index+=1
index=0
for i in range(2,18,3):
flag[i]=thirdchar[index]^t[i] #2 5,8,11,14,17
index+=1
index=0
for i in range(1,18,3):
for f in range(32,126): #常用可輸入字符,符合條件的留下來
if (flag[i-1]^t[i-1])*(f^t[i])%(flag[i+1]^t[i+1])==masterArray[index]:
flag[i]=f
index+=1
break;
print('tuctf{'+''.join(map(chr,flag))+'}')
tuctf{AfricanOrEuropean?}