bomb lab phase_dufused

bomb lab을 다 깻지만 히든 스테이지가 있다고 하더라. 그래서 해보고자 했다.

phase로 시작하는 함수가 있나 찾아보는데 defused를 찾았다.

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
43
44
(gdb) disas phase
phase_1        phase_2        phase_3        phase_4        phase_5        phase_6        phase_defused  phases.h
(gdb) disas phase
phase_1        phase_2        phase_3        phase_4        phase_5        phase_6        phase_defused  phases.h
(gdb) disas phase
phase_1        phase_2        phase_3        phase_4        phase_5        phase_6        phase_defused  phases.h
(gdb) disas phase
No symbol "phase" in current context.
(gdb) disas phase_defused
Dump of assembler code for function phase_defused:
   0x00000000004015a3 <+0>:	sub    $0x78,%rsp
   0x00000000004015a7 <+4>:	mov    %fs:0x28,%rax
   0x00000000004015b0 <+13>:	mov    %rax,0x68(%rsp)
   0x00000000004015b5 <+18>:	xor    %eax,%eax
   0x00000000004015b7 <+20>:	cmpl   $0x6,0x2021ce(%rip)        # 0x60378c <num_input_strings>
   0x00000000004015be <+27>:	jne    0x40161e <phase_defused+123>
   0x00000000004015c0 <+29>:	lea    0x10(%rsp),%r8
   0x00000000004015c5 <+34>:	lea    0xc(%rsp),%rcx
   0x00000000004015ca <+39>:	lea    0x8(%rsp),%rdx
   0x00000000004015cf <+44>:	mov    $0x4025f9,%esi
   0x00000000004015d4 <+49>:	mov    $0x603890,%edi
   0x00000000004015d9 <+54>:	callq  0x400bb0 <__isoc99_sscanf@plt>
   0x00000000004015de <+59>:	cmp    $0x3,%eax
   0x00000000004015e1 <+62>:	jne    0x401614 <phase_defused+113>
   0x00000000004015e3 <+64>:	mov    $0x402602,%esi
   0x00000000004015e8 <+69>:	lea    0x10(%rsp),%rdi
   0x00000000004015ed <+74>:	callq  0x40131d <strings_not_equal>
   0x00000000004015f2 <+79>:	test   %eax,%eax
   0x00000000004015f4 <+81>:	jne    0x401614 <phase_defused+113>
   0x00000000004015f6 <+83>:	mov    $0x4024d8,%edi
   0x00000000004015fb <+88>:	callq  0x400ae0 <puts@plt>
   0x0000000000401600 <+93>:	mov    $0x402500,%edi
   0x0000000000401605 <+98>:	callq  0x400ae0 <puts@plt>
   0x000000000040160a <+103>:	mov    $0x0,%eax
   0x000000000040160f <+108>:	callq  0x401234 <secret_phase>
   0x0000000000401614 <+113>:	mov    $0x402538,%edi
   0x0000000000401619 <+118>:	callq  0x400ae0 <puts@plt>
   0x000000000040161e <+123>:	mov    0x68(%rsp),%rax
   0x0000000000401623 <+128>:	xor    %fs:0x28,%rax
   0x000000000040162c <+137>:	je     0x401633 <phase_defused+144>
   0x000000000040162e <+139>:	callq  0x400b00 <__stack_chk_fail@plt>
   0x0000000000401633 <+144>:	add    $0x78,%rsp
   0x0000000000401637 <+148>:	retq   
End of assembler dump.

