Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

« Newer Snippets
Older Snippets »
Showing 11-20 of 77 total

bScan - Simple Web Aplications Scanner

// Web application scanner (ex: phpBB, myCMS, myBlog, mySite etc..) - Only in PHP !
// 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

Repetition in Regular Expressions

This irb session example helps demonstrate repetition in regular expressions using * ? + {}

Definitions:

? - the preceding token is optional
+ - find the token 1 or more times
* - find the token 0 or more times
{n} - repeat the token n no of times


irb(main):058:0> "this song is my favourite"[/favou?rite/]
=> "favourite"
irb(main):059:0> "this song is my favorite"[/favou?rite/]
=> "favorite"

irb(main):100:0> "this is my favourite\s"[/this\s((song|video)\s)?is/]
=> "this is"
irb(main):101:0> "this song is my favourite\s"[/this\s((song|video)\s)?is/]
=> "this song is"
irb(main):102:0> "this flower is my favourite\s"[/this\s((song|video)\s)?is/]
=> nil
irb(main):103:0> "this video is my favourite\s"[/this\s((song|video)\s)?is/]
=> "this video is"

irb(main):105:0> "anything you say"[/.*/]
=> "anything you say"
irb(main):119:0> "will be repeated"[/.*/]
=> "will be repeated"
irb(main):116:0> "good times</p>"[/.*[^<\/p>]/]
=> "good times"

irb(main):220:0> "test 123 test 123"[/\d+/]
=> "123"
irb(main):224:0> "test 123 test 123"[/\d{2}/]
=> "12"
irb(main):226:0> "test 123 test 123"[/\w+/]
=> "test"

irb(main):008:0> "try this test that"[/try.\b\w+/]
=> "try this"
irb(main):009:0> "try this test that"[/test.\b\w+/]
=> "test that"

irb(main):233:0> "test 123 test 123"[/\w+\s\d+/]
=> "test 123"
irb(main):248:0> "test 123 test 123"[/\w+\s\d+.*/]
=> "test 123 test 123"
irb(main):249:0> "test this test 123"[/\w+\s\d+.*/]
=> "test 123"
irb(main):250:0> "test this test that"[/\w+\s\d+.*/]
=> nil
irb(main):279:0> "try this test that"[/try\s\w[^\s]+/]
=> "try this"
irb(main):280:0> "try this test that"[/test\s\w[^\s]+/]
=> "test that"

irb(main):310:0> "try this test that"[/test\s\w\B+/]
=> "test tha"
irb(main):308:0> "try this test that"[/try\s\w\B+./]
=> "try this"
irb(main):309:0> "try this test that"[/test\s\w\B+./]
=> "test that"

irb(main):322:0> "try this test that"[/try\s\w+\b/]
=> "try this"
irb(main):323:0> "try this test that"[/test\s\w+\b/]
=> "test that"

irb(main):008:0> "try this test that"[/try.\b\w+/]
=> "try this"
irb(main):009:0> "try this test that"[/test.\b\w+/]
=> "test that"

irb(main):010:0> "try this test that"[/test.\w+/]
=> "test that"
irb(main):011:0> "try this test that"[/try.\w+/]
=> "try this"

irb(main):012:0> "try this test that"[/try\s\w+/]
=> "try this"
irb(main):013:0> "try this test that"[/test\s\w+/]
=> "test that"

irb(main):015:0> "try this test that"[/try\s\w+\s\w+/]
=> "try this test"

irb(main):041:0> "try this test that"[/\w+\s\w+$/]
=> "test that"
irb(main):043:0> "try this test that"[/^\w+\s\w+/]
=> "try this"



Note: Similar to CSS the more specific an expression or selector is the less ambiguous it is.

Alternation in Regular Expressions

The following code from an irb session highlights optional pattern matching using an OR operator, represented as a bar (|).

