/CVE-2024-38473-Nuclei-Template

Nuclei template to detect Apache servers vulnerable to CVE-2024-38473

Primary LanguageHTML

CVE-2024-38473 Nuclei Template

image

Description

Nuclei template designed to detect Apache servers vulnerable to CVE-2024-38473. It first identifies servers running Apache < 2.4.60 with default PHP-FPM settings. Then, it fuzzes for potential PHP files protected by ACLs that might be bypassed due to this vulnerability.

Install

  1. To use this Nuclei template, you need to clone the repository. You can do this by running the following command:

    git clone https://github.com/juanschallibaum/CVE-2024-38473-Nuclei-Template
  2. Navigate to the cloned repository directory:

    cd CVE-2024-38473-Nuclei-Template

Usage

  • Run nuclei template in single host:

    nuclei -t CVE-2024-38473.yaml -u http://example.com
  • Run nuclei template against a list of hosts:

    nuclei -t CVE-2024-38473.yaml -l hosts.txt
  • Run nuclei template in single host specifying a valid .html or .php file:

    nuclei -t CVE-2024-38473.yaml -u http://example.com/valid.php

    Running Nuclei this way may yield a higher detection rate. You can also include URLs in this format within the hosts file to run the template against that list.

Testing Environment

To easily test the CVE-2024-38473 vulnerability, you can set up a vulnerable environment using Docker. Follow these steps to quickly verify the effectiveness of the Nuclei template:

  1. Ensure Docker Daemon is Running: Make sure the Docker daemon is running on your system. You can start it with the following command if it's not already running:

    sudo systemctl start docker
  2. Run the Docker Container: Within the repository directory, use the following Docker command to start a container with a vulnerable Apache and PHP-FPM setup:

    docker run -p 8787:80 -v "$(pwd)/test-env-webroot:/app" webdevops/php-apache:7.1
  3. Test the Vulnerability:

    • Manually: Open your web browser and navigate to http://localhost:8787 to interact with the Apache server running in the Docker container. Access http://localhost:8787/info.php to test the vulnerability. This file is protected by an ACL, and if the ACL bypass is successful, you will see the output of phpinfo():

      2024-08-23 00-28-42

    • Using Nuclei Template: Run the following Nuclei command to test the server with the template:

      nuclei -t CVE-2024-38473.yaml -u http://localhost:8787

Context

On August 8, 2024, security researcher Orange Tsai gave a presentation at Black Hat USA 2024 titled: Confusion Attacks: Exploiting Hidden Semantic Ambiguity in Apache HTTP Server!. In this presentation, he reported multiple vulnerabilities affecting Apache HTTP Server. He explained that Apache has a highly modular architecture, composed of hundreds of modules, each performing its function while reading and writing to a shared structure called request_rec, which consists of nearly 100 fields.

The root cause of the vulnerabilities reported by the security researcher lies in the inconsistency in how different Apache modules treats the various fields of the shared structure. For example, mod_authz_core treats the field r->filename as a file, while mod_proxy treats it as a URL, leading to discrepancies that result in a wide range of vulnerabilities.

Vulnerability Details

In his presentation, Orange Tsai defines a type of attack called "Filename Confusion." Although this attack has a varied attack surface, CVE-2024-38473, which we cover in this template, refers to how we can apply the "Filename Confusion" attack to bypass Apache ACLs and gain access to restricted files.

The issue arises when Apache's authentication module, mod_authz_core, treats the r->filename attribute as a file, while mod_proxy treats it as a URL. Due to this, Apache installations with PHP-FPM in their default configuration are affected by this vulnerability. Imagine that a server running Apache and PHP-FPM has an ACL configured like the following to protect access to the admin.php file with credentials:

<Files "admin.php">
    AuthType Basic 
    AuthName "Admin Panel"
    AuthUserFile "/etc/apache2/.htpasswd"
    Require valid-user
</Files>

Due to the vulnerability, it is possible to bypass ACLs like the one above that involve protecting an individual file. In fact, this can be done as easily as sending the following request: http://server/admin.php%3fooo.php.

