Shell injected on servers via bypass of local file inclusion defenses
UPDATED A security researcher has chained a pair of vulnerabilities in popular web hosting platform Control Web Panel (CWP) to achieve pre-authenticated remote command execution (RCE) as root.
Paulos Yibelo achieved RCE by using a null byte-powered file inclusion payload in order to add a malicious API key, leveraging this API key to write to a file, then including this file through abuse of the file inclusion bug.
CWP, a free-to-use, Linux control panel formerly known as CentOS Web Panel, is in active use by more than 200,000 servers, according to Yibelo.
The researcher’s first key discovery was how two unauthenticated PHP pages, /user/loader.php and /user/index.php, deployed local file inclusion (LFI) protection that, when the ‘scripts’ parameter contained ‘..’, blocked processing of the input and instead displayed ‘hacking attempt’ to the user.
This output, from the GETSecurity() function, contained stristr(). Yibelo resolved to bypass stristr(), which searches for the first occurrence of a string inside another string.
He first sought to trick PHP into treating characters other than dots as ‘.’, but this foundered on the fact that PHP doesn’t normalize any of its characters to dots.
Then the researcher alighted on the idea of bypassing stristr(), a case-insensitive alternative to strstr(), by finding unique characters that C language, in which PHP is written, processes as a dot when lower-cased.
This route “didn’t yield any useful results but we did find some weird quirky behaviors worthy of future posts”, reads a blog post published by Yibelo for Octagon Networks, a team of researchers he recently co-founded.
Joining the dots
Tricking PHP into thinking that no consecutive dots (..) were present did prove fruitful, however, with fuzzing surfacing a bypass – /.%00./ – for the LFI check (CVE-2021-45467).
“Most [of] PHP’s functions in CWP (including the require() and include() functions) seem to process /.%00./ as /../ – similarly, while stristr() ignores the null bytes, it still counts its size so it bypasses the check,” he explained.
The file inclusion bug meant he could send a request that forced the server to register any API key he wanted, enabling him to write to .txt files. (CVE-2021-45466).
The resulting RCE chain is visualized in this YouTube video.
Yibelo bypassed an initial fix for the file inclusion bug, which attempted to detect if a null byte was sandwiched between dots, by simply adding further null bytes.
The researcher said some servers appeared to have been exploited via reversals of this patch.
Yibelo told The Daily Swig that the CWP maintainers rolled out a further patch “in their latest version with a better way to find and delete null bytes: $text = str_replace(chr(0), '', $text);.”
The CWP maintainers told The Daily Swig: “It was fixed in some older versions a few months ago but we have recently improved it in version 0.9.8.1022 to remove those files since they are old and have not been in use for more than two years.
“As always automatic updates resolves all issues so keeping the server up to date will get all resolved.”
They added that “CWP works only for six months without an update, and that allows us to disable CWP on servers not updated for six months so they don't get compromised”.
Replication problems have been flagged on Reddit. Yibelo said that, so far, the security issues appear to be CWP-specific.
The researcher said he would publish a full proof of concept “once enough servers migrate to the latest version”.
This article was updated on January 31 with comments from the maintainers of CWP, and then on February 14 to reflect the fact the product in question is now called Control Web Panel and no longer, as previously indicated, CentOS Web Panel