无论给出什么标志,Optparse 默认为 usage_page
Optparser defaulting to usage_page no matter what flag is given
我正在尝试 OptParse
并尝试将其正确设置为 运行,但是,截至目前,我所有的选项都默认为 usage_page 方法。我不确定为什么会发生这种情况,我试图将 CHOICES
常量移动到 begin/rescue 子句的正上方,我还尝试使用 start = OptParser.new
;options = start.parse_argv(ARGV)
这些都不起作用。我也尝试过(正如您从我的代码中看到的那样)将 OptParser.new
和 CHOICES = OptParse.parse_argv(ARGV)
分开,我有点困惑,需要一些帮助,为什么我没有尝试在职的?没看懂,要么告诉我不是变量,不是方法,要么就是抛出用法页面?
(这是我正在尝试提供帮助的开源 project)
我的来源:
PATH = Dir.pwd
VERSION = Whitewidow.version
SEARCH = File.readlines("#{PATH}/lib/search_query.txt").sample
info = YAML.load_file("#{PATH}/lib/rand-agents.yaml")
@user_agent = info['user_agents'][info.keys.sample]
OPTIONS = Struct.new(:default, :file, :example)
def usage_page
Format.usage("You can run me with the following flags: #{File.basename(__FILE__)} -[d|e|h] -[f] <path/to/file/if/any>")
exit
end
def examples_page
Format.usage('This is my examples page, I\'ll show you a few examples of how to get me to do what you want.')
Format.usage('Running me with a file: whitewidow.rb -f <path/to/file> keep the file inside of one of my directories.')
Format.usage('Running me default, if you don\'t want to use a file, because you don\'t think I can handle it, or for whatever reason, you can run me default by passing the Default flag: whitewidow.rb -d this will allow me to scrape Google for some SQL vuln sites, no guarentees though!')
Format.usage('Running me with my Usage flag will show you the boring usage page.. Yeah it\'s not very exciting..')
end
class OptParser
def self.parse_argv(options)
args = OPTIONS.new
opt_parser = OptionParser.new do |opts|
opts.banner = usage_page
opts.on('-d', '--default', 'Run me in default mode, I\'ll scrape Google for SQL vulns.') do |d|
args[:default] = d
end
opts.on('-fFILE', '--file=FILE', 'Pass me the name of the file. Leave out the beginning forward slash. (/lib/ <= incorrect lib/ <=correct)') do |f|
args.fileFILE = f
end
opts.on('-e', '--example', 'Shows my example page. It\'s really not that hard to figure out, but I\'m a nice albino widow.') do |e|
args[:example] = e
end
opts.on('-h', '--help', 'Shows a complete list of all my usages, with what they do, and their secondary flag.') do
puts opts
exit
end
opts.on('-u', '--usage', 'Shows my usage page, a short list of possible flags, use the help flag (-h) for a more complete list.') do
usage_page
exit
end
end
opt_parser.parse!(options)
return args
end
end
def pull_proxy
info = parse("http://www.nntime.com/",'.odd', 1)
@ip = info[/\D\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\D/].gsub(">", "").gsub("<", "")
@port = info[/8080/] || info[/3128/] || info[/80/] || info[/3129/] || info[/6129/]
proxy = "#{@ip}:#{@port}"
Format.info("Proxy discovered: #{proxy}")
end
def page(site)
Nokogiri::HTML(RestClient.get(site))
end
def parse(site, tag, i)
parsing = page(site)
parsing.css(tag)[i].to_s
end
def get_urls
if OPTIONS[:default]
Format.info('I\'ll run in default mode then!')
Format.info("I'm searching for possible SQL vulnerable sites, using search query #{SEARCH}")
agent = Mechanize.new
agent.user_agent = @user_agent
page = agent.get('http://www.google.com/')
google_form = page.form('f')
google_form.q = "#{SEARCH}"
url = agent.submit(google_form, google_form.buttons.first)
url.links.each do |link|
if link.href.to_s =~ /url.q/
str = link.href.to_s
str_list = str.split(%r{=|&})
urls = str_list[1]
next if urls.split('/')[2].start_with? 'whosebug.com', 'github.com', 'www.sa-k.net', 'yoursearch.me', 'search1.speedbit.com', 'duckfm.net', 'search.clearch.org', 'webcache.googleusercontent.com'
next if urls.split('/')[1].start_with? 'ads/preferences?hl=en'
urls_to_log = URI.decode(urls)
Format.success("Site found: #{urls_to_log}")
sleep(1)
File.open("#{PATH}/tmp/SQL_sites_to_check.txt", 'a+') { |s| s.puts("#{urls_to_log}'") }
end
end
Format.info("I've dumped possible vulnerable sites into #{PATH}/tmp/SQL_sites_to_check.txt")
else
begin_vulnerability_check
end
end
def begin_vulnerability_check
(OPTIONS.file) ? file = IO.read(ARGV[1]) : file = IO.read("#{PATH}/tmp/SQL_sites_to_check.txt")
#if options.file
file.each_line do |vuln|
Format.info("Let's check this file out..")
#IO.read("#{PATH}/#{ARGV[1]}").each_line do |vuln|
begin
Format.info("Parsing page for SQL syntax error: #{vuln.chomp}")
Timeout::timeout(10) do
begin
if parse("#{vuln.chomp}'", 'html', 0)[/You have an error in your SQL syntax/]
Format.success("URL: #{vuln.chomp} returned SQL syntax error, temporarily dumped to SQL_VULN.txt")
File.open("#{PATH}/tmp/SQL_VULN.txt", "a+") { |s| s.puts(vuln) }
sleep(1)
else
Format.warning("URL: #{vuln.chomp} is not vulnerable, dumped to non_exploitable.txt")
File.open("#{PATH}/log/non_exploitable.txt", "a+") { |s| s.puts(vuln) }
sleep(1)
end
rescue Timeout::Error, OpenSSL::SSL::SSLError
Format.info("URL: #{vuln.chomp} failed to load dumped to non_exploitable.txt")
File.open("#{PATH}/log/non_exploitable.txt", "a+") { |s| s.puts(vuln) }
next
sleep(1)
end
end
rescue RestClient::ResourceNotFound, RestClient::InternalServerError, RestClient::RequestTimeout, RestClient::Gone, RestClient::SSLCertificateNotVerified, RestClient::Forbidden, OpenSSL::SSL::SSLError, Errno::ECONNREFUSED, URI::InvalidURIError, Errno::ECONNRESET, Timeout::Error, OpenSSL::SSL::SSLError, ArgumentError, RestClient::MultipleChoices, RestClient::Unauthorized, SocketError, RestClient::BadRequest, RestClient::ServerBrokeConnection => e
Format.err("URL: #{vuln.chomp} failed due to an error while connecting, URL dumped to non_exploitable.txt")
File.open("#{PATH}/log/non_exploitable.txt", "a+") { |s| s.puts(vuln) }
next
end
end
usage_page if OPTIONS.nil?
end
case OPTIONS
when OPTIONS[:default] || OPTIONS.file
begin
Whitewidow.spider
sleep(1)
Credits.credits
sleep(1)
Legal.legal
get_urls
begin_vulnerability_check
File.truncate("#{PATH}/tmp/SQL_sites_to_check.txt", 0)
Format.info("I'm truncating SQL_sites_to_check file back to #{File.size("#{PATH}/tmp/SQL_sites_to_check.txt")}")
Copy.file("#{PATH}/tmp/SQL_VULN.txt", "#{PATH}/log/SQL_VULN.LOG")
File.truncate("#{PATH}/tmp/SQL_VULN.txt", 0)
Format.info("I've run all my tests and queries, and logged all important information into #{PATH}/log/SQL_VULN.LOG") unless File.size("#{PATH}/log/SQL_VULN.LOG") == 0
rescue Mechanize::ResponseCodeError, RestClient::ServiceUnavailable, OpenSSL::SSL::SSLError, RestClient::BadGateway => e
d = DateTime.now
Format.fatal("Well this is pretty crappy.. I seem to have encountered a #{e} error. I'm gonna take the safe road and quit scanning before I break something. You can either try again, or manually delete the URL that caused the error.")
File.open("#{PATH}/log/error_log.LOG", 'a+'){ |error| error.puts("[#{d.month}-#{d.day}-#{d.year} :: #{Time.now.strftime("%T")}]#{e}") }
Format.info("I'll log the error inside of #{PATH}/log/error_log.LOG for further analysis.")
end
when OPTIONS[:example]
examples_page
else
Format.info("You failed to pass me a flag, let's try again and pass a flag this time!")
end
OptParser.new
OPTIONS = OptParser.parse_argv(ARGV)
OptionParser 的使用非常简单,但是您要以非常困难的方式进行操作。从这个开始:
require 'optparse'
options = {}
OptionParser.new do |opt|
opt.on('-f', '--foo', 'Foo it') { |o| options[:foo] = o }
opt.on('-b', '--[no-]bar', 'Maybe bar it') { |o| options[:bar] = o }
opt.on('-i', '--int INTEGER', Integer, 'I want an integer') { |o| options[:int] = o }
opt.on('-o', '--float FLOAT', Float, 'I want a Float') { |o| options[:float] = o }
opt.on('-a', '--array INTEGER', Array, 'I want an Array') { |o| options[:array] = o }
end.parse!
puts options
并将其保存到test.rb,然后运行它:
$ ruby test.rb -h
Usage: test [options]
-f, --foo Foo it
-b, --[no-]bar Maybe bar it
-i, --int INTEGER I want an integer
-o, --float FLOAT I want a Float
-a, --array INTEGER I want an Array
所以内置帮助有效。
$ ruby test.rb -f
{:foo=>true}
它看到 -f
标志。
$ ruby test.rb --bar
{:bar=>true}
它看到 --bar
标志。
$ ruby test.rb --no-bar
{:bar=>false}
据了解,应该关闭 --bar
。
$ ruby test.rb --foo --no-bar
{:foo=>true, :bar=>false}
它理解这两个标志。
$ ruby test.rb -i 1
{:int=>1}
是的,它将 "1"
强制转换为整数。
$ ruby test.rb -i 1.1
test.rb:10:in `<main>': invalid argument: -i 1.1 (OptionParser::InvalidArgument)
是的,它期望一个 Integer 而得到一个 float 并抱怨。
$ ruby test.rb -o 1.1
{:float=>1.1}
$ ruby test.rb -o 1.0
{:float=>1.0}
有花车很开心
$ ruby test.rb -o 1
{:float=>1.0}
并将 "1"
强制转换为 Float。不错。
$ ruby test.rb -a 1
{:array=>["1"]}
$ ruby test.rb -a 1,2
{:array=>["1", "2"]}
$ ruby test.rb -a 1,2,zed
{:array=>["1", "2", "zed"]}
它可以正确处理数组。
options
是设置的标志及其参数的一个很好的容器。使用它允许许多不同的分支逻辑方式。我倾向于这样:
require 'optparse'
options = {}
OptionParser.new do |opt|
opt.on('-f', '--foo', 'Foo it') { |o| options[:foo] = o }
opt.on('-b', '--[no-]bar', 'Maybe bar it') { |o| options[:bar] = o }
opt.on('-i', '--int INTEGER', Integer, 'I want an integer') { |o| options[:int] = o }
opt.on('-o', '--float FLOAT', Float, 'I want a Float') { |o| options[:float] = o }
opt.on('-a', '--array INTEGER', Array, 'I want an Array') { |o| options[:array] = o }
end.parse!
str = case
when options.values_at(:foo, :bar).all?
'foo and bar'
when options.values_at(:int, :float, :array).one?
'one of int, float or array'
when options[:foo]
'foo'
when options[:bar]
'bar'
end
puts '%s set' % str
不要创建 OptionParser class。当您调用它 "OptionParser" 时,您打开了 class,然后您创建的任何方法都被添加到其中,可能会覆盖核心方法,从而破坏 class。相反,用一个块创建它的一个实例,然后在块的末尾使用 parse!
来控制它并让它找出传递给它的标志。
OptionParser class 非常强大,因此文档可能有点混乱,但示例很有帮助。
我正在尝试 OptParse
并尝试将其正确设置为 运行,但是,截至目前,我所有的选项都默认为 usage_page 方法。我不确定为什么会发生这种情况,我试图将 CHOICES
常量移动到 begin/rescue 子句的正上方,我还尝试使用 start = OptParser.new
;options = start.parse_argv(ARGV)
这些都不起作用。我也尝试过(正如您从我的代码中看到的那样)将 OptParser.new
和 CHOICES = OptParse.parse_argv(ARGV)
分开,我有点困惑,需要一些帮助,为什么我没有尝试在职的?没看懂,要么告诉我不是变量,不是方法,要么就是抛出用法页面?
(这是我正在尝试提供帮助的开源 project)
我的来源:
PATH = Dir.pwd
VERSION = Whitewidow.version
SEARCH = File.readlines("#{PATH}/lib/search_query.txt").sample
info = YAML.load_file("#{PATH}/lib/rand-agents.yaml")
@user_agent = info['user_agents'][info.keys.sample]
OPTIONS = Struct.new(:default, :file, :example)
def usage_page
Format.usage("You can run me with the following flags: #{File.basename(__FILE__)} -[d|e|h] -[f] <path/to/file/if/any>")
exit
end
def examples_page
Format.usage('This is my examples page, I\'ll show you a few examples of how to get me to do what you want.')
Format.usage('Running me with a file: whitewidow.rb -f <path/to/file> keep the file inside of one of my directories.')
Format.usage('Running me default, if you don\'t want to use a file, because you don\'t think I can handle it, or for whatever reason, you can run me default by passing the Default flag: whitewidow.rb -d this will allow me to scrape Google for some SQL vuln sites, no guarentees though!')
Format.usage('Running me with my Usage flag will show you the boring usage page.. Yeah it\'s not very exciting..')
end
class OptParser
def self.parse_argv(options)
args = OPTIONS.new
opt_parser = OptionParser.new do |opts|
opts.banner = usage_page
opts.on('-d', '--default', 'Run me in default mode, I\'ll scrape Google for SQL vulns.') do |d|
args[:default] = d
end
opts.on('-fFILE', '--file=FILE', 'Pass me the name of the file. Leave out the beginning forward slash. (/lib/ <= incorrect lib/ <=correct)') do |f|
args.fileFILE = f
end
opts.on('-e', '--example', 'Shows my example page. It\'s really not that hard to figure out, but I\'m a nice albino widow.') do |e|
args[:example] = e
end
opts.on('-h', '--help', 'Shows a complete list of all my usages, with what they do, and their secondary flag.') do
puts opts
exit
end
opts.on('-u', '--usage', 'Shows my usage page, a short list of possible flags, use the help flag (-h) for a more complete list.') do
usage_page
exit
end
end
opt_parser.parse!(options)
return args
end
end
def pull_proxy
info = parse("http://www.nntime.com/",'.odd', 1)
@ip = info[/\D\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\D/].gsub(">", "").gsub("<", "")
@port = info[/8080/] || info[/3128/] || info[/80/] || info[/3129/] || info[/6129/]
proxy = "#{@ip}:#{@port}"
Format.info("Proxy discovered: #{proxy}")
end
def page(site)
Nokogiri::HTML(RestClient.get(site))
end
def parse(site, tag, i)
parsing = page(site)
parsing.css(tag)[i].to_s
end
def get_urls
if OPTIONS[:default]
Format.info('I\'ll run in default mode then!')
Format.info("I'm searching for possible SQL vulnerable sites, using search query #{SEARCH}")
agent = Mechanize.new
agent.user_agent = @user_agent
page = agent.get('http://www.google.com/')
google_form = page.form('f')
google_form.q = "#{SEARCH}"
url = agent.submit(google_form, google_form.buttons.first)
url.links.each do |link|
if link.href.to_s =~ /url.q/
str = link.href.to_s
str_list = str.split(%r{=|&})
urls = str_list[1]
next if urls.split('/')[2].start_with? 'whosebug.com', 'github.com', 'www.sa-k.net', 'yoursearch.me', 'search1.speedbit.com', 'duckfm.net', 'search.clearch.org', 'webcache.googleusercontent.com'
next if urls.split('/')[1].start_with? 'ads/preferences?hl=en'
urls_to_log = URI.decode(urls)
Format.success("Site found: #{urls_to_log}")
sleep(1)
File.open("#{PATH}/tmp/SQL_sites_to_check.txt", 'a+') { |s| s.puts("#{urls_to_log}'") }
end
end
Format.info("I've dumped possible vulnerable sites into #{PATH}/tmp/SQL_sites_to_check.txt")
else
begin_vulnerability_check
end
end
def begin_vulnerability_check
(OPTIONS.file) ? file = IO.read(ARGV[1]) : file = IO.read("#{PATH}/tmp/SQL_sites_to_check.txt")
#if options.file
file.each_line do |vuln|
Format.info("Let's check this file out..")
#IO.read("#{PATH}/#{ARGV[1]}").each_line do |vuln|
begin
Format.info("Parsing page for SQL syntax error: #{vuln.chomp}")
Timeout::timeout(10) do
begin
if parse("#{vuln.chomp}'", 'html', 0)[/You have an error in your SQL syntax/]
Format.success("URL: #{vuln.chomp} returned SQL syntax error, temporarily dumped to SQL_VULN.txt")
File.open("#{PATH}/tmp/SQL_VULN.txt", "a+") { |s| s.puts(vuln) }
sleep(1)
else
Format.warning("URL: #{vuln.chomp} is not vulnerable, dumped to non_exploitable.txt")
File.open("#{PATH}/log/non_exploitable.txt", "a+") { |s| s.puts(vuln) }
sleep(1)
end
rescue Timeout::Error, OpenSSL::SSL::SSLError
Format.info("URL: #{vuln.chomp} failed to load dumped to non_exploitable.txt")
File.open("#{PATH}/log/non_exploitable.txt", "a+") { |s| s.puts(vuln) }
next
sleep(1)
end
end
rescue RestClient::ResourceNotFound, RestClient::InternalServerError, RestClient::RequestTimeout, RestClient::Gone, RestClient::SSLCertificateNotVerified, RestClient::Forbidden, OpenSSL::SSL::SSLError, Errno::ECONNREFUSED, URI::InvalidURIError, Errno::ECONNRESET, Timeout::Error, OpenSSL::SSL::SSLError, ArgumentError, RestClient::MultipleChoices, RestClient::Unauthorized, SocketError, RestClient::BadRequest, RestClient::ServerBrokeConnection => e
Format.err("URL: #{vuln.chomp} failed due to an error while connecting, URL dumped to non_exploitable.txt")
File.open("#{PATH}/log/non_exploitable.txt", "a+") { |s| s.puts(vuln) }
next
end
end
usage_page if OPTIONS.nil?
end
case OPTIONS
when OPTIONS[:default] || OPTIONS.file
begin
Whitewidow.spider
sleep(1)
Credits.credits
sleep(1)
Legal.legal
get_urls
begin_vulnerability_check
File.truncate("#{PATH}/tmp/SQL_sites_to_check.txt", 0)
Format.info("I'm truncating SQL_sites_to_check file back to #{File.size("#{PATH}/tmp/SQL_sites_to_check.txt")}")
Copy.file("#{PATH}/tmp/SQL_VULN.txt", "#{PATH}/log/SQL_VULN.LOG")
File.truncate("#{PATH}/tmp/SQL_VULN.txt", 0)
Format.info("I've run all my tests and queries, and logged all important information into #{PATH}/log/SQL_VULN.LOG") unless File.size("#{PATH}/log/SQL_VULN.LOG") == 0
rescue Mechanize::ResponseCodeError, RestClient::ServiceUnavailable, OpenSSL::SSL::SSLError, RestClient::BadGateway => e
d = DateTime.now
Format.fatal("Well this is pretty crappy.. I seem to have encountered a #{e} error. I'm gonna take the safe road and quit scanning before I break something. You can either try again, or manually delete the URL that caused the error.")
File.open("#{PATH}/log/error_log.LOG", 'a+'){ |error| error.puts("[#{d.month}-#{d.day}-#{d.year} :: #{Time.now.strftime("%T")}]#{e}") }
Format.info("I'll log the error inside of #{PATH}/log/error_log.LOG for further analysis.")
end
when OPTIONS[:example]
examples_page
else
Format.info("You failed to pass me a flag, let's try again and pass a flag this time!")
end
OptParser.new
OPTIONS = OptParser.parse_argv(ARGV)
OptionParser 的使用非常简单,但是您要以非常困难的方式进行操作。从这个开始:
require 'optparse'
options = {}
OptionParser.new do |opt|
opt.on('-f', '--foo', 'Foo it') { |o| options[:foo] = o }
opt.on('-b', '--[no-]bar', 'Maybe bar it') { |o| options[:bar] = o }
opt.on('-i', '--int INTEGER', Integer, 'I want an integer') { |o| options[:int] = o }
opt.on('-o', '--float FLOAT', Float, 'I want a Float') { |o| options[:float] = o }
opt.on('-a', '--array INTEGER', Array, 'I want an Array') { |o| options[:array] = o }
end.parse!
puts options
并将其保存到test.rb,然后运行它:
$ ruby test.rb -h
Usage: test [options]
-f, --foo Foo it
-b, --[no-]bar Maybe bar it
-i, --int INTEGER I want an integer
-o, --float FLOAT I want a Float
-a, --array INTEGER I want an Array
所以内置帮助有效。
$ ruby test.rb -f
{:foo=>true}
它看到 -f
标志。
$ ruby test.rb --bar
{:bar=>true}
它看到 --bar
标志。
$ ruby test.rb --no-bar
{:bar=>false}
据了解,应该关闭 --bar
。
$ ruby test.rb --foo --no-bar
{:foo=>true, :bar=>false}
它理解这两个标志。
$ ruby test.rb -i 1
{:int=>1}
是的,它将 "1"
强制转换为整数。
$ ruby test.rb -i 1.1
test.rb:10:in `<main>': invalid argument: -i 1.1 (OptionParser::InvalidArgument)
是的,它期望一个 Integer 而得到一个 float 并抱怨。
$ ruby test.rb -o 1.1
{:float=>1.1}
$ ruby test.rb -o 1.0
{:float=>1.0}
有花车很开心
$ ruby test.rb -o 1
{:float=>1.0}
并将 "1"
强制转换为 Float。不错。
$ ruby test.rb -a 1
{:array=>["1"]}
$ ruby test.rb -a 1,2
{:array=>["1", "2"]}
$ ruby test.rb -a 1,2,zed
{:array=>["1", "2", "zed"]}
它可以正确处理数组。
options
是设置的标志及其参数的一个很好的容器。使用它允许许多不同的分支逻辑方式。我倾向于这样:
require 'optparse'
options = {}
OptionParser.new do |opt|
opt.on('-f', '--foo', 'Foo it') { |o| options[:foo] = o }
opt.on('-b', '--[no-]bar', 'Maybe bar it') { |o| options[:bar] = o }
opt.on('-i', '--int INTEGER', Integer, 'I want an integer') { |o| options[:int] = o }
opt.on('-o', '--float FLOAT', Float, 'I want a Float') { |o| options[:float] = o }
opt.on('-a', '--array INTEGER', Array, 'I want an Array') { |o| options[:array] = o }
end.parse!
str = case
when options.values_at(:foo, :bar).all?
'foo and bar'
when options.values_at(:int, :float, :array).one?
'one of int, float or array'
when options[:foo]
'foo'
when options[:bar]
'bar'
end
puts '%s set' % str
不要创建 OptionParser class。当您调用它 "OptionParser" 时,您打开了 class,然后您创建的任何方法都被添加到其中,可能会覆盖核心方法,从而破坏 class。相反,用一个块创建它的一个实例,然后在块的末尾使用 parse!
来控制它并让它找出传递给它的标志。
OptionParser class 非常强大,因此文档可能有点混乱,但示例很有帮助。