Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
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.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2022-46169 — Cacti 1.2.22 unauthenticated command injection | Kitploit
Tools/GitHubGitHub/k4pxd/cve-2022-46169
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & EducationRed Teaming
GitHubk4pxd/cve-2022-46169

CVE-2022-46169

Cacti 1.2.22 unauthenticated command injection

View Repository
8h 50m 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

CVE-2022-46169 — Cacti 1.2.22 Unauthenticated Command Injection


Download Tool
FieldDetails
ProductCacti
Affected version1.2.22
VulnerabilityUnauthenticated OS command injection
CVECVE-2022-46169
CWECWE-77 — Command Injection
SeverityCritical
CVSS v3.19.8
Attack vectorNetwork
AuthenticationNone
User interactionNone
ImpactConfidentiality / Integrity / Availability
Fixed version1.2.23
Vulnerable componentremote_agent.php
Additional componentlib/functions.php
Main vulnerable actionpolldata

The published CVSS vector is:

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

The official advisory rates it 9.8 Critical. (GitHub)

1. Root cause

There are actually two bugs chained together.

Stage 1 — Authorization bypass

Cacti's remote_agent.php accepts requests without normal authentication, but attempts to determine whether the requester is an authorized poller.

The authorization flow effectively does:

root@kitploit:~
HTTP request
     │
     ▼
remote_agent.php
     │
     ▼
remote_client_authorized()
     │
     ▼
get_client_addr()
     │
     ▼
gethostbyaddr()
     │
     ▼
poller table hostname comparison

The problem is get_client_addr().

In 1.2.22 it examines numerous HTTP-derived server variables, including forwarded-client-IP headers. The advisory explains that attacker-controlled HTTP_* values can influence the IP returned by this function. (GitHub)

That means the application can be tricked into believing:

root@kitploit:~
Attacker
   ↓
"my IP is the Cacti server"
   ↓
gethostbyaddr()
   ↓
Cacti server hostname
   ↓
matches poller table
   ↓
AUTHORIZED

So the attacker doesn't need a legitimate Cacti account.


2. The second vulnerability — command injection

After bypassing the authorization check, the interesting endpoint functionality is the polldata action.

The relevant execution path is approximately:

root@kitploit:~
remote_agent.php
      │
      ▼
    polldata
      │
      ▼
 poll_for_data()
      │
      ├── host_id
      ├── local_data_ids
      └── poller_id
              │
              ▼
       poller_item lookup
              │
              ▼
 POLLER_ACTION_SCRIPT_PHP
              │
              ▼
          proc_open()
              │
              ▼
       OS command execution

The important mistake is the handling of poller_id.

The application retrieves it using:

root@kitploit:~
get_nfilter_request_var()

rather than enforcing that it is an integer.

That attacker-controlled value eventually becomes part of a command passed to PHP's proc_open(). The official advisory explicitly identifies this as the command-injection primitive. (GitHub)

Conceptually:

root@kitploit:~
attacker-controlled input
        ↓
     poller_id
        ↓
 string concatenation
        ↓
     proc_open()
        ↓
 operating-system command

This is the critical part of the vulnerability.


3. Why it becomes RCE

The interesting thing for your PoC analysis is that neither bug alone is the whole story.

It's a vulnerability chain:

root@kitploit:~
        ┌──────────────────────────┐
        │ Unauthenticated attacker │
        └────────────┬─────────────┘
                     │
                     ▼
          remote_agent.php
                     │
                     ▼
        Authorization bypass
          via client IP logic
                     │
                     ▼
              polldata
                     │
                     ▼
            poller_item lookup
                     │
                     ▼
       POLLER_ACTION_SCRIPT_PHP
                     │
                     ▼
             attacker input
              → poller_id
                     │
                     ▼
                proc_open()
                     │
                     ▼
              Command execution
                     │
                     ▼
                    RCE

That's a very important distinction to make in your write-up:

CVE-2022-46169 is not simply "a bad parameter in remote_agent.php." It is a chained authorization-bypass + command-injection vulnerability.

The official advisory confirms that the vulnerable execution condition requires a poller_item whose action is POLLER_ACTION_SCRIPT_PHP. (GitHub)


4. Environmental prerequisite

Your PoC should explicitly document this because it is an important analytical detail.

The target needs a suitable poller_item configured with:

root@kitploit:~
POLLER_ACTION_SCRIPT_PHP

The Cacti advisory notes that this is common on production installations because predefined templates such as Device - Uptime and Device - Polling Time can create these entries. (GitHub)

So don't write:

