BUUCTF Reverse/[ACTF新生赛2020]easyre
发现UPX壳
进行脱壳
用IDA32位打开,找到main函数进行分析
int __cdecl main(int argc, const char **argv, const char **envp)
{
_BYTE v4[12]; // [esp+12h] [ebp-2Eh] BYREF
_DWORD v5[3]; // [esp+1Eh] [ebp-22h]
_BYTE v6[5]; // [esp+2Ah] [ebp-16h] BYREF
int v7; // [esp+2Fh] [ebp-11h]
int v8; // [esp+33h] [ebp-Dh]
int v9; // [esp+37h] [ebp-9h]
char v10; // [esp+3Bh] [ebp-5h]
int i; // [esp+3Ch] [ebp-4h]
sub_401A10();
qmemcpy(v4, "*F'\"N,\"(I?+@", sizeof(v4));
printf("Please input:");
scanf("%s", v6);
if ( v6[0] != 65 || v6[1] != 67 || v6[2] != 84 || v6[3] != 70 || v6[4] != 123 || v10 != 125 )
return 0;
v5[0] = v7;
v5[1] = v8;
v5[2] = v9;
for ( i = 0; i <= 11; ++i )
{
if ( v4[i] != byte_402000[*((char *)v5 + i) - 1] )
return 0;
}
printf("You are correct!");
return 0;
}
将v6转成字符看看,得到ACTF{
看一下v10的值,v10 = }
看到for循环,推测flag在v5中
for ( i = 0; i <= 11; ++i )
{
if ( v4[i] != byte_402000[*((char *)v5 + i) - 1] )
return 0;
}
跟进byte_402000,注意看清楚逗号
注意
从for循环条件中推出flag为12位,但是v4长度有14位。注意v4中的 \" ,这是c语言中的转义字符,只代表一个 "
for ( i = 0; i <= 11; ++i )
{
if ( v4[i] != byte_402000[*((char *)v5 + i) - 1] )
return 0;
}
qmemcpy(v4, "*F'\"N,\"(I?+@", sizeof(v4));
所以得到(在python中字符串有三种表现形式,三个单引号(’’’)、双引号(")、单引号(’))
v4 = '''*F'"N,"(I?+@'''
然后得到(python中 \ 要用 \\ 表示,详情请看这个Python中关于反斜杠(\)用法的总结)
by = '''~}|{zyxwvutsrqponmlkjihgfedcba`_^]\\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)
然后写出脚本
by = '''~}|{zyxwvutsrqponmlkjihgfedcba`_^]\\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$# !"'''
v4 = '''*F'"N,"(I?+@'''
for i in range(len(v4)):
for j in range(len(by)):
if v4[i] == by[j]:
#print("v5[{}] - 1 = {} ,v5[{}] = {} ".format(i,j,i,chr(j + 1)))
print(chr(j + 1),end = '')
运行得到结果