// Find XSS, sql injection, remote file inclusion
##################################################################################### # Black_H / Nooz -- 30:01:07 # Bl4ck.H<>gmail<>com # class BScan ##################################################################################### # Regex # @@space = '([[:space:]]*)' @@userdat = '(' @@userdat += '(\$_SERVER\[([\'\"]*)HTTP_)|' @@userdat += '(\$_GET)|' @@userdat += '(\$_POST)|' @@userdat += '(\$_COOKIE)|' @@userdat += '(\$_REQUEST)|' @@userdat += '(\$_FILES)|' @@userdat += '(\$_ENV)|' @@userdat += '(\$_HTTP_COOKIE_VARS)|' @@userdat += '(\$_HTTP_ENV_VARS)|' @@userdat += '(\$_HTTP_GET_VARS)|' @@userdat += '(\$_HTTP_POST_FILES)|' @@userdat += '(\$_HTTP_POST_VARS)|' @@userdat += '(\$_HTTP_SERVER_VARS\[([\'\"]*)HTTP_)' @@userdat += ')' @@regex = Hash.new @@regex = {'TYPE' => 'vars overwrite','LEVEL' => '2','REGEX' => /extract#{@@space}\((.*)#{@@userdat}(.*)\)/i}, {'TYPE' => 'vars overwrite','LEVEL' => '2','REGEX' => /import_request_variables#{@@space}\((.*)\)/i}, {'TYPE' => 'fopen vuln','LEVEL' => '3','REGEX' => /fopen#{@@space}\((.*)#{@@userdat}(.*)\)/i}, {'TYPE' => 'copy vuln','LEVEL' => '3','REGEX' => /copy#{@@space}\((.*)#{@@userdat}(.*)\)/i}, {'TYPE' => 'fwrite vuln','LEVEL' => '3','REGEX' => /fwrite#{@@space}\((.*)#{@@userdat}(.*)\)/i}, {'TYPE' => 'sql injection','LEVEL' => '2','REGEX' => /(mysql_query|mssql_query|mysqli_query)#{@@space}\((.*)#{@@userdat}(.*)\)/i}, {'TYPE' => 'crlf injection','LEVEL' => '1','REGEX' => /mail#{@@space}\((.*)#{@@userdat}(.*)\)/i}, {'TYPE' => 'cross site scripting','LEVEL' => '1','REGEX' => /\<\?\=#{@@space}(.*)#{@@userdat}/i}, {'TYPE' => 'cross site scripting','LEVEL' => '1','REGEX' => /(print|echo|print_r|var_dump)#{@@space}(|\(|\")(.*)#{@@userdat}/i}, {'TYPE' => 'php code execution','LEVEL' => '3','REGEX' => /eval#{@@space}\((.*)#{@@userdat}(.*)\)/i}, {'TYPE' => 'php code execution','LEVEL' => '3','REGEX' => /file_put_contents#{@@space}\((.*)#{@@userdat}(.*)\)/i}, {'TYPE' => 'variable attribution', 'LEVEL' => '2','REGEX' => /(.*)\$#{@@userdat}(.*)/i}, {'TYPE' => 'chmod affectation','LEVEL' => '1','REGEX' => /chmod#{@@space}\((.*)#{@@userdat}(.*)\)/i}, {'TYPE' => 'file disclosure','LEVEL' => '2','REGEX' => /(readfile|file_get_contents|file)#{@@space}\((.*)#{@@userdat}(.*)\)/i}, {'TYPE' => 'file disclosure','LEVEL' => '2','REGEX' => /(show_source|highlight_file)#{@@space}\((.*)#{@@userdat}(.*)\)/i}, {'TYPE' => 'bzopen vuln','LEVEL' => '2','REGEX' => /bzopen#{@@space}\((.*)#{@@userdat}(.*)\)/i}, {'TYPE' => 'file deletion','LEVEL' => '2','REGEX' => /(rmdir|unlink|delete)#{@@space}\((.*)#{@@userdat}(.*)\)/i}, {'TYPE' => 'command execution','LEVEL' => '3','REGEX' => /(exec|system|passthru|shell_exec|proc_open|pcntl_exec)#{@@space}\((.*)#{@@userdat}(.*)\)/i}, {'TYPE' => 'buffer overflow','LEVEL' => '3','REGEX' => /(confirm_phpdoc_compiled|mssql_pconnect|mssql_connect|crack_opendict|snmpget|ibase_connect)#{@@space}\((.*)#{@@userdat}(.*)\)/i}, {'TYPE' => 'ip falsification','LEVEL' => '1','REGEX' => /(.*)(HTTP_CLIENT_IP|HTTP_X_FORWARDED_FOR|HTTP_PC_REMOTE_ADDR)(.*)/i}, {'TYPE' => 'putenv vuln','LEVEL' => '2','REGEX' => /putenv#{@@space}\((.*)#{@@userdat}(.*)\)/i}, {'TYPE' => 'full path disclosure','LEVEL' => '1','REGEX' => /(htmlentities|htmlspecialchars)#{@@space}\((.*)#{@@userdat}(.*)\)/i}, {'TYPE' => 'magic_quotes_gpc bypass','LEVEL' => '1','REGEX' => /(stripslashes|urldecode)#{@@space}\((.*)#{@@userdat}(.*)\)/i}, {'TYPE' => 'file inclusion','LEVEL' => '3','REGEX' => /(include|include_once|require|require_once)#{@@space}(|\(|\")(.*)#{@@userdat}/i} ##################################################################################### # Main # def initialize() ################ # Usage if (ARGV.length < 4) puts ' --------------------------------------------------------------------- | Credits: Black_H <bl4ck.h@gmail.com> | | URL: Lemon-Inside.sup.fr | | Note: Premier code Ruby | --------------------------------------------------------------------- --------------------------------------------------------------------- | Usage: scan.rb -d <Dossier> -i <Save.html> | | Ex: scan.rb -d ./ -i output.html | --------------------------------------------------------------------- ' end ################ # Options & Vars @@scan_alldir = self.options('d') @@out_file = self.options('i') @@ban = [".", "..", "scan.rb", @@out_file.to_s] @@scan_buffer = Array.new ################ # Options Error ? if (@@scan_alldir != false and @@scan_alldir.empty? == false) self.dscan(@@scan_alldir) self.output(@@scan_buffer) @@scan_buffer = '' end end ##################################################################################### # Dir Scan # def dscan(dir) d = Dir.open(dir.to_s) d = d.sort - @@ban d.each { |fichier| case File.ftype(dir+fichier) when "directory" self.dscan(dir + fichier + "/") when "file" puts 'Scan => ' + dir + fichier self.fscan(dir + fichier) end } end ##################################################################################### # File Scan # def fscan(file) fichier = File.readlines(file) i = 1 fichier.each { |line| @@regex.each { |info| test = (line =~ info['REGEX']) if (test) @@scan_buffer += ['FILE' => file, 'LINE' => i.to_s, 'MATCH' => line, 'LEVEL' => info['LEVEL'], 'TYPE' => info['TYPE']] # 5 , 1 , 3 , 4 , 2 next @@scan_buffer end } i += 1 } end ##################################################################################### # Output buffer # def output(buffer) @html_hmodel = '<html>' @html_hmodel += '<style type="text/css">' @html_hmodel += '<!--' @html_hmodel += '.level0 {background-color: #CCCCCC;}' @html_hmodel += '.level1 {background-color: #33FF66;}' @html_hmodel += '.level2 {background-color: #FFFF33;}' @html_hmodel += '.level3 {background-color: #FF0000;}' @html_hmodel += '--></style><body><h1>BScan v1.0</h1><pre>' code = @html_hmodel buffer.each { |infos| keys = infos.keys code += "<span class='level" + infos["LEVEL"] + "'>" + keys[1].to_s + ' : ' + infos["TYPE"] + '</span><br />' code += "<span class='" + infos["LEVEL"] + "'>" + keys[3].to_s + ' : ' + infos["LEVEL"] + '</span><br />' code += "<span class='" + infos["LEVEL"] + "'>" + keys[4].to_s + ' : ' + infos["FILE"] + '</span><br />' code += "<span class='" + infos["LEVEL"] + "'>" + keys[0].to_s + ' : ' + infos["LINE"] + '</span><br />' code += "<span class='" + infos["LEVEL"] + "'>" + keys[2].to_s + ' : ' + infos["MATCH"] + '</span><br />' } code += "</pre></body></html>" fhtml = File.open(@@out_file.to_s, "w") fhtml.write code code = '' end ##################################################################################### # Parse & Get Options # def options(param) i = 0 ARGV.each { |valeur| if (valeur == '-' + param.to_s) return ARGV[i+1] elseif (valeur != '-' + param.to_s) return false end i += 1 } end end scan = BScan.new