여기서 secret_phase를 부르는걸 알았다. 정확하게 어떻게 진입하는지 알기위해서 bomb.c를 봤더니 각 phase함수가 끝낼때마다. phase_defuse를 부르더라. 아 근데 진입조건찾는거부터 난관이다 진입조건을 체크해보니 전혀 모르겠다. 근데 주석으로 친절히 설명해놨다. num_input_strings 변수인데 아마 줄을 입력받을때 여기서 저장을 해놓지 않을까? 란 생각을 했다.

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
(gdb) disas read_line
Dump of assembler code for function read_line:
   0x000000000040147d <+0>:	sub    $0x8,%rsp
   0x0000000000401481 <+4>:	mov    $0x0,%eax
   0x0000000000401486 <+9>:	callq  0x4013db <skip>
   0x000000000040148b <+14>:	test   %rax,%rax
   0x000000000040148e <+17>:	jne    0x4014fe <read_line+129>
   0x0000000000401490 <+19>:	mov    0x2022d9(%rip),%rax        # 0x603770 <stdin@@GLIBC_2.2.5>
   0x0000000000401497 <+26>:	cmp    %rax,0x2022f2(%rip)        # 0x603790 <infile>
   0x000000000040149e <+33>:	jne    0x4014b4 <read_line+55>
   0x00000000004014a0 <+35>:	mov    $0x4025b5,%edi
   0x00000000004014a5 <+40>:	callq  0x400ae0 <puts@plt>
   0x00000000004014aa <+45>:	mov    $0x8,%edi
   0x00000000004014af <+50>:	callq  0x400be0 <exit@plt>
   0x00000000004014b4 <+55>:	mov    $0x4025d3,%edi
   0x00000000004014b9 <+60>:	callq  0x400ab0 <getenv@plt>
   0x00000000004014be <+65>:	test   %rax,%rax
   0x00000000004014c1 <+68>:	je     0x4014cd <read_line+80>
   0x00000000004014c3 <+70>:	mov    $0x0,%edi
   0x00000000004014c8 <+75>:	callq  0x400be0 <exit@plt>
   0x00000000004014cd <+80>:	mov    0x20229c(%rip),%rax        # 0x603770 <stdin@@GLIBC_2.2.5>
   0x00000000004014d4 <+87>:	mov    %rax,0x2022b5(%rip)        # 0x603790 <infile>
   0x00000000004014db <+94>:	mov    $0x0,%eax
   0x00000000004014e0 <+99>:	callq  0x4013db <skip>
   0x00000000004014e5 <+104>:	test   %rax,%rax
   0x00000000004014e8 <+107>:	jne    0x4014fe <read_line+129>
   0x00000000004014ea <+109>:	mov    $0x4025b5,%edi
   0x00000000004014ef <+114>:	callq  0x400ae0 <puts@plt>
   0x00000000004014f4 <+119>:	mov    $0x0,%edi
   0x00000000004014f9 <+124>:	callq  0x400be0 <exit@plt>
   0x00000000004014fe <+129>:	mov    0x202288(%rip),%esi        # 0x60378c <num_input_strings>
   0x0000000000401504 <+135>:	movslq %esi,%rax
   0x0000000000401507 <+138>:	lea    (%rax,%rax,4),%rdx
   0x000000000040150b <+142>:	shl    $0x4,%rdx
   0x000000000040150f <+146>:	add    $0x6037a0,%rdx
   0x0000000000401516 <+153>:	mov    $0x0,%eax
   0x000000000040151b <+158>:	mov    $0xffffffffffffffff,%rcx
   0x0000000000401522 <+165>:	mov    %rdx,%rdi
   0x0000000000401525 <+168>:	repnz scas %es:(%rdi),%al
   0x0000000000401527 <+170>:	not    %rcx
   0x000000000040152a <+173>:	sub    $0x1,%rcx
   0x000000000040152e <+177>:	cmp    $0x4e,%ecx
   0x0000000000401531 <+180>:	jle    0x401579 <read_line+252>
   0x0000000000401533 <+182>:	mov    $0x4025de,%edi
   0x0000000000401538 <+187>:	callq  0x400ae0 <puts@plt>
   0x000000000040153d <+192>:	mov    0x202249(%rip),%eax        # 0x60378c <num_input_strings>