irb(main):003:0> "chickens are sleeping"[/chick|sleeping/]
=> "chick"
irb(main):004:0> "chickens are sleeping"[/sleeping/]
=> "sleeping"
irb(main):005:0> "chickens are sleeping"[/sleeping|chicken/]
=> "chicken"
irb(main):006:0> "chickens are sleeping"[/sleeping|are|chicken/]
=> "chicken"
irb(main):007:0> "chickens are sleeping"[/sleeping|are/]
=> "are"
irb(main):008:0> "chickens are sleeping"[/[^sleeping|are]/]
=> "c"
irb(main):009:0> "chickens are sleeping"[/[^sleeping|are].[a-z]*\s/]
=> "chickens "
irb(main):011:0> "chickens are sleeping"[/[^chickens|are].[a-z]*\s/]
=> " are "
irb(main):015:0> "chickens are sleeping"[/[sleeping|are].[a-z]*\s/]
=> "ickens "
irb(main):020:0> "scared chickens are sleeping"[/are|sleeping/]
=> "are"
irb(main):026:0> "scared chickens are sleeping"[/(are|sleeping)../]
=> "ared "
irb(main):023:0> "scared chickens are sleeping"[/\b(are|sleeping)\b/]
=> "are"
irb(main):025:0> "scared chickens are sleeping"[/\b(are|sleeping)\b.../]
=> "are sl"
irb(main):032:0> "scared chickens are sleeping"[/(monkeys|dancing)|(sheep|laughing)/]
=> nil
irb(main):033:0> "scared chickens are sleeping"[/(monkeys|dancing)|(sheep|laughing)|(chickens)/]
=> "chickens"
irb(main):034:0> "scared chickens are sleeping"[/(monkeys|sleeping)|(sheep|laughing)|(chickens)/]
=> "chickens"

Anchors in Regular Expressions

Anchors are about finding matches beginning with or ending with a certain pattern.

This example from an irb session helps to show what \b, \w, ^, $ and \B do. \b - matches a word boundary, \w - matches a word character, ^ - matches a character at the beginning of a line, $ - matches the character at the end of a line, and \B matches a word boundary charcter which does not match \w.

irb(main):010:0> "paella"[/\ba/]
=> nil
irb(main):013:0> "artistic paella wake"[/\wa/]
=> "pa"
irb(main):026:0> "artistic paella wake"[/\B.[a-z]a$/]
=> nil
irb(main):027:0> "artistic paella wake"[/\B.[a-z]$/]
=> "ke"
irb(main):039:0> "artistic paella wake"[/\B./]
=> "r"
irb(main):040:0> "artistic paella wake"[/\Ba./]
=> "ae"
irb(main):044:0> "artistic paella wake"[/[^\B.{3}]/]
=> "a"
irb(main):046:0> "artistic paella wake"[/[^\B.]{3}/]
=> "art"
irb(main):047:0> "artistic paella wake"[/[^\w]{3}/]
=> nil
irb(main):047:0> "artistic paella wake"[/[^\w]{3}/]
=> nil
irb(main):048:0> "artistic paella wake"[/[^\br]{3}/]
=> "tis"
irb(main):050:0> "artistic paella wake"[/[^\b]{3}/]
=> "art"
irb(main):051:0> "artistic paella wake"[/[^\ba]{3}/]
=> "rti"
irb(main):054:0> "artistic paella wake"[/\ba/]
=> "a"
irb(main):055:0> "artistic paella wake"[/\ba./]
=> "ar"
irb(main):058:0> "people paella wake"[/\bp./]
=> "pe"
irb(main):060:0> "apostrophe paella wake"[/\bpa./]
=> "pae"
irb(main):061:0> "apostrophe paella wake"[/\bp./]
=> "pa"
irb(main):062:0> "apostrophe paella wake"[/\Bp./]
=> "po"
irb(main):064:0> "pancake paella wake"[/\Bp./]
=> nil
irb(main):065:0> "anticipated paella wake"[/\Bp./]
=> "pa"
irb(main):066:0> "anticipated paella wake"[/\Bp../]
=> "pat"
irb(main):067:0> "anticipated paella wake"[/\wp../]
=> "ipat"

