@@ -50,69 +50,80 @@ Patch the binary to remove the _set_timer_ function using NOPs.
50
50
51
51
Studying the binary, it seems that it's doing the Fibonacci sequence recursively, that's why it takes so long.
52
52
53
- First, we patch the binary so that it does not use such a huge number .
53
+ We can use Python to calculate the result iteratively. This will make the process a lot faster .
54
54
55
- ``` asm
56
- [0x0040074b]> wa mov edi, 5 @ 0x0040074f
57
- [0x0040074b]> pdf
58
- / (fcn) sym.calculate_key 16
59
- | sym.calculate_key ();
60
- | ; CALL XREF from sym.get_key (0x4007e1)
61
- | 0x0040074b 55 push rbp
62
- | 0x0040074c 4889e5 mov rbp, rsp
63
- | 0x0040074f bf05000000 mov edi, 5
64
- | 0x00400754 e8adffffff call sym.fib
65
- | 0x00400759 5d pop rbp
66
- \ 0x0040075a c3 ret
67
- ```
68
-
69
- Instead of doing the fibonacci sequence recurvsively, we can do it iteratively in c.
55
+ Code stolen from: https://gist.github.com/sgammon/4185115
70
56
71
- ``` c
72
- # include < stdio.h >
57
+ ``` python
58
+ n = 1083
73
59
74
- int main () {
75
- int n = 1083;
60
+ def fib (n ):
61
+ i = 0
62
+ nextterm = 1
63
+ present = 1
64
+ previous = 0
76
65
77
- long previous = 1;
78
- long current = 1;
79
- long next = 1;
66
+ while i < n:
67
+ nextterm = present + previous
68
+ present = previous
69
+ previous = nextterm
70
+ i = i + 1
71
+ return nextterm
80
72
81
- for (int i = 3; i <= n; ++i) {
82
- next = current + previous;
83
- previous = current;
84
- current = next;
85
- }
86
- printf ("%d\n", next);
87
- return 0;
88
- }
73
+ result = fib(n)
74
+ print (result & (2 ** 64 - 1 ))
89
75
```
90
76
91
- We can see that there's an integer overflow because it's negative. But it's just what we need to feed into our register.
77
+ We need to convert the huge number into a 64-bit number so that our program can process it. This is done by doing ` result & (2 ** 64 - 1) ` . We get ` 13519797236961659458 `
92
78
93
- ```
94
- $ gcc calculate.c
95
- $ ./a.out
96
- -1066907070
79
+ Now all we have to do is to patch the binary, and set ` rax = 13519797236961659458 ` . We will need 10 bytes to create this instruction. We can ovewrite from addresses ` 0x004007dc ` to ` 0x004007e5 ` .
80
+
81
+ ``` asm
82
+ / (fcn) sym.get_key 43
83
+ | sym.get_key ();
84
+ | ...
85
+ | ...
86
+ | 0x004007d7 e854fdffff call sym.imp.puts ; int puts(const char *s)
87
+ | 0x004007dc b800000000 mov eax, 0
88
+ | 0x004007e1 e865ffffff call sym.calculate_key
89
+ | 0x004007e6 8905d4082000 mov dword [obj.key], eax ; obj.__TMC_END ; [0x6010c0:4]=0
90
+ | 0x004007ec bfcb094000 mov edi, str.Done_calculating_key ; 0x4009cb ; "Done calculating key" ; const char *s
91
+ | 0x004007f1 e83afdffff call sym.imp.puts ; int puts(const char *s)
92
+ | ...
93
+ \ ...
97
94
```
98
95
99
- Set a break point after the _ fib _ function and edit _ rax _ to the value we calculated using the C program (-1066907070)
96
+ Now all we have left to do is to patch it and run it.
100
97
101
98
``` asm
102
- [0x0040074b]> db 0x00400759
103
- [0x0040074b]> dc
99
+ [0x004007ce]> wa mov rax, 13519797236961659458 @ 0x004007dc
100
+ Written 10 byte(s) (mov rax, 13519797236961659458) = wx 48b8424a68c0f4f79fbb
101
+ [0x004007ce]> pdf
102
+ / (fcn) sym.get_key 43
103
+ | sym.get_key ();
104
+ | ; CALL XREF from sym.main (0x400887)
105
+ | 0x004007ce 55 push rbp
106
+ | 0x004007cf 4889e5 mov rbp, rsp
107
+ | 0x004007d2 bfb8094000 mov edi, str.Calculating_key... ; 0x4009b8 ; "Calculating key..." ; const char *s
108
+ | 0x004007d7 e854fdffff call sym.imp.puts ; int puts(const char *s)
109
+ | 0x004007dc 48b8424a68c0. movabs rax, 0xbb9ff7f4c0684a42
110
+ | 0x004007e6 8905d4082000 mov dword [obj.key], eax ; obj.__TMC_END ; [0x6010c0:4]=0
111
+ | 0x004007ec bfcb094000 mov edi, str.Done_calculating_key ; 0x4009cb ; "Done calculating key" ; const char *s
112
+ | 0x004007f1 e83afdffff call sym.imp.puts ; int puts(const char *s)
113
+ | 0x004007f6 90 nop
114
+ | 0x004007f7 5d pop rbp
115
+ \ 0x004007f8 c3 ret
116
+ ```
117
+
118
+ ```
119
+ $ ./be-quick-or-be-dead-2_patched
104
120
Be Quick Or Be Dead 2
105
121
=====================
106
122
107
123
Calculating key...
108
- hit breakpoint at: 400759
109
- [0x0040074b]> dr rax = -1066907070
110
- 0x00000005 ->0xffffffffc0684a42
111
- [0x0040074b]> dc
112
124
Done calculating key
113
125
Printing flag:
114
126
picoCTF{the_fibonacci_sequence_can_be_done_fast_88f31f48}
115
- [0x7f1d298a3916]>
116
127
```
117
128
118
129
And we get the flag.
0 commit comments