Skip to content

Commit a9e5134

Browse files
committed
Updated solution for be-quick-or-be-dead-2
1 parent 4e31b1f commit a9e5134

File tree

5 files changed

+74
-65
lines changed

5 files changed

+74
-65
lines changed

Reversing/be-quick-or-be-dead-2/README.md

+55-44
Original file line numberDiff line numberDiff line change
@@ -50,69 +50,80 @@ Patch the binary to remove the _set_timer_ function using NOPs.
5050

5151
Studying the binary, it seems that it's doing the Fibonacci sequence recursively, that's why it takes so long.
5252

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.
5454

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
7056

71-
```c
72-
#include <stdio.h>
57+
```python
58+
n = 1083
7359

74-
int main() {
75-
int n = 1083;
60+
def fib(n):
61+
i = 0
62+
nextterm = 1
63+
present = 1
64+
previous = 0
7665

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
8072

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))
8975
```
9076

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`
9278

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+
\ ...
9794
```
9895

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.
10097

10198
```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
104120
Be Quick Or Be Dead 2
105121
=====================
106122
107123
Calculating key...
108-
hit breakpoint at: 400759
109-
[0x0040074b]> dr rax = -1066907070
110-
0x00000005 ->0xffffffffc0684a42
111-
[0x0040074b]> dc
112124
Done calculating key
113125
Printing flag:
114126
picoCTF{the_fibonacci_sequence_can_be_done_fast_88f31f48}
115-
[0x7f1d298a3916]>
116127
```
117128

118129
And we get the flag.

Reversing/be-quick-or-be-dead-2/solution/Makefile

-4
This file was deleted.
Binary file not shown.

Reversing/be-quick-or-be-dead-2/solution/calculate.c

-17
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
n = 1083
2+
3+
def fib(n):
4+
i = 0
5+
nextterm = 1
6+
present = 1
7+
previous = 0
8+
9+
while i < n:
10+
nextterm = present + previous
11+
present = previous
12+
previous = nextterm
13+
i = i + 1
14+
#print nextterm
15+
16+
return nextterm
17+
18+
result = fib(n)
19+
print(result & (2 ** 64 - 1))

0 commit comments

Comments
 (0)