---Type <return> to continue, or q <return> to quit---
   0x0000000000401543 <+198>:	lea    0x1(%rax),%edx
   0x0000000000401546 <+201>:	mov    %edx,0x202240(%rip)        # 0x60378c <num_input_strings>
   0x000000000040154c <+207>:	cltq   
   0x000000000040154e <+209>:	imul   $0x50,%rax,%rax
   0x0000000000401552 <+213>:	movabs $0x636e7572742a2a2a,%rdi
   0x000000000040155c <+223>:	mov    %rdi,0x6037a0(%rax)
   0x0000000000401563 <+230>:	movabs $0x2a2a2a64657461,%rdi
   0x000000000040156d <+240>:	mov    %rdi,0x6037a8(%rax)
   0x0000000000401574 <+247>:	callq  0x40141c <explode_bomb>
   0x0000000000401579 <+252>:	sub    $0x1,%ecx
   0x000000000040157c <+255>:	movslq %ecx,%rcx
   0x000000000040157f <+258>:	movslq %esi,%rax
   0x0000000000401582 <+261>:	lea    (%rax,%rax,4),%rax
   0x0000000000401586 <+265>:	shl    $0x4,%rax
   0x000000000040158a <+269>:	movb   $0x0,0x6037a0(%rcx,%rax,1)
   0x0000000000401592 <+277>:	lea    0x1(%rsi),%eax
   0x0000000000401595 <+280>:	mov    %eax,0x2021f1(%rip)        # 0x60378c <num_input_strings>
   0x000000000040159b <+286>:	mov    %rdx,%rax
   0x000000000040159e <+289>:	add    $0x8,%rsp
   0x00000000004015a2 <+293>:	retq   
End of assembler dump.

코드는 읽지않았지만 주석을 보니 대충 그런것 같다.

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
(gdb) c
Continuing.
Phase 1 defused. How about the next one?

Breakpoint 1, 0x00000000004015b7 in phase_defused ()
(gdb) x/4wx 0x60378c
0x60378c <num_input_strings>:	0x00000002	0x00604260	0x00000000	0x00000000
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) n
Program not restarted.
(gdb) c
Continuing.
That's number 2.  Keep going!

Breakpoint 1, 0x00000000004015b7 in phase_defused ()
(gdb) x/4wx 0x60378c
0x60378c <num_input_strings>:	0x00000003	0x006042600x00000000	0x00000000
(gdb) c
Continuing.
Halfway there!

Breakpoint 1, 0x00000000004015b7 in phase_defused ()
(gdb) x/4wx 0x60378c
0x60378c <num_input_strings>:	0x00000004	0x006042600x00000000	0x00000000
(gdb) c
Continuing.
So you got that one.  Try this one.

Breakpoint 1, 0x00000000004015b7 in phase_defused ()
(gdb) x/4wx 0x60378c
0x60378c <num_input_strings>:	0x00000005	0x006042600x00000000	0x00000000
(gdb) c
Continuing.
Good work!  On to the next...

Breakpoint 1, 0x00000000004015b7 in phase_defused ()
(gdb) x/4wx 0x60378c
0x60378c <num_input_strings>:	0x00000006	0x006042600x00000000	0x00000000

비교 부분을 break 처리하고 확인하니 줄이 입력될때마다 1씩 증가한다 따라서 phase6이 끝나면 진입한다. 그뒤에 sscnaf를 부르고 eax가 3개인지 봐서는 추가로 값을 입력 받는걸 처리하는것같다.

인자로 들어가는 고정 문자열을 뽑아봤다

1
2
3
4
(gdb) x/s 0x4025f9
0x4025f9:	"%d %d %s"
(gdb) x/s 0x603890
0x603890 <input_strings+240>:	"40 2"

phase_4의 정답 값이다 아마 이뒤에 %s를 넣고 여기에 대한 답을 원하는 듯하다.

