arachni 0.2.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (262) hide show
  1. data/ACKNOWLEDGMENTS.md +14 -0
  2. data/AUTHORS.md +6 -0
  3. data/CHANGELOG.md +162 -0
  4. data/CONTRIBUTORS.md +10 -0
  5. data/EXPLOITATION.md +429 -0
  6. data/HACKING.md +101 -0
  7. data/LICENSE.md +341 -0
  8. data/README.md +350 -0
  9. data/Rakefile +86 -0
  10. data/bin/arachni +22 -0
  11. data/bin/arachni_web +77 -0
  12. data/bin/arachni_xmlrpc +21 -0
  13. data/bin/arachni_xmlrpcd +82 -0
  14. data/bin/arachni_xmlrpcd_monitor +74 -0
  15. data/conf/README.webui.yaml.txt +44 -0
  16. data/conf/webui.yaml +11 -0
  17. data/external/metasploit/LICENSE +24 -0
  18. data/external/metasploit/modules/exploits/unix/webapp/arachni_exec.rb +142 -0
  19. data/external/metasploit/modules/exploits/unix/webapp/arachni_path_traversal.rb +113 -0
  20. data/external/metasploit/modules/exploits/unix/webapp/arachni_php_eval.rb +150 -0
  21. data/external/metasploit/modules/exploits/unix/webapp/arachni_php_include.rb +141 -0
  22. data/external/metasploit/modules/exploits/unix/webapp/arachni_sqlmap.rb +92 -0
  23. data/external/metasploit/plugins/arachni.rb +536 -0
  24. data/getoptslong.rb +241 -0
  25. data/lib/anemone.rb +2 -0
  26. data/lib/anemone/cookie_store.rb +35 -0
  27. data/lib/anemone/core.rb +371 -0
  28. data/lib/anemone/exceptions.rb +5 -0
  29. data/lib/anemone/http.rb +144 -0
  30. data/lib/anemone/page.rb +337 -0
  31. data/lib/anemone/page_store.rb +160 -0
  32. data/lib/anemone/storage.rb +34 -0
  33. data/lib/anemone/storage/base.rb +75 -0
  34. data/lib/anemone/storage/exceptions.rb +15 -0
  35. data/lib/anemone/storage/mongodb.rb +89 -0
  36. data/lib/anemone/storage/pstore.rb +50 -0
  37. data/lib/anemone/storage/redis.rb +90 -0
  38. data/lib/anemone/storage/tokyo_cabinet.rb +57 -0
  39. data/lib/anemone/tentacle.rb +40 -0
  40. data/lib/arachni.rb +16 -0
  41. data/lib/audit_store.rb +346 -0
  42. data/lib/component_manager.rb +293 -0
  43. data/lib/component_options.rb +395 -0
  44. data/lib/exceptions.rb +76 -0
  45. data/lib/framework.rb +637 -0
  46. data/lib/http.rb +809 -0
  47. data/lib/issue.rb +302 -0
  48. data/lib/module.rb +4 -0
  49. data/lib/module/auditor.rb +455 -0
  50. data/lib/module/base.rb +188 -0
  51. data/lib/module/element_db.rb +158 -0
  52. data/lib/module/key_filler.rb +87 -0
  53. data/lib/module/manager.rb +87 -0
  54. data/lib/module/output.rb +68 -0
  55. data/lib/module/trainer.rb +240 -0
  56. data/lib/module/utilities.rb +110 -0
  57. data/lib/options.rb +547 -0
  58. data/lib/parser.rb +2 -0
  59. data/lib/parser/auditable.rb +522 -0
  60. data/lib/parser/elements.rb +296 -0
  61. data/lib/parser/page.rb +149 -0
  62. data/lib/parser/parser.rb +717 -0
  63. data/lib/plugin.rb +4 -0
  64. data/lib/plugin/base.rb +110 -0
  65. data/lib/plugin/manager.rb +162 -0
  66. data/lib/report.rb +4 -0
  67. data/lib/report/base.rb +119 -0
  68. data/lib/report/manager.rb +92 -0
  69. data/lib/rpc/xml/client/base.rb +71 -0
  70. data/lib/rpc/xml/client/dispatcher.rb +49 -0
  71. data/lib/rpc/xml/client/instance.rb +88 -0
  72. data/lib/rpc/xml/server/base.rb +90 -0
  73. data/lib/rpc/xml/server/dispatcher.rb +357 -0
  74. data/lib/rpc/xml/server/framework.rb +206 -0
  75. data/lib/rpc/xml/server/instance.rb +191 -0
  76. data/lib/rpc/xml/server/module/manager.rb +46 -0
  77. data/lib/rpc/xml/server/options.rb +124 -0
  78. data/lib/rpc/xml/server/output.rb +299 -0
  79. data/lib/rpc/xml/server/plugin/manager.rb +58 -0
  80. data/lib/ruby.rb +5 -0
  81. data/lib/ruby/object.rb +32 -0
  82. data/lib/ruby/string.rb +74 -0
  83. data/lib/ruby/xmlrpc/server.rb +27 -0
  84. data/lib/spider.rb +200 -0
  85. data/lib/typhoeus/request.rb +91 -0
  86. data/lib/typhoeus/response.rb +34 -0
  87. data/lib/ui/cli/cli.rb +744 -0
  88. data/lib/ui/cli/output.rb +279 -0
  89. data/lib/ui/web/log.rb +82 -0
  90. data/lib/ui/web/output_stream.rb +94 -0
  91. data/lib/ui/web/report_manager.rb +222 -0
  92. data/lib/ui/web/server.rb +903 -0
  93. data/lib/ui/web/server/db/placeholder +0 -0
  94. data/lib/ui/web/server/public/banner.png +0 -0
  95. data/lib/ui/web/server/public/bodybg-small.png +0 -0
  96. data/lib/ui/web/server/public/bodybg.png +0 -0
  97. data/lib/ui/web/server/public/css/smoothness/images/pbar-ani.gif +0 -0
  98. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  99. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  100. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  101. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  102. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  103. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  104. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  105. data/lib/ui/web/server/public/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  106. data/lib/ui/web/server/public/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
  107. data/lib/ui/web/server/public/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  108. data/lib/ui/web/server/public/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
  109. data/lib/ui/web/server/public/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
  110. data/lib/ui/web/server/public/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  111. data/lib/ui/web/server/public/css/smoothness/jquery-ui-1.8.9.custom.css +573 -0
  112. data/lib/ui/web/server/public/favicon.ico +0 -0
  113. data/lib/ui/web/server/public/footer.jpg +0 -0
  114. data/lib/ui/web/server/public/icons/error.png +0 -0
  115. data/lib/ui/web/server/public/icons/info.png +0 -0
  116. data/lib/ui/web/server/public/icons/ok.png +0 -0
  117. data/lib/ui/web/server/public/icons/status.png +0 -0
  118. data/lib/ui/web/server/public/js/jquery-1.4.4.min.js +167 -0
  119. data/lib/ui/web/server/public/js/jquery-ui-1.8.9.custom.min.js +781 -0
  120. data/lib/ui/web/server/public/logo.png +0 -0
  121. data/lib/ui/web/server/public/nav-left.jpg +0 -0
  122. data/lib/ui/web/server/public/nav-right.jpg +0 -0
  123. data/lib/ui/web/server/public/nav-selected-left.jpg +0 -0
  124. data/lib/ui/web/server/public/nav-selected-right.jpg +0 -0
  125. data/lib/ui/web/server/public/reports/placeholder +1 -0
  126. data/lib/ui/web/server/public/sidebar-bottom.jpg +0 -0
  127. data/lib/ui/web/server/public/sidebar-h4.jpg +0 -0
  128. data/lib/ui/web/server/public/sidebar-top.jpg +0 -0
  129. data/lib/ui/web/server/public/spider.png +0 -0
  130. data/lib/ui/web/server/public/style.css +604 -0
  131. data/lib/ui/web/server/tmp/placeholder +0 -0
  132. data/lib/ui/web/server/views/dispatcher.erb +85 -0
  133. data/lib/ui/web/server/views/dispatcher_error.erb +14 -0
  134. data/lib/ui/web/server/views/error.erb +1 -0
  135. data/lib/ui/web/server/views/flash.erb +18 -0
  136. data/lib/ui/web/server/views/home.erb +14 -0
  137. data/lib/ui/web/server/views/instance.erb +213 -0
  138. data/lib/ui/web/server/views/layout.erb +95 -0
  139. data/lib/ui/web/server/views/log.erb +40 -0
  140. data/lib/ui/web/server/views/modules.erb +71 -0
  141. data/lib/ui/web/server/views/options.erb +23 -0
  142. data/lib/ui/web/server/views/output_results.erb +51 -0
  143. data/lib/ui/web/server/views/plugins.erb +42 -0
  144. data/lib/ui/web/server/views/report_formats.erb +30 -0
  145. data/lib/ui/web/server/views/reports.erb +55 -0
  146. data/lib/ui/web/server/views/settings.erb +120 -0
  147. data/lib/ui/web/server/views/welcome.erb +38 -0
  148. data/lib/ui/xmlrpc/dispatcher_monitor.rb +204 -0
  149. data/lib/ui/xmlrpc/xmlrpc.rb +843 -0
  150. data/logs/placeholder +0 -0
  151. data/metamodules/autothrottle.rb +74 -0
  152. data/metamodules/timeout_notice.rb +118 -0
  153. data/metamodules/uniformity.rb +98 -0
  154. data/modules/audit/code_injection.rb +136 -0
  155. data/modules/audit/code_injection_timing.rb +115 -0
  156. data/modules/audit/code_injection_timing/payloads.txt +4 -0
  157. data/modules/audit/csrf.rb +301 -0
  158. data/modules/audit/ldapi.rb +103 -0
  159. data/modules/audit/ldapi/errors.txt +26 -0
  160. data/modules/audit/os_cmd_injection.rb +103 -0
  161. data/modules/audit/os_cmd_injection/payloads.txt +2 -0
  162. data/modules/audit/os_cmd_injection_timing.rb +104 -0
  163. data/modules/audit/os_cmd_injection_timing/payloads.txt +3 -0
  164. data/modules/audit/path_traversal.rb +141 -0
  165. data/modules/audit/response_splitting.rb +105 -0
  166. data/modules/audit/rfi.rb +193 -0
  167. data/modules/audit/sqli.rb +120 -0
  168. data/modules/audit/sqli/regexp_ids.txt +90 -0
  169. data/modules/audit/sqli_blind_rdiff.rb +321 -0
  170. data/modules/audit/sqli_blind_timing.rb +103 -0
  171. data/modules/audit/sqli_blind_timing/payloads.txt +51 -0
  172. data/modules/audit/trainer.rb +89 -0
  173. data/modules/audit/unvalidated_redirect.rb +90 -0
  174. data/modules/audit/xpath.rb +104 -0
  175. data/modules/audit/xpath/errors.txt +26 -0
  176. data/modules/audit/xss.rb +99 -0
  177. data/modules/audit/xss_event.rb +134 -0
  178. data/modules/audit/xss_path.rb +125 -0
  179. data/modules/audit/xss_script_tag.rb +112 -0
  180. data/modules/audit/xss_tag.rb +112 -0
  181. data/modules/audit/xss_uri.rb +125 -0
  182. data/modules/recon/allowed_methods.rb +104 -0
  183. data/modules/recon/backdoors.rb +131 -0
  184. data/modules/recon/backdoors/filenames.txt +16 -0
  185. data/modules/recon/backup_files.rb +177 -0
  186. data/modules/recon/backup_files/extensions.txt +28 -0
  187. data/modules/recon/common_directories.rb +138 -0
  188. data/modules/recon/common_directories/directories.txt +265 -0
  189. data/modules/recon/common_files.rb +138 -0
  190. data/modules/recon/common_files/filenames.txt +17 -0
  191. data/modules/recon/directory_listing.rb +171 -0
  192. data/modules/recon/grep/captcha.rb +62 -0
  193. data/modules/recon/grep/credit_card.rb +85 -0
  194. data/modules/recon/grep/cvs_svn_users.rb +73 -0
  195. data/modules/recon/grep/emails.rb +59 -0
  196. data/modules/recon/grep/html_objects.rb +53 -0
  197. data/modules/recon/grep/private_ip.rb +54 -0
  198. data/modules/recon/grep/ssn.rb +53 -0
  199. data/modules/recon/htaccess_limit.rb +82 -0
  200. data/modules/recon/http_put.rb +95 -0
  201. data/modules/recon/interesting_responses.rb +118 -0
  202. data/modules/recon/unencrypted_password_forms.rb +119 -0
  203. data/modules/recon/webdav.rb +126 -0
  204. data/modules/recon/xst.rb +107 -0
  205. data/path_extractors/anchors.rb +35 -0
  206. data/path_extractors/forms.rb +35 -0
  207. data/path_extractors/frames.rb +38 -0
  208. data/path_extractors/generic.rb +39 -0
  209. data/path_extractors/links.rb +35 -0
  210. data/path_extractors/meta_refresh.rb +39 -0
  211. data/path_extractors/scripts.rb +37 -0
  212. data/path_extractors/sitemap.rb +31 -0
  213. data/plugins/autologin.rb +137 -0
  214. data/plugins/content_types.rb +90 -0
  215. data/plugins/cookie_collector.rb +99 -0
  216. data/plugins/form_dicattack.rb +185 -0
  217. data/plugins/healthmap.rb +94 -0
  218. data/plugins/http_dicattack.rb +133 -0
  219. data/plugins/metamodules.rb +118 -0
  220. data/plugins/proxy.rb +248 -0
  221. data/plugins/proxy/server.rb +66 -0
  222. data/plugins/waf_detector.rb +184 -0
  223. data/profiles/comprehensive.afp +74 -0
  224. data/profiles/full.afp +75 -0
  225. data/reports/afr.rb +59 -0
  226. data/reports/ap.rb +55 -0
  227. data/reports/html.rb +179 -0
  228. data/reports/html/default.erb +967 -0
  229. data/reports/metareport.rb +139 -0
  230. data/reports/metareport/arachni_metareport.rb +174 -0
  231. data/reports/plugin_formatters/html/content_types.rb +82 -0
  232. data/reports/plugin_formatters/html/cookie_collector.rb +66 -0
  233. data/reports/plugin_formatters/html/form_dicattack.rb +54 -0
  234. data/reports/plugin_formatters/html/healthmap.rb +76 -0
  235. data/reports/plugin_formatters/html/http_dicattack.rb +54 -0
  236. data/reports/plugin_formatters/html/metaformatters/timeout_notice.rb +65 -0
  237. data/reports/plugin_formatters/html/metaformatters/uniformity.rb +71 -0
  238. data/reports/plugin_formatters/html/metamodules.rb +93 -0
  239. data/reports/plugin_formatters/html/waf_detector.rb +54 -0
  240. data/reports/plugin_formatters/stdout/content_types.rb +73 -0
  241. data/reports/plugin_formatters/stdout/cookie_collector.rb +61 -0
  242. data/reports/plugin_formatters/stdout/form_dicattack.rb +52 -0
  243. data/reports/plugin_formatters/stdout/healthmap.rb +72 -0
  244. data/reports/plugin_formatters/stdout/http_dicattack.rb +53 -0
  245. data/reports/plugin_formatters/stdout/metaformatters/timeout_notice.rb +55 -0
  246. data/reports/plugin_formatters/stdout/metaformatters/uniformity.rb +68 -0
  247. data/reports/plugin_formatters/stdout/metamodules.rb +89 -0
  248. data/reports/plugin_formatters/stdout/waf_detector.rb +48 -0
  249. data/reports/plugin_formatters/xml/content_types.rb +91 -0
  250. data/reports/plugin_formatters/xml/cookie_collector.rb +70 -0
  251. data/reports/plugin_formatters/xml/form_dicattack.rb +57 -0
  252. data/reports/plugin_formatters/xml/healthmap.rb +82 -0
  253. data/reports/plugin_formatters/xml/http_dicattack.rb +57 -0
  254. data/reports/plugin_formatters/xml/metaformatters/timeout_notice.rb +67 -0
  255. data/reports/plugin_formatters/xml/metaformatters/uniformity.rb +82 -0
  256. data/reports/plugin_formatters/xml/metamodules.rb +91 -0
  257. data/reports/plugin_formatters/xml/waf_detector.rb +58 -0
  258. data/reports/stdout.rb +182 -0
  259. data/reports/txt.rb +77 -0
  260. data/reports/xml.rb +231 -0
  261. data/reports/xml/buffer.rb +98 -0
  262. metadata +516 -0
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Arachni::Options
2
+ audit_cookies: true
3
+ audit_forms: true
4
+ audit_links: true
5
+ authed_by:
6
+ dir:
7
+ exclude: []
8
+
9
+ exclude_cookies: []
10
+
11
+ http_req_limit: 20
12
+ include: []
13
+
14
+ load_profile:
15
+ lsmod: []
16
+
17
+ lsplug: []
18
+
19
+ lsrep: []
20
+
21
+ mods:
22
+ - interesting_responses
23
+ - common_files
24
+ - xst
25
+ - http_put
26
+ - webdav
27
+ - directory_listing
28
+ - allowed_methods
29
+ - htaccess_limit
30
+ - ssn
31
+ - private_ip
32
+ - emails
33
+ - credit_card
34
+ - cvs_svn_users
35
+ - captcha
36
+ - html_objects
37
+ - unencrypted_password_forms
38
+ - backdoors
39
+ - backup_files
40
+ - common_directories
41
+ - trainer
42
+ - os_cmd_injection
43
+ - sqli
44
+ - xss_script_tag
45
+ - sqli_blind_rdiff
46
+ - path_traversal
47
+ - xss_event
48
+ - xss_uri
49
+ - sqli_blind_timing
50
+ - code_injection
51
+ - rfi
52
+ - xss_tag
53
+ - response_splitting
54
+ - csrf
55
+ - os_cmd_injection_timing
56
+ - ldapi
57
+ - code_injection_timing
58
+ - xss_path
59
+ - xpath
60
+ - unvalidated_redirect
61
+ - xss
62
+ plugins:
63
+ healthmap: {}
64
+
65
+ content_types: {}
66
+
67
+ redirect_limit: 20
68
+ redundant: []
69
+
70
+ reports:
71
+ stdout: {}
72
+
73
+ save_profile:
74
+ user_agent: Arachni/0.2.2
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Arachni::Options
2
+ audit_cookies: true
3
+ audit_forms: true
4
+ audit_headers: true
5
+ audit_links: true
6
+ authed_by:
7
+ dir:
8
+ exclude: []
9
+
10
+ exclude_cookies: []
11
+
12
+ http_req_limit: 20
13
+ include: []
14
+
15
+ load_profile:
16
+ lsmod: []
17
+
18
+ lsplug: []
19
+
20
+ lsrep: []
21
+
22
+ mods:
23
+ - interesting_responses
24
+ - common_files
25
+ - xst
26
+ - http_put
27
+ - webdav
28
+ - directory_listing
29
+ - allowed_methods
30
+ - htaccess_limit
31
+ - ssn
32
+ - private_ip
33
+ - emails
34
+ - credit_card
35
+ - cvs_svn_users
36
+ - captcha
37
+ - html_objects
38
+ - unencrypted_password_forms
39
+ - backdoors
40
+ - backup_files
41
+ - common_directories
42
+ - trainer
43
+ - os_cmd_injection
44
+ - sqli
45
+ - xss_script_tag
46
+ - sqli_blind_rdiff
47
+ - path_traversal
48
+ - xss_event
49
+ - xss_uri
50
+ - sqli_blind_timing
51
+ - code_injection
52
+ - rfi
53
+ - xss_tag
54
+ - response_splitting
55
+ - csrf
56
+ - os_cmd_injection_timing
57
+ - ldapi
58
+ - code_injection_timing
59
+ - xss_path
60
+ - xpath
61
+ - unvalidated_redirect
62
+ - xss
63
+ plugins:
64
+ healthmap: {}
65
+
66
+ content_types: {}
67
+
68
+ redirect_limit: 20
69
+ redundant: []
70
+
71
+ reports:
72
+ stdout: {}
73
+
74
+ save_profile:
75
+ user_agent: Arachni/0.2.2
@@ -0,0 +1,59 @@
1
+ =begin
2
+ Arachni
3
+ Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
4
+
5
+ This is free software; you can copy and distribute and modify
6
+ this program under the term of the GPL v2.0 License
7
+ (See LICENSE file for details)
8
+
9
+ =end
10
+
11
+ module Arachni
12
+ module Reports
13
+
14
+ #
15
+ # Arachni Framework Report (.afr)
16
+ #
17
+ # @author: Tasos "Zapotek" Laskos
18
+ # <tasos.laskos@gmail.com>
19
+ # <zapotek@segfault.gr>
20
+ # @version: 0.1
21
+ #
22
+ class AFR < Arachni::Report::Base
23
+
24
+ #
25
+ # @param [AuditStore] audit_store
26
+ # @param [Hash] options options passed to the report
27
+ #
28
+ def initialize( audit_store, options )
29
+ @audit_store = audit_store
30
+ @options = options
31
+ end
32
+
33
+ def run( )
34
+
35
+ print_line( )
36
+ print_status( 'Dumping audit results in \'' + @options['outfile'] + '\'.' )
37
+
38
+ @audit_store.save( @options['outfile'] )
39
+
40
+ print_status( 'Done!' )
41
+ end
42
+
43
+ def self.info
44
+ {
45
+ :name => 'Arachni Framework Report',
46
+ :description => %q{Saves the file in the default Arachni Framework Report (.afr) format.},
47
+ :author => 'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>',
48
+ :version => '0.1',
49
+ :options => [
50
+ Arachni::OptString.new( 'outfile', [ false, 'Where to save the report.',
51
+ Time.now.to_s + '.afr' ] ),
52
+ ]
53
+ }
54
+ end
55
+
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,55 @@
1
+ =begin
2
+ Arachni
3
+ Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
4
+
5
+ This is free software; you can copy and distribute and modify
6
+ this program under the term of the GPL v2.0 License
7
+ (See LICENSE file for details)
8
+
9
+ =end
10
+
11
+ module Arachni
12
+ module Reports
13
+
14
+ #
15
+ # Awesome prints an {AuditStore#to_h} hash.
16
+ #
17
+ # @author: Tasos "Zapotek" Laskos
18
+ # <tasos.laskos@gmail.com>
19
+ # <zapotek@segfault.gr>
20
+ # @version: 0.1
21
+ #
22
+ class AP < Arachni::Report::Base
23
+
24
+ #
25
+ # @param [AuditStore] audit_store
26
+ # @param [Hash] options options passed to the report
27
+ # @param [String] outfile where to save the report
28
+ #
29
+ def initialize( audit_store, options )
30
+ @audit_store = audit_store
31
+ end
32
+
33
+ def run( )
34
+
35
+ print_line( )
36
+ print_status( 'Awesome printing AuditStore as a Hash...' )
37
+
38
+ ap @audit_store.to_h
39
+
40
+ print_status( 'Done!' )
41
+ end
42
+
43
+ def self.info
44
+ {
45
+ :name => 'AP',
46
+ :description => %q{Awesome prints an AuditStore hash.},
47
+ :author => 'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>',
48
+ :version => '0.1'
49
+ }
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,179 @@
1
+ =begin
2
+ Arachni
3
+ Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
4
+
5
+ This is free software; you can copy and distribute and modify
6
+ this program under the term of the GPL v2.0 License
7
+ (See LICENSE file for details)
8
+
9
+ =end
10
+
11
+ require 'erb'
12
+ require 'base64'
13
+ require 'cgi'
14
+
15
+ module Arachni
16
+
17
+ module Reports
18
+
19
+ #
20
+ # Creates an HTML report of the audit.
21
+ #
22
+ # @author: Tasos "Zapotek" Laskos
23
+ # <tasos.laskos@gmail.com>
24
+ # <zapotek@segfault.gr>
25
+ # @version: 0.2
26
+ #
27
+ class HTML < Arachni::Report::Base
28
+
29
+ #
30
+ # @param [AuditStore] audit_store
31
+ # @param [Hash] options options passed to the report
32
+ #
33
+ def initialize( audit_store, options )
34
+ @audit_store = audit_store
35
+ @options = options
36
+ end
37
+
38
+ #
39
+ # Runs the HTML report.
40
+ #
41
+ def run( )
42
+
43
+ print_line( )
44
+ print_status( 'Creating HTML report...' )
45
+
46
+ report = ERB.new( IO.read( @options['tpl'] ) )
47
+
48
+ __prepare_data
49
+
50
+ @plugins = format_plugin_results( @audit_store.plugins )
51
+
52
+ __save( @options['outfile'], report.result( binding ) )
53
+
54
+ print_status( 'Saved in \'' + @options['outfile'] + '\'.' )
55
+ end
56
+
57
+ def self.info
58
+ {
59
+ :name => 'HTML Report',
60
+ :description => %q{Exports a report as an HTML document.},
61
+ :author => 'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>',
62
+ :version => '0.2',
63
+ :options => [
64
+ Arachni::OptPath.new( 'tpl', [ false, 'Template to use.',
65
+ File.dirname( __FILE__ ) + '/html/default.erb' ] ),
66
+ Arachni::OptString.new( 'outfile', [ false, 'Where to save the report.',
67
+ Time.now.to_s + '.html' ] ),
68
+ ]
69
+ }
70
+ end
71
+
72
+ private
73
+
74
+ def self.prep_description( str )
75
+ placeholder = '--' + rand( 1000 ).to_s + '--'
76
+ cstr = str.gsub( /^\s*$/xm, placeholder )
77
+ cstr.gsub!( /^\s*/xm, '' )
78
+ cstr.gsub!( placeholder, "\n" )
79
+ cstr.chomp
80
+ end
81
+
82
+
83
+ def __save( outfile, out )
84
+ file = File.new( outfile, 'w' )
85
+ file.write( out )
86
+ file.close
87
+ end
88
+
89
+ def __prepare_data( )
90
+
91
+ @graph_data = {
92
+ :severities => {
93
+ Issue::Severity::HIGH => 0,
94
+ Issue::Severity::MEDIUM => 0,
95
+ Issue::Severity::LOW => 0,
96
+ Issue::Severity::INFORMATIONAL => 0,
97
+ },
98
+ :issues => {},
99
+ :elements => {
100
+ Issue::Element::FORM => 0,
101
+ Issue::Element::LINK => 0,
102
+ Issue::Element::COOKIE => 0,
103
+ Issue::Element::HEADER => 0,
104
+ Issue::Element::BODY => 0,
105
+ Issue::Element::PATH => 0,
106
+ Issue::Element::SERVER => 0,
107
+ },
108
+ :verification => {
109
+ 'Yes' => 0,
110
+ 'No' => 0
111
+ }
112
+ }
113
+
114
+ @audit_store.issues.each_with_index {
115
+ |issue, i|
116
+
117
+ @graph_data[:severities][issue.severity] ||= 0
118
+ @graph_data[:severities][issue.severity] += 1
119
+ @total_severities ||= 0
120
+ @total_severities += 1
121
+
122
+ @graph_data[:issues][issue.name] ||= 0
123
+ @graph_data[:issues][issue.name] += 1
124
+
125
+ @graph_data[:elements][issue.elem] ||= 0
126
+ @graph_data[:elements][issue.elem] += 1
127
+ @total_elements ||= 0
128
+ @total_elements += 1
129
+
130
+ verification = issue.verification ? 'Yes' : 'No'
131
+ @graph_data[:verification][verification] ||= 0
132
+ @graph_data[:verification][verification] += 1
133
+ @total_verifications ||= 0
134
+ @total_verifications += 1
135
+
136
+ issue.variations.each_with_index {
137
+ |variation, j|
138
+
139
+ if( variation['response'] && !variation['response'].empty? )
140
+ @audit_store.issues[i].variations[j]['escaped_response'] =
141
+ Base64.encode64( variation['response'] ).gsub( /\n/, '' )
142
+ end
143
+
144
+ response = {}
145
+ if !variation['headers']['response'].is_a?( Hash )
146
+ variation['headers']['response'].split( "\n" ).each {
147
+ |line|
148
+ field, value = line.split( ':', 2 )
149
+ next if !value
150
+ response[field] = value
151
+ }
152
+ end
153
+ variation['headers']['response'] = response.dup
154
+
155
+ }
156
+
157
+ }
158
+
159
+ @graph_data[:severities].each {
160
+ |severity, cnt|
161
+ @graph_data[:severities][severity] = ((cnt/Float(@total_severities)) * 100).to_i
162
+ }
163
+
164
+ @graph_data[:elements].each {
165
+ |elem, cnt|
166
+ @graph_data[:elements][elem] = ((cnt/Float(@total_elements)) * 100).to_i
167
+ }
168
+
169
+ @graph_data[:verification].each {
170
+ |verification, cnt|
171
+ @graph_data[:verification][verification] = ((cnt/Float(@total_verifications)) * 100).to_i
172
+ }
173
+
174
+ end
175
+
176
+ end
177
+
178
+ end
179
+ end
@@ -0,0 +1,967 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+
4
+ <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US" xml:lang="en-US">
5
+ <head>
6
+ <title>Web Application Security Report - Arachni Framework</title>
7
+ <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.8/themes/base/jquery-ui.css" type="text/css" media="all" />
8
+ <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
9
+ <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.8/jquery-ui.min.js" type="text/javascript"></script>
10
+ <script src="http://zapotek.github.com/arachni/charts/highcharts.js" type="text/javascript"></script>
11
+
12
+ <!--
13
+ Design by:
14
+ * Christos Chiotis <chris@survivetheinternet.com>
15
+ * Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
16
+
17
+ Copyright (c) Arachni 2011.
18
+ -->
19
+
20
+ <script type="text/javascript">
21
+ //<![CDATA[
22
+
23
+ if( typeof jQuery == 'undefined' ) {
24
+ alert( "Could not load the necessary JavaScript libraries -- the presentation and functionality of the report will be crippled.\n" +
25
+ "Make sure that your internet connection is working and try refreshing the page." );
26
+ }
27
+
28
+ function getElem( id ){
29
+ return document.getElementById(id)
30
+ }
31
+
32
+ function toggleElem( id ){
33
+
34
+ if( getElem(id).style.display == 'none' ||
35
+ getElem(id).style.display == '' )
36
+ {
37
+ getElem(id).style.display = 'block';
38
+ sign = '[-]';
39
+ } else {
40
+ getElem(id).style.display = 'none';
41
+ sign = '[+]';
42
+ }
43
+
44
+ if( getElem(id + '_sign') ){
45
+ getElem(id + '_sign').innerHTML = sign;
46
+ }
47
+ }
48
+
49
+
50
+ function inspect( id ){
51
+ $( id ).dialog({
52
+ height: 500,
53
+ width: 1000,
54
+ modal: true
55
+ });
56
+ }
57
+
58
+ jQuery(function($){
59
+
60
+ tabs = function(options) {
61
+
62
+ var defaults = {
63
+ selector: '.tabs',
64
+ selectedClass: 'selected'
65
+ };
66
+
67
+ if(typeof options == 'string') defaults.selector = options;
68
+ var options = $.extend(defaults, options);
69
+
70
+ return $(options.selector).each(function(){
71
+
72
+ var obj = this;
73
+ var targets = Array();
74
+
75
+ function show(i){
76
+ $.each(targets,function(index,value){
77
+ $(value).hide();
78
+ })
79
+ $(targets[i]).fadeIn('fast');
80
+ $(obj).children().removeClass(options.selectedClass);
81
+ selected = $(obj).children().get(i);
82
+ $(selected).addClass(options.selectedClass);
83
+ };
84
+
85
+ $('a',this).each(function(i){
86
+ targets.push($(this).attr('href'));
87
+ $(this).click(function(e){
88
+ e.preventDefault();
89
+ show(i);
90
+ });
91
+ });
92
+
93
+ show(0);
94
+
95
+ });
96
+ }
97
+
98
+ // initialize the function
99
+ // as a parameter we are sending a selector. For this particular script we must select the unordered (or ordered) list item element
100
+ tabs('nav ul');
101
+
102
+ });
103
+
104
+ var issues; // globally available
105
+ $(document).ready(function() {
106
+ issues = new Highcharts.Chart({
107
+ chart: {
108
+ renderTo: 'chart-issues',
109
+ defaultSeriesType: 'column',
110
+ backgroundColor: '#ccc'
111
+ },
112
+ title: {
113
+ text: 'Issues by type'
114
+ },
115
+ xAxis: {
116
+ categories: <%=@graph_data[:issues].keys.to_s %>
117
+ },
118
+ yAxis: {
119
+ title: {
120
+ text: ''
121
+ }
122
+ },
123
+ series: [{
124
+ data: <%=@graph_data[:issues].values.to_s %>
125
+ }]
126
+ });
127
+ });
128
+
129
+ var severities;
130
+ $(document).ready(function() {
131
+ severities = new Highcharts.Chart({
132
+ chart: {
133
+ renderTo: 'chart-severities',
134
+ backgroundColor: '#ccc'
135
+ },
136
+ title: {
137
+ text: 'Severity levels'
138
+ },
139
+ tooltip: {
140
+ formatter: function() {
141
+ return '<b>'+ this.point.name +'</b>: '+ this.y +' %';
142
+ }
143
+ },
144
+ series: [{
145
+ type: 'pie',
146
+ data: [
147
+ <%@graph_data[:severities].each do |severity| %>
148
+ <%=severity.to_s%>,
149
+ <%end%>
150
+ ]
151
+ }]
152
+ });
153
+ });
154
+
155
+ var elements;
156
+ $(document).ready(function() {
157
+ elements = new Highcharts.Chart({
158
+ chart: {
159
+ renderTo: 'chart-elements',
160
+ backgroundColor: '#ccc'
161
+ },
162
+ title: {
163
+ text: 'Issues by elements'
164
+ },
165
+ tooltip: {
166
+ formatter: function() {
167
+ return '<b>'+ this.point.name +'</b>: '+ this.y +' %';
168
+ }
169
+ },
170
+ series: [{
171
+ type: 'pie',
172
+ data: [
173
+ <%@graph_data[:elements].each do |severity| %>
174
+ <%=severity.to_s%>,
175
+ <%end%>
176
+ ]
177
+ }]
178
+ });
179
+ });
180
+
181
+ var verification;
182
+ $(document).ready(function() {
183
+ elements = new Highcharts.Chart({
184
+ chart: {
185
+ renderTo: 'chart-verification',
186
+ backgroundColor: '#ccc'
187
+ },
188
+ title: {
189
+ text: 'Issues which require manual verification'
190
+ },
191
+ tooltip: {
192
+ formatter: function() {
193
+ return '<b>'+ this.point.name +'</b>: '+ this.y +' %';
194
+ }
195
+ },
196
+ series: [{
197
+ type: 'pie',
198
+ data: [
199
+ <%@graph_data[:verification].each do |severity| %>
200
+ <%=severity.to_s%>,
201
+ <%end%>
202
+ ]
203
+ }]
204
+ });
205
+ });
206
+
207
+ //]]>
208
+ </script>
209
+
210
+ <style type="text/css">
211
+ /*<![CDATA[*/
212
+
213
+ body {
214
+ background: #ddd;
215
+ margin:0;
216
+ padding:0;
217
+ font-family: Verdana, Geneva, sans-serif;
218
+ font-size: 12px;
219
+ color: #333;
220
+ }
221
+
222
+ .wrapper {
223
+ background: #ddd url('bodybg.png') repeat-x scroll top left;
224
+ }
225
+
226
+ .subpage {
227
+ background-image: url('bodybg-small.png');
228
+ }
229
+
230
+ * {
231
+ margin:0;
232
+ padding:0;
233
+ }
234
+
235
+ /** element defaults **/
236
+ table {
237
+ width: 100%;
238
+ text-align: left;
239
+ }
240
+
241
+ th, td {
242
+ padding: 10px 10px;
243
+ }
244
+
245
+ th {
246
+ color: #fff;
247
+ background: #2978A1 none repeat-x scroll -15px 0;
248
+ }
249
+
250
+ td {
251
+ color: #111;
252
+ vertical-align: top
253
+ }
254
+
255
+ code, blockquote {
256
+ display: block;
257
+ border-left: 5px solid #ddd;
258
+ padding: 10px;
259
+ margin-bottom: 20px;
260
+ }
261
+ code {
262
+ background-color: #ddd;
263
+ border: none;
264
+ }
265
+ blockquote {
266
+ border-left: 5px solid #333;
267
+ }
268
+
269
+ blockquote p {
270
+ font-style: italic;
271
+ font-family: Georgia, "Times New Roman", Times, serif;
272
+ margin: 0;
273
+ height: 1%;
274
+ }
275
+
276
+ p {
277
+ line-height: 1.9em;
278
+ margin-bottom: 20px;
279
+ }
280
+
281
+ a {
282
+ color: #256F94;
283
+ text-decoration: none
284
+ }
285
+
286
+ a:hover {
287
+ color: #BC6637;
288
+ }
289
+
290
+ a:focus {
291
+ outline: none;
292
+ }
293
+
294
+ fieldset {
295
+ display: block;
296
+ border: none;
297
+ border-top: 1px solid #ccc;
298
+ }
299
+
300
+ fieldset legend {
301
+ font-weight: bold;
302
+ font-size: 13px;
303
+ padding-right: 10px;
304
+ color: #666;
305
+ }
306
+
307
+ fieldset form {
308
+ padding-top: 15px;
309
+ }
310
+
311
+ fieldset p label {
312
+ float: left;
313
+ width: 150px;
314
+ }
315
+
316
+ form input, form select, form textarea {
317
+ padding: 5px;
318
+ color: #333333;
319
+ border: 1px solid #999;
320
+ font-family: Arial, Helvetica, sans-serif;
321
+ font-size: 12px;
322
+ -moz-border-radius: 5px;
323
+ -webkit-border-radius: 5px;
324
+ }
325
+
326
+ form input.formbutton {
327
+ border: none;
328
+ background: #FFFFFF url(bodybg.png) repeat-x scroll 0 -160px;
329
+ color: #ffffff;
330
+ font-weight: bold;
331
+ padding: 5px 10px;
332
+ font-size: 12px;
333
+ font-family: Tahoma, Geneva, sans-serif;
334
+ letter-spacing: 1px;
335
+ width: auto;
336
+ overflow: visible;
337
+ -moz-border-radius: 5px;
338
+ -webkit-border-radius: 5px;
339
+ }
340
+
341
+ form.searchform p {
342
+ margin: 5px 0;
343
+ }
344
+
345
+ form.searchform input.s {
346
+ border: 1px solid #000;
347
+ }
348
+
349
+ form.settings input, textarea {
350
+ float: right;
351
+ margin-right: 10px
352
+ }
353
+
354
+ .options input, textarea {
355
+ float: right;
356
+ margin-right: 10px
357
+ }
358
+
359
+ form.reset input {
360
+ float: left;
361
+ }
362
+
363
+
364
+ span.required {
365
+ font-family: Verdana, Arial, Helvetica, sans-serif;
366
+ color: #ff0000;
367
+ }
368
+
369
+ h1 {
370
+ color: #1F5D7C;
371
+ font-family: Arial, Helvetica, sans-serif;
372
+ font-size: 35px;
373
+ }
374
+
375
+ h2 {
376
+ color: #111;
377
+ font-family: Arial, Helvetica, sans-serif;
378
+ font-size: 28px;
379
+ letter-spacing: -0.5px;
380
+ padding: 0 0 5px;
381
+ margin: 0;
382
+ font-weight: normal;
383
+ }
384
+
385
+ h3 {
386
+ color: #BC6637;
387
+ font-family: Arial, Helvetica, sans-serif;
388
+ font-size: 18px;
389
+ font-weight: bold;
390
+ margin-bottom: 10px;
391
+ }
392
+
393
+ h4 {
394
+ padding-bottom: 10px;
395
+ font-size: 15px;
396
+ color: #666;
397
+ }
398
+
399
+ h5 {
400
+ padding-bottom: 10px;
401
+ font-size: 13px;
402
+ color: #666;
403
+ }
404
+
405
+ ul, ol {
406
+ margin: 0 0 35px 35px;
407
+ }
408
+
409
+ li {
410
+ padding-bottom: 5px;
411
+ }
412
+
413
+ li ol, li ul {
414
+ font-size: 1.0em;
415
+ margin-bottom: 0;
416
+ padding-top: 5px;
417
+ }
418
+
419
+ iframe {
420
+ border: 1px solid
421
+ }
422
+
423
+ .clear {
424
+ clear: both;
425
+ }
426
+
427
+ .notice {
428
+ color: #222;
429
+ background: #e3e4e3;
430
+ border: 1px solid #d5d5d5;
431
+ padding: 7px 10px;
432
+ display: block;
433
+ text-align: left
434
+ -moz-border-radius: 5px;
435
+ -webkit-border-radius: 5px;
436
+ }
437
+
438
+ .left {
439
+ float: left;
440
+ width: 49%;
441
+ padding-right: 5px
442
+ }
443
+
444
+ .right {
445
+ float: right;
446
+ width: 50%;
447
+ border-left: 1px
448
+ }
449
+
450
+ .variation{
451
+ display: none;
452
+ padding: 20px;
453
+ padding-left: 40px;
454
+ padding-top: 0px
455
+ }
456
+
457
+ .hidden {
458
+ display: none
459
+ }
460
+
461
+ .separator {
462
+ min-width: 100%;
463
+ border-bottom: 1px solid #333333
464
+ }
465
+
466
+ .ui-widget-bg { border-top: 1px dotted #aed0ea; font-size:9px; }
467
+ .ui-widget-bar {position:absolute;zIndex:10;bottom:0;font-size:10px; }
468
+
469
+ .graphs li{
470
+ list-style-type:none;
471
+ }
472
+
473
+ /* Security Reports Style */
474
+
475
+ header, nav, article, section, footer, address {display:block;}
476
+
477
+ header{
478
+ height: 38px;
479
+ overflow:hidden;
480
+ background:#e1e1e1;
481
+ background:-webkit-gradient(linear, left top, left bottom, from(#cccccc), to(#e1e1e1));
482
+ background:-moz-linear-gradient(top, #cccccc, #e1e1e1);
483
+ padding:0 5px;
484
+ }
485
+ header h1{
486
+ line-height:32px;
487
+ font-size:14px;
488
+ text-shadow:#fff 0 1px 0;
489
+ text-align:center;
490
+ display: inline
491
+ }
492
+
493
+ nav{
494
+ height:34px;
495
+ overflow:hidden;
496
+ }
497
+ nav ul{
498
+ margin:0;
499
+ padding:0 5px;
500
+ width:100%;
501
+ height:34px;
502
+ -moz-box-shadow:inset -2px 2px 2px #999;
503
+ -webkit-box-shadow:inset -2px 2px 2px #999;
504
+ box-shadow:inset -2px 0px 2px #999;
505
+ background:#ddd;
506
+ }
507
+ nav li{
508
+ list-style:none;
509
+ float:left;
510
+ height:24px;
511
+ line-height:24px;
512
+ -moz-box-shadow:0 0 3px #888;
513
+ -webkit-box-shadow:0 0 3px #888;
514
+ box-shadow:0 0 3px #888;
515
+ -webkit-border-bottom-right-radius:3px;
516
+ -webkit-border-bottom-left-radius:3px;
517
+ -moz-border-radius-bottomright:3px;
518
+ -moz-border-radius-bottomleft:3px;
519
+ border-bottom-right-radius:3px;
520
+ border-bottom-left-radius:3px;
521
+ margin:0 2px;
522
+ width:200px;
523
+ overflow:hidden;
524
+ position:relative;
525
+ background:#ccc;
526
+ background:-webkit-gradient(linear, left top, left bottom, from(#ccc), to(#aaa));
527
+ background:-moz-linear-gradient(top, #ccc, #aaa);
528
+ }
529
+ nav li a, nav li a:visited, nav li a:hover{
530
+ list-style:none;
531
+ display:block;
532
+ position:absolute;
533
+ top:0;
534
+ left:-2px;
535
+ height:24px;
536
+ line-height:24px;
537
+ width:204px;
538
+ text-align:center;
539
+ color:#333;
540
+ font-size:13px;
541
+ text-shadow:#e8e8e8 0 1px 0;
542
+ -moz-box-shadow:inset 0 1px 1px #888;
543
+ -webkit-box-shadow:inset 0 1px 1px #888;
544
+ box-shadow:inset 0 1px 1px #888;
545
+ }
546
+ nav li.selected {background:#e1e1e1;background:-webkit-gradient(linear, left top, left bottom, from(#e1e1e1), to(#d1d1d1));background:-moz-linear-gradient(top, #e1e1e1, #d1d1d1);}
547
+ nav li.selected a {-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none;}
548
+ nav li a:focus {outline:none;}
549
+
550
+ /* style your sections here */
551
+ section {padding:20px;background:#ddd;}
552
+ section hr {margin:10px 0;}
553
+ section h2 {border-bottom:1px solid #444;margin:0 0 20px 0;padding:0 0 10px 0;}
554
+ section p.notice {
555
+ white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */
556
+ white-space: -pre-wrap; /* Opera 4-6 */
557
+ white-space: -o-pre-wrap; /* Opera 7 */
558
+ white-space: pre-wrap; /* css-3 */
559
+ word-wrap: break-word; /* Internet Explorer 5.5+ */
560
+ }
561
+ section div.variations form input {cursor:pointer;}
562
+ /*]]>*/
563
+ </style>
564
+
565
+ </head>
566
+
567
+ <body>
568
+
569
+ <div id="contentreport">
570
+ <header>
571
+ <h1>Report for <%=CGI.escapeHTML(@audit_store.options['url'])%> (Generated on <strong><%=Time.now%></strong>)</h1>
572
+ <span style="float: right">Found a false positive? <a href="<%=CGI.escapeHTML(REPORT_FP)%>">Report it here</a>.</span>
573
+ </header>
574
+
575
+ <nav>
576
+ <ul>
577
+ <li><a href="#summary">Summary</a></li>
578
+ <li><a href="#issues">Issues</a></li>
579
+ <li><a href="#plugins">Plugin results</a></li>
580
+ <li><a href="#sitemap">Sitemap</a></li>
581
+ <li><a href="#configuration">Configuration</a></li>
582
+ </ul>
583
+ </nav>
584
+
585
+ <section class="tab" id="summary">
586
+ <h2>Summary</h2>
587
+
588
+ <h3>Charts</h3>
589
+
590
+ <div id="chart-issues" style="width: 1000px">
591
+ </div>
592
+
593
+ <p class="clear">&nbsp;</p>
594
+
595
+ <div id="chart-severities" style="width: 500px; float:left">
596
+ </div>
597
+
598
+ <div id="chart-elements" style="width: 450px">
599
+ </div>
600
+
601
+ <p class="clear">&nbsp;</p>
602
+
603
+ <div id="chart-verification" style="width: 333px">
604
+ </div>
605
+
606
+
607
+ <p class="clear">&nbsp;</p>
608
+ <p class="clear">&nbsp;</p>
609
+
610
+ <hr/>
611
+
612
+
613
+ <h3>Found <%=@audit_store.issues.size%> issues</h3>
614
+
615
+ <% @audit_store.issues.each_with_index do |issue, i| %>
616
+ <p>
617
+ <h5>[<%=i+1%>] <%= issue.name %> ( Severity: <%= issue.severity %> )</h5>
618
+ In <%= issue.elem %>
619
+
620
+ <% if issue.var%>
621
+ input <em><%= issue.var %></em>
622
+ <%end%>
623
+
624
+ <% if issue.method %>
625
+ using <%= issue.method %>
626
+ <%end%>
627
+
628
+ at <a href="<%= issue.url %>"><%= issue.url %></a>.
629
+ </p>
630
+ <%end%>
631
+
632
+ </section>
633
+
634
+ <section class="tab" id="configuration">
635
+ <h2>Configuration</h2>
636
+
637
+ <strong>Version</strong>: <%=@audit_store.version%><br />
638
+ <strong>Revision</strong>: <%=@audit_store.revision%><br />
639
+ <strong>Audit started on</strong>: <%=@audit_store.start_datetime%><br />
640
+ <strong>Audit finished on</strong>: <%=@audit_store.finish_datetime%><br />
641
+ <strong>Runtime</strong>: <%=@audit_store.delta_time%><br />
642
+
643
+ <p>&nbsp;</p>
644
+ <h3>Runtime options</h3>
645
+
646
+ <strong>URL:</strong> <%=@audit_store.options['url']%><br />
647
+ <strong>User agent:</strong> <%=::CGI.escapeHTML( @audit_store.options['user_agent'] )%><br />
648
+
649
+ <p>&nbsp;</p>
650
+
651
+ <table>
652
+ <tr>
653
+ <th>Audited elements</th>
654
+ <th>Modules</th>
655
+ <th>Filters</th>
656
+ <th>Cookies</th>
657
+ </tr>
658
+ <tr>
659
+ <td>
660
+ <ul>
661
+
662
+ <% if @audit_store.options['audit_links']%>
663
+ <li>Links</li>
664
+ <%end%>
665
+
666
+ <% if @audit_store.options['audit_forms']%>
667
+ <li>Forms</li>
668
+ <%end%>
669
+
670
+ <% if @audit_store.options['audit_cookies']%>
671
+ <li>Cookies</li>
672
+ <%end%>
673
+
674
+ <% if @audit_store.options['audit_headers']%>
675
+ <li>Headers</li>
676
+ <%end%>
677
+
678
+ </ul>
679
+ </td>
680
+
681
+ <td>
682
+ <ul>
683
+ <% @audit_store.options['mods'].each do |mod|%>
684
+ <li><%=mod%></li>
685
+ <%end%>
686
+ </ul>
687
+ </td>
688
+
689
+ <td>
690
+ <ul>
691
+
692
+ <li>Exclude:
693
+ <ul>
694
+ <% if !@audit_store.options['exclude'].empty?%>
695
+ <% @audit_store.options['exclude'].each do |rule|%>
696
+
697
+ <li><%=CGI.escapeHTML( rule )%></li>
698
+
699
+ <%end%>
700
+ <% else %>
701
+ <li>N/A</li>
702
+ <%end%>
703
+ </ul>
704
+ </li>
705
+
706
+ <li>Include:
707
+
708
+ <ul>
709
+ <% if !@audit_store.options['include'].empty?%>
710
+ <% @audit_store.options['include'].each do |rule|%>
711
+
712
+ <li><%=CGI.escapeHTML( rule )%></li>
713
+
714
+ <%end%>
715
+ <% else %>
716
+ <li>N/A</li>
717
+ <%end%>
718
+ </ul>
719
+ </li>
720
+
721
+ <li>Redundant:
722
+
723
+ <ul>
724
+ <% if !@audit_store.options['redundant'].empty?%>
725
+ <% @audit_store.options['redundant'].each do |rule|%>
726
+
727
+ <li><%=CGI.escapeHTML( rule['regexp'] )%> - Count: <%=rule['count']%></li>
728
+
729
+ <%end%>
730
+ <% else %>
731
+ <li>N/A</li>
732
+ <%end%>
733
+ </ul>
734
+ </li>
735
+
736
+ </ul>
737
+ </td>
738
+
739
+ <td>
740
+ <ul>
741
+ <% if @audit_store.options['cookies'] && !@audit_store.options['cookies'].empty?%>
742
+ <% @audit_store.options['cookies'].each_pair do |name, val|%>
743
+ <li><%=CGI.escapeHTML( name )%> = <%=CGI.escapeHTML( val )%></li>
744
+ <%end%>
745
+ <% else %>
746
+ <li>N/A</li>
747
+ <%end%>
748
+ </ul>
749
+
750
+ </td>
751
+ </tr>
752
+ </table>
753
+ </section>
754
+
755
+ <section class="tab" id="issues">
756
+ <h2>Issues</h2>
757
+ <p> &nbsp; </p>
758
+
759
+ <% if @plugins['metamodules']%>
760
+ <div class="metamodules notice">
761
+ <%=@plugins['metamodules']%>
762
+ </div>
763
+
764
+ <hr/>
765
+
766
+ <%end%>
767
+
768
+ <% @audit_store.issues.each_with_index do |issue, i|%>
769
+ <%idx = i+1%>
770
+ <div class="issue">
771
+
772
+ <h3 id="issue_<%=idx%>">
773
+ <a href="#issue_<%=idx%>">[<%=idx%>] <%=CGI.escapeHTML(issue.name)%></a>
774
+ </h3>
775
+
776
+ <div class="left">
777
+ <ul>
778
+ <li><strong>Module name</strong>: <%=CGI.escapeHTML(issue.mod_name)%> <br/>
779
+ (Internal module name: <strong><%=CGI.escapeHTML(issue.internal_modname)%></strong>)</li>
780
+
781
+ <% if issue.var %>
782
+ <li><strong>Affected variable</strong>: <%=CGI.escapeHTML(issue.var)%></li>
783
+ <%end%>
784
+
785
+ <li><strong>Affected URL</strong>: <a href="<%=CGI.escapeHTML(issue.url)%>"><%= CGI.escapeHTML(issue.url)%></a> </li>
786
+ <li><strong>HTML Element</strong>: <%=issue.elem%></li>
787
+ <li><strong>Requires manual verification?</strong>: <%=issue.verification ? 'Yes' : 'No'%></li>
788
+ <hr/>
789
+
790
+ <% if issue.cwe %>
791
+ <li><strong>CWE</strong>: <%=issue.cwe%><br/>
792
+ (<a target="_blank" href="<%=issue.cwe_url%>"><%=issue.cwe_url%></a>)</li>
793
+ <%end%>
794
+
795
+ <li><strong>Severity</strong>: <%=issue.severity%></li>
796
+ <li><strong>CVSSV2</strong>: <%=issue.cvssv2%></li>
797
+
798
+ </ul>
799
+
800
+ <p>
801
+ <h3>References</h3>
802
+ <ul>
803
+ <% if issue.references && !issue.references.empty? %>
804
+ <% issue.references.each_pair do |source, url| %>
805
+
806
+ <li><%=CGI.escapeHTML(source)%> - <a target="_blank" href="<%=url%>"><%=url%></a></li>
807
+
808
+ <%end%>
809
+ <%else%>
810
+ <li>N/A</li>
811
+ <%end%>
812
+ </ul>
813
+ </p>
814
+
815
+ </div>
816
+
817
+ <div class="right">
818
+ <p>
819
+ <h3>Description</h3>
820
+ <blockquote><p><%=CGI.escapeHTML(issue.description)%></p></blockquote>
821
+ </p>
822
+
823
+ <% if issue.remedy_guidance && !issue.remedy_guidance.empty? %>
824
+ <p>
825
+ <h3>Remedial guidance</h3>
826
+ <blockquote><p><%=CGI.escapeHTML(issue.remedy_guidance)%></p></blockquote>
827
+ </p>
828
+ <%end%>
829
+
830
+ <% if issue.remedy_code && !issue.remedy_code.empty? %>
831
+ <p>
832
+ <h3>Remedial code</h3>
833
+ <pre class="code notice"><%=CGI.escapeHTML(issue.remedy_code)%></pre>
834
+ </p>
835
+ <%end%>
836
+
837
+
838
+ </div>
839
+
840
+ <div class="clear variations" style="display: block;">
841
+ <% issue.variations.each_with_index do |variation, j| %>
842
+ <% var_idx = j + 1%>
843
+
844
+ <h5 class="variation_header">
845
+ <a href='javascript:toggleElem( "var_<%=var_idx%>_<%=idx%>" )'>
846
+ <span id="var_<%=var_idx%>_<%=idx%>_sign">[+]</span>
847
+ Variation <%=var_idx%>
848
+ </a>
849
+ </h5>
850
+
851
+ <strong>Affected URL</strong>:
852
+ <p class="notice"><a href="<%=CGI.escapeHTML(variation['url'])%>"><%=CGI.escapeHTML(variation['url'])%></a></p>
853
+
854
+ <% if (variation['response'] && !variation['response'].empty?) && variation['regexp_match'] %>
855
+
856
+ <div class="hidden" id="inspection-dialog_<%=var_idx%>_<%=idx%>" title="Relevant content is shown in red.">
857
+ <% match = CGI.escapeHTML( variation['regexp_match'] )%>
858
+ <pre> <%=CGI.escapeHTML( variation['response'] ).gsub( match, '<strong style="color: red">' + match + '</strong>' ) %> </pre>
859
+ </div>
860
+
861
+ <form style="display:inline" action="#">
862
+ <input onclick="javascript:inspect( '#inspection-dialog_<%=var_idx%>_<%=idx%>')" type="button" value="Inspect" />
863
+ </form>
864
+
865
+ <%end%>
866
+
867
+ <% if issue.method && (issue.elem.downcase == 'form' || issue.elem.downcase == 'link' ) &&
868
+ ( issue.method.downcase == 'get' || issue.method.downcase == 'post' ) %>
869
+ <form style="display:inline" action="<%=issue.url%>" target="_blank" method="<%=issue.method.downcase%>">
870
+ <% if variation['opts'][:combo]%>
871
+ <%variation['opts'][:combo].each_pair do |name, value|%>
872
+ <input type="hidden" name="<%=CGI.escapeHTML(name)%>" value="<%=CGI.escapeHTML( value )%>" />
873
+ <%end%>
874
+ <%end%>
875
+ <input type="submit" value="Replay" />
876
+ </form>
877
+ <%end%>
878
+
879
+ <br/><br/>
880
+
881
+ <div class="variation" id="var_<%=var_idx%>_<%=idx%>">
882
+
883
+ <% if variation['injected'] %>
884
+ <strong>Injected value</strong>:
885
+ <pre> <%=CGI.escapeHTML(variation['injected'])%> </pre>
886
+ <br/>
887
+ <%end%>
888
+
889
+ <% if variation['id'] %>
890
+ <strong>ID</strong>:
891
+ <pre><%=CGI.escapeHTML(variation['id'])%></pre>
892
+ <br/>
893
+ <%end%>
894
+
895
+ <% if variation['regexp'] %>
896
+ <strong>Regular expression</strong>:
897
+ <pre><%=CGI.escapeHTML(variation['regexp'])%></pre>
898
+ <br/>
899
+ <%end%>
900
+
901
+ <% if variation['regexp_match'] %>
902
+ <strong>Matched by the regular expression</strong>:
903
+ <pre><%=CGI.escapeHTML(variation['regexp_match'])%> </pre>
904
+ <%end%>
905
+
906
+ <br/>
907
+
908
+ <table>
909
+ <tr>
910
+ <th colspan="2" style="text-align: center">Headers</th>
911
+ </tr>
912
+ <tr>
913
+ <th>Request</th>
914
+ <th>Response</th>
915
+ </tr>
916
+ <tr>
917
+ <td>
918
+ <% if variation['headers']['request'].is_a?( Hash ) %>
919
+ <pre class="notice"><% variation['headers']['request'].each_pair do |name, val| %><strong><%=name%></strong><%="\t" + CGI.escapeHTML(val) + "\n"%><%end%></pre>
920
+ <%end%>
921
+ </td>
922
+ <td>
923
+ <% if variation['headers']['response'].is_a?( Hash ) %>
924
+ <pre class="notice"><% variation['headers']['response'].each_pair do |name, val| %><strong><%=name%></strong><%="\t" + CGI.escapeHTML(val) + "\n"%><%end%></pre>
925
+ <%end%>
926
+ </td>
927
+ </tr>
928
+ </table>
929
+
930
+ <% if variation['escaped_response']%>
931
+ <h5>HTML Response</h5>
932
+ <iframe style="width: 100%; height: 400px" src="data:text/html;base64, <%=variation['escaped_response']%>"></iframe>
933
+ <%end%>
934
+
935
+ </div>
936
+ <%end%>
937
+
938
+ </div>
939
+
940
+ </div>
941
+
942
+ <p class="clear separator">&nbsp;</p>
943
+
944
+ <%end%>
945
+ </section>
946
+
947
+ <section class="tab" id="plugins">
948
+ <h2>Plugin results</h2>
949
+ <p> &nbsp; </p>
950
+
951
+ <%@plugins.values.each do |plugin|%>
952
+ <p><%=plugin%></p>
953
+ <%end%>
954
+ </section>
955
+
956
+ <section class="tab" id="sitemap">
957
+ <h2>Sitemap</h2>
958
+ <p> &nbsp; </p>
959
+ <h3><%=@audit_store.sitemap.size%> pages</h3>
960
+ <% @audit_store.sitemap.each do |url| %>
961
+ <a href="<%=CGI.escapeHTML(url)%>"><%=CGI.escapeHTML(url)%></a><br/>
962
+ <%end%>
963
+
964
+ </section>
965
+ </div>
966
+ </body>
967
+ </html>