Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
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.

FeedsContactPrivacy© 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
171 month 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


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])

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:

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][1])

That means the application can be tricked into believing:

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:

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:

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][1])

Conceptually:

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:

        ┌──────────────────────────┐
        │ 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][1])


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:

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][1])

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:

host_id
local_data_id

Then it examines the resulting item's action.

The vulnerable condition is effectively:

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][1])

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:

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.

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][1])

C. proc_open()

Download Tool