1
2
(gdb) x/s 0x402602
0x402602:	"DrEvil"

이를 phase_4 정답 뒤에 붙이면 될듯하다. 그러고 실행했더니 해당 문구가 떴다.

1
2
Curses, you've found the secret phase!
But finding it and solving it are quite different...

이제 secret_phase를 분석해보자.

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
(gdb) disas secret_phase 
Dump of assembler code for function secret_phase:
   0x0000000000401234 <+0>:	push   %rbx
   0x0000000000401235 <+1>:	callq  0x40147d <read_line>
   0x000000000040123a <+6>:	mov    $0xa,%edx
   0x000000000040123f <+11>:	mov    $0x0,%esi
   0x0000000000401244 <+16>:	mov    %rax,%rdi
   0x0000000000401247 <+19>:	callq  0x400b90 <strtol@plt>
   0x000000000040124c <+24>:	mov    %rax,%rbx
   0x000000000040124f <+27>:	lea    -0x1(%rax),%eax
   0x0000000000401252 <+30>:	cmp    $0x3e8,%eax
   0x0000000000401257 <+35>:	jbe    0x40125e <secret_phase+42>
   0x0000000000401259 <+37>:	callq  0x40141c <explode_bomb>
   0x000000000040125e <+42>:	mov    %ebx,%esi
   0x0000000000401260 <+44>:	mov    $0x603110,%edi
   0x0000000000401265 <+49>:	callq  0x4011f6 <fun7>
   0x000000000040126a <+54>:	test   %eax,%eax
   0x000000000040126c <+56>:	je     0x401273 <secret_phase+63>
   0x000000000040126e <+58>:	callq  0x40141c <explode_bomb>
   0x0000000000401273 <+63>:	mov    $0x4023e0,%edi
   0x0000000000401278 <+68>:	callq  0x400ae0 <puts@plt>
   0x000000000040127d <+73>:	callq  0x4015a3 <phase_defused>
   0x0000000000401282 <+78>:	pop    %rbx
   0x0000000000401283 <+79>:	retq   
End of assembler dump.

3e8+1 아니 근데 분석하려는데 계속 sigkill을 쏜다 왜이러지? 혹시 sol.txt에 값을 적어서 봐야하는가? 느낌상 해당 함수 실행시간에 시간제한이 있는것같다. break point를 걸고 확인하고 그뒤를 실행하면 프로그램이 터지는것같다. 따라서 값은 sol.txt에서 수정하면서 하기로했다. 아 근데 하고보니까 그냥 sol.txt에만 값을 적는것으로 충분한듯하다.

0x0000000000401252을 통과하기 위해 rax 값이 맞게 세팅을 해야하는거같다.

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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
(gdb) disas strtol
strtol         strtol@plt     strtol_l.c     strtold.c      strtold_l.c    strtoll
strtol.c       strtol_l       strtold        strtold_l      strtold_nan.c  strtoll_l
(gdb) disas strtol@plt
No symbol "plt" in current context.
(gdb) disas strtol
Dump of assembler code for function __strtol:
   0x00007ffff7a291c0 <+0>:	mov    0x3a5c01(%rip),%rax        # 0x7ffff7dcedc8
   0x00007ffff7a291c7 <+7>:	xor    %ecx,%ecx
   0x00007ffff7a291c9 <+9>:	mov    %fs:(%rax),%r8
   0x00007ffff7a291cd <+13>:	jmpq   0x7ffff7a29210 <__GI_____strtol_l_internal>
End of assembler dump.
(gdb) disas 0x400b90
Dump of assembler code for function strtol@plt:
   0x0000000000400b90 <+0>:	jmpq   *0x2024f2(%rip)        # 0x603088
   0x0000000000400b96 <+6>:	pushq  $0xe
   0x0000000000400b9b <+11>:	jmpq   0x400aa0
