[0day-rubbish] RCDevs WebADM 2.4.14 authenticated log viewer sid command injection to webadm uid 999 code execution (7.2)
Full Disclosuremailing list archivesFrom: disclosure via Fulldisclosure <fulldis 2026-10-6 17:44:50 Author: seclists.org(查看原文) 阅读量:2 收藏

fulldisclosure logo

Full Disclosure mailing list archives


From: disclosure via Fulldisclosure <fulldisclosure () seclists org>
Date: Mon, 5 Oct 2026 17:53:47 +0000

0day Rubbish Research Team is publicly disclosing a vulnerability in RCDevs WebADM
2.4.14, Freeware Edition, the closed-source IAM/MFA management platform from RCDevs
Security SA (Luxembourg) that fronts the vendor's OpenOTP, SpanKey and TiQR
authentication products.

Type: OS command injection (CWE-78, with CWE-20 and CWE-116 contributing, and
CWE-732/CWE-276 and CWE-250 added for two auxiliary conditions). The administrator
console log viewer admin/logfile_viewer.php interpolates the sid GET parameter,
percent-decoded once and with no escaping of any kind, into the single-quoted shell
command grep -E '<sid>' <logfile> | tail -n 10000 which the page hands to PHP's
popen(). A single apostrophe closes the quoted grep pattern, everything after it is
parsed by /bin/sh as command text, and the trailing quote pair re-opens an empty
quoted string that swallows the remainder of the pipeline. There is no escapeshellarg,
no escapeshellcmd, no quote stripping, no charset allow-list and no length cap on the
recorded path; the absence of a filter, not the bypass of one, is the root cause.
Commands execute as the webadm service account, uid=999(webadm) gid=999(webadm)
groups=999(webadm), the identity the webadm-httpd workers run under with no privilege
drop configured. Root was not achieved, is not claimed, and no privilege escalation
was attempted.

The endpoint does not echo command output into its HTTP response, so confirmation is
out-of-band: the injected command appends a line to /opt/webadm/logs/webadm.log and
the same endpoint reads that file back over HTTPS when asked for a different log
selector. This also means the finding is self-verifying rather than interpretive.
The published advisory reproduces the identity string but deliberately not the
per-run marker token or the container hostname from the run, since both are artefacts
of one execution on one host.

Scoring. One score is published: 7.2 High, CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H.
That vector computes to 7.107826 raw and is taken to 7.2 by the CVSS ceiling-to-tenth
Roundup, which is why a calculator reporting 7.1 is not in disagreement with anything
but with the specification's rounding rule. Our research record carried a higher base
score beside this same PR:H vector, and that pairing cannot compute; the higher figure
is the base score of the PR:L variant, which asserts that an authenticated principal
below administrator reaches the sink. This research did not support that assertion:
the session is issued by an LDAP bind as the administrator DN, the no-cookie negative
control never reached popen(), and no lower-privileged console role was documented.
The advisory therefore publishes 7.2 alone and leaves PR:L as an open question about
the product's role model, to be amended if an auditor- or help-desk-class role can
open this viewer in a shipped or supported configuration. Scope Changed was
considered and rejected: under S:C the same vector would compute to 9.1, but the
injected command runs as the same identity, on the same host, with the same backend
access the vulnerable application already holds, so no authorization boundary is
crossed. No unauthenticated reading is published. License registration was required
to bring the console up, the record documents no vendor-shipped default administrator
credential, and this research did not establish whether one exists, so no PR:N figure
is claimed on evidence the record does not carry.

Authentication: post-authentication console administrator. Eleven endpoints reachable
without a console session were examined in full, plus two independent adversarial
passes tasked specifically with breaking the "a session is required" conclusion. That
sweep found no shell sink and no file-write sink reachable from unauthenticated input;
every include hit was a static framework bootstrap; the certificate signing daemon on
port 5000 carries no shell strings; and the mail() transport keeps recipients off the
command line, removing the notification path as an injection route. The advisory
publishes that disposition table so the negative result is auditable. Unauthenticated
remote code execution was not reached and none is claimed.

Impact: arbitrary OS command execution as the webadm application account on the host
that runs an identity platform, which is why the qualitative weight exceeds what the
number alone conveys. From uid 999 an attacker can read and rewrite platform
configuration under /opt/webadm, including the httpd and PHP configuration defining
routing, authentication domains and backend connectivity - a persistence path that
survives a service restart without touching the operating system; reach the directory
backend on the local LDAP listener and the application database on the local MariaDB
listener with the credentials the application itself carries, which for an MFA
platform means user records, OTP state and second-factor enrolments, so modification
can disable, redirect or re-enrol a user's second factor; interact with the
certificate signing daemon from inside the trust boundary where its network-level
protections no longer apply; write to product logs, supporting both anti-forensics
and the observation channel this exploit uses; and disrupt availability of the console
and of the authentication path it fronts, locking out users of every relying
application. Everything gained sits inside the authorization domain the application
already occupies, hence Scope Unchanged, but the content of that domain is the
identity infrastructure of whatever WebADM was deployed to protect.

