buby 1.1.6-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+
2
+ require 'buby/extends/buby_array_wrapper'
3
+ require 'buby/extends/http_request_response'
4
+ require 'buby/extends/scan_issue'
@@ -0,0 +1,41 @@
1
+
2
+ class Buby
3
+ class BubyArrayWrapper
4
+ include Enumerable
5
+
6
+ attr_reader :array_obj
7
+
8
+ def initialize(obj)
9
+ @array_obj = obj
10
+ end
11
+
12
+ def [](*args)
13
+ if args.size == 1 and args.first.kind_of? Numeric
14
+ self.array_obj[args[0]]
15
+ else
16
+ self.to_a(*args)
17
+ end
18
+ end
19
+
20
+ def each
21
+ self.array_obj.size.times do |idx|
22
+ yield self.array_obj[idx]
23
+ end
24
+ end
25
+
26
+ def size
27
+ self.array_obj.size
28
+ end
29
+ alias length size
30
+
31
+ def first
32
+ return(self.array_obj[0]) if(self.size > 0)
33
+ end
34
+
35
+ def last
36
+ return self.array_obj[self.size - 1] if(self.size > 0)
37
+ end
38
+
39
+ end
40
+
41
+ end
@@ -0,0 +1,95 @@
1
+ require 'uri'
2
+
3
+ class Buby
4
+
5
+ class HttpRequestResponseList < BubyArrayWrapper
6
+ def initialize(obj)
7
+ HttpRequestResponseHelper.implant(obj[0]) if obj.size > 0
8
+ super(obj)
9
+ end
10
+
11
+ end
12
+
13
+
14
+ module HttpRequestResponseHelper
15
+
16
+ # returns the response as a Ruby String object - returns an empty string
17
+ # if response is nil.
18
+ def response_str
19
+ return response().nil? ? "" : ::String.from_java_bytes(response())
20
+ end
21
+ alias response_string response_str
22
+ alias rsp_str response_str
23
+
24
+
25
+ # returns an array of response headers split into header name and value.
26
+ # For example:
27
+ # [
28
+ # ["HTTP/1.1 301 Moved Permanently"],
29
+ # ["Server", "Apache/1.3.41 ..."],
30
+ # ...
31
+ # ]
32
+ def response_headers
33
+ if headers=(@rsp_split ||= rsp_str.split(/\r?\n\r?\n/, 2))[0]
34
+ @rsp_headers ||= headers.split(/\r?\n/).map {|h| h.split(/\s*:\s*/,2)}
35
+ end
36
+ end
37
+ alias rsp_headers response_headers
38
+
39
+ # Returns the message body of the response, minus headers
40
+ def response_body
41
+ (@rsp_split ||= rsp_str.split(/\r?\n\r?\n/, 2))[1]
42
+ end
43
+ alias rsp_body response_body
44
+
45
+
46
+ # Returns the full request as a Ruby String - returns an empty string if
47
+ # request is nil.
48
+ def request_str
49
+ return request().nil? ? "" : ::String.from_java_bytes(request())
50
+ end
51
+ alias request_string request_str
52
+ alias req_str request_str
53
+
54
+
55
+ # Returns a split array of headers. Example:
56
+ # [
57
+ # ["GET / HTTP/1.1"],
58
+ # ["Host", "www.example.org"],
59
+ # ["User-Agent", "Mozilla/5.0 (..."],
60
+ # ...
61
+ # ]
62
+ def request_headers
63
+ if headers=(@req_split ||= req_str.split(/\r?\n\r?\n/, 2))[0]
64
+ @req_headers ||= headers.split(/\r?\n/).map {|h| h.split(/\s*:\s*/,2)}
65
+ end
66
+ end
67
+ alias req_headers request_headers
68
+
69
+
70
+ # Returns the request message body or an empty string if there is none.
71
+ def request_body
72
+ (@req_split ||= req_str.split(/\r?\n\r?\n/, 2))[1]
73
+ end
74
+ alias req_body request_body
75
+
76
+
77
+ # Returns a Ruby URI object derived from the java.net.URL object
78
+ def uri
79
+ @uri ||= URI.parse url.to_s if not url.nil?
80
+ end
81
+
82
+
83
+ # one-shot method to implant ourselves onto a target object's class
84
+ # interface in ruby. All later instances will also get 'us' for free!
85
+ def self.implant(base)
86
+ return if @implanted
87
+ base.class.instance_eval { include(HttpRequestResponseHelper) }
88
+ @implanted = true
89
+ end
90
+
91
+
92
+ def self.implanted? ; @implanted; end
93
+ end
94
+
95
+ end
@@ -0,0 +1,36 @@
1
+ require 'uri'
2
+
3
+ class Buby
4
+
5
+ class ScanIssuesList < BubyArrayWrapper
6
+ def initialize(obj)
7
+ ScanIssueHelper.implant(obj[0]) if obj.size > 0
8
+ super(obj)
9
+ end
10
+
11
+ end
12
+
13
+ module ScanIssueHelper
14
+ # Returns a Ruby URI object derived from the java.net.URL object
15
+ def uri
16
+ @uri ||= URI.parse url.to_s if not url.nil?
17
+ end
18
+
19
+ # one-shot method to implant ourselves onto a target object's class
20
+ # interface in ruby. All later instances will also get 'us' for free!
21
+ def self.implant(base)
22
+ return if @implanted
23
+ base.class.instance_eval { include(ScanIssueHelper) }
24
+ @implanted = true
25
+ end
26
+
27
+ def http_messages
28
+ HttpRequestResponseList.new( self.getHttpMessages() )
29
+ end
30
+ alias messages http_messages
31
+ alias messages http_messages
32
+
33
+ def self.implanted? ; @implanted; end
34
+ end
35
+ end
36
+
@@ -0,0 +1,31 @@
1
+
2
+ require 'rubygems'
3
+ require 'buby'
4
+ require 'drb'
5
+
6
+ module DrbBuby
7
+ attr_reader :drb_server
8
+
9
+ def evt_register_callbacks(cb)
10
+ super(cb)
11
+ # cb.issueAlert("[DrbBuby] Service on: #{@drb_server.uri}")
12
+ end
13
+
14
+ def init_DrbBuby
15
+ ## want to bind the DRb service on a specific socket?
16
+ uri ='druby://127.0.0.1:9999'
17
+ ## or let it choose one automatically:
18
+ # uri = nil
19
+ @drb_server = DRb.start_service uri, self
20
+ puts "[DrbBuby] Service on: #{@drb_server.uri}"
21
+ self.alert("[DrbBuby] Service on: #{@drb_server.uri}")
22
+ end
23
+ end
24
+
25
+ if __FILE__ == $0
26
+ $burp = Buby.new
27
+ $burp.extend(DrbBuby)
28
+ $burp.start_burp()
29
+ $burp.init_DrbBuby
30
+ end
31
+
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ # notice... we're using MRI ruby here, not JRuby (but either will work)
3
+
4
+ require 'drb'
5
+
6
+ unless drb_uri = ARGV.shift
7
+ STDERR.puts "Usage: #{File.basename $0} druby://<addr>:<port>"
8
+ exit 1
9
+ end
10
+
11
+ drb = DRbObject.new nil, drb_uri
12
+ rsp=drb.make_http_request 'example.com', 80, false, "GET / HTTP/1.0\r\n\r\n"
13
+
14
+ puts rsp
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env jruby
2
+
3
+ require 'rubygems'
4
+ require 'buby'
5
+ require 'mechanize'
6
+ require 'rbkb/http'
7
+ require 'irb'
8
+
9
+ include Java
10
+
11
+ # This Buby handler implementation simply keeps cookie state synched
12
+ # for a Mechanize agent by intercepting all requests sent through the
13
+ # Burp proxy. This lets you use Mechanize in tandem with your browser
14
+ # through Burp without having to fuss around with cookies.
15
+ module MechGlue
16
+ attr_accessor :mech_agent
17
+
18
+ def evt_proxy_message(*param)
19
+ msg_ref, is_req, rhost, rport, is_https, http_meth, url,
20
+ resourceType, status, req_content_type, message, action = param
21
+
22
+ if (not is_req) and (message =~ /Set-Cookie/i)
23
+
24
+ rsp = Rbkb::Http::Response.new(message, :ignore_content_length => true)
25
+
26
+ # Get an uri object ready for mechanize
27
+ uri = URI.parse(url)
28
+ uri.scheme = (is_https)? "https" : "http"
29
+ uri.host = rhost
30
+ uri.port = rport
31
+
32
+ # Grab cookies from headers:
33
+ rsp.headers.get_header_value('Set-Cookie').each do |cookie|
34
+ WWW::Mechanize::Cookie.parse(uri, cookie) do |c|
35
+ @mech_agent.cookie_jar.add(uri, c)
36
+ end
37
+ end
38
+ end
39
+ return(message)
40
+ end
41
+ end
42
+
43
+
44
+ if __FILE__ == $0
45
+ $mech = WWW::Mechanize.new
46
+ #$mech.set_proxy('localhost', '8080')
47
+
48
+ $burp = Buby.new()
49
+ $burp.extend(MechGlue)
50
+ $burp.mech_agent = $mech
51
+ $burp.start_burp
52
+
53
+ puts "$burp is set to #{$burp.class}"
54
+ puts "$mech is set to #{$mech.class}"
55
+ IRB.start
56
+ end
57
+
@@ -0,0 +1,124 @@
1
+ require 'uri'
2
+ require 'htmlentities'
3
+
4
+ # This set up as a buby module extension. You can load it from the CLI when
5
+ # launching buby as follows:
6
+ #
7
+ # buby -r csrf_poc_generator.rb -e CsrfPocGenerator -i
8
+ #
9
+ module PocGenerator
10
+ HEX = %w{0 1 2 3 4 5 6 7 8 9 a b c d e f}
11
+
12
+ # Take a HTTP POST string and convert it to HTML proof of concept with a
13
+ # form full of hidden variables that gets auto-submitted on load.
14
+ #
15
+ # Especially handy for burp since you don't always know whether what you're
16
+ # playing with in repeater will actually work in the browser. Also handy for
17
+ # testing reflected/stored XSS if the request happens to require a POST.
18
+ #
19
+ # Handles www-form-urlencoded as well as multi-part. Note if your multi-part
20
+ # data has any files in it, they'll just get jammed into a hidden var with
21
+ # the rest. This may or may not be what you actually want.
22
+ #
23
+ # @param req can be a index into proxy_history, string, java byte array, or
24
+ # HttpRequestResponse object
25
+ #
26
+ # @param options:
27
+ # :uri = uri to set form action to (default - auto)
28
+ # :meth = form http method (default - POST)
29
+ # :enc = form enctype (default - 'application/www-form-urlencoded')
30
+ # :host = override 'host' in uri with this. (default - auto)
31
+ # :scheme = override 'scheme' in uri with this. (default - 'http')
32
+ # :port = override 'port' in uri with this. (default - blank)
33
+ #
34
+ # The URI, host scheme, and port are all automatically pulled from req if
35
+ # it is a HttpRequest. Otherwise, the code will attempt to gather this info
36
+ # from the Host: header and HTTP action. Note that in the latter case, the
37
+ # determination of http/https is impossible, so you'll want to specify the
38
+ # scheme
39
+ def post_to_poc(req, opts = {})
40
+ uri = opts[:uri]
41
+ meth = opts[:meth] || "POST"
42
+ enc = opts[:enc] || opts[:encoding] || 'application/www-form-urlencoded'
43
+ host = opts[:host]
44
+ scheme = opts[:scheme]
45
+ port = opts[:port]
46
+
47
+ reqstr =
48
+ if req.kind_of? String
49
+ req
50
+ elsif req.respond_to? :java_class and req.java_class.to_s == "[B"
51
+ String.from_java_bytes
52
+ elsif req.kind_of? Numeric
53
+ req = getProxyHistory()[req]
54
+ uri ||= req.uri
55
+ req.req_str
56
+ elsif req.respond_to?(:req_str)
57
+ req.req_str
58
+ end
59
+
60
+ params = getParameters(reqstr).to_a.select {|x| x[2] == "body parameter"}.map {|p| [p[0], p[1].chomp]}
61
+ headers = getHeaders(reqstr).to_a
62
+ verb, action, vers = headers.first.split(/\s+/, 3)
63
+
64
+ if headers.grep(/^content-type: application\/(?:x-)?(?:www-form-url|url-)encoded(?:\W|$)/i)
65
+ params = params.map do |p|
66
+ p.map do |f|
67
+ f.gsub(/%[a-f0-9]{2}/i) do |x|
68
+ ((HEX.index(x[1,1].downcase) << 4) + HEX.index(x[2,1].downcase)).chr
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ if uri.nil?
75
+ uri =
76
+ if req.respond_to? :uri
77
+ uri = req.uri
78
+ else
79
+ uri = URI.parse(action)
80
+ end
81
+ elsif uri.is_a? String
82
+ uri = URI.parse(action)
83
+ end
84
+
85
+ if opts[:host]
86
+ uri.host = host
87
+ uri.scheme = scheme if scheme
88
+ elsif host.nil? and hhost = headers.grep(/host: (.*)$/i){|h| $1 }.first
89
+ uri.host, uri.port = hhost.split(':', 2)
90
+ uri.scheme = scheme || 'http'
91
+ else
92
+ uri.scheme = scheme if scheme
93
+ end
94
+
95
+ uri.port = port if port
96
+
97
+ ret = %{<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
98
+ <html><head></head>
99
+ <body>
100
+ <form name="doit_form" method="#{meth.to_s.upcase}" action=#{uri.to_s.inspect} enctype=#{enc.inspect}>
101
+ }
102
+
103
+ coder = HTMLEntities.new
104
+ params.each do |p|
105
+ name = coder.encode(p[0]).inspect
106
+ val = coder.encode(p[1]).inspect
107
+ ret << " <input type=\"hidden\" name=#{name} value=#{val} />\n"
108
+ end
109
+
110
+ ret << %{
111
+ <input type="submit" value="click me if this doesnt redirect'" />
112
+ </form>
113
+ <script> document.doit_form.submit(); </script>
114
+ </body>
115
+ </html>}
116
+
117
+ return ret
118
+ end
119
+
120
+ def init_CsrfPocGenerator
121
+ # nop
122
+ end
123
+ end
124
+
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env jruby
2
+ require 'rubygems'
3
+ require 'buby'
4
+
5
+ module VerbTamperer
6
+ def evt_proxy_message(*param)
7
+ msg_ref, is_req, rhost, rport, is_https, http_meth, url,
8
+ resourceType, status, req_content_type, message, action = param
9
+
10
+ if is_req and http_meth == "GET"
11
+ message[0,3] = "PET"
12
+ action[0] = Buby::ACTION_DONT_INTERCEPT
13
+
14
+ return super(*param).dup
15
+ else
16
+ return super(*param)
17
+ end
18
+ end
19
+ end
20
+
21
+ if __FILE__ == $0
22
+ $burp = Buby.new()
23
+ $burp.extend(VerbTamperer)
24
+ $burp.start_burp()
25
+ end
@@ -0,0 +1,21 @@
1
+
2
+ module WatchScan
3
+ def evt_http_message(tool_name, is_request, message_info)
4
+ super(tool_name, is_request, message_info)
5
+ if tool_name == 'scanner'
6
+ if is_request
7
+ puts "#"*70, "# REQUEST: #{message_info.url.toString}", "#"*70
8
+ puts message_info.req_str
9
+ puts
10
+ else
11
+ puts "#"*70, "# RESPONSE: #{message_info.url.toString}", "#"*70
12
+ puts message_info.rsp_str
13
+ puts
14
+ end
15
+ end
16
+ end
17
+
18
+ def init_WatchScan
19
+ puts "WatchScan module initialized"
20
+ end
21
+ end