Lab 01 Bomb Lab

这个实验要很小心很小心的做,因为会炸。

基础知识

  • GDB 调试基础 GDB 常用命令
  • Assembly Language 汇编语言 基本命令

0x01 strcmp()

仔细看这段汇编代码,里面首先从0x804a6b8这个位置获取的变量移到$ebp-0xc位置中,然后调用strings_not_equal() 函数,传入我们的输入$ebp+0x8 这个字符串,以及刚刚获取到的变量。结果存在$eax寄存器中,然后使用test指令对于$eax中保存的结果进行处理。test指令对于两个操作数进行and操作,并根据结果对于ZF进行标记。如果and操作为零,则ZF标志为1。而je指令在ZF被置位的时候跳转。因此我们需要上一个 调用函数的返回值为0。

我们再研究一下这个函数strings_not_equal() 这个函数。

image-20190830182110872

对于传入的两个字符串变量首先进行计算长度(调用string_length())函数,然后将数据存储在的eax和ebx两个寄存器中的数据,进行比较。如果长度相等,则继续调用后面的函数进行比较。否则,返回1.C语言代码如下。 比较两个字符串,相同返回0,不同返回1。

因此我们需要输入和题目字符串中相同的字符串量。"What were the last four digits of your childhood telephone number?"

0x02 funcall

注意加断点!加断点!加断点!不要让程序去一个你不知道的地方。首先看汇编。

程序传入了三个字符串,然后调用了一个叫func_game()的函数。在func_game()函数中,传入了4个参数,分别是(input_string, “rock”,”paper”,”scissors”) 分别存储在$ebp+0x8, $ebp+0xc,$ebp+0x10, $ebp+0x14位置。然后将其传入本地变量中进行保存,同时调用string_not_equal()函数进行处理,如果出现不同的情况,eax返回为1,将不进行跳转,对于$ebp-0xc中的变量进行加一操作。最后,从第72行开始,判断$ebp-0xc中变量中的值,如果不是2的话,则bomb,否则输出key. 我们在string_not_equal()函数进行加断点处理,看这个函数的参数是那两个,就可以知道我们需要输入的是那个啦。

image-20190901130726013

0x03 password

废话不多说,直接上汇编。

image-20190901143505513

注意里面对于输入的字符串调用了一个strings_equal()函数,并且需要这个函数的返回值为1(因为后续经过一个test指令加上一个jne指令),也就是和这个字符串不同,在strings_equal()函数里面,对两个字符串进行取长度操作,并将长度作为返回值的依据,如果长度相等,则返回0, 不同则返回1。因此,我们只需要输入一个长度不同于11的字符串便可以解除这个炸弹了。

0x04 quick

image-20190903111946542

首先调用read_six_number() 函数,暗示我们需要输入6个数字,将数字存储在eax寄存器所指向的$ebp-0x24这个位置。然后将第一个数字的位置,$ebp-0x24位置的数字进行test 然后通过jns进行跳转。所以要求第一个位置的数字不得小于0。之后通过$eax, $ebx,$ecx, 以及$edx四个寄存器进行循环判断,相对应位置的值是否满足条件a[i] = a[i-1] + i,如果不满足就bomb.

因此,我们只要输入符合要求的一组数据即可。

0x05 jump

先上汇编

image-20190903113617822

jump函数首先调用sscanf()函数,从输入字符串中读取两个数,读到$ebp-0x14和$ebp-0x18中, 并且返回读到数字的个数在$eax中。首先判断返回值是否大于1, 不大于则bomb。 紧接着判断$ebp-0x14这个数是否比7大,如果超过7,则bomb。然后进行条件跳转,按照$ebp-0x14中读到的数进行跳转。如果输入的为零,则跳转到0x804951e这个位置。最后将对应数字进行比较,如果不相等,则跳转bomb.

0x06 binary

和前面的类似,读取两个数到$ebp-0x18以及$ebp-0x1c这两个位置,然后将返回值所在的$eax位置的数据和2进行比较,所以输入的必须是两个数字。然后将读到的第一个数字和0以及和e(16进制数,换成十进制就是14) 进行比较,如果小于0或者大于14都将爆炸。然后调用func4()函数,通过几个判断指令,控制程序的跳转。func4()函数的返回值必须为11。通过测试以及计算,1 11符合条件。