"Every Cacti 1.2.22 installation is automatically exploitable."

A more technically accurate statement is:

Cacti 1.2.22 is vulnerable, and successful command execution depends on the presence of an appropriate poller_item configuration.


5. Why host_id and local_data_id matter

poll_for_data() doesn't simply execute the supplied poller_id.

It first queries poller_item using values corresponding to:

root@kitploit:~
host_id
local_data_id

Then it examines the resulting item's action.

The vulnerable condition is effectively:

root@kitploit:~
host_id
   +
local_data_id
   ↓
poller_item
   ↓
action == POLLER_ACTION_SCRIPT_PHP
   ↓
vulnerable execution path

The original advisory notes that these identifiers can be discovered because the relevant entries exist in the application's database, and that suitable entries are likely to exist on productive installations. (GitHub)

For a public PoC, I'd demonstrate this prerequisite explicitly rather than hiding it.


6. Safe PoC methodology

For something you're publishing, I recommend making the PoC demonstrate command execution without giving readers a weaponized reverse-shell payload.

For example, structure your demonstration as:

root@kitploit:~
1. Deploy Cacti 1.2.22 in an isolated VM
2. Configure a poller_item using POLLER_ACTION_SCRIPT_PHP
3. Confirm remote_agent.php is reachable
4. Demonstrate the authorization decision being influenced
5. Reach the polldata execution path
6. Use a harmless command-execution marker
7. Capture the resulting application/log evidence
8. Upgrade to 1.2.23
9. Repeat the test
10. Demonstrate that the vulnerability is no longer exploitable

That gives you a legitimate vulnerability demonstration without turning the write-up into a ready-made Internet RCE weapon.


7. Source-code analysis for your report

You can divide the vulnerable code into three areas.

A. remote_agent.php

Responsible for exposing the remote-agent functionality and dispatching the requested action.

root@kitploit:~
remote_agent.php
      │
      └── action = polldata
                 │
                 ▼
            poll_for_data()

B. lib/functions.php

Contains get_client_addr().

The problematic design is trusting HTTP-derived values when deciding the requester's actual network address.

The official advisory lists multiple HTTP-related variables that are inspected before falling back to the actual remote address. (GitHub)

C. proc_open()

The final dangerous sink is the construction of the PHP command executed through proc_open().

The advisory identifies the vulnerable flow as:

root@kitploit:~
poller_id
    ↓
get_nfilter_request_var()
    ↓
command construction
    ↓
proc_open()

(GitHub)


8. Why the patch fixes it

The Cacti advisory identifies two important remediation changes.

First, poller_id should be treated as an integer:

root@kitploit:~
get_nfilter_request_var()
             ↓
get_filter_request_var()

Second, the value should additionally be shell-escaped before being incorporated into the command:

root@kitploit:~
escapeshellarg($poller_id)

The advisory specifically recommends both measures. (GitHub)

The authorization side also needs to stop allowing an attacker to arbitrarily influence the client IP used for authorization. (GitHub)


9. Version comparison

root@kitploit:~
Cacti 1.2.22
     │
     ├── vulnerable
     ├── authorization bypass
     ├── command injection
     └── potential unauthenticated RCE
     
Cacti 1.2.23
     │
     └── CVE-2022-46169 patched

The vendor advisory lists 1.2.22 as affected and 1.2.23 as the patched 1.2.x release. (GitHub)

Amazon's security advisory independently describes the issue as allowing an unauthenticated attacker to execute arbitrary commands and gives it a 9.8 CVSS score. (AWS Training and Certification)


10. Good title for your published PoC

I'd use something like:

CVE-2022-46169 — Unauthenticated Command Injection / RCE in Cacti 1.2.22

Or more technical:

CVE-2022-46169: Analysis of the Cacti 1.2.22 Remote Agent Authorization Bypass and Command Injection Chain

And your vulnerability summary can say:

Cacti 1.2.22 contains a critical vulnerability chain in the remote-agent functionality. An attacker can manipulate the client-address determination logic to bypass the remote-agent authorization check. Once the polldata functionality is reached, insufficient validation of the poller_id parameter allows attacker-controlled data to reach a command executed through proc_open(). Under configurations containing a POLLER_ACTION_SCRIPT_PHP poller item, this can result in unauthenticated remote command execution. The issue was fixed in Cacti 1.2.23. (GitHub)

One important correction for your research: don't confuse this with CVE-2023-39362. That later Cacti RCE affects 1.2.24 and was fixed in 1.2.25, so it isn't the vulnerability you want for a 1.2.22 PoC. (NVD)