Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
lighttpd-win32-dotdot-space — lighttpd 1.4.85 - High - Remote - Path - native Win32 GET /..%20/ reads outside document-root | Kitploit
Tools/GitHubGitHub/abraxas/lighttpd-win32-dotdot-space
Vulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration TestingLabs & Practice
GitHubabraxas/lighttpd-win32-dotdot-space

lighttpd-win32-dotdot-space

lighttpd 1.4.85 - High - Remote - Path - native Win32 GET /..%20/ reads outside document-root

View Repository
2 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

Abraxas Labs - lighttpd-win32-dotdot-space

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  lighttpd-win32-dotdot-space

lighttpd-win32-dotdot-space

Class: File read Reach: Remote

lighttpd 1.4.85 (4852959) - lighttpd

Native _WIN32 staticfile joins document-root to rel_path after buffer_path_simplify. Simplify only folds ../ when the third byte is /. http_response_prepare_physical strips trailing spaces and dots from the whole path only. GET /..%20/windows/win.ini therefore stays /.. /windows/win.ini. _wstati64 / _wopen without a \\?\ prefix then let Win32 strip the space per component and treat that segment as ...

Unauthenticated GET/HEAD on native Windows lighttpd reads a regular file outside document-root that the worker account can open. Unix/Linux is not this leftover. File read, not RCE.

The lab is a gadget of those pin functions. It is not a live native Win32 worker. Last line uses how=gadget.

IDno CVE yet
ClassFile read (path traversal, native Win32 ..%20/)
ReachRemote (unauthenticated GET/HEAD)
CWECWE-22
CVSSHigh: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Productlighttpd1.4
Affected1.4.85 (4852959e67ef51ea68084984400d3264b854c97d) native _WIN32
Authnone. Default mod_staticfile
LicenseGNU Affero GPL v3.0
Lab127.0.0.1 only, how=gadget

What an attacker can do

Needs native Windows lighttpd serving static files. Worker account must be able to open the target regular file.

PrivilegeMethod / sinkLab-proven or inferred
Read a file outside document-rootUnauth GET /..%20/<name>Lab-proven (gadget). HTTP 200 body is the parent secret
Same class for other trailing ASCII space/dot on a non-final .. componenturl-decode then simplify keeps .. Lab-proven for %20. Inferred for other trailing space/dot
HEAD the same pathstaticfile HEADInferred. Lab used GET
Negative: real /../buffer_path_simplify folds ../Lab-proven. 404, simplified /windows/win.ini, no witness
Negative: Unix POSIX open of the unsimplified physical stringopen("/srv/htdocs/.. /windows/win.ini")Lab-proven. ENOENT

Closed on this leftover: Unix/Linux staticfile; Cygwin (same strip, POSIX open); 1.4.85 %5C parseopt; CVE-2018-19052 alias; CVE-2014-2324 Host. Not RCE. Not a write.

How I found it

I pinned tag lighttpd-1.4.85. Twenty hunts. Default Unix/Linux staticfile, FastCGI, proxy, TLS, auth, HTTP/2, alias/rewrite: none at this bar. The 1.4.81-1.4.85 parser wave already closed trailers, CGI header conflicts, and invalid backend Content-Length.

buffer_path_simplify only folds ../ when walk[2] == '/'. WIN32 strip in http_response_prepare_physical (src/response.c 334-360) is the whole-path tail. _wstati64 / _wopen (src/fs_win32.c 24-77) pass UTF-16 without \\?\, so Win32 strips trailing spaces per component and .. becomes ... Physical join is doc_root + rel_path with no post-stat basedir check.

Wrong turns already recorded: treating Unix ENOENT as "not a bug" (it is the negative control); calling Cygwin native Win32; claiming 1.4.85 %5C is this leftover; inflating file read to RCE. Theatre: a reverse shell. The oracle is a 200 body from the parent of document-root.

Lab

python3 lighttpd-win32-dotdot-space-Abraxas-Labs.py

or

cd lab
./run.sh

The lab is a faithful gadget of buffer_urldecode_path, buffer_path_simplify (Win32 '\\' map), the response.c tail strip, and _wstati64 without \\?\. Unix POSIX open is the negative control. Win32 resolve is implemented as the same per-component trailing-space strip, then . / .., then a POSIX open of the resolved path. Loopback HTTP 127.0.0.1:19400.

  1. GET /index.html -> 200 public-index, no witness.
  2. GET /../windows/win.ini -> 404, simplified /windows/win.ini.
  3. GET /..%20/windows/win.ini -> decoded /.. /windows/win.ini, simplify kept the space, Unix ENOENT, Win32 resolved /srv/windows/win.ini, 200 witness.
SUCCESS lighttpd-win32-dotdot-space how=gadget win32-get=200 unix-open=enoent simplify-kept-dotdot-space=yes LIGHTTPD-WIN32-DOTDOT-SPACE-WITNESS

The fix

Strip trailing spaces and dots per path component before simplify, or prefix Win32 opens with \\?\ and reject a physical path that does not stay under document-root.

References

  • github.com/lighttpd/lighttpd1.4 tag lighttpd-1.4.85 (4852959e67ef51ea68084984400d3264b854c97d)
  • src/buffer.c · src/response.c · src/fs_win32.c
  • Nearby patched (not this leftover): CVE-2025-12642 trailers · 1.4.85 %5C parseopt · CVE-2018-19052 alias · CVE-2014-2324 Host
  • CWE-22

License

GNU Affero GPL v3.0. See LICENSE. Loopback lab only. No warranty.

Download Tool