32位程序,无壳,拖进ida,找到关键函数
int __cdecl main(int a1, char **a2)
{
if ( a1 > 1 && sub_8048414(a2[1], 0) ) // 需要sub_8048414返回1,也就是需要a2[1],满足105那些
{
puts("Access granted");
sub_8048538((int)a2[1]);
}
else
{
puts("Access denied");
}
return 0;
}
需要sub_8048414满足返回1的条件,然后执行sub_8048538函数,先看这个函数
int __cdecl sub_8048538(int a1)
{
int v2[33]; // [esp+18h] [ebp-A0h]
int i; // [esp+9Ch] [ebp-1Ch]
qmemcpy(v2, &unk_8048760, sizeof(v2));
for ( i = 0; i <= 32; ++i ) // 33个元素
putchar(v2[i] ^ *(char *)(a1 + i % 8)); // 对v2数组进行操作,取a1的前8个异或操作
return putchar(10);
}
从这里看出,这里就是得到flag的关键了,v2是已知的,确定a1就是关键点,确定a1的函数如下
signed int __cdecl sub_8048414(_BYTE *a1, int a2)
{
signed int result; // eax
switch ( a2 )
{
case 0:
if ( *a1 == 105 ) // 根据a2的值执行不同的操作,a1是105,101,110那些就执行goto 19,不然就是返回0
goto LABEL_19; // a2取01345679
result = 0;
break;
case 1:
if ( *a1 == 101 )
goto LABEL_19;
result = 0;
break;
case 3:
if ( *a1 == 110 )
goto LABEL_19;
result = 0;
break;
case 4:
if ( *a1 == 100 )
goto LABEL_19;
result = 0;
break;
case 5:
if ( *a1 == 97 )
goto LABEL_19;
result = 0;
break;
case 6:
if ( *a1 == 103 )
goto LABEL_19;
result = 0;
break;
case 7:
if ( *a1 == 115 )
goto LABEL_19;
result = 0;
break;
case 9:
if ( *a1 == 114 )
LABEL_19:
result = sub_8048414(a1 + 1, 7 * (a2 + 1) % 11);// 仍然需要有01345679,所以之后就是7,1,3,6,5,9,4,2
else // 因为需要前8个,就是105,115,101,110,103,97,114,100
result = 0;
break;
default:
result = 1;
break;
}
return result;
}
要让这个函数返回1,只能跳到19去执行或者default
在这个函数中,如果要让跳到19,就需要满足a2取01345679其中一个,同时a1是105,101的那些值,并且跳到19后,参数变化,递归这个函数,同样满足“a2取01345679其中一个,同时a1是105,101的那些值”这个条件,a2起始值为0,之后进入函数,递归执行,前8个是0,7,1,3,6,5,9,4,对应的a1就是:105,115,101,110,103,97,114,100
编写python脚本得到flag
a = [105,115,101,110,103,97,114,100]
v2 = [0x0F,0x1F,0x4,0x9,0x1c,0x12,0x42,0x9,0x0c,0x44,0x0d,0x7,0x9,0x6,0x2d,0x37,0x59,0x1e,0x0,0x59,0x0f,0x8,0x1c,0x23,0x36,0x7,0x55,0x2,0x0c,0x8,0x41,0x0a,0x14]
flag = ''
for i in range(33):
flag += chr(v2[i]^a[(i%8)])
print(flag)