emonti-buby 1.1.3.1 → 1.1.4

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.
data/History.txt CHANGED
@@ -1,3 +1,14 @@
1
+ == 1.1.4 / 2009-09-14
2
+ * enhancements
3
+ * buby got implants! (har har)
4
+ * Ruby wrapper classes added for proxy_history, site_map, and scan_issues
5
+ * Extensions module for IHttpRequestResponse burp's class implementation
6
+ * Extensions module for IScanIssue burp's class implementation
7
+ * Added -s/--state, -r/--require, -e/--extend to buby cmd-line executable
8
+ * Added -v/--version buby cmd-line flag
9
+ * Modified samples for use as modules with -r/-e as well as run standalone
10
+ * Added drb client and server sample
11
+
1
12
  == 1.1.3.1 / 2009-09-09
2
13
  * fix
3
14
  * fixed a typo in the String type-check for Buby.getParameters()
data/README.rdoc CHANGED
@@ -34,8 +34,7 @@ The java BurpExtender included with Buby is an implementation of IBurpExtender w
34
34
  The C version of ruby will not work.
35
35
 
36
36
  * Burp (pro or free version): Buby is useless without a copy of Burp.
37
- Buby has been tested successfully with both Burp Suite free and pro versions.
38
- As of version 1.1.0, Buby supports both pre and post 1.2.09 Burp extensions.
37
+ Buby has been tested successfully with Burp 1.2.x.
39
38
 
40
39
 
41
40
  == BUILD/INSTALL:
@@ -97,24 +96,22 @@ Your configuration details can be substituted below.
97
96
  ln -s ~/tools/burp.jar ~/jruby-1.1.5/lib/ruby/1.8/java/burp.jar
98
97
 
99
98
  Now everything should be ready to go. Try at least the first few parts of the
100
- test below to confirm everything is set up. Or if you installed the gem, just
101
- run 'buby' from the command-line.
102
-
99
+ test below to confirm everything is set up.
103
100
 
104
101
  == TEST AND USAGE EXAMPLE:
105
102
 
106
- The gem includes a command-line tool called 'buby' but it doesn't do much right
107
- now. You can, however, use this as a minimal test to confirm whether Burp can
108
- be launched from ruby and that Buby and Burp are connected.
109
-
110
- Launch buby for simple testing and debugging with the 'buby' command-line tool:
103
+ The gem includes a command-line executable called 'buby'. You can use this to
104
+ test your Buby set-up and try out a few features.
111
105
 
112
106
  $ buby -h
113
107
  Usage: buby [options]
114
- -i, --interactive Start IRB
115
- -d, --debug Debug info
116
- -B, --load-burp=PATH Load Burp Jar from PATH
117
- -h, --help Show this help message
108
+ -i, --interactive Start IRB
109
+ -d, --debug Debug info
110
+ -B, --load-burp=PATH Load Burp Jar from PATH
111
+ -s, --state=FILE Restore burp state file on startup
112
+ -r, --require=LIB load a ruby lib (or jar) after Burp loads
113
+ -e, --extend=MOD Extend Buby with a module (loaded via -r?)
114
+ -h, --help Show this help message
118
115
 
119
116
  $ buby -i -d