0x07 array

和前面类似,读取两个数到$ebp-0x18以及$ebp-0x1c这两个位置。使用代码进行计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
a = [0xa, 2, 0xe, 7, 8, 0xc, 0xf, 0xb, 0, 4, 1, 0xd, 3, 9, 6, 5]

for v3 in range(0, 16):
v3_bak = v3
for v2 in range(0, 1000):
v3 = v3_bak
v3 &= 0xf
v6 = 0
v5 = 0
while v3 != 15:
v6 += 1
v3 = a[v3]
v5 += v3
if v6 == 15:
break
if v6 == 15 and v5 == v2:
print(v3_bak, v2)

0x08 list

首先调用read_six_number()函数,暗示我们的输入是6个数字。然后通过一个循环,要求每个数字都不一样,同时在1-6这个范围中。逻辑比较麻烦,但是还是可以理解的。注意观察到里面的一个链表结构。

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
for a1 in range(1, 7):
for a2 in range(1, 7):
for a3 in range(1, 7):
for a4 in range(1, 7):
for a5 in range(1, 7):
for a6 in range(1, 7):
try:
node = {
0x804c4e0: [0x351, 1, 0x804c4d4],
0x804c4d4: [0x127, 2, 0x804c4c8],
0x804c4c8: [0x144, 3, 0x804c4bc],
0x804c4bc: [0x31e, 4, 0x804c4b0],
0x804c4b0: [0x3df, 5, 0x804c4a4],
0x804c4a4: [0x250, 6, 0]
}
v2 = [0] * 6
v3 = [a1, a2, a3, a4, a5, a6]
for i in range(6):
for j in range(i + 1, 6):
if v3[i] == v3[j]:
raise Exception()
# print(v3)
for i in range(0, 6):
v7 = 0x804c4e0
for j in range(1, v3[i]):
v7 = node[v7][2]
v2[i] = v7
v4 = v2[0]
v7 = v2[0]
for i in range(1, 6):
node[v7][2] = v2[i]
v7 = node[v7][2]
node[v7][2] = 0
v7 = v4
for i in range(0, 5):
if node[v7][0] > node[node[v7][2]][0]:
raise Exception()
v7 = node[v7][2]
print(v3)
except Exception as e:
# print(str(e))
continue

0x09 pi

在compute_pi()函数计算结束时候,查看相对应的内存即可。

0x10 secret

secret() 函数里面存在迭代,使用下面函数进行求解。

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
28
29
30
31
32
33
34
35
36
d = {
0x804c594: [0x24, 0x804c588, 0x804c57c],
0x804c588: [0x8, 0x804c558, 0x804c570],
0x804c57c: [0x32, 0x804c564, 0x804c54c],
0x804c570: [0x16, 0x804c504, 0x804c51c],
0x804c564: [0x2d, 0x804c540, 0x804c4f8],
0x804c558: [0x6, 0x804c534, 0x804c510],
0x804c54c: [0x6b, 0x804c528, 0x804c4ec],
0x804c540: [0x28, 0, 0],
0x804c534: [1, 0, 0],
0x804c528: [0x63, 0, 0],
0x804c51c: [0x23, 0, 0],
0x804c510: [0x7, 0, 0],
0x804c504: [0x14, 0, 0],
0x804c4f8: [0x2f, 0, 0],
0x804c4ec: [0x3e9, 0, 0],
}


def func7(a1, a2):
if a1 == 0:
return -1
if a2 < d[a1][0]:
return 2 * func7(d[a1][1], a2)
if a2 == d[a1][0]:
return 0
return 2 * func7(d[a1][2], a2) + 1


for v1 in range(1, 10001):
try:
if func7(0x804c594, v1) == 5:
print(v1)
except Exception as e:
print(str(e))
continue

文章作者:Xingjiali Zhang

最后更新:2019年09月03日 19:09:29

原始链接:http://yoursite.com/2019/09/03/lab01/

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 3.0 许可协议,转载请注明出处!