Verification boundary, stated plainly. All dynamic work was performed against a
Docker container running WebADM 2.4.14 Freeware Edition, reached over TLS on the
container's HTTPS listener by a pure-standard-library Python client, driven from the
container host, and recorded across four independent runs that each used their own
marker and all returned the same uid 999 identity. The container's published ports
were mapped to loopback addresses and no request crossed a network boundary, so
remote reachability is argued from the product's own binding configuration for an
admin console vhost that exists to be reached over a network, not measured from a
separate host. The application ships as a Blowfish-encrypted opcache file_cache corpus
that only the vendor's custom webadm-runphp interpreter (PHP 8.2.30, ZTS) decodes at
load time, so there is no plaintext PHP on disk: the decoder was located in that
interpreter by following cross-references to the container magic, the parser and the
decryption were reimplemented offline, and 315 files were recovered. That recovery
yields the literal string layer, not vendor source text, so the sink construction in
the advisory is labelled as a reconstruction from decoded string literals plus
observed behaviour, confirmed by the executed result. Exactly one command shape was
executed and only that shape is claimed - a single echo carrying three command
substitutions and a redirection into the product log - because the target shell
rejected top-level parentheses and statement separators inside the injected text; a
nested sh -c wrapper, a pipeline, an && -joined chain and any write into the document
root were never exercised. Privilege escalation, persistence and lateral movement to
the LDAP or MariaDB backends were reasoned about from the identity and the listener
layout, not executed. Only WebADM 2.4.14 Freeware Edition was tested; other versions
and licensed editions with additional web service modules installed are unclaimed.

Two detection notes worth carrying into any rule. Every /admin/*.php request returns
HTTP 200 together with the WebADM doctype even with no session cookie, because the
framework renders the common HTML shell before the page logic runs the session check,
so status code, response length and doctype are unusable as authorization signals and
will produce false positives if used that way. Detect on shell metacharacters in sid,
above all the apostrophe, and on unstructured lines appearing in
/opt/webadm/logs/webadm.log; process ancestry alone is weak, because a webadm-httpd
child running grep and tail for the viewer is normal behaviour.

Mitigation summary: escapeshellarg() on sid at the sink (escapeshellcmd is not an
acceptable substitute, since it does not move a value out of the quoting context it
was placed in); remove the shell entirely with proc_open() over an argument vector or
filter the file in PHP with a bounded tail counter, which also covers the second
interpolation site, the file operand derived from the log selector; validate sid
against the alphanumeric shape the product's own random_id() generates and return 400
on mismatch; resolve the log selector through a fixed server-side enumeration; set an
explicit minimal User= and Group= for the httpd workers and stop the service account
from appending to any log the viewer displays back; set disable_functions in php.ini,
which the recorded configuration does not; and add a regression test that fails on a
metacharacter. Until a patch exists operators should bind the admin vhost to a
management interface, VPN or mutually authenticated proxy, treat console
administrator credentials as tier-zero secrets behind a second factor, alert on the
indicators above, and on suspicion of exploitation rotate the administrator, LDAP and
database credentials and audit second-factor enrolments for the interval in question.

Full technical analysis and a reproducible proof-of-concept:
  https://0day-rubbish.com/blog/rcdevs-webadm-logfile-viewer-sid-command-injection

Project archive (ongoing disclosure series):
  https://github.com/Exploit-Garbage/0day-Rubbish

RCDevs Security SA has been notified through the general corporate contact mailbox it
publishes for enquiries, support and problem submissions; the vendor publishes no
RFC 9116 security.txt and we found no product security page, vulnerability-disclosure
policy or researcher intake form, so there was no pre-publication channel for us to
use and this disclosure is unconditional. No vulnerability identifier has been
assigned to this finding yet.

--
0day Rubbish Research Team
disclosure () 0day-rubbish com
https://0day-rubbish.com
_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: https://seclists.org/fulldisclosure/


Current thread:

  • [0day-rubbish] RCDevs WebADM 2.4.14 authenticated log viewer sid command injection to webadm uid 999 code execution (7.2) disclosure via Fulldisclosure (Oct 06)

文章来源: https://seclists.org/fulldisclosure/2026/Oct/7
如有侵权请联系:admin#unsafe.sh