End of assembler dump.
(gdb) disas 0x603088
Dump of assembler code for function _GLOBAL_OFFSET_TABLE_:
   0x0000000000603000:	sub    %ch,(%rsi)
   0x0000000000603002:	(bad)  
   0x0000000000603003:	add    %al,(%rax)
   0x0000000000603005:	add    %al,(%rax)
   0x0000000000603007:	add    %dh,-0x1f(%rax)
   0x000000000060300a:	push   %rdi
   0x000000000060300c:	(bad)  
   0x000000000060300d:	jg     0x60300f
   0x000000000060300f:	add    %ah,-0x82139(%rax)
   0x0000000000603015:	jg     0x603017
   0x0000000000603017:	add    %dh,0x400a(%rsi)
   0x000000000060301d:	add    %al,(%rax)
   0x000000000060301f:	add    %al,%dh
   0x0000000000603021:	or     0x0(%rax),%al
   0x0000000000603024:	add    %al,(%rax)
   0x0000000000603026:	add    %al,(%rax)
   0x0000000000603028:	(bad)  
   0x0000000000603029:	or     0x0(%rax),%al
   0x000000000060302c:	add    %al,(%rax)
   0x000000000060302e:	add    %al,(%rax)
   0x0000000000603030:	xor    %cl,-0x5a(%rdx)
   0x0000000000603033:	idiv   %edi
   0x0000000000603035:	jg     0x603037
   0x0000000000603037:	add    %dh,%dh
   0x0000000000603039:	or     0x0(%rax),%al
   0x000000000060303c:	add    %al,(%rax)
   0x000000000060303e:	add    %al,(%rax)
   0x0000000000603040:	(bad)  
   0x0000000000603041:	or     0x0(%rax),%eax
   0x0000000000603044:	add    %al,(%rax)
   0x0000000000603046:	add    %al,(%rax)
   0x0000000000603048:	(bad)  
   0x0000000000603049:	or     0x0(%rax),%eax
   0x000000000060304c:	add    %al,(%rax)
   0x000000000060304e:	add    %al,(%rax)
   0x0000000000603050:	or     %es:0x0(%rax),%eax
   0x0000000000603054:	add    %al,(%rax)
   0x0000000000603056:	add    %al,(%rax)
   0x0000000000603058:	or     %ss:0x0(%rax),%eax
   0x000000000060305c:	add    %al,(%rax)
   0x000000000060305e:	add    %al,(%rax)
   0x0000000000603060:	mov    $0x5a,%al
   0x0000000000603062:	movabs 0xa62b9000007ffff7,%al
   0x000000000060306b:	idiv   %edi
