Reverse1 背景2 总结 2 总结

前几天网安老师给我们几个留了个作业,让我们进行Reverse实验,因为没接触过,这次就随便做做就行,随遇而安……

1.1 crackme

在crackme.c文件中,我发现这是一个验证合法用户身份的c语音,只有用户输入1234567时才会通过验证,其他输入都不能通过验证。

图1 验证登录

在IDA中打开crackme.exe,将此处的jnz改为jz即可

图2 程序修改位置

在UltraEdit中打开crackme.exe,在1130行将jnz对应的16进制数改为jz对应的16进制数并保存

图3 修改为jz

结果发现,crackme.exe直接运行结束,跳过了输入口令的步骤

1.2 overflow,overflow2,overflow3

在crackme.c文件中,我发现这一段代码和上面做的crackme的C代码一样,我们可以通过输入qqqqqqqq或者222222222222222222来使栈溢出而绕过验证,至于原理我也说不清楚,因为我不太喜欢逆向,个人在ctf题目中都是做Web题目。

1.3 Reverse题目的wp

这是个二进制程序,首先用IDA打开,查看流程,发现这是32位ELF文件。本题为入门题,可以直接使用IDA的F5功能,查看程序流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int __cdecl main(int argc, const char **argv, const char **envp)
{
char flag[29]; // [esp+Bh] [ebp-2Dh]
int n; // [esp+28h] [ebp-10h]
int i; // [esp+2Ch] [ebp-Ch]
*(_DWORD *)flag = 0xC881E8F1;
*(_DWORD *)&flag[4] = 0xCECF81D2;
*(_DWORD *)&flag[8] = 0x81C081D5;
*(_DWORD *)&flag[12] = 0xC8D5C0D3;
*(_DWORD *)&flag[16] = 0xCDC0CFCE;
*(_DWORD *)&flag[20] = 0xCCD4CF81;
*(_DWORD *)&flag[24] = 0x8FD3C4C3;
flag[28] = 0;
printf("What is magic number? ");
__isoc99_scanf("%d", &n);
if ( n == 0x12B9B0A1 )
{
for ( i = 0; flag[i]; ++i )
flag[i] ^= n;
printf("Flag is FLAG{%s}n", flag);
}
else
{
puts("Try Hard.");
}
return 0;
}

可以看出程序首先要求输入一个数n,然后跟数值0x12B9B0A1比较,如果相等,则对flag数组的每一个元素(字节)与n进行XOR运算,就可以得到flag(需要注意的是因为flag数组的每个元素为一个字节,所以虽然与n进行XOR,实际起作用的只有n的低位字节,即0xA1)。
所以只需要写一个脚本完成这个过程即可,我们使用Python完成该部分脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from struct import pack
a = [0xC881E8F1, #可以看出是flag经过XOR异或加密得到的密文
0xCECF81D2,
0x81C081D5,
0xC8D5C0D3,
0xCDC0CFCE,
0xCCD4CF81,
0x8FD3C4C3]
t = ""
for i in a:
t += pack("<I",i).decode('ISO-8859-1')
flag = ""
for i in range(len(t)):
flag += chr(ord(t[i])^0xa1)
print(flag)

2 总结

这次作业有点难为我了,在平常的CTF比赛中,我都是捡着Web和Misc的题目来做,逆向这一类的题目我是一题都没做过,所以说我就把上课听懂的内容复现了,剩下的三个overflow都没做,但内容又感觉太少了,所以就又写了一道hackme中的逆向题helloworld。


转载请注明来源,欢迎对文章中的引用来源进行考证,指出任何有错误或不够清晰的表达,可以邮件至 [email protected]