To understand this in depth, it's important to consider that when Apache processes a request like the one above, the mod_authz_core module reads the value admin.php?fooo.php from the r->filename field of the shared structure. It treats this value as the name of the requested file, and when it compares it against the ACL, it does not match because admin.php?fooo.php is different from admin.php.

Then, since admin.php?fooo.php ends in .php, the request is handled by PHP-FPM. PHP-FPM removes everything following the ? in the filename received from Apache before processing it, treating it as a URL rather than a file. As a result, PHP-FPM will process admin.php directly. Because the ACL check was passed earlier, the attacker can access admin.php without authentication.

Nuclei Template

The current Nuclei template aims not only to discover protected files by brute force but also includes logic to identify when a server has a vulnerable Apache < 2.4.60 configuration with PHP-FPM, even if cases of files protected by ACLs are not detected. In the basic flow, it first tries to identify if the server has a vulnerable configuration, and then, if positive, it attempts to identify common files that may be protected by ACLs.

The idea behind detecting vulnerable configurations with Apache < 2.4.60 and PHP-FPM is based on two basic premises:

  • In a vulnerable configuration, if file.php exists on the server, then the request to http://server/file.php%3fooo.php would return the same 200 status code and the same body length as the request to http://server/file.php (because after PHP-FPM removes %3fooo.php, the requested file would be the same).

  • In a vulnerable configuration, if file.html exists on the server, then the request to http://server/file.html%3fooo.php would return 403 Access Denied. This is because PHP-FPM would attempt to load a file with a .html extension instead of .php, which by default is not allowed.

Detailed Template Flow

The template flow consists of 7 groups of requests. They need to be executed in order and must meet the respective match conditions to proceed to the next group of requests. This helps minimize the number of requests sent in vain when conditions are already known to be unmet.

Request #1

The template sends a request to index.phpooo.php%3fooo.php, which is a non-existent file. The idea is to filter out false positives in cases where index.php%3fooo.php returns a 200 status code and the same body as index.php, even when PHP-FPM is not configured. This could occur, for example, when there are rules that rewrite any requested file or files that start with "index" to index.php, such as:

RewriteRule . /index.php [L]
RewriteRule ^index\.php(.*)$ index.php [L]
RewriteRule ^index(.*)$ index.php [L]

This request should return a 200 status code if the server has rules like the ones mentioned above, or a 404 status code in normal cases where PHP-FPM might be configured. If this request does not return a 404 status code, the template will stop processing on this host.

Request #2

The template sends a request to foo.phpooo.php%3fooo.php which is a non-existent file. The idea is to filter out false positives in cases where index.html%3fooo.php returns a 403 status code, even when PHP-FPM is not configured. This could occur, for example, when there are rules that prohibit the %3f character anywhere in the URL or that restrict access to files ending with .php. Examples of such rules include:

<FilesMatch "\.php$">
   Require all denied
</FilesMatch>

RewriteCond %{REQUEST_URI} (%3f)
RewriteRule ^(.*)$ - [F]

This request should return a 403 status code if the server has rules like the ones mentioned above, or a 404 status code in normal cases where PHP-FPM might be configured. If this request does not return a 404 status code, the template will stop processing on this host.

Request #3

The template sends requests to identify some available files on the server. First, it tries to identify if index.php is available. Then, it checks for index.html and index.htm. Finally, it tests for the file present in the URL provided by the user if it exists. If Nuclei is run specifying a valid file in the URL, it can enhance detection effectiveness in cases where classic index files do not exist.

Request #4

The template sends a request to a non-existent file to filter out the last false positives in cases where index.php%3fooo.php returns a 200 status code and the same body as index.php, even when PHP-FPM is not configured. Some web servers, especially those that are not Apache, ignore everything following the %3f. Therefore, if we send index.php%3fooo.php, the server treats it as index.php. To filter these cases, the template send a request to index.php%3fooo.html (if index.php was found on the server) or index.html%3fooo.html (if index.html was found on the server). Since it ends with .html, in normal cases where PHP-FPM might be configured, it would not be processed by PHP-FPM and would be treated as a static file that logically does not exist, resulting in a 404 status code. However, it would return a 200 status code in cases we want to filter, where everything following the %3f is ignored. If this request does not return a 404 status code, the template will stop processing on this host.