---Type <return> to continue, or q <return> to quit---
   0x000000000060306d:	jg     0x60306f
   0x000000000060306f:	add    %dl,0x2e(%rax)
   0x0000000000603072:	movabs %al,0x400b7600007ffff7
   0x000000000060307b:	add    %al,(%rax)
   0x000000000060307d:	add    %al,(%rax)
   0x000000000060307f:	add    %al,0x400b(%rsi)
   0x0000000000603085:	add    %al,(%rax)
   0x0000000000603087:	add    %dl,0x400b(%rsi)
   0x000000000060308d:	add    %al,(%rax)
   0x000000000060308f:	add    %ah,0x400b(%rsi)
   0x0000000000603095:	add    %al,(%rax)
   0x0000000000603097:	add    %dl,0x5(%rax)
   0x000000000060309a:	cmpsb  %es:(%rdi),%ds:(%rsi)
   0x000000000060309b:	idiv   %edi
   0x000000000060309d:	jg     0x60309f
   0x000000000060309f:	add    %al,%dh
   0x00000000006030a1:	or     0x0(%rax),%eax
   0x00000000006030a4:	add    %al,(%rax)
   0x00000000006030a6:	add    %al,(%rax)
   0x00000000006030a8:	movabs 0xe600007ffff7a62e,%al
   0x00000000006030b1:	or     0x0(%rax),%eax
   0x00000000006030b4:	add    %al,(%rax)
   0x00000000006030b6:	add    %al,(%rax)
   0x00000000006030b8:	testb  $0x40,(%rbx)
   0x00000000006030bb:	add    %al,(%rax)
   0x00000000006030bd:	add    %al,(%rax)
   0x00000000006030bf:	add    %al,(%rsi)
   0x00000000006030c1:	or     $0x40,%al
   0x00000000006030c3:	add    %al,(%rax)
   0x00000000006030c5:	add    %al,(%rax)
   0x00000000006030c7:	add    %dl,(%rsi)
   0x00000000006030c9:	or     $0x40,%al
   0x00000000006030cb:	add    %al,(%rax)
   0x00000000006030cd:	add    %al,(%rax)
   0x00000000006030cf:	add    %ah,(%rax)
   0x00000000006030d1:	rex.WB movabs 0x400c3600007ffff7,%rax
   0x00000000006030db:	add    %al,(%rax)
   0x00000000006030dd:	add    %al,(%rax)
   0x00000000006030df:	add    %al,0xc(%rsi)
   0x00000000006030e2:	add    %al,(%rax)
   0x00000000006030e5:	add    %al,(%rax)
   0x00000000006030e7:	add    %al,(%rax)
End of assembler dump.

솔직히 너무 답이없어서 포기하고 이부분 뒤의 rax 값을 보니 그냥 입력한 숫자가 그대로 들어가는 듯하다.따라서 그뒤의 검사를 하는 부분에 +1만 하면될듯하다. 3e8 은 1000이다 따라서 1001이하가 입력값 그후 fun7을 부른다. fun7을 부른 뒤의 어셈을 분석해보니 eax가 0이 되게하는게 목표이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
(gdb) disas fun7
Dump of assembler code for function fun7:
   0x00000000004011f6 <+0>:	sub    $0x8,%rsp
   0x00000000004011fa <+4>:	test   %rdi,%rdi
   0x00000000004011fd <+7>:	je     0x40122a <fun7+52>
   0x00000000004011ff <+9>:	mov    (%rdi),%edx
   0x0000000000401201 <+11>:	cmp    %esi,%edx
   0x0000000000401203 <+13>:	jle    0x401212 <fun7+28>
   0x0000000000401205 <+15>:	mov    0x8(%rdi),%rdi
   0x0000000000401209 <+19>:	callq  0x4011f6 <fun7>
   0x000000000040120e <+24>:	add    %eax,%eax
   0x0000000000401210 <+26>:	jmp    0x40122f <fun7+57>
   0x0000000000401212 <+28>:	mov    $0x0,%eax
   0x0000000000401217 <+33>:	cmp    %esi,%edx
   0x0000000000401219 <+35>:	je     0x40122f <fun7+57>
   0x000000000040121b <+37>:	mov    0x10(%rdi),%rdi
   0x000000000040121f <+41>:	callq  0x4011f6 <fun7>
   0x0000000000401224 <+46>:	lea    0x1(%rax,%rax,1),%eax
   0x0000000000401228 <+50>:	jmp    0x40122f <fun7+57>
   0x000000000040122a <+52>:	mov    $0xffffffff,%eax
   0x000000000040122f <+57>:	add    $0x8,%rsp
   0x0000000000401233 <+61>:	retq   
End of assembler dump.

eax를 0으로 되게 하기 위해서 28줄로 옮기고 esi 를 edx와 같게 하면된다. esi = 입력값 *edi = 0x24

근데 보니까 0x0000000000401201을 통과하기위해서는 입력값을 edi의 값과 같게만 하면된다.

36

1
2
3
4
5
(gdb) c
Continuing.
Wow! You've defused the secret stage!
Congratulations! You've defused the bomb!
[Inferior 1 (process 4073) exited normally]
Posted 2020-08-14