Shorthand Character Classes in Regular Expressions

Learning Regular Expressions can seem tedious however with a little knowledge you can programmatically select or validate specific text in a few lines of code. key: \d = digit; \w = alphanumeric; \s space (includes tabs and line-breaks)

irb(main):462:0> "happy"[/\d/]
=> nil
irb(main):463:0> "happy"[/\w/]
=> "h"
irb(main):464:0> "123 happy"[/\w/]
=> "1"
irb(main):465:0> "123 happy"[/\d/]
=> "1"
irb(main):466:0> "123 happy"[/\d\s/]
=> "3 "
irb(main):467:0> "123 happy"[/\d{3}/]
=> "123"
irb(main):468:0> "123 happy"[/\d{3}\s\w{3}/]
=> "123 hap"

Character sets in Regular Expressions

Here is a listing from my irb session, as you can see I'm learning character sets with regular expressions. The characters ('a' and 'e') within the square brackets are treated as operands which are XORed between the characters 'h' and 'y'.

irb(main):155:0> "hello"[/[ae]/]
=> "e"
irb(main):156:0> "hello"[/h[ae]y/]
=> nil
irb(main):157:0> "hay"[/h[ae]y/]
=> "hay"
irb(main):158:0> "howdy"[/h[ae]y/]
=> nil
irb(main):159:0> "hardy"[/h[ae]y/]
=> nil
irb(main):160:0> "hardy"[/h[ae]/]
=> "ha"
irb(main):161:0> "hardy"[/h[ae]y/]
=> nil
irb(main):162:0> "hoy"[/h[ae]y/]
=> nil
irb(main):165:0> "they"[/h[ae]y/]
=> "hey"
irb(main):166:0> "they would"[/h[ae]y/]
=> "hey"

Fancy little ruby input prompter

for i in 1..100
  print "Now at #{i}. Restart? "
  retry if gets =~ /^y/i
end

Regular Expressions with MySQL

SELECT * FROM texts WHERE content REGEXP '[^a-z]Hello[^a-z]' ;


If you really want to force a REGEXP comparison to be case sensitive, use the BINARY keyword to make one of the strings a binary string.
SELECT * FROM texts WHERE content REGEXP BINARY '[^a-zA-Z]Hello[^a-zA-Z]' ;


Warning: some characters do not work. Example :
SELECT * FROM texts WHERE content REGEXP '[^\w]Hello[^\w]' ;


ab-d.fr source code

Regex-based parsing technique


#!/usr/local/bin/ruby -w

# Regular expressions and strings with embedded objects
# From: http://t-a-w.blogspot.com/2007/06/regular-expressions-and-strings-with.html
# Author: Tomasz Węgrzanowski
# License: 
# Creative Commons License, http://creativecommons.org/licenses/by-sa/3.0/
# GNU Free Documentation License, http://en.wikipedia.org/wiki/GNU_Free_Documentation_License


def hash_or_die(kw)
  Hash.new{|ht,k| raise "Unknown key: #{k}"}.merge(kw)
end

def parse(data)
  esc = hash_or_die "\\" => "A", "\"" => "B", "n" => "C", "'" => "D"
  rev_esc = hash_or_die "A" => "\\", 'B' => "\"", "C" => "n", "D" => "'"
  data = data.gsub(/\\(.)/) {"\x00" + esc[$1]}
  strs = []
  data = data.gsub(/('[^']*')/) { # '
    strs << $1
    "\x01<#{strs.size-1}>"
  }
  records = []
  data.scan(/\((.*?)\)/) {
    records << $1.split(/,/).map{|field|
      field.gsub(/\x01<(\d+)>/) {
        strs[$1.to_i]}.gsub(/\x00(.)/){ rev_esc[$1]
      }
    }
  }
  records
end

def sql_str_unquote(str)
  str =~ /\A'(.*)'\Z/ or raise "SQL string format is wrong: #{str}"
  $1.gsub(/\\(.)/) {$1}
