arachni 0.2.2.1

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.
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>