120
117
  [:got_extender, #<Java::Default::BurpExtender:0x80 ...>]
@@ -157,7 +154,7 @@ test through a browser configured to use Burp as its proxy.
157
154
 
158
155
 
159
156
  With $DEBUG = true, you should see the debugging output from Ruby as the proxy
160
- passes your request back to your Ruby runtime.
157
+ passes your request back to your HTTP client/browser.
161
158
 
162
159
  It will look something like the following in IRB:
163
160
 
data/bin/buby CHANGED
@@ -21,6 +21,25 @@ begin
21
21
  o.on("-B", "--load-burp=PATH", "Load Burp Jar from PATH") do |b|
22
22
  args[:load_burp] = b
23
23
  end
24
+
25
+ o.on('-s', '--state=FILE', "Restore burp state file on startup") do |r|
26
+ args[:restore] = r
27
+ end
28
+
29
+ o.on('-r', '--require=LIB',
30
+ 'load a ruby lib (or jar) after Burp loads') do |i|
31
+ (args[:requires] ||= []).push(i)
32
+ end
33
+
34
+ o.on('-e', '--extend=MOD',
35
+ 'Extend Buby with a module (loaded via -r?)') do |m|
36
+ (args[:extensions] ||= []).push(m)
37
+ end
38
+
39
+ o.on('-v', '--version', 'Prints version and exits.') do
40
+ puts "#{File.basename $0} v#{Buby::VERSION}"
41
+ exit 0
42
+ end
24
43
  end
25
44
 
26
45
  opts.parse!(ARGV)
@@ -28,7 +47,9 @@ begin
28
47
  if jar=args[:load_burp]
29
48
  raise "Load Burp Error: #{jar} did not provide burp.StartBurp" unless Buby.load_burp(jar)
30
49
  end
50
+
31
51
  raise "Load Burp Error: Specify a path to your burp.jar with -B" unless Buby.burp_loaded?
52
+
32
53
  rescue
33
54
  STDERR.puts $!
34
55
  exit 1
@@ -38,6 +59,39 @@ $DEBUG=true if args[:debug]
38
59
 
39
60
  $burp = Buby.start_burp()
40
61
 
62
+ if libs=args[:requires]
63
+ libs.each {|lib| STDERR.puts "Loading: #{lib.inspect}"; require(lib)}
64
+ end
65
+
66
+ def resolve_const(str)
67
+ raise "can't resolve empty name #{str.inspect}" if str.empty?
68
+ names = str.split('::')
69
+ obj = ::Object
70
+ names.each do |name|
71
+ raise "#{name.inspect} is not defined" unless obj.const_defined?(name)
72
+ obj = obj.const_get(name)
73
+ end
74
+ return obj if obj != ::Object
75
+ end
76
+
77
+ if mods=args[:extensions]
78
+ mods.each do |mod|
79
+ obj = resolve_const(mod)
80
+ raise "#{obj.name} is not a module" unless obj.kind_of? Module
81
+ STDERR.puts "Extending $burp with: #{obj.name}"
82
+ $burp.extend(obj)
83
+ if $burp.respond_to?(imeth=:"init_#{mod.split('::').last}")
84
+ $burp.__send__ imeth
85
+ end
86
+ end
87
+ end
88
+
89
+ if f=args[:restore]
90
+ raise "no such file #{f.inspect}" unless File.exists?(f)
91
+ STDERR.puts "Restoring burp state from: #{f.inspect}"
92
+ $burp.restore_state(f)
93
+ end
94
+
41
95
  if args[:irb]
42
96
  # yucky hack...
43
97
  IRB.setup(nil)
@@ -51,3 +105,4 @@ if args[:irb]
51
105
  " Important Note: You'll need to exit by closing the burp window."
52
106
  IRB.start()
53
107
  end
108
+
data/buby.gemspec CHANGED
@@ -2,17 +2,17 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{buby}
5
- s.version = "1.1.3.1"
5
+ s.version = "1.1.4"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Eric Monti - Matasano Security"]
9
- s.date = %q{2009-08-25}
9
+ s.date = %q{2009-09-21}
10
10
  s.default_executable = %q{buby}
11
11
  s.description = %q{Buby is a mashup of JRuby with the popular commercial web security testing tool Burp Suite from PortSwigger. Burp is driven from and tied to JRuby with a Java extension using the BurpExtender API. This extension aims to add Ruby scriptability to Burp Suite with an interface comparable to the Burp's pure Java extension interface.}
12
12
  s.email = %q{emonti@matasano.com}
13
13
  s.executables = ["buby"]
14
14
  s.extra_rdoc_files = ["History.txt", "README.rdoc", "bin/buby"]
15
- s.files = ["History.txt", "README.rdoc", "Rakefile", "bin/buby", "buby.gemspec", "java/buby.jar", "java/src/BurpExtender.java", "java/src/burp/IBurpExtender.java", "java/src/burp/IBurpExtenderCallbacks.java", "java/src/burp/IHttpRequestResponse.java", "java/src/burp/IScanIssue.java", "java/src/burp/IScanQueueItem.java", "lib/buby.rb", "samples/mechanize_burp.rb", "samples/verb_tamperer.rb", "spec/buby_spec.rb", "spec/spec_helper.rb", "tasks/ann.rake", "tasks/bones.rake", "tasks/gem.rake", "tasks/git.rake", "tasks/notes.rake", "tasks/post_load.rake", "tasks/rdoc.rake", "tasks/rubyforge.rake", "tasks/setup.rb", "tasks/spec.rake", "tasks/svn.rake", "tasks/test.rake", "tasks/zentest.rake", "test/test_buby.rb"]
15
+ s.files = ["History.txt", "README.rdoc", "Rakefile", "bin/buby", "buby.gemspec", "java/buby.jar", "java/src/BurpExtender.java", "java/src/burp/IBurpExtender.java", "java/src/burp/IBurpExtenderCallbacks.java", "java/src/burp/IHttpRequestResponse.java", "java/src/burp/IScanIssue.java", "java/src/burp/IScanQueueItem.java", "lib/buby.rb", "lib/buby/extends.rb", "lib/buby/extends/buby_array_wrapper.rb", "lib/buby/extends/http_request_response.rb", "lib/buby/extends/scan_issue.rb", "samples/drb_buby.rb", "samples/drb_sample_cli.rb", "samples/mechanize_burp.rb", "samples/verb_tamperer.rb", "samples/watch_scan.rb", "spec/buby_spec.rb", "spec/spec_helper.rb", "tasks/ann.rake", "tasks/bones.rake", "tasks/gem.rake", "tasks/git.rake", "tasks/notes.rake", "tasks/post_load.rake", "tasks/rdoc.rake", "tasks/rubyforge.rake", "tasks/setup.rb", "tasks/spec.rake", "tasks/svn.rake", "tasks/test.rake", "tasks/zentest.rake", "test/test_buby.rb"]
16
16
  s.homepage = %q{http://emonti.github.com/buby}
17
17
  s.rdoc_options = ["--main", "README.rdoc"]
18
18
  s.require_paths = ["lib", "java"]
@@ -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,4 @@
1
+
2
+ require 'buby/extends/buby_array_wrapper'
3
+ require 'buby/extends/http_request_response'
4
+ require 'buby/extends/scan_issue'
data/lib/buby.rb CHANGED
@@ -2,6 +2,7 @@ include Java
2
2
 
3
3
  require 'pp'
4
4
  require "buby.jar"
5
+ require 'buby/extends.rb'
5
6
 
6
7
  include_class 'BurpExtender'
7
8
 
@@ -78,7 +79,7 @@ include_class 'BurpExtender'
78
79
  class Buby
79
80
 
80
81
  # :stopdoc:
81
- VERSION = '1.1.3'
82
+ VERSION = '1.1.4'
82
83
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
83
84
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
84
85
  # :startdoc:
@@ -226,7 +227,7 @@ class Buby
226
227
  alias send_to_spider sendToSpider
227
228
  alias spider sendToSpider
228
229
 
229
- # This method is a __send__ call back gate for the IBurpExtenderCallbacks
230
+ # This method is a __send__ callback gate for the IBurpExtenderCallbacks
230
231
  # reference. It first checks to see if a method is available before calling
231
232
  # with the specified arguments, and raises an exception if it is unavailable.
232
233
  #
@@ -243,33 +244,37 @@ class Buby
243
244
  cb.__send__ meth, *args
244
245
  end
245
246
 
247
+
246
248
  # Returns a Java array of IHttpRequestResponse objects pulled directly from
247
249
  # the Burp proxy history.
248
250
  def getProxyHistory
249
- _check_and_callback(:getProxyHistory)
251
+ HttpRequestResponseList.new(_check_and_callback(:getProxyHistory))
250
252
  end
251
253
  alias proxy_history getProxyHistory
252
254
  alias get_proxy_history getProxyHistory
253
255
 
256
+
254
257
  # Returns a Java array of IHttpRequestResponse objects pulled directly from
255
258
  # the Burp site map for all urls matching the specified literal prefix.
256
259
  # The prefix can be nil to return all objects.
257
260
  def getSiteMap(urlprefix=nil)
258
- _check_and_callback(:getSiteMap, urlprefix)
261
+ HttpRequestResponseList.new(_check_and_callback(:getSiteMap, urlprefix))
259
262
  end
260
263
  alias site_map getSiteMap
261
264
  alias get_site_map getSiteMap
262
265
 
266
+
263
267
  # This method returns all of the current scan issues for URLs matching the
264
268
  # specified literal prefix. The prefix can be nil to match all issues.
265
269
  #
266
270
  # IMPORTANT: This method is only available with Burp 1.2.15 and higher.
267
271
  def getScanIssues(urlprefix=nil)
268
- _check_and_callback(:getScanIssues, urlprefix)
272
+ ScanIssuesList.new( _check_and_callback(:getScanIssues, urlprefix) )
269
273
  end
270
274
  alias scan_issues getScanIssues
271
275
  alias get_scan_issues getScanIssues
272
276
 
277
+
273
278
  # Restores Burp session state from a previously saved state file.
274
279
  # See also: saveState
275
280
  #
@@ -281,6 +286,7 @@ class Buby
281
286
  end
282
287
  alias restore_state restoreState
283
288
 
289
+
284
290
  # Saves the current Burp session to a state file. See also restoreState.
285
291
  #
286
292
  # IMPORTANT: This method is only available with Burp 1.2.09 and higher.
@@ -291,6 +297,7 @@ class Buby
291
297
  end
292
298
  alias save_state saveState
293
299
 
300
+
294
301
  # Parses a raw HTTP request message and returns an associative array
295
302
  # containing parameters as they are structured in the 'Parameters' tab in the
296
303
  # Burp request UI.
@@ -305,6 +312,7 @@ class Buby
305
312
  alias parameters getParameters
306
313
  alias get_parameters getParameters
307
314
 
315
+
308
316
  # Parses a raw HTTP message (request or response ) and returns an associative
309
317
  # array containing the headers as they are structured in the 'Headers' tab
310
318
  # in the Burp request/response viewer UI.
@@ -510,7 +518,8 @@ class Buby
510
518
  #
511
519
  # This method should be overridden if you wish to implement functionality
512
520
  # relating to generalized requests and responses from any BurpSuite tool.
513
- # You may want to use evt_proxy_message if you only intend to work with only
521
+ #
522
+ # You may want to use evt_proxy_message if you only intend to work on
514
523
  # proxied messages. Note, however, the IHttpRequestResponse Java object is
515
524
  # not used in evt_proxy_message and gives evt_http_message a somewhat
516
525
  # nicer interface to work with.
@@ -523,7 +532,8 @@ class Buby
523
532
  # * message_info = an instance of the IHttpRequestResponse Java class with
524
533
  # methods for accessing and manipulating various attributes of the message.
525
534
  #
526
- def evt_http_message tool_name, is_request, message_info
535
+ def evt_http_message(tool_name, is_request, message_info)
536
+ HttpRequestResponseHelper.implant(message_info)
527
537
  pp([:got_http_message, tool_name, is_request, message_info]) if $DEBUG
528
538
  end
529
539
 
@@ -540,6 +550,7 @@ class Buby
540
550
  # * issue = an instance of the IScanIssue Java class with methods for viewing
541
551
  # information on the scan issue that was generated.
542
552
  def evt_scan_issue(issue)
553
+ ScanIssueHelper.implant(issue)
543
554
  pp([:got_scan_issue, issue]) if $DEBUG
544
555
  end
545
556
 
@@ -561,7 +572,7 @@ class Buby
561
572
  # Yields each entry in the site map to a block (which is required)
562
573
  def with_site_map(urlprefix=nil, statefile=nil)
563
574
  with_statefile(statefile) do |this|
564
- this.site_map(urlprefix).to_a.each {|h| yield h}
575
+ this.site_map(urlprefix).each {|h| yield h }
565
576
  end
566
577
  end
567
578
 
@@ -574,14 +585,13 @@ class Buby
574
585
  # Yields each entry in the proxy history to a block (which is required)
575
586
  def with_proxy_history(statefile=nil)
576
587
  with_statefile(statefile) do |this|
577
- this.proxy_history.to_a.each {|h| yield h }
588
+ this.proxy_history.each {|h| yield h }
578
589
  end
579
590
  end
580
591
 
581
592
  # This is a convenience wrapper which loads a given burp statefile and lets
582
- # its caller to perform actions with burp on it inside of a block.
583
- # It expects a block to yield 'self' is yielded for the duration
584
- # of the statefile load.
593
+ # its caller perform actions via burp while its loaded on it inside of a
594
+ # block. The old state is restored after the block completes.
585
595
  #
586
596
  # It can safely be used without a statefile argument, in which case the
587
597
  # current session state is used.
@@ -593,10 +603,9 @@ class Buby
593
603
  # save current state:
594
604
  old_state=".#{$$}.#{Time.now.to_i}.state.bak"
595
605
  self.alert "Saving current state to temp statefile: #{old_state}"
596
- self.save_state old_state
597
-
606
+ self.save_state(old_state)
598
607
  self.alert "Restoring state: #{statefile}"
599
- self.restore_state statefile
608
+ self.restore_state(statefile)
600
609
  end
601
610
 
602
611
  yield self
@@ -619,17 +628,10 @@ class Buby
619
628
  # This method also accepts an optional block which is passed each of the
620
629
  # matched history members.
621
630
  def search_proxy_history(statefile=nil, urlrx=nil)
622
- ret = nil
623
- with_statefile(statefile) do |this|
624
- ret = this.proxy_history.to_a.select do |r|
625
- if urlrx
626
- true if r.url.to_s =~ urlrx
627
- else
628
- true
629
- end
630
- end
631
- if block_given?
632
- ret.each {|r| yield r }
631
+ ret = []
632
+ with_proxy_history(statefile) do |r|
633
+ if (not urlrx) or r.url.to_s =~ urlrx
634
+ ret << r if (not block_given?) or yield(r)
633
635
  end
634
636
  end
635
637
  return ret
@@ -644,11 +646,10 @@ class Buby
644
646
  # and harvest from.
645
647
  def harvest_cookies_from_history(cookie=nil, urlrx=nil, statefile=nil)
646
648
  ret = []
647
- search_proxy_history(statefile, urlrx) do |msg|
648
- rsp = String.from_java_bytes(msg.response)
649
- found = []
650
- find_cookie_in_response(rsp, cookie) {|c| found << c}
651
- ret += found.map {|f| f << msg }
649
+ search_proxy_history(statefile, urlrx) do |hrr|
650
+ ret += hrr.rsp_headers.select do |h|
651
+ h[0].downcase == 'set-cookie'
652
+ end.map{|h| h[1]}
652
653
  end
653
654
  return ret
654
655
  end
@@ -737,6 +738,7 @@ class Buby
737
738
 
738
739
  end # Buby
739
740
 
741
+
740
742
  # Try requiring 'burp.jar' from the Ruby lib-path
741
743
  unless Buby.burp_loaded?
742
744
  begin require "burp.jar"
@@ -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
@@ -12,38 +12,27 @@ include Java
12
12
  # for a Mechanize agent by intercepting all requests sent through the
13
13
  # Burp proxy. This lets you use Mechanize in tandem with your browser
14
14
  # through Burp without having to fuss around with cookies.
15
- class MechGlue < Buby
15
+ module MechGlue
16
16
  attr_accessor :mech_agent
17
17
 
18
- def initialize(mech_agent, other=nil)
19
- super(other)
20
- @mech_agent = mech_agent
21
- end
22
-
23
18
  def evt_proxy_message(*param)
24
19
  msg_ref, is_req, rhost, rport, is_https, http_meth, url,
25
20
  resourceType, status, req_content_type, message, action = param
26
21
 
27
22
  if (not is_req) and (message =~ /Set-Cookie/i)
28
23
 
29
- begin
30
- rsp = Rbkb::Http::Response.parse(message)
31
- rescue
32
- rsp = nil
33
- end
34
-
35
- if rsp
36
- # Get an uri object ready for mechanize
37
- uri = URI.parse(url)
38
- uri.scheme = (is_https)? "https" : "http"
39
- uri.host = rhost
40
- uri.port = rport
41
-
42
- # Grab cookies from headers:
43
- rsp.headers.get_header_value('Set-Cookie').each do |cookie|
44
- WWW::Mechanize::Cookie.parse(uri, cookie) do |c|
45
- $mech.cookie_jar.add(uri, c)
46
- end
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)
47
36
  end
48
37
  end
49
38
  end
@@ -56,10 +45,13 @@ if __FILE__ == $0
56
45
  $mech = WWW::Mechanize.new
57
46
  #$mech.set_proxy('localhost', '8080')
58
47
 
59
- $burp = MechGlue.new($mech)
48
+ $burp = Buby.new()
49
+ $burp.extend(MechGlue)
50
+ $burp.mech_agent = $mech
60
51
  $burp.start_burp
61
52
 
62
53
  puts "$burp is set to #{$burp.class}"
63
54
  puts "$mech is set to #{$mech.class}"
64
55
  IRB.start
65
56
  end
57
+
@@ -2,7 +2,7 @@
2
2
  require 'rubygems'
3
3
  require 'buby'
4
4
 
5
- class VerbTamperer < Buby
5
+ module VerbTamperer
6
6
  def evt_proxy_message(*param)
7
7
  msg_ref, is_req, rhost, rport, is_https, http_meth, url,
8
8
  resourceType, status, req_content_type, message, action = param
@@ -18,4 +18,8 @@ class VerbTamperer < Buby
18
18
  end
19
19
  end
20
20
 
21
- VerbTamperer.start_burp()
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: emonti-buby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3.1
4
+ version: 1.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Monti - Matasano Security
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-25 00:00:00 -07:00
12
+ date: 2009-09-21 00:00:00 -07:00
13
13
  default_executable: buby
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -46,8 +46,15 @@ files:
46
46
  - java/src/burp/IScanIssue.java
47
47
  - java/src/burp/IScanQueueItem.java
48
48
  - lib/buby.rb
49
+ - lib/buby/extends.rb
50
+ - lib/buby/extends/buby_array_wrapper.rb
51
+ - lib/buby/extends/http_request_response.rb
52
+ - lib/buby/extends/scan_issue.rb
53
+ - samples/drb_buby.rb
54
+ - samples/drb_sample_cli.rb
49
55
  - samples/mechanize_burp.rb
50
56
  - samples/verb_tamperer.rb
57
+ - samples/watch_scan.rb
51
58
  - spec/buby_spec.rb
52
59
  - spec/spec_helper.rb
53
60
  - tasks/ann.rake