end


=begin

page_fn = Dir["plwiki-*-page.sql"].sort[-1]
externallinks_fn = Dir["plwiki-*-externallinks.sql"].sort[-1]

pages = {}

File.open(page_fn).each{|line|
  next unless line =~ /\AINSERT INTO `page` VALUES (.*)\Z/
  parse($1).each{|id,ns,title,*stuff|
    next unless ns == "0"
    title = sql_str_unquote(title)
    pages[id] = title
  }
}

File.open(externallinks_fn).each{|line|
  next unless line =~ /\AINSERT INTO `externallinks` VALUES (.*)\Z/
  parse($1).each{|from,to,index|
    title = pages[from]
    next unless title
    to = sql_str_unquote(to)
    next unless to =~ /\Ahttp:\/\//
    puts "#{title}\t#{to}"
  }
}

=end


sql_dump = <<-EOS

INSERT INTO `page` VALUES (1,0,'Astronomia','',1800,0,0,0.600461925007833,'20070601091320',8076762,8584,0), (2,0,'AWK','',329,0,0,0.487812640599732,'20070530195555',8058046,4265,0), (4,0,'Alergologia','',108,0,0,0.580574716050713,'20070520093413',7912844,292,0), ...
INSERT INTO `page` VALUES (14880,0,'Dźwignica_linotorowa','',26,0,0,0.597327036408081,'20060814072401',4282357,727,0), (14881,0,'Urządzenia_transportowe','',91,0,0,0.176666489966834,'20070527090143',2976610,1041,0), ...

EOS


pages = {}

sql_dump.each{|line|
  next unless line =~ /\AINSERT INTO `page` VALUES (.*)\Z/
  parse($1).each{|id,ns,title,*stuff|
    next unless ns == "0"
    title = sql_str_unquote(title)
    pages[id] = title
  }
}


p pages

=begin

sql_dump.each{|line|
  next unless line =~ /\AINSERT INTO `externallinks` VALUES (.*)\Z/
  parse($1).each{|from,to,index|
    title = pages[from]
    next unless title
    to = sql_str_unquote(to)
    next unless to =~ /\Ahttp:\/\//
    puts "#{title}\t#{to}"
  }
}

=end


#-----------------


require 'pp'

lisp_code = '(a (b c) (d (e) f g) (((h))))'
nodes = []

lisp_code.gsub!(/([a-z]+)/) {
  nodes << [:atom, $1]
  "<#{nodes.size-1}>"
}

#p nodes

lisp_code.gsub!(/\s/,"")
#puts lisp_code

true while lisp_code.gsub!(/\(((?:<\d+>)*)\)/) {
  #p nodes
  nodes << [:app, *$1.scan(/<(\d+)>/).map{|x,| nodes[x.to_i]}]
  "<#{nodes.size-1}>"
}
lisp_code =~ /<(\d+)>/

#puts
#p nodes
#puts

pp nodes[$1.to_i]

# Output:
#  [:app,
#  [:atom, "a"],
#  [:app, [:atom, "b"], [:atom, "c"]],
#  [:app, [:atom, "d"], [:app, [:atom, "e"]], [:atom, "f"], [:atom, "g"]],
#  [:app, [:app, [:app, [:atom, "h"]]]]]


#------------------


math_code = '(2 + 2 * 2) / ((2 + 2) * 2)'
nodes = []

math_code.gsub!(/(\d+)/) {
  nodes << $1.to_i
  "<#{nodes.size-1}>"
}
math_code.gsub!(/\s/,"")

until math_code =~ /\A<(\d+)>\Z/
  next if math_code.gsub!(/\((<\d+>)\)/) { $1 }
  next if math_code.gsub!(/<(\d+)>([\*\/])<(\d+)>/) {
    nodes << [$2, nodes[$1.to_i], nodes[$3.to_i]]
    "<#{nodes.size-1}>"
  }
  next