miketracy-wwmd 0.2.12 → 0.2.14
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/wwmd.rb +1 -1
- data/lib/wwmd/mixins.rb +6 -0
- data/lib/wwmd/nokogiri_html2text.rb +1 -0
- data/lib/wwmd/page.rb +10 -179
- data/lib/wwmd/{form.rb → page/form.rb} +0 -0
- data/lib/wwmd/{form_array.rb → page/form_array.rb} +2 -2
- data/lib/wwmd/page/parsing_convenience.rb +87 -0
- data/lib/wwmd/page/reporting_helpers.rb +86 -0
- data/lib/wwmd/{page/urlparse.rb → urlparse.rb} +13 -3
- data/lib/wwmd/viewstate.rb +2 -1
- data/lib/wwmd/viewstate/viewstate_class_helpers.rb +1 -0
- data/lib/wwmd/viewstate/viewstate_deserializer_methods.rb +10 -6
- data/lib/wwmd/viewstate/viewstate_types.rb +4 -0
- data/lib/wwmd/{page/config.rb → wwmd_config.rb} +0 -0
- data/lib/wwmd/{page/utils.rb → wwmd_utils.rb} +0 -0
- data/spec/urlparse_test.spec +13 -1
- data/wwmd.gemspec +0 -0
- metadata +11 -9
data/lib/wwmd.rb
CHANGED
@@ -15,7 +15,7 @@ require 'rexml/document'
|
|
15
15
|
module WWMD
|
16
16
|
|
17
17
|
# :stopdoc:
|
18
|
-
VERSION = "0.2.
|
18
|
+
VERSION = "0.2.14"
|
19
19
|
PARSER = :nokogiri # :nokogiri || :hpricot
|
20
20
|
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
21
21
|
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
data/lib/wwmd/mixins.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'htmlentities'
|
2
|
+
|
1
3
|
=begin rdoc
|
2
4
|
mixins all around
|
3
5
|
=end
|
@@ -50,6 +52,10 @@ class String
|
|
50
52
|
|
51
53
|
@@he = HTMLEntities.new
|
52
54
|
|
55
|
+
def strip_up
|
56
|
+
self.gsub(/[^\x20-\x7e,\n]/,"").gsub(/^\n/,"")
|
57
|
+
end
|
58
|
+
|
53
59
|
# ip address to int
|
54
60
|
def ip_to_int
|
55
61
|
self.split('.').inject(0) { |a,e| (a << 8) + e.to_i }
|
data/lib/wwmd/page.rb
CHANGED
@@ -122,7 +122,7 @@ module WWMD
|
|
122
122
|
rescue => e
|
123
123
|
@last_error = e
|
124
124
|
putw "WARN: #{e.class}" if e.class =~ /Curl::Err/
|
125
|
-
self.logged_in = false
|
125
|
+
# self.logged_in = false
|
126
126
|
end
|
127
127
|
self.set_data
|
128
128
|
return [self.code,self.page_status,self.body_data.size]
|
@@ -139,9 +139,7 @@ module WWMD
|
|
139
139
|
#
|
140
140
|
# returns: <tt>array [ code, body_data.size ]</tt>
|
141
141
|
def submit(iform=nil,reg=WWMD::ESCAPE[:default])
|
142
|
-
|
143
|
-
this is just getting worse and worse
|
144
|
-
=end
|
142
|
+
##### this is just getting worse and worse
|
145
143
|
if iform.class == "Symbol"
|
146
144
|
reg = iform
|
147
145
|
iform = nil
|
@@ -191,15 +189,8 @@ module WWMD
|
|
191
189
|
#
|
192
190
|
# returns: <tt>array [ code, body_data.size ]</tt>
|
193
191
|
def get(url=nil,parse=true)
|
194
|
-
if url && parse
|
192
|
+
if !(url =~ /[a-z]+:\/\//) && parse
|
195
193
|
self.url = @urlparse.parse(self.opts[:base_url],url).to_s if url
|
196
|
-
=begin
|
197
|
-
base = url.clip
|
198
|
-
args = url.clop
|
199
|
-
base = @urlparse.parse(self.opts[:base_url],base).to_s
|
200
|
-
self.url = base
|
201
|
-
self.url += ("?" + args) if args
|
202
|
-
=end
|
203
194
|
elsif url
|
204
195
|
self.url = url
|
205
196
|
end
|
@@ -220,174 +211,14 @@ module WWMD
|
|
220
211
|
self.submit(form)
|
221
212
|
end
|
222
213
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
# return text representation of page code
|
231
|
-
#
|
232
|
-
# override with specific statuses in helper depending on page text
|
233
|
-
# etc to include statuses outside 200 = OK and other = ERR
|
234
|
-
def page_status
|
235
|
-
return "ERR" if self.response_code != 200
|
236
|
-
return "OK"
|
237
|
-
end
|
238
|
-
|
239
|
-
alias_method :status, :page_status#:nodoc:
|
240
|
-
|
241
|
-
# return value of @logged_in
|
242
|
-
def logged_in?
|
243
|
-
return @logged_in
|
244
|
-
end
|
245
|
-
|
246
|
-
# return a string of flags:
|
247
|
-
# Ll links
|
248
|
-
# Jj javascript includes
|
249
|
-
# Ff forms
|
250
|
-
# Cc comments
|
251
|
-
def report_flags
|
252
|
-
self.has_links? ? ret = "L" : ret = "l"
|
253
|
-
self.has_jlinks? ? ret += "J" : ret += "j"
|
254
|
-
self.has_form? ? ret += "F" : ret += "f"
|
255
|
-
self.has_comments? ? ret += "C" : ret += "c"
|
256
|
-
return ret
|
257
|
-
end
|
258
|
-
|
259
|
-
def has_links?; return !@links.empty?; end
|
260
|
-
def has_jlinks?; return !@jlinks.empty?; end
|
261
|
-
def has_form?; return !(@forms.size < 1); end
|
262
|
-
def has_comments?; return !@comments.empty?; end
|
263
|
-
|
264
|
-
# return page size in bytes
|
265
|
-
def size
|
266
|
-
return self.body_data.size
|
267
|
-
end
|
268
|
-
|
269
|
-
#:section: Other methods
|
270
|
-
|
271
|
-
def all_tags#:nodoc:
|
272
|
-
return self.search("*").map { |x| x.name }
|
273
|
-
end
|
274
|
-
|
275
|
-
# return MD5 for DOM fingerprint
|
276
|
-
# take all tag names in page.to_s.md5
|
277
|
-
def fingerprint
|
278
|
-
self.all_tags.to_s.md5
|
279
|
-
end
|
280
|
-
alias_method :fp, :fingerprint #:nodoc:
|
281
|
-
|
282
|
-
# set link using an integer link from self.report
|
283
|
-
#--
|
284
|
-
# NOTE: I always use page.get(page.l(1)) anyway.
|
285
|
-
#++
|
286
|
-
def set_link(index)
|
287
|
-
self.url = @links[index]
|
288
|
-
end
|
289
|
-
|
290
|
-
# return link at index from @links array
|
291
|
-
def get_link(index)
|
292
|
-
@links[index]
|
293
|
-
end
|
294
|
-
|
295
|
-
alias_method :link, :get_link #:nodoc:
|
296
|
-
alias_method :l, :get_link #:nodoc:
|
297
|
-
|
298
|
-
# alias_method for body_data
|
299
|
-
def raw
|
300
|
-
self.body_data
|
301
|
-
end
|
302
|
-
|
303
|
-
# alias_method for last_effective_url
|
304
|
-
def current_url
|
305
|
-
self.last_effective_url
|
306
|
-
end
|
307
|
-
|
308
|
-
alias_method :current, :current_url
|
309
|
-
alias_method :cur, :current_url
|
310
|
-
|
311
|
-
# the last http response code
|
312
|
-
def code
|
313
|
-
self.response_code # .to_s
|
314
|
-
end
|
315
|
-
|
316
|
-
#:section: Parsing convenience methods
|
317
|
-
# methods that help parse and find information on a page including
|
318
|
-
# access to forms etc.
|
319
|
-
|
320
|
-
# grep for regexp and remove leading whitespace
|
321
|
-
def grep(reg)
|
322
|
-
self.body_data.grep(reg).map { |i| i.gsub(/^\s+/, "") }
|
323
|
-
end
|
324
|
-
|
325
|
-
# return this page's form (at index id) as a FormArray
|
326
|
-
def get_form(id=nil)
|
327
|
-
id = 0 if not id
|
328
|
-
return nil if forms.empty?
|
329
|
-
@forms[id].to_form_array
|
330
|
-
end
|
331
|
-
|
332
|
-
# return the complete url to the form action on this page
|
333
|
-
def action(id=nil)
|
334
|
-
id = 0 if not id
|
335
|
-
act = self.forms[id].action
|
336
|
-
return self.last_effective_url if (act.nil? || act.empty?)
|
337
|
-
return @urlparse.parse(self.last_effective_url,act).to_s
|
338
|
-
end
|
339
|
-
|
340
|
-
# return an array of Element objects for an xpath search
|
341
|
-
def search(xpath)
|
342
|
-
self.scrape.hdoc.search(xpath)
|
343
|
-
end
|
344
|
-
|
345
|
-
# return an array of inner_html for each <script> tag encountered
|
346
|
-
def dump_scripts
|
347
|
-
self.get_tags("//script").map { |s| s.inner_html if s.inner_html.strip != '' }
|
348
|
-
end
|
349
|
-
|
350
|
-
alias_method :scripts, :dump_scripts
|
351
|
-
|
352
|
-
#:section: Input and Output Helpers
|
353
|
-
|
354
|
-
# set self.opts[:base_url]
|
355
|
-
def setbase(url=nil)
|
356
|
-
return nil if not url
|
357
|
-
self.opts[:base_url] = url
|
358
|
-
self.base_url = url
|
359
|
-
end
|
360
|
-
|
361
|
-
# return md5sum for self.body_data
|
362
|
-
def md5
|
363
|
-
return self.body_data.md5
|
364
|
-
end
|
365
|
-
|
366
|
-
# write self.body_data to file
|
367
|
-
def write(filename)
|
368
|
-
File.write(filename,self.body_data)
|
369
|
-
return "wrote to " + filename
|
370
|
-
end
|
371
|
-
|
372
|
-
# read self.body_data from file
|
373
|
-
def read(filename)
|
374
|
-
self.body_data = File.read(filename)
|
214
|
+
# send arbitrary verb (only works with patch to taf2-curb
|
215
|
+
def verb(verb)
|
216
|
+
return false if !@curl_object.respond_to?(:http_verb)
|
217
|
+
self.clear_data
|
218
|
+
self.headers["Referer"] = self.cur if self.use_referer
|
219
|
+
self.http_verb(verb)
|
375
220
|
self.set_data
|
376
|
-
|
377
|
-
|
378
|
-
# does this response have SET-COOKIE headers?
|
379
|
-
def set_cookies?
|
380
|
-
ret = []
|
381
|
-
self.header_data.each do |x|
|
382
|
-
if x[0].upcase == "SET-COOKIE"
|
383
|
-
ret << x[1]
|
384
|
-
end
|
385
|
-
end
|
386
|
-
return ret
|
387
|
-
end
|
388
|
-
|
389
|
-
def time
|
390
|
-
self.total_time
|
221
|
+
return [self.code, self.body_data.size]
|
391
222
|
end
|
392
223
|
|
393
224
|
#:section: Data callbacks and method_missing
|
File without changes
|
@@ -234,12 +234,12 @@ module WWMD
|
|
234
234
|
alias_method :squeeze_keys!, :remove_null_keys!
|
235
235
|
|
236
236
|
# dump a web page containing a csrf example of the current FormArray
|
237
|
-
def to_csrf(action)
|
237
|
+
def to_csrf(action,unescval=false)
|
238
238
|
ret = ""
|
239
239
|
ret << "<html><body>\n"
|
240
240
|
ret << "<form method='post' id='wwmdtest' name='wwmdtest' action='#{action}'>\n"
|
241
241
|
self.each do |key,val|
|
242
|
-
val = val.unescape.gsub(/'/) { %q[\'] }
|
242
|
+
val = val.unescape.gsub(/'/) { %q[\'] } if unescval
|
243
243
|
ret << "<input name='#{key.to_s.unescape}' type='hidden' value='#{val}' />\n"
|
244
244
|
# ret << "<input name='#{key.to_s.unescape}' type='hidden' value='#{val.to_s.unescape.gsub(/'/,"\\'")}' />\n"
|
245
245
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module WWMD
|
2
|
+
class Page
|
3
|
+
#:section: Parsing convenience methods
|
4
|
+
# methods that help parse and find information on a page including
|
5
|
+
# access to forms etc.
|
6
|
+
|
7
|
+
# grep for regexp and remove leading whitespace
|
8
|
+
def grep(reg)
|
9
|
+
self.body_data.grep(reg).map { |i| i.gsub(/^\s+/, "") }
|
10
|
+
end
|
11
|
+
|
12
|
+
# return this page's form (at index id) as a FormArray
|
13
|
+
def get_form(id=nil)
|
14
|
+
id = 0 if not id
|
15
|
+
return nil if forms.empty?
|
16
|
+
@forms[id].to_form_array
|
17
|
+
end
|
18
|
+
|
19
|
+
# return the complete url to the form action on this page
|
20
|
+
def action(id=nil)
|
21
|
+
id = 0 if not id
|
22
|
+
act = self.forms[id].action
|
23
|
+
return self.last_effective_url if (act.nil? || act.empty?)
|
24
|
+
return @urlparse.parse(self.last_effective_url,act).to_s
|
25
|
+
end
|
26
|
+
|
27
|
+
# return an array of Element objects for an xpath search
|
28
|
+
def search(xpath)
|
29
|
+
self.scrape.hdoc.search(xpath)
|
30
|
+
end
|
31
|
+
|
32
|
+
# return an array of inner_html for each <script> tag encountered
|
33
|
+
def dump_scripts
|
34
|
+
self.get_tags("//script").map { |s| s.inner_html if s.inner_html.strip != '' }
|
35
|
+
end
|
36
|
+
|
37
|
+
alias_method :scripts, :dump_scripts
|
38
|
+
|
39
|
+
# set link using an integer link from self.report
|
40
|
+
#--
|
41
|
+
# NOTE: I always use page.get(page.l(1)) anyway.
|
42
|
+
#++
|
43
|
+
def set_link(index)
|
44
|
+
self.url = @links[index]
|
45
|
+
end
|
46
|
+
|
47
|
+
# return link at index from @links array
|
48
|
+
def get_link(index)
|
49
|
+
@links[index]
|
50
|
+
end
|
51
|
+
|
52
|
+
alias_method :link, :get_link #:nodoc:
|
53
|
+
alias_method :l, :get_link #:nodoc:
|
54
|
+
|
55
|
+
def all_tags#:nodoc:
|
56
|
+
return self.search("*").map { |x| x.name }
|
57
|
+
end
|
58
|
+
|
59
|
+
def furl(url)
|
60
|
+
self.url = @urlparse.parse(self.opts[:base_url],url).to_s
|
61
|
+
end
|
62
|
+
|
63
|
+
# set self.opts[:base_url]
|
64
|
+
def setbase(url=nil)
|
65
|
+
return nil if not url
|
66
|
+
self.opts[:base_url] = url
|
67
|
+
self.base_url = url
|
68
|
+
end
|
69
|
+
|
70
|
+
# write self.body_data to file
|
71
|
+
def write(filename)
|
72
|
+
File.write(filename,self.body_data)
|
73
|
+
return "wrote to " + filename
|
74
|
+
end
|
75
|
+
|
76
|
+
# read self.body_data from file
|
77
|
+
def read(filename)
|
78
|
+
self.body_data = File.read(filename)
|
79
|
+
self.set_data
|
80
|
+
end
|
81
|
+
|
82
|
+
# alias_method for body_data
|
83
|
+
def raw
|
84
|
+
self.body_data
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module WWMD
|
2
|
+
class Page
|
3
|
+
#:section: Reporting helper methods
|
4
|
+
# These are methods that generate data for a parsed page
|
5
|
+
|
6
|
+
# return text representation of page code
|
7
|
+
#
|
8
|
+
# override with specific statuses in helper depending on page text
|
9
|
+
# etc to include statuses outside 200 = OK and other = ERR
|
10
|
+
def page_status
|
11
|
+
return "ERR" if self.response_code != 200
|
12
|
+
return "OK"
|
13
|
+
end
|
14
|
+
|
15
|
+
alias_method :status, :page_status#:nodoc:
|
16
|
+
|
17
|
+
# return value of @logged_in
|
18
|
+
def logged_in?
|
19
|
+
return @logged_in
|
20
|
+
end
|
21
|
+
|
22
|
+
# return a string of flags:
|
23
|
+
# Ll links
|
24
|
+
# Jj javascript includes
|
25
|
+
# Ff forms
|
26
|
+
# Cc comments
|
27
|
+
def report_flags
|
28
|
+
self.has_links? ? ret = "L" : ret = "l"
|
29
|
+
self.has_jlinks? ? ret += "J" : ret += "j"
|
30
|
+
self.has_form? ? ret += "F" : ret += "f"
|
31
|
+
self.has_comments? ? ret += "C" : ret += "c"
|
32
|
+
return ret
|
33
|
+
end
|
34
|
+
|
35
|
+
def has_links?; return !@links.empty?; end
|
36
|
+
def has_jlinks?; return !@jlinks.empty?; end
|
37
|
+
def has_form?; return !(@forms.size < 1); end
|
38
|
+
def has_comments?; return !@comments.empty?; end
|
39
|
+
|
40
|
+
# return page size in bytes
|
41
|
+
def size
|
42
|
+
return self.body_data.size
|
43
|
+
end
|
44
|
+
|
45
|
+
# return md5sum for self.body_data
|
46
|
+
def md5
|
47
|
+
return self.body_data.md5
|
48
|
+
end
|
49
|
+
|
50
|
+
# does this response have SET-COOKIE headers?
|
51
|
+
def set_cookies?
|
52
|
+
ret = []
|
53
|
+
self.header_data.each do |x|
|
54
|
+
if x[0].upcase == "SET-COOKIE"
|
55
|
+
ret << x[1]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
return ret
|
59
|
+
end
|
60
|
+
|
61
|
+
def time
|
62
|
+
self.total_time
|
63
|
+
end
|
64
|
+
|
65
|
+
# return MD5 for DOM fingerprint
|
66
|
+
# take all tag names in page.to_s.md5
|
67
|
+
def fingerprint
|
68
|
+
self.all_tags.to_s.md5
|
69
|
+
end
|
70
|
+
alias_method :fp, :fingerprint #:nodoc:
|
71
|
+
|
72
|
+
# alias_method for last_effective_url
|
73
|
+
def current_url
|
74
|
+
self.last_effective_url
|
75
|
+
end
|
76
|
+
|
77
|
+
alias_method :current, :current_url
|
78
|
+
alias_method :cur, :current_url
|
79
|
+
|
80
|
+
# the last http response code
|
81
|
+
def code
|
82
|
+
self.response_code # .to_s
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
@@ -1,10 +1,14 @@
|
|
1
|
+
require 'htmlentities'
|
2
|
+
require 'wwmd/mixins'
|
3
|
+
require 'wwmd/mixins_extends'
|
1
4
|
module WWMD
|
5
|
+
|
2
6
|
# yay for experiments in re-inventing the wheel
|
3
7
|
class URLParse
|
4
8
|
HANDLERS = [:https,:http,:ftp,:file]
|
5
9
|
attr_reader :proto,:location,:path,:script,:rpath,:params,:base_url,:fqpath
|
6
10
|
|
7
|
-
def initialize()
|
11
|
+
def initialize(*args)
|
8
12
|
# nothing to see here, move along
|
9
13
|
end
|
10
14
|
|
@@ -26,7 +30,7 @@ module WWMD
|
|
26
30
|
# does this work for http://location/? probably not
|
27
31
|
@base += "/" if (!@base.has_ext? || @base.split("/").size == 3)
|
28
32
|
@rpath = make_me_path.join("/")
|
29
|
-
@params
|
33
|
+
@rpath += "?#{@params}" if @params
|
30
34
|
@path = "/" + @rpath
|
31
35
|
if @rpath.has_ext?
|
32
36
|
@path = "/" + @rpath.dirname
|
@@ -41,12 +45,18 @@ module WWMD
|
|
41
45
|
def make_me_path
|
42
46
|
@proto,tpath = @base.split(":",2)
|
43
47
|
tpath ||= ""
|
48
|
+
@params = tpath.clop
|
49
|
+
tpath = tpath.clip
|
44
50
|
if @actual.empty?
|
45
51
|
a_path = tpath.split("/").reject { |x| x.empty? }
|
46
52
|
else
|
47
53
|
a_path = tpath.dirname.split("/").reject { |x| x.empty? }
|
48
54
|
end
|
49
55
|
@location = a_path.shift
|
56
|
+
if @actual.clop
|
57
|
+
@params = @actual.clop
|
58
|
+
@actual = @actual.clip
|
59
|
+
end
|
50
60
|
a_path = [] if (@actual =~ (/^\//))
|
51
61
|
b_path = @actual.split("/").reject { |x| x.empty? }
|
52
62
|
a_path.pop if (a_path[-1] =~ /^\?/).kind_of?(Fixnum) && !b_path.empty?
|
@@ -54,7 +64,7 @@ module WWMD
|
|
54
64
|
d_path = []
|
55
65
|
c_path.each do |x|
|
56
66
|
(d_path.pop;next) if x == ".."
|
57
|
-
next if x == "."
|
67
|
+
next if (x == "." || x =~ /^\?/)
|
58
68
|
d_path << x
|
59
69
|
end
|
60
70
|
return d_path
|
data/lib/wwmd/viewstate.rb
CHANGED
@@ -5,8 +5,8 @@ module WWMD
|
|
5
5
|
end
|
6
6
|
require 'rubygems'
|
7
7
|
require 'nokogiri'
|
8
|
-
require 'htmlentities'
|
9
8
|
require 'rexml/document'
|
9
|
+
require 'htmlentities'
|
10
10
|
require 'wwmd/mixins'
|
11
11
|
require 'wwmd/mixins_extends'
|
12
12
|
require 'wwmd/mixins_external'
|
@@ -59,6 +59,7 @@ module WWMD
|
|
59
59
|
@indexed_strings = []
|
60
60
|
@mac = nil
|
61
61
|
@debug = false
|
62
|
+
self.deserialize if b64
|
62
63
|
end
|
63
64
|
|
64
65
|
# mac_enabled?
|
@@ -13,21 +13,21 @@ module WWMD
|
|
13
13
|
|
14
14
|
def type(t=nil)
|
15
15
|
typeref,typeval = self.deserialize_type
|
16
|
-
dlog(t,"typeref = #{typeref} typeval = #{typeval}")
|
16
|
+
dlog(t,"typeref = 0x#{typeref.to_s(16)} typeval = #{typeval}")
|
17
17
|
VSType.new(typeref,typeval)
|
18
18
|
end
|
19
19
|
|
20
20
|
def string_formatted(t=nil)
|
21
21
|
typeref,typeval = self.deserialize_type
|
22
22
|
str = self.read_string
|
23
|
-
dlog(t,"typeref = #{typeref} typeval = #{typeval} string = #{str}")
|
23
|
+
dlog(t,"typeref = 0x#{typeref.to_s(16)} typeval = #{typeval} string = #{str}")
|
24
24
|
VSStringFormatted.new(typeref,typeval,str)
|
25
25
|
end
|
26
26
|
|
27
27
|
def int_enum(t=nil)
|
28
28
|
typeref,typeval = self.deserialize_type
|
29
29
|
index = self.read_7bit_encoded_int
|
30
|
-
dlog(t,"typeref = #{typeref} typeval = #{typeval} index = #{index}")
|
30
|
+
dlog(t,"typeref = 0x#{typeref.to_s(16)} typeval = #{typeval} index = #{index}")
|
31
31
|
VSIntEnum.new(typeref,typeval,index)
|
32
32
|
end
|
33
33
|
|
@@ -44,7 +44,7 @@ module WWMD
|
|
44
44
|
typeref,typeval = self.deserialize_type
|
45
45
|
size = read_7bit_encoded_int
|
46
46
|
elems = read_7bit_encoded_int
|
47
|
-
dlog(t,"typeref = #{typeref} typeval = #{typeval} size = #{size} elems = #{elems}")
|
47
|
+
dlog(t,"typeref = 0x#{typeref.to_s(16)} typeval = #{typeval} size = #{size} elems = #{elems}")
|
48
48
|
me = VSSparseArray.new(typeref,typeval,size,elems)
|
49
49
|
if elems > size
|
50
50
|
raise "Invalid sparse_array"
|
@@ -79,7 +79,7 @@ module WWMD
|
|
79
79
|
def array(t=nil)
|
80
80
|
typeref,typeval = self.deserialize_type
|
81
81
|
len = read_7bit_encoded_int
|
82
|
-
dlog(t,"typeref = #{typeref} typeval = #{typeval} len = #{len}")
|
82
|
+
dlog(t,"typeref = 0x#{typeref.to_s(16)} typeval = #{typeval} len = #{len}")
|
83
83
|
me = VSArray.new(typeref,typeval)
|
84
84
|
(1..len).each do |i|
|
85
85
|
me.add(self.deserialize_value)
|
@@ -203,7 +203,11 @@ module WWMD
|
|
203
203
|
def deserialize_value
|
204
204
|
@last_offset = self.offset
|
205
205
|
token = self.read_byte # self.read_raw_byte
|
206
|
-
|
206
|
+
if not (tsym = VIEWSTATE_TYPES[token])
|
207
|
+
puts "TOKEN: [0x#{token.to_s(16)}] at #{last_offset}"
|
208
|
+
puts @bufarr.slice(0..31).join("").hexdump
|
209
|
+
raise "Invalid Type [0x#{token.to_s(16)}] at #{last_offset}" if not (tsym = VIEWSTATE_TYPES[token])
|
210
|
+
end
|
207
211
|
nobj = self.send(tsym,token)
|
208
212
|
raise "Invalid Class Returned #{nobj.class}" if not VIEWSTATE_TYPES.include?(nobj.opcode)
|
209
213
|
return nobj
|
File without changes
|
File without changes
|
data/spec/urlparse_test.spec
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
require 'wwmd'
|
2
|
+
require 'wwmd/urlparse'
|
3
3
|
include WWMD
|
4
4
|
require 'spec'
|
5
5
|
|
@@ -34,6 +34,11 @@ describe URLParse do
|
|
34
34
|
@up.script.should == "test.php"
|
35
35
|
end
|
36
36
|
|
37
|
+
it "should parse GET params correctly" do
|
38
|
+
@up.parse(@base,"http://www.location.com/test.php?foo=bar&baz=eep").to_s.should \
|
39
|
+
== "http://www.location.com/test.php?foo=bar&baz=eep"
|
40
|
+
end
|
41
|
+
|
37
42
|
it "should return the path if the path is fully qualified" do
|
38
43
|
@up.parse(@base,"http://www.location.com/").to_s.should == "http://www.location.com/"
|
39
44
|
@up.parse(@base,"http://www.location.com").to_s.should == "http://www.location.com/"
|
@@ -86,4 +91,11 @@ describe URLParse do
|
|
86
91
|
@up.parse("http://www.example.com:8888/foobar/barBaz.do?logFile=../../../../../../../../../../../../etc/passwd&foo=foobar.log&bazeep=false").to_s.should \
|
87
92
|
== "http://www.example.com:8888/foobar/barBaz.do?logFile=../../../../../../../../../../../../etc/passwd&foo=foobar.log&bazeep=false"
|
88
93
|
end
|
94
|
+
|
95
|
+
it "should not remove directory traversal params 2" do
|
96
|
+
@up.parse("http://www.example.com:8888", "/foobar/barBaz.do?logFile=../../../../../../../../../../../../etc/passwd&foo=foobar.log&bazeep=false").to_s.should \
|
97
|
+
== "http://www.example.com:8888/foobar/barBaz.do?logFile=../../../../../../../../../../../../etc/passwd&foo=foobar.log&bazeep=false"
|
98
|
+
end
|
99
|
+
|
89
100
|
end
|
101
|
+
|
data/wwmd.gemspec
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: miketracy-wwmd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael L. Tracy
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-06-02 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -30,7 +30,7 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.2.8.0
|
34
34
|
version:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: nokogiri
|
@@ -50,7 +50,7 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - ">="
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 2.5.
|
53
|
+
version: 2.5.1
|
54
54
|
version:
|
55
55
|
description: WWMD was originally intended to provide a console helper tool for conducting web application security assessments (which is something I find myself doing alot of). I've spent alot of time and had alot of success writing application specific fuzzers + scrapers to test with. WWMD provides a base of useful code to help you work with web sites both in IRB and by writing scripts that can be as generic or as application specific as you choose. There's alot of helpful stuff crammed in here and its usage has evolved alot. It's not intended to replace, remove or be better than any of the tools you currently use. In fact, WWMD works best *with* the tools you currently use to get stuff done. You get convenience methods for getting, scraping, spidering, decoding, decrypting and munging user inputs, pages and web applications. It doesn't try to be smart. That's up to you. What's here is the basic framework for getting started. There's a raft of cookbook scripts and examples that are coming soon so make sure you check the wiki regularly.
|
56
56
|
email: mtracy@matasano.com
|
@@ -70,8 +70,6 @@ files:
|
|
70
70
|
- examples/wwmd_example.rb
|
71
71
|
- lib/wwmd.rb
|
72
72
|
- lib/wwmd/encoding.rb
|
73
|
-
- lib/wwmd/form.rb
|
74
|
-
- lib/wwmd/form_array.rb
|
75
73
|
- lib/wwmd/guid.rb
|
76
74
|
- lib/wwmd/hpricot_html2text.rb
|
77
75
|
- lib/wwmd/mixins.rb
|
@@ -80,15 +78,17 @@ files:
|
|
80
78
|
- lib/wwmd/nokogiri_html2text.rb
|
81
79
|
- lib/wwmd/page.rb
|
82
80
|
- lib/wwmd/page/auth.rb
|
83
|
-
- lib/wwmd/page/config.rb
|
84
81
|
- lib/wwmd/page/constants.rb
|
82
|
+
- lib/wwmd/page/form.rb
|
83
|
+
- lib/wwmd/page/form_array.rb
|
85
84
|
- lib/wwmd/page/headers.rb
|
86
85
|
- lib/wwmd/page/inputs.rb
|
87
86
|
- lib/wwmd/page/irb_helpers.rb
|
87
|
+
- lib/wwmd/page/parsing_convenience.rb
|
88
|
+
- lib/wwmd/page/reporting_helpers.rb
|
88
89
|
- lib/wwmd/page/scrape.rb
|
89
90
|
- lib/wwmd/page/spider.rb
|
90
|
-
- lib/wwmd/
|
91
|
-
- lib/wwmd/page/utils.rb
|
91
|
+
- lib/wwmd/urlparse.rb
|
92
92
|
- lib/wwmd/viewstate.rb
|
93
93
|
- lib/wwmd/viewstate/viewstate_class_helpers.rb
|
94
94
|
- lib/wwmd/viewstate/viewstate_deserializer_methods.rb
|
@@ -115,6 +115,8 @@ files:
|
|
115
115
|
- lib/wwmd/viewstate/vs_type.rb
|
116
116
|
- lib/wwmd/viewstate/vs_unit.rb
|
117
117
|
- lib/wwmd/viewstate/vs_value.rb
|
118
|
+
- lib/wwmd/wwmd_config.rb
|
119
|
+
- lib/wwmd/wwmd_utils.rb
|
118
120
|
- spec/README
|
119
121
|
- spec/form_array.spec
|
120
122
|
- spec/spider_csrf_test.spec
|