#!/usr/bin/env ruby require "XSpear" Options = Struct.new(:url, :data, :headers, :params, :options ) class Parser def self.parse(options) args = Options.new('xspear') args.options = {} if options.empty? banner puts 'please ' + "'-h'".yellow + ' option' exit end opt_parser = OptionParser.new do |opts| opts.banner = "Usage: xspear -u [target] -[options] [value]\n[ e.g ]\n$ ruby a.rb -u 'https://www.hahwul.com/?q=123' --cookie='role=admin'\n\n[ Options ]" opts.on('-u', '--url=target_URL', '[required] Target Url') do |n| args.url = n end opts.on('-d', '--data=POST Body', '[optional] POST Method Body data') do |n| args.options['data'] = n end opts.on('--headers=HEADERS', '[optional] Add HTTP Headers') do |n| args.options['headers'] = n end opts.on('--cookie=COOKIE', '[optional] Add Cookie') do |n| args.options['cookie'] = 'Cookie: ' + n end opts.on('--raw=FILENAME', '[optional] Load raw file(e.g raw_sample.txt)') do |n| args.options['raw'] = n end opts.on('-p', '--param=PARAM', '[optional] Test paramters') do |n| args.options['params'] = n end opts.on('-b', '--BLIND=URL', '[optional] Add vector of Blind XSS',' + with XSS Hunter, ezXSS, HBXSS, etc...',' + e.g : -b https://hahwul.xss.ht') do |n| args.options['blind'] = n end opts.on('-t', '--threads=NUMBER', '[optional] thread , default: 10') do |n| args.options['thread'] = n end opts.on('-o', '--output=FILENAME', '[optional] Save JSON Result') do |n| args.options['output'] = n end opts.on('-v', '--verbose=1~3', '[optional] Show log depth', ' + Default value: 2', ' + v=1 : quite mode', ' + v=2 : show scanning log', ' + v=3 : show detail log(req/res)') do |n| args.options['verbose'] = n end opts.on('-h', '--help', 'Prints this help') do banner puts opts exit end opts.on('--version', 'Show XSpear version') do puts XSpear::VERSION exit end opts.on('--update', 'Update with online') do puts "[RubyGem user] : $ gem update XSpear" puts "[Soft | Developer & Git clone user] : $ git pull -v " puts "[Hard | Developer & Git clone user] : $ git reset --hard HEAD; git pull -v " exit end end opt_parser.parse!(options) args end end options = Parser.parse ARGV if !options.options['raw'].nil? begin method = "" path = "" headers_hash = {} headers = "" data = "" switch = true file = File.open options.options['raw'] r = file.read file.close r.each_line do |line| if switch temp = line.split(" ") method = temp[0] path = temp[1] switch = false else if line.include? ": " temp = line.split(": ") hn = temp[0] hd = line.sub(hn+": ", "") headers_hash[hn] = hd headers = headers + "#{hn}: #{hd}\n" elsif line.size > 2 # data data = line else # blank end end end # Burp or ZAP # http, https로 시작하면 zap 아니면 burp 포맷 url = "" if (path.index('http://') == 0 || path.index('https://') == 0) url = path else url = "http://"+headers_hash['Host'].to_s.chomp!+"/"+path end options.url = url if headers.length > 0 options.options['headers'] = headers end if method == "POST" && data.size options.options['data'] = data end rescue => e puts "RAW file Error #{e}" exit end end exit unless options.url options.options['thread'] = 10 unless options.options['thread'] options.options['verbose'] = 2 unless options.options['verbose'] options.options['thread'] = options.options['thread'].to_i if options.options['verbose'].to_i != 1 banner end s = XspearScan.new options.url, options.options s.run