Request #5

The template sends a request to identify the vulnerable configuration. There are 2 cases, of which at least one of the match conditions must be satisfied:

  • Case 1: In Request #3, index.php was found. In this case, if Apache < 2.4.60 and PHP-FPM is enabled with the default configuration, it should strip the %3fooo.php part and load index.php, resulting in a 200 response with the same length as obtained in Request #3. If mod_php or another handler is used, it would treat index.php%3fooo.php as the full file name and return a 404. For this case to match, the request must return 200 and a body with the same length as the response from Request #3.

  • Case 2: In Request #3, index.html was found. In this case, if Apache < 2.4.60 and PHP-FPM is enabled with the default configuration, it should strip the %3fooo.php part and attempt to load index.html, which would return a 403 Access Denied, as PHP-FPM would be trying to load a file with a disallowed extension. If mod_php or another handler is used, it would treat index.php%3fooo.php as the full file name and return a 404. For this case to match, the request must return 404.

Request #6

If the template has reached this point, it indicates that the server has a vulnerable configuration. Consequently, the template sends requests to fuzz for potential protected files that return a 403 status code or require authentication and return a 401 status code. By default, it attempts to identify only a handful of the most common and potentially protected file names. However, you can uncomment a line to use a custom wordlist with 350 possible PHP file names.

Request #7

The template sends a request to validate that the protected file identified in Request #6 returns a 200 status code with the bypass.

Considerations

  • If any match condition from Request #5 is met, it indicates that the server is running Apache < 2.4.60 with default PHP-FPM settings. This means that if there is an ACL protecting an individual file, it may be bypassed. However, many times these vulnerable configurations can be detected without identifying any protected files. By default, the template uses the wordlist wordlists/potential_protected_php_files_10.php to fuzz for protected files. This list includes the top 10 PHP file names most likely to be protected by ACLs. Alternatively, a larger wordlist with 350 entries is available: wordlists/potential_protected_php_files_350.php. To switch to the larger list, comment out the 10-entry wordlist and uncomment the 350-entry list in the YAML section of Request #6 in the template, as follows:

    #fuzz: wordlists/potential_protected_php_files_10.txt
    fuzz: wordlists/potential_protected_php_files_350.txt

    Using the larger wordlist can increase the chances of finding protected PHP files. However, the potential_protected_php_files_350.txt wordlist may contain uncommon PHP file names and may lack more common PHP file names that could be protected by ACLs. Therefore, any improvements or additions to the wordlist are welcome. Additionally, even larger custom wordlists can be employed for further exploration.

  • Note that bypassable ACLs may be configured for different virtual hosts, in .htaccess files in any directory of the application, not just the root directory. Therefore, to maximize the chance of identifying ACL-protected files, it is recommended to perform a thorough reconnaissance of directories and subdomains, and run the template against all identified URLs with different subdomains and directories.

  • Currently, the flow of Request #6 stops after identifying the first ACL-protected file. However, there might be more. This happens because I haven't found a way to fuzz multiple files with Nuclei, store the results, and then use them in a follow-up request to verify if the bypass actually grants access to the protected files. Therefore, any suggestions on how the template can be modified to identify multiple protected files and validate that they are indeed bypassable are also welcome.

Helpful Resources

Credits

All credits for reporting the vulnerabilities and conducting the outstanding research go to Orange Tsai. His extensive work on Apache HTTP Server vulnerabilities, including CVE-2024-38473, has significantly contributed to enhancing security awareness. I, Juan Schallibaum, am responsible solely for creating this Nuclei template to facilitate the testing and detection of CVE-2024-38473.

Disclaimer

Usage of this Nuclei template for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to adhere to all applicable local, state, and federal laws. The developers assume no liability for any misuse, damage, or legal consequences resulting from the use of this template. Always ensure you have explicit permission before conducting any security testing.