签层饼
真有一千层函数呀,沿着输入存入的两个变量找,找到3个函数:
主函数给出了flag的组织方式,
check1说number2<882408,
check2说number1 = number2^333509
check_n说返回的条件,但是由于这个数是个随机数不能确定,而且number2很小可以爆破。
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
int v3; // eax
printf("Hello!Welcome to ctfshow,You need to input two numbers\n");
printf("number1:");
scanf("%d", &number1);
printf("\n");
printf("number2:");
scanf("%d", &number2);
v3 = time(0);
sub_4B9370(v3);
dword_528DC0 = (rand() - 999) % 500;
if ( dword_528DC0 > 9999999 )
printf("提示:这里的R是想写成任意范围的,但是因为运算溢出"); // 提示:这里的R是想写成任意范围的
if ( number1 > 0 && number2 > 0 )
{
sub_40431D();
if ( dword_525A30 )
{
printf("%d", dword_528DC0);
printf("Key Error");
}
else
{
printf("yeah!Your flag:ctfshow{c52e1e1a33%d0e%dc}", number1, number2);
}
}
else
{
printf("Error");
}
......
}
int check1()
{
int result; // eax
result = sub_4015B4(881778, 666); // a1^a2
if ( number2 <= result ) // <882408
result = sub_4098EA();
return result;
}
int check2()
{
int result; // eax
result = sub_4015B4(number2, 333509); // number1 = number2 ^333509
if ( number1 == result )
result = sub_40C63A();
return result;
}
int check_n()
{
dword_525A30 = 1;
if ( dword_528DC0 * dword_528DC0 * number2 - 1877 * dword_528DC0 + 1 < 0
|| dword_528DC0 * dword_528DC0 * number2 - 1877 * dword_528DC0 != -1 )
{
dword_525A30 ^= 1u;
}
return sub_408724();
}
一般情况下实际的数应该在给定数比较近,所以一般不从0开始爆,而是从大向小爆。大概率少用时。
import subprocess
for n2 in range(882408,-1,-1):
n1 = n2^333509
p = subprocess.Popen('./千层饼.exe', stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.stdin.write(f"{n1}\n{n2}".encode())
p.stdin.close()
data = p.stdout.read()
p.stdout.close()
if b'flag' in data:
print(data)
break
#b'Hello!Welcome to ctfshow,You need to input two numbers\r\nnumber1:\r\nnumber2:
#yeah!Your flag:ctfshow{c52e1e1a335489030e882402c}'
Tea_tube_pot
看名字就是tea加密,而且用了3次,不过都不难,直接逆回即可。第2段在中间变的v5所以处理v4时与v3时v5差1个。第3段虽然用了判断两种情况,但参数是固定的,所以只需看一半。
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
if ( check_c11() && (unsigned int)check_CA5(a1, a2) && (unsigned int)check_D45() )
puts("Congrts!Your Flag is 'ctfshow{'+PART1+PART2+PART3+'}'!");
return 0LL;
}
__int64 __fastcall sub_71A(unsigned int *input, _DWORD *a2)
{
__int64 result; // rax
unsigned int v3; // [rsp+1Ch] [rbp-24h]
unsigned int v4; // [rsp+20h] [rbp-20h]
int v5; // [rsp+24h] [rbp-1Ch]
unsigned int i; // [rsp+28h] [rbp-18h]
v3 = *input; // input,'This_is_teatube!'
v4 = input[1];
v5 = 0;
for ( i = 0; i <= 0x1F; ++i )
{
v5 -= 0x61C88647;
v3 += (v4 + v5) ^ (16 * v4 + *a2) ^ ((v4 >> 5) + a2[1]);
v4 += (v3 + v5) ^ (16 * v3 + a2[2]) ^ ((v3 >> 5) + a2[3]);
}
*input = v3;
result = v4;
input[1] = v4;
return result;
}
__int64 __fastcall sub_7F8(unsigned int a1, unsigned int *a2, __int64 a3)
{
__int64 result; // rax
unsigned int i; // [rsp+24h] [rbp-14h]
unsigned int v3; // [rsp+28h] [rbp-10h]
unsigned int v4; // [rsp+2Ch] [rbp-Ch]
unsigned int v5; // [rsp+30h] [rbp-8h]
v3 = *a2;
v4 = a2[1];
v5 = 0;
for ( i = 0; i < a1; ++i )
{
v3 += (((v4 >> 5) ^ (16 * v4)) + v4) ^ (*(_DWORD *)(4LL * (v5 & 3) + a3) + v5);
v5 -= 0x61C88647;
v4 += (((v3 >> 5) ^ (16 * v3)) + v3) ^ (*(_DWORD *)(4LL * ((v5 >> 11) & 3) + a3) + v5);
}
*a2 = v3;
result = v4;
a2[1] = v4;
return result;
}
__int64 __fastcall sub_8D3(unsigned int *a1, int a2, __int64 a3)
{
unsigned int *v3; // rax
unsigned int *v4; // rax
__int64 result; // rax
unsigned int *v6; // rax
int v7; // [rsp+Ch] [rbp-2Ch]
unsigned int v8; // [rsp+20h] [rbp-18h]
unsigned int v9; // [rsp+20h] [rbp-18h]
unsigned int v10; // [rsp+24h] [rbp-14h]
unsigned int v11; // [rsp+24h] [rbp-14h]
unsigned int v12; // [rsp+24h] [rbp-14h]
unsigned int v13; // [rsp+28h] [rbp-10h]
unsigned int v14; // [rsp+28h] [rbp-10h]
unsigned int j; // [rsp+2Ch] [rbp-Ch]
int i; // [rsp+2Ch] [rbp-Ch]
int v17; // [rsp+30h] [rbp-8h]
int v18; // [rsp+30h] [rbp-8h]
int v19; // [rsp+34h] [rbp-4h]
unsigned int v20; // [rsp+34h] [rbp-4h]
if ( a2 <= 1 )
{
if ( a2 < -1 )
{
v7 = -a2;
v18 = 52 / -a2 + 6;
v14 = -1640531527 * v18;
v9 = *a1;
do
{
v20 = (v14 >> 2) & 3;
for ( i = v7 - 1; i; --i )
{
v11 = a1[i - 1];
v6 = &a1[i];
*v6 -= ((v9 ^ v14) + (v11 ^ *(_DWORD *)(4LL * (v20 ^ i & 3) + a3))) ^ (((4 * v9) ^ (v11 >> 5))
+ ((v9 >> 3) ^ (16 * v11)));
v9 = *v6;
}
v12 = a1[v7 - 1];
*a1 -= (((4 * v9) ^ (v12 >> 5)) + ((v9 >> 3) ^ (16 * v12))) ^ ((v9 ^ v14) + (v12 ^ *(_DWORD *)(4LL * v20 + a3)));
result = *a1;
v9 = *a1;
v14 += 1640531527;
--v18;
}
while ( v18 );
}
}
else
{
v17 = 52 / a2 + 6; // 32
v13 = 0;
v10 = a1[a2 - 1]; // v10 = a1[1]
do
{
v13 -= 0x61C88647;
v19 = (v13 >> 2) & 3;
for ( j = 0; j < a2 - 1; ++j )
{
v8 = a1[j + 1];
v3 = &a1[j];
*v3 += ((v8 ^ v13) + (v10 ^ *(_DWORD *)(4LL * (v19 ^ j & 3) + a3))) ^ (((4 * v8) ^ (v10 >> 5))
+ ((v8 >> 3) ^ (16 * v10)));
v10 = *v3;
}
v4 = &a1[a2 - 1];
*v4 += ((*a1 ^ v13) + (v10 ^ *(_DWORD *)(4LL * (v19 ^ j & 3) + a3))) ^ (((4 * *a1) ^ (v10 >> 5))
+ ((*a1 >> 3) ^ (16 * v10)));
result = *v4;
v10 = result;
--v17;
}
while ( v17 );
}
return result;
}
逆程序
from pwn import u32,p32
'''
for ( i = 0; i <= 0x1F; ++i )
{
v5 -= 0x61C88647;
v3 += (v4 + v5) ^ (16 * v4 + *a2) ^ ((v4 >> 5) + a2[1]);
v4 += (v3 + v5) ^ (16 * v3 + a2[2]) ^ ((v3 >> 5) + a2[3]);
}
'''
a2 = [u32(b'This'), u32(b'_is_'), u32(b'teat'), u32(b'ube!')]
v5 = [0]*0x20
t = 0
for i in range(0x20):
t = (t - 0x61C88647) & 0xffffffff
v5[i] = t
#print(hex(t))
v3 = 0x5FD744F6
v4 = 0x95832046
for i in range(0x1f,-1,-1):
v4 -= (v3 + v5[i])^(16 * v3 + a2[2]) ^ ((v3>>5) + a2[3])
v4 = v4&0xffffffff
v3 -= (v4 + v5[i])^(16 * v4 + a2[0]) ^ ((v4>>5) + a2[1])
v3 = v3&0xffffffff
flag = b'ctfshow{'+p32(v3)+p32(v4)
#v3 += (((v4 >> 5) ^ (16 * v4)) + v4) ^ (*(_DWORD *)(4LL * (v5 & 3) + a3) + v5);
#v4 += (((v3 >> 5) ^ (16 * v3)) + v3) ^ (*(_DWORD *)(4LL * ((v5 >> 11) & 3) + a3) + v5);
v3 = 0xFD731313
v4 = 0x6662CB90
v5 = [0] + v5
for i in range(0x1f,-1,-1):
v4 -= (((v3 >> 5) ^ (16 * v3)) + v3) ^ (a2[(v5[i+1] >> 11) & 3] + v5[i+1])
v4 &= 0xffffffff
v3 -= (((v4 >> 5) ^ (16 * v4)) + v4) ^ (a2[v5[i] & 3] + v5[i])
v3 &= 0xffffffff
flag += p32(v3)+p32(v4)
v3 = 0x4B136C82
v4 = 0x1A6E9613
v5 = v5[1:]
for i in range(0x1f,-1,-1):
v4 -= ((v3 ^ v5[i]) + (v3 ^ a2[(((v5[i]>>2)&3)^1)&3])) ^ (((4 * v3) ^ (v3 >> 5))+ ((v3 >> 3) ^ (16 * v3)))
v4 &= 0xffffffff
v3 -= ((v4 ^ v5[i]) + (v4 ^ a2[(((v5[i]>>2)&3)^0)&3])) ^ (((4 * v4) ^ (v4 >> 5))+ ((v4 >> 3) ^ (16 * v4)))
v3 &= 0xffffffff
flag += p32(v3)+p32(v4)+b'}'
print(flag)
#ctfshow{T1nyENCryPti0nA19ori7hM!}