确定是32位无壳程序
放入静态分析工具ida32里查看:
发现栈指针不平衡,"alt + k"手动调节一下,加个负号即可:
调节好之后查看伪代码:
BOOL __usercall sub_401000@<eax>(int a1@<ebp>)
{
BOOL result; // eax
HANDLE v2; // [esp-14h] [ebp-14h]
HANDLE v3; // [esp-10h] [ebp-10h]
DWORD v4; // [esp-Ch] [ebp-Ch] BYREF
int v5; // [esp-8h] [ebp-8h]
void *retaddr; // [esp+0h] [ebp+0h]
v5 = a1;
v2 = GetStdHandle(0xFFFFFFF6);
v3 = GetStdHandle(0xFFFFFFF5);
WriteFile(v3, aYouCrushedThat, 0x43u, &v4, 0);
ReadFile(v2, &unk_402159, 0x32u, &v4, 0);
if ( sub_401084(retaddr, &unk_402159, v4) )
result = WriteFile(v3, aYouAreSuccess, 0x11u, &v4, 0);
else
result = WriteFile(v3, aYouAreFailure, 0x11u, &v4, 0);
return result;
}
关于writefile函数和readfile函数,虽说无关紧要,但还是贴一下msdn文档了解一下:
查看关键函数:
int __usercall sub_401084@<eax>(int result@<eax>, int a2, char *a3, int a4)
{
__int16 v4; // bx
int v5; // ecx
_BYTE *v7; // edi
char v8; // al
unsigned int v9; // kr00_4
char v10; // al
char v11; // cf
__int16 v12; // ax
bool v13; // zf
_BYTE *v14; // edi
int v15; // [esp+0h] [ebp-Ch]
v4 = 0;
v5 = 37;
if ( a4 >= 37 )
{
v7 = (a2 + 36);
while ( 1 )
{
LOWORD(result) = 455;
v15 = result;
v8 = *a3++;
v9 = __readeflags();
v10 = v15 ^ v8;
__writeeflags(v9);
v12 = (__ROL1__(1, v4 & 3) + v11 + v10);//关键操作,v11是进位标志位
v4 += v12;
v13 = *v7 == v12; //*v7==v12,v7指针会从后往前依次读取a2的值
v14 = v7 + 1;
if ( !v13 ) //v13==1
LOWORD(v5) = 0;
result = v15;
if ( !v5 )
break;
v7 = v14 - 2;
if ( !--v5 )
return result;
}
}
return 0;
}
这个函数里面的v12 = (ROL1(1, v4 & 3) + v11 + v10);语句是加密的关键函数,而v13 = *v7 == v12是检查函数。可以看出要将加密后的字符串一个个加密一个个判断,然后跟倒置的a2做比对。
我静态分析没有看出每次v7的值是什么,所以选择od动态调试看一下。在ida里面tab查看v12 = (ROL1(1, v4 & 3) + v11 + v10);对应的汇编代码:
根据定义v7的伪代码我们也知道了v7的值所在的地址是放在di寄存器里面的
所以我们在加密语句处下断点,看寄存器di的值,再数据窗口跟随地址就可以得到每次v7的值。
由于我们动态调试随便输入的password,所以为了避免加密过程中会跳出循环,我直接把跳转语句“ jecxz short loc_4010D7 ”给nop掉,这样就可以统计v7的值,为后续写exp做准备。
但我们只是获得了32个数据,但最后5个忽略也无伤大雅,因为从提示我们推测最后的结果肯定是“ @flare-on.com ”结尾,这32个统计如下:
v7=[0xAA, 0xEC, 0xA4, 0xBA, 0xAF, 0xAE, 0xAA, 0x8A, 0xC0, 0xA7,
0xB0, 0xBC, 0x9A, 0xBA, 0xA5, 0xA5, 0xBA, 0xAF, 0xB8, 0x9D,
0xB8, 0xF9, 0xAE, 0x9D, 0xAB, 0xB4, 0xBC, 0xB6, 0xB3, 0x90,
0x9A, 0xA8]
EXP
自己写的exp:
def rol(value, count):
temp=((value>>(8-count))&0xFF)|((value<<count)& 0xFF)
return temp
v7=[0xAA, 0xEC, 0xA4, 0xBA, 0xAF, 0xAE, 0xAA, 0x8A, 0xC0, 0xA7,0xB0, 0xBC, 0x9A, 0xBA, 0xA5, 0xA5, 0xBA, 0xAF, 0xB8, 0x9D,0xB8, 0xF9, 0xAE, 0x9D, 0xAB, 0xB4, 0xBC, 0xB6, 0xB3, 0x90,0x9A, 0xA8]
flag=''
v4=0
for i in range(len(v7)):
flag+=chr((v7[len(v7)-i-1]-rol(1,v4&3)-1)^0xC7)
v4+=v7[len(v7)-i-1]
print('flag{'+flag+'n.com}')
贴上别的博主的exp学习一下
sumv = 0
lenv = 37
rolv = 1
flag = 1
result = ''
values = [0xa8,0x9a,0x90,0xb3,0xb6,0xbc,0xb4,0xab,0x9d,0xae,0xf9,0xb8,0x9d,0xb8,0xaf,0xba,0xa5,0xa5,0xba,0x9a,0xbc,0xb0,0xa7,0xc0,0x8a,0xaa,0xae,0xaf,0xba,0xa4,0xec,0xaa,0xae,0xeb,0xad,0xaa,0xaf,]
for i in range(37):
rolv = (1 << (sumv & 3)) % 256
code = (455 ^ (values[i] - rolv - flag)% 256) %256
result = result + chr(code)
sumv = sumv + values[i]
print result
v7=[0xAA, 0xEC, 0xA4, 0xBA, 0xAF, 0xAE, 0xAA, 0x8A, 0xC0, 0xA7,
0xB0, 0xBC, 0x9A, 0xBA, 0xA5, 0xA5, 0xBA, 0xAF, 0xB8, 0x9D,
0xB8, 0xF9, 0xAE, 0x9D, 0xAB, 0xB4, 0xBC, 0xB6, 0xB3, 0x90,
0x9A, 0xA8]
v7=v7[::-1]
flag=""
v4=0
for i in range(len(v7)):
tmp=(1<<(v4&0x3))
flag+=chr((v7[i]-tmp-1)^0xc7)
v4+=v7[i]
print(flag)
// An highlighted block
var foo = 'bar';
运行一下得到flag:
flag{a_Little_b1t_harder_plez@flare-on.com}