feat: PowerShell/CIM WMI transport (Windows backend) - #17
Draft
somethingwithproof wants to merge 14 commits into
Draft
feat: PowerShell/CIM WMI transport (Windows backend)#17somethingwithproof wants to merge 14 commits into
somethingwithproof wants to merge 14 commits into
Conversation
Automated fixes: - XSS: escape request variables in HTML value attributes - SQLi: convert string-concat queries to prepared statements - Deserialization: add allowed_classes=>false - Temp files: replace rand() with tempnam() Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
- Change Dependabot ecosystem from npm to composer (PHP-only repo) - Remove PHP from CodeQL paths-ignore so security PRs get analysis - Remove committed .omc session artifacts, add .omc/ to .gitignore Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Linux_WMI::clean() escaped the username, password, binary and command but left
the device hostname only trimmed and the query namespace untouched, so
getcommand() interpolated them raw into the wmic command line that exec() runs
on the Cacti server. A device-supplied hostname such as
127.0.0.1; touch /tmp/pwned #
therefore ran a command on the poller.
Escape the hostname and namespace with cacti_escapeshellarg, and on Windows
strip the cmd.exe metacharacters (" & | ^ < > ( ) %) that cmd.exe interprets
despite quoting. A standalone regression test in tests/ verifies both.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Escape account/query/tool output on render (html_escape/__esc), bind the remaining WMI queries as prepared statements, and drop wmi_accounts.php and wmi_tools.php from the Template Editor auth augment so credential management and the live query tool stay behind the WMI Management realm. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
The default separator (|+|) contains pipe characters, so the unquoted --delimiter=|+| made exec() split the command into a shell pipeline (exit 127, no data). Quote it in getcommand() while keeping the property raw for the explode() in fetch(). issue#5 Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
…hp8-transport-modernization
…p8-transport-modernization
Type the properties and method signatures, replace var/sizeof, and move the wmic command construction behind a Wmi_Transport interface (Wmic_Shell_Transport by default, injectable) so a PowerShell/CIM backend can be added without touching the parser. Behaviour and the shell-escaping guards are unchanged; the existing injection test still passes. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Short array syntax, single-quoted literals, comment style and indentation to match the checked-in .php-cs-fixer.php. Mechanical only; no logic change. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Second Wmi_Transport backend: runs Get-CimInstance through pwsh/powershell.exe so the plugin works on a Windows Cacti server and against modern Windows hosts the legacy wmic client cannot authenticate to. The credential and every device-supplied value pass through the child environment and a fixed stdin script (run via proc_open with an argv array), never the command line, so no shell or process listing sees the password and nothing is interpolated into the script. issue#15 Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
A Windows Cacti server has no Linux wmic binary, so default to the PowerShell transport there and to wmic elsewhere; an explicit transport still wins. Update the injection test to select the wmic transport explicitly for its win32 case. issue#15 Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Analyse linux_wmi.php at level 6 with signature stubs for the two Cacti core functions it calls. Add the array value-type docblocks the level requires. The loosely typed page files stay out of scope for now. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Augment the existing README with the two WMI transports (wmic on Linux, PowerShell/CIM on Windows or for hardened hosts), their requirements, the access model, and the credential storage posture. Preserve the existing changelog and authors. issue#15 Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
somethingwithproof
force-pushed
the
feature/powershell-cim-transport
branch
from
August 30, 2026 08:13
8ca0173 to
3ea5113
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft. Phase 2 of the CIM backend (issue #15), stacked on #16. Merge order: #13, #14, #16, then this. Diff includes the earlier PRs until they land; I will rebase clean.
Adds
PowerShellCim_Transport, a secondWmi_Transportbackend that runsGet-CimInstancethroughpwsh/powershell.exe. It works on a Windows Cacti server and, for a remote target, over WinRM/CIM against modern Windows hosts the legacy Linuxwmicclient can no longer authenticate to (NTLM deprecation, DCOM hardening).Credential handling (the reason this is its own PR)
proc_openwith an argv array. No shell is involved, the password never appears on the command line or inps, and nothing is interpolated into the script, so there is no PowerShell injection.PSCredentialfrom$env:WMI_PASS. Env is process-scoped; the caveat versus a plaintext file is documented, and it is strictly better than the legacy argv exposure.Output contract
The script emits the class name, the separator-joined column header, then one separator-joined row per instance, so
Linux_WMIparses it exactly like wmic output. Namespace\is translated to/for CIM.Tests
tests/WmiPowerShellTransportTest.php(standalone, injectable runner, no live PowerShell): asserts the password is off argv and out of the script, that it travels via env, the class/header/row parsing, and the empty-result and non-zero-exit error paths.php tests/WmiPowerShellTransportTest.phpexits 0.Not in this PR (Phases 3-4)
Server-OS auto-detection, a per-account transport/auth-level UI, and docs. Tracked in #15.