arachni 0.3 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (348) hide show
  1. data/ACKNOWLEDGMENTS.md +1 -1
  2. data/CHANGELOG.md +146 -0
  3. data/CONTRIBUTORS.md +1 -0
  4. data/HACKING.md +3 -3
  5. data/README.md +81 -49
  6. data/Rakefile +11 -14
  7. data/bin/arachni +4 -8
  8. data/bin/arachni_rpc +17 -0
  9. data/bin/arachni_rpcd +18 -0
  10. data/bin/arachni_rpcd_monitor +18 -0
  11. data/bin/arachni_web +25 -48
  12. data/bin/arachni_web_autostart +3 -3
  13. data/conf/README.webui.yaml.txt +7 -21
  14. data/external/metasploit/plugins/arachni.rb +0 -7
  15. data/extras/modules/recon/raft_dirs.rb +108 -0
  16. data/extras/modules/recon/raft_dirs/raft-large-directories.txt +62290 -0
  17. data/extras/modules/recon/raft_files.rb +110 -0
  18. data/extras/modules/recon/raft_files/raft-large-files.txt +37037 -0
  19. data/extras/modules/recon/svn_digger_dirs.rb +108 -0
  20. data/extras/modules/recon/svn_digger_dirs/Licence.txt +674 -0
  21. data/extras/modules/recon/svn_digger_dirs/ReadMe-Arachni.txt +4 -0
  22. data/extras/modules/recon/svn_digger_dirs/ReadMe.txt +6 -0
  23. data/extras/modules/recon/svn_digger_dirs/all-dirs.txt +5960 -0
  24. data/extras/modules/recon/svn_digger_files.rb +114 -0
  25. data/extras/modules/recon/svn_digger_files/Licence.txt +674 -0
  26. data/extras/modules/recon/svn_digger_files/ReadMe-Arachni.txt +4 -0
  27. data/extras/modules/recon/svn_digger_files/ReadMe.txt +6 -0
  28. data/extras/modules/recon/svn_digger_files/all-extensionless.txt +25419 -0
  29. data/extras/modules/recon/svn_digger_files/all.txt +43135 -0
  30. data/lib/arachni.rb +2 -7
  31. data/lib/{audit_store.rb → arachni/audit_store.rb} +68 -60
  32. data/lib/{component_manager.rb → arachni/component_manager.rb} +8 -8
  33. data/lib/{component_options.rb → arachni/component_options.rb} +34 -4
  34. data/lib/{crypto → arachni/crypto}/rsa_aes_cbc.rb +1 -2
  35. data/lib/arachni/database.rb +4 -0
  36. data/lib/arachni/database/base.rb +125 -0
  37. data/lib/arachni/database/hash.rb +384 -0
  38. data/lib/arachni/database/queue.rb +93 -0
  39. data/lib/{exceptions.rb → arachni/exceptions.rb} +1 -1
  40. data/lib/arachni/framework.rb +899 -0
  41. data/lib/{http.rb → arachni/http.rb} +63 -166
  42. data/lib/{issue.rb → arachni/issue.rb} +46 -17
  43. data/lib/{mixins → arachni/mixins}/observable.rb +1 -1
  44. data/lib/arachni/mixins/progress_bar.rb +81 -0
  45. data/lib/arachni/mixins/terminal.rb +106 -0
  46. data/lib/{module.rb → arachni/module.rb} +0 -0
  47. data/lib/{module → arachni/module}/auditor.rb +250 -86
  48. data/lib/{module → arachni/module}/base.rb +8 -18
  49. data/lib/{module → arachni/module}/element_db.rb +10 -2
  50. data/lib/{module → arachni/module}/key_filler.rb +1 -1
  51. data/lib/arachni/module/manager.rb +145 -0
  52. data/lib/{module → arachni/module}/output.rb +6 -1
  53. data/lib/{module → arachni/module}/trainer.rb +48 -52
  54. data/lib/{module → arachni/module}/utilities.rb +66 -15
  55. data/lib/{nokogiri → arachni/nokogiri}/xml/node.rb +0 -0
  56. data/lib/arachni/options.rb +986 -0
  57. data/lib/{parser.rb → arachni/parser.rb} +0 -0
  58. data/lib/{parser → arachni/parser}/auditable.rb +111 -32
  59. data/lib/{parser → arachni/parser}/elements.rb +28 -20
  60. data/lib/{parser → arachni/parser}/page.rb +20 -3
  61. data/lib/{parser → arachni/parser}/parser.rb +100 -63
  62. data/lib/{plugin.rb → arachni/plugin.rb} +0 -0
  63. data/lib/{plugin → arachni/plugin}/base.rb +43 -6
  64. data/lib/{plugin → arachni/plugin}/manager.rb +40 -13
  65. data/lib/{report.rb → arachni/report.rb} +0 -0
  66. data/lib/{report → arachni/report}/base.rb +43 -2
  67. data/lib/{report → arachni/report}/manager.rb +7 -18
  68. data/lib/arachni/rpc/client/base.rb +42 -0
  69. data/lib/{rpc/xml → arachni/rpc}/client/dispatcher.rb +12 -13
  70. data/lib/arachni/rpc/client/instance.rb +62 -0
  71. data/lib/arachni/rpc/server/base.rb +51 -0
  72. data/lib/arachni/rpc/server/dispatcher.rb +438 -0
  73. data/lib/arachni/rpc/server/framework.rb +1163 -0
  74. data/lib/arachni/rpc/server/instance.rb +184 -0
  75. data/lib/{rpc/xml → arachni/rpc}/server/module/manager.rb +8 -5
  76. data/lib/arachni/rpc/server/node.rb +267 -0
  77. data/lib/{rpc/xml → arachni/rpc}/server/options.rb +6 -35
  78. data/lib/{rpc/xml → arachni/rpc}/server/output.rb +29 -3
  79. data/lib/{rpc/xml → arachni/rpc}/server/plugin/manager.rb +5 -6
  80. data/lib/{ruby.rb → arachni/ruby.rb} +1 -2
  81. data/lib/arachni/ruby/array.rb +31 -0
  82. data/lib/{ruby → arachni/ruby}/object.rb +1 -1
  83. data/lib/{ruby → arachni/ruby}/string.rb +1 -1
  84. data/lib/{spider.rb → arachni/spider.rb} +83 -110
  85. data/lib/arachni/typhoeus/hydra.rb +7 -0
  86. data/lib/{typhoeus → arachni/typhoeus}/request.rb +11 -9
  87. data/lib/{typhoeus → arachni/typhoeus}/response.rb +4 -0
  88. data/lib/{ui → arachni/ui}/cli/cli.rb +154 -84
  89. data/lib/{ui → arachni/ui}/cli/output.rb +57 -19
  90. data/lib/{ui/xmlrpc → arachni/ui/rpc}/dispatcher_monitor.rb +11 -10
  91. data/lib/{ui/xmlrpc/xmlrpc.rb → arachni/ui/rpc/rpc.rb} +102 -158
  92. data/lib/{ui → arachni/ui}/web/addon_manager.rb +23 -3
  93. data/lib/arachni/ui/web/addons/autodeploy.rb +207 -0
  94. data/lib/{ui → arachni/ui}/web/addons/autodeploy/lib/manager.rb +142 -35
  95. data/lib/arachni/ui/web/addons/autodeploy/views/index.erb +291 -0
  96. data/lib/{ui → arachni/ui}/web/addons/sample.rb +1 -1
  97. data/lib/{ui → arachni/ui}/web/addons/sample/views/index.erb +0 -0
  98. data/lib/{ui → arachni/ui}/web/addons/scheduler.rb +30 -22
  99. data/lib/{ui → arachni/ui}/web/addons/scheduler/views/index.erb +56 -22
  100. data/lib/{ui → arachni/ui}/web/addons/scheduler/views/options.erb +0 -0
  101. data/lib/arachni/ui/web/dispatcher_manager.rb +274 -0
  102. data/lib/arachni/ui/web/instance_manager.rb +69 -0
  103. data/lib/{ui → arachni/ui}/web/log.rb +1 -1
  104. data/lib/arachni/ui/web/output_stream.rb +54 -0
  105. data/lib/{ui → arachni/ui}/web/report_manager.rb +48 -54
  106. data/lib/{ui → arachni/ui}/web/scheduler.rb +42 -47
  107. data/lib/arachni/ui/web/server.rb +1197 -0
  108. data/lib/{ui → arachni/ui}/web/server/db/placeholder +0 -0
  109. data/lib/{ui → arachni/ui}/web/server/public/banner.png +0 -0
  110. data/lib/{ui → arachni/ui}/web/server/public/bodybg-small.png +0 -0
  111. data/lib/{ui → arachni/ui}/web/server/public/bodybg.png +0 -0
  112. data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/pbar-ani.gif +0 -0
  113. data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  114. data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  115. data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  116. data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  117. data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  118. data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  119. data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  120. data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  121. data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
  122. data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  123. data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
  124. data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
  125. data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  126. data/lib/{ui → arachni/ui}/web/server/public/css/smoothness/jquery-ui-1.8.9.custom.css +0 -0
  127. data/lib/{ui → arachni/ui}/web/server/public/favicon.ico +0 -0
  128. data/lib/{ui → arachni/ui}/web/server/public/footer.jpg +0 -0
  129. data/lib/{ui/web/server/public/icons/error.png → arachni/ui/web/server/public/icons/bad.png} +0 -0
  130. data/lib/arachni/ui/web/server/public/icons/error.png +0 -0
  131. data/lib/{ui → arachni/ui}/web/server/public/icons/info.png +0 -0
  132. data/lib/{ui → arachni/ui}/web/server/public/icons/ok.png +0 -0
  133. data/lib/{ui → arachni/ui}/web/server/public/icons/status.png +0 -0
  134. data/lib/{ui → arachni/ui}/web/server/public/js/jquery-1.4.4.min.js +0 -0
  135. data/lib/{ui → arachni/ui}/web/server/public/js/jquery-ui-1.8.9.custom.min.js +0 -0
  136. data/lib/{ui → arachni/ui}/web/server/public/js/jquery-ui-timepicker.js +0 -0
  137. data/lib/{ui → arachni/ui}/web/server/public/logo.png +0 -0
  138. data/lib/{ui → arachni/ui}/web/server/public/nav-left.jpg +0 -0
  139. data/lib/{ui → arachni/ui}/web/server/public/nav-right.jpg +0 -0
  140. data/lib/{ui → arachni/ui}/web/server/public/nav-selected-left.jpg +0 -0
  141. data/lib/{ui → arachni/ui}/web/server/public/nav-selected-right.jpg +0 -0
  142. data/lib/{ui → arachni/ui}/web/server/public/plugins/sample/style.css +0 -0
  143. data/lib/{ui/web/server/tmp → arachni/ui/web/server/public/reports}/placeholder +0 -0
  144. data/lib/{ui → arachni/ui}/web/server/public/sidebar-bottom.jpg +0 -0
  145. data/lib/{ui → arachni/ui}/web/server/public/sidebar-h4.jpg +0 -0
  146. data/lib/{ui → arachni/ui}/web/server/public/sidebar-top.jpg +0 -0
  147. data/lib/{ui → arachni/ui}/web/server/public/spider.png +0 -0
  148. data/lib/{ui → arachni/ui}/web/server/public/style.css +3 -2
  149. data/lib/arachni/ui/web/server/tmp/placeholder +0 -0
  150. data/lib/{ui → arachni/ui}/web/server/views/addon.erb +0 -0
  151. data/lib/{ui → arachni/ui}/web/server/views/addons.erb +0 -0
  152. data/lib/{ui → arachni/ui}/web/server/views/dispatcher_error.erb +0 -0
  153. data/lib/arachni/ui/web/server/views/dispatchers.erb +175 -0
  154. data/lib/arachni/ui/web/server/views/dispatchers_edit.erb +71 -0
  155. data/lib/arachni/ui/web/server/views/error.erb +22 -0
  156. data/lib/{ui → arachni/ui}/web/server/views/flash.erb +2 -2
  157. data/lib/arachni/ui/web/server/views/home.erb +60 -0
  158. data/lib/{ui → arachni/ui}/web/server/views/instance.erb +55 -75
  159. data/lib/arachni/ui/web/server/views/js/home.erb +32 -0
  160. data/lib/{ui → arachni/ui}/web/server/views/layout.erb +2 -2
  161. data/lib/{ui → arachni/ui}/web/server/views/log.erb +0 -0
  162. data/lib/arachni/ui/web/server/views/module.erb +30 -0
  163. data/lib/{ui → arachni/ui}/web/server/views/modules.erb +2 -22
  164. data/lib/{ui → arachni/ui}/web/server/views/options.erb +0 -0
  165. data/lib/{ui → arachni/ui}/web/server/views/output_results.erb +4 -4
  166. data/lib/{ui → arachni/ui}/web/server/views/plugins.erb +23 -12
  167. data/lib/{ui → arachni/ui}/web/server/views/report_formats.erb +1 -1
  168. data/lib/{ui → arachni/ui}/web/server/views/reports.erb +1 -1
  169. data/lib/{ui → arachni/ui}/web/server/views/settings.erb +59 -16
  170. data/lib/{ui → arachni/ui}/web/server/views/welcome.erb +3 -1
  171. data/lib/{ui → arachni/ui}/web/utilities.rb +8 -3
  172. data/lib/arachni/version.rb +16 -0
  173. data/modules/audit/code_injection.rb +11 -20
  174. data/modules/audit/code_injection_timing.rb +2 -6
  175. data/modules/audit/csrf.rb +8 -16
  176. data/modules/audit/ldapi.rb +5 -11
  177. data/modules/audit/os_cmd_injection.rb +5 -9
  178. data/modules/audit/os_cmd_injection_timing.rb +4 -8
  179. data/modules/audit/path_traversal.rb +7 -13
  180. data/modules/audit/response_splitting.rb +8 -21
  181. data/modules/audit/rfi.rb +6 -46
  182. data/modules/audit/sqli.rb +5 -11
  183. data/modules/audit/sqli/regexp_ids.txt +0 -6
  184. data/modules/audit/sqli_blind_rdiff.rb +5 -10
  185. data/modules/audit/sqli_blind_timing.rb +4 -9
  186. data/modules/audit/trainer.rb +6 -12
  187. data/modules/audit/unvalidated_redirect.rb +6 -17
  188. data/modules/audit/xpath.rb +5 -12
  189. data/modules/audit/xss.rb +37 -23
  190. data/modules/audit/xss_event.rb +5 -10
  191. data/modules/audit/xss_path.rb +47 -41
  192. data/modules/audit/xss_script_tag.rb +5 -10
  193. data/modules/audit/xss_tag.rb +5 -10
  194. data/modules/audit/xss_uri.rb +17 -89
  195. data/modules/recon/allowed_methods.rb +6 -15
  196. data/modules/recon/backdoors.rb +12 -52
  197. data/modules/recon/backup_files.rb +25 -88
  198. data/modules/recon/common_directories.rb +8 -54
  199. data/modules/recon/common_files.rb +7 -58
  200. data/modules/recon/directory_listing.rb +6 -15
  201. data/modules/recon/grep/captcha.rb +1 -1
  202. data/modules/recon/grep/credit_card.rb +62 -27
  203. data/modules/recon/grep/cvs_svn_users.rb +1 -1
  204. data/modules/recon/grep/emails.rb +1 -1
  205. data/modules/recon/grep/html_objects.rb +1 -1
  206. data/modules/recon/grep/private_ip.rb +1 -1
  207. data/modules/recon/grep/ssn.rb +9 -9
  208. data/modules/recon/htaccess_limit.rb +6 -14
  209. data/modules/recon/http_put.rb +7 -15
  210. data/modules/recon/interesting_responses.rb +7 -13
  211. data/modules/recon/mixed_resource.rb +100 -0
  212. data/modules/recon/unencrypted_password_forms.rb +8 -20
  213. data/modules/recon/webdav.rb +6 -16
  214. data/modules/recon/xst.rb +7 -13
  215. data/path_extractors/anchors.rb +1 -1
  216. data/path_extractors/forms.rb +1 -1
  217. data/path_extractors/frames.rb +1 -1
  218. data/path_extractors/generic.rb +47 -3
  219. data/path_extractors/links.rb +1 -1
  220. data/path_extractors/meta_refresh.rb +1 -1
  221. data/path_extractors/scripts.rb +3 -4
  222. data/path_extractors/sitemap.rb +1 -1
  223. data/plugins/autologin.rb +9 -18
  224. data/plugins/beep_notify.rb +51 -0
  225. data/plugins/cookie_collector.rb +12 -12
  226. data/plugins/defaults/autothrottle.rb +86 -0
  227. data/plugins/{content_types.rb → defaults/content_types.rb} +25 -19
  228. data/plugins/{healthmap.rb → defaults/healthmap.rb} +30 -18
  229. data/plugins/defaults/metamodules/remedies/discovery.rb +164 -0
  230. data/plugins/defaults/metamodules/remedies/manual_verification.rb +65 -0
  231. data/{metamodules/timeout_notice.rb → plugins/defaults/metamodules/remedies/timing_attacks.rb} +26 -22
  232. data/{metamodules → plugins/defaults/metamodules}/uniformity.rb +15 -14
  233. data/plugins/{profiler.rb → defaults/profiler.rb} +19 -30
  234. data/plugins/defaults/resolver.rb +55 -0
  235. data/plugins/email_notify.rb +108 -0
  236. data/plugins/form_dicattack.rb +8 -16
  237. data/plugins/http_dicattack.rb +4 -12
  238. data/plugins/libnotify.rb +86 -0
  239. data/plugins/proxy.rb +8 -17
  240. data/plugins/proxy/server.rb +3 -3
  241. data/plugins/rescan.rb +60 -0
  242. data/plugins/waf_detector.rb +5 -16
  243. data/profiles/full.afp +3 -30
  244. data/reports/afr.rb +2 -5
  245. data/reports/ap.rb +3 -1
  246. data/reports/html.rb +210 -68
  247. data/reports/html/default.erb +72 -1014
  248. data/reports/html/default/configuration.erb +126 -0
  249. data/reports/html/default/css/jquery-ui.css +570 -0
  250. data/reports/html/default/css/jquery.jqplot.min.css +1 -0
  251. data/reports/html/default/css/main.css +391 -0
  252. data/reports/html/default/issue.erb +189 -0
  253. data/reports/html/default/issues.erb +65 -0
  254. data/reports/html/default/js/charts.js +146 -0
  255. data/reports/html/default/js/helpers.js +95 -0
  256. data/reports/html/default/js/init.js +73 -0
  257. data/reports/html/default/js/lib/jqplot.barRenderer.min.js +57 -0
  258. data/reports/html/default/js/lib/jqplot.categoryAxisRenderer.min.js +57 -0
  259. data/reports/html/default/js/lib/jqplot.cursor.min.js +57 -0
  260. data/reports/html/default/js/lib/jqplot.pieRenderer.min.js +57 -0
  261. data/reports/html/default/js/lib/jqplot.pointLabels.min.js +57 -0
  262. data/reports/html/default/js/lib/jquery-ui.min.js +404 -0
  263. data/reports/html/default/js/lib/jquery.jqplot.min.js +57 -0
  264. data/reports/html/default/js/lib/jquery.min.js +167 -0
  265. data/reports/html/default/plugins.erb +22 -0
  266. data/reports/html/default/search.erb +8 -0
  267. data/reports/html/default/sitemap.erb +15 -0
  268. data/reports/html/default/summary.erb +68 -0
  269. data/reports/html/default/summary_issue.erb +19 -0
  270. data/reports/json.rb +51 -0
  271. data/reports/marshal.rb +49 -0
  272. data/reports/metareport.rb +4 -6
  273. data/reports/metareport/arachni_metareport.rb +1 -1
  274. data/reports/plugin_formatters/html/autologin.rb +30 -41
  275. data/reports/plugin_formatters/html/content_types.rb +1 -10
  276. data/reports/plugin_formatters/html/cookie_collector.rb +36 -44
  277. data/reports/plugin_formatters/html/discovery.rb +50 -0
  278. data/reports/plugin_formatters/html/form_dicattack.rb +24 -32
  279. data/reports/plugin_formatters/html/healthmap.rb +45 -54
  280. data/reports/plugin_formatters/html/http_dicattack.rb +24 -32
  281. data/reports/plugin_formatters/html/profiler.rb +17 -48
  282. data/reports/plugin_formatters/html/profiler/template.erb +6 -99
  283. data/reports/plugin_formatters/html/resolver.rb +63 -0
  284. data/reports/plugin_formatters/html/{metaformatters/timeout_notice.rb → timing_attacks.rb} +7 -19
  285. data/reports/plugin_formatters/html/{metaformatters/uniformity.rb → uniformity.rb} +5 -17
  286. data/reports/plugin_formatters/html/waf_detector.rb +24 -32
  287. data/reports/plugin_formatters/stdout/autologin.rb +30 -35
  288. data/reports/plugin_formatters/stdout/content_types.rb +41 -46
  289. data/reports/plugin_formatters/stdout/cookie_collector.rb +33 -38
  290. data/reports/plugin_formatters/stdout/discovery.rb +47 -0
  291. data/reports/plugin_formatters/stdout/form_dicattack.rb +27 -32
  292. data/reports/plugin_formatters/stdout/healthmap.rb +47 -51
  293. data/reports/plugin_formatters/stdout/http_dicattack.rb +27 -32
  294. data/reports/plugin_formatters/stdout/metamodules.rb +48 -55
  295. data/reports/plugin_formatters/stdout/profiler.rb +60 -65
  296. data/reports/plugin_formatters/stdout/resolver.rb +45 -0
  297. data/reports/plugin_formatters/stdout/{metaformatters/timeout_notice.rb → timing_attacks.rb} +6 -14
  298. data/reports/plugin_formatters/stdout/{metaformatters/uniformity.rb → uniformity.rb} +6 -14
  299. data/reports/plugin_formatters/stdout/waf_detector.rb +23 -28
  300. data/reports/plugin_formatters/xml/autologin.rb +36 -41
  301. data/reports/plugin_formatters/xml/content_types.rb +47 -52
  302. data/reports/plugin_formatters/xml/cookie_collector.rb +39 -44
  303. data/reports/plugin_formatters/xml/discovery.rb +54 -0
  304. data/reports/plugin_formatters/xml/form_dicattack.rb +22 -27
  305. data/reports/plugin_formatters/xml/healthmap.rb +53 -58
  306. data/reports/plugin_formatters/xml/http_dicattack.rb +22 -27
  307. data/reports/plugin_formatters/xml/profiler.rb +61 -77
  308. data/reports/plugin_formatters/xml/resolver.rb +53 -0
  309. data/reports/plugin_formatters/xml/{metaformatters/timeout_notice.rb → timing_attacks.rb} +3 -15
  310. data/reports/plugin_formatters/xml/{metaformatters/uniformity.rb → uniformity.rb} +4 -14
  311. data/reports/plugin_formatters/xml/waf_detector.rb +23 -28
  312. data/reports/stdout.rb +1 -1
  313. data/reports/txt.rb +2 -5
  314. data/reports/xml.rb +2 -5
  315. data/reports/xml/buffer.rb +6 -2
  316. data/reports/yaml.rb +49 -0
  317. metadata +419 -278
  318. data/bin/arachni_xmlrpc +0 -21
  319. data/bin/arachni_xmlrpcd +0 -82
  320. data/bin/arachni_xmlrpcd_monitor +0 -74
  321. data/getoptslong.rb +0 -242
  322. data/lib/anemone.rb +0 -2
  323. data/lib/framework.rb +0 -673
  324. data/lib/module/manager.rb +0 -111
  325. data/lib/options.rb +0 -547
  326. data/lib/rpc/xml/client/base.rb +0 -76
  327. data/lib/rpc/xml/client/instance.rb +0 -88
  328. data/lib/rpc/xml/server/base.rb +0 -112
  329. data/lib/rpc/xml/server/dispatcher.rb +0 -386
  330. data/lib/rpc/xml/server/framework.rb +0 -206
  331. data/lib/rpc/xml/server/instance.rb +0 -191
  332. data/lib/ruby/xmlrpc/server.rb +0 -27
  333. data/lib/ui/web/addons/autodeploy.rb +0 -172
  334. data/lib/ui/web/addons/autodeploy/views/index.erb +0 -124
  335. data/lib/ui/web/dispatcher_manager.rb +0 -165
  336. data/lib/ui/web/instance_manager.rb +0 -87
  337. data/lib/ui/web/output_stream.rb +0 -94
  338. data/lib/ui/web/server.rb +0 -925
  339. data/lib/ui/web/server/public/reports/placeholder +0 -1
  340. data/lib/ui/web/server/views/dispatchers.erb +0 -100
  341. data/lib/ui/web/server/views/dispatchers_edit.erb +0 -42
  342. data/lib/ui/web/server/views/error.erb +0 -1
  343. data/lib/ui/web/server/views/home.erb +0 -25
  344. data/metamodules/autothrottle.rb +0 -74
  345. data/plugins/metamodules.rb +0 -118
  346. data/profiles/comprehensive.afp +0 -74
  347. data/reports/plugin_formatters/html/metamodules.rb +0 -93
  348. data/reports/plugin_formatters/xml/metamodules.rb +0 -91
@@ -1,21 +0,0 @@
1
- #!/usr/bin/env ruby
2
- =begin
3
- Arachni
4
- Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
5
-
6
- This is free software; you can copy and distribute and modify
7
- this program under the term of the GPL v2.0 License
8
- (See LICENSE file for details)
9
-
10
- =end
11
-
12
- require 'pp'
13
- require 'ap'
14
-
15
- cwd = File.expand_path( File.dirname( __FILE__ ) )
16
- $:.unshift( cwd )
17
- require cwd + '/../getoptslong.rb'
18
- require Arachni::Options.instance.dir['lib'] + 'ui/xmlrpc/xmlrpc'
19
-
20
- client = Arachni::UI::XMLRPC.new( Arachni::Options.instance )
21
- client.run
@@ -1,82 +0,0 @@
1
- #!/usr/bin/env ruby
2
- =begin
3
- Arachni
4
- Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
5
-
6
- This is free software; you can copy and distribute and modify
7
- this program under the term of the GPL v2.0 License
8
- (See LICENSE file for details)
9
-
10
- =end
11
-
12
- require 'getoptlong'
13
- require 'pp'
14
- require 'ap'
15
-
16
- cwd = File.expand_path( File.dirname( __FILE__ ) )
17
- $:.unshift( cwd )
18
-
19
- require cwd + '/../lib/options'
20
- options = Arachni::Options.instance
21
-
22
- options.dir = Hash.new
23
- options.dir['root'] = File.expand_path( cwd + '/../' ) + '/'
24
- options.dir['modules'] = options.dir['root'] + 'modules/'
25
- options.dir['reports'] = options.dir['root'] + 'reports/'
26
- options.dir['plugins'] = options.dir['root'] + 'plugins/'
27
- options.dir['lib'] = options.dir['root'] + 'lib/'
28
-
29
- # Construct getops struct
30
- opts = GetoptLong.new(
31
- [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
32
- [ '--port', GetoptLong::OPTIONAL_ARGUMENT ],
33
- [ '--debug', GetoptLong::NO_ARGUMENT ],
34
- [ '--reroute-to-logfile', GetoptLong::NO_ARGUMENT ],
35
- [ '--pool-size', GetoptLong::REQUIRED_ARGUMENT ],
36
- [ '--ssl', GetoptLong::NO_ARGUMENT ],
37
- [ '--ssl-pkey', GetoptLong::REQUIRED_ARGUMENT ],
38
- [ '--ssl-cert', GetoptLong::REQUIRED_ARGUMENT ],
39
- [ '--ssl-ca', GetoptLong::REQUIRED_ARGUMENT ],
40
- )
41
-
42
- begin
43
- opts.each {
44
- |opt, arg|
45
-
46
- case opt
47
-
48
- when '--help'
49
- options.help = true
50
-
51
- when '--debug'
52
- options.debug = true
53
-
54
- when '--reroute-to-logfile'
55
- options.reroute_to_logfile = true
56
-
57
- when '--port'
58
- options.rpc_port = arg.to_i
59
-
60
- when '--pool-size'
61
- options.pool_size = arg.to_i
62
-
63
- when '--ssl'
64
- options.ssl = true
65
-
66
- when '--ssl-pkey'
67
- options.ssl_pkey = arg.to_s
68
-
69
- when '--ssl-cert'
70
- options.ssl_cert = arg.to_s
71
-
72
- when '--ssl-ca'
73
- options.ssl_ca = arg.to_s
74
-
75
- end
76
- }
77
- end
78
-
79
- require options.dir['lib'] + 'rpc/xml/server/dispatcher'
80
-
81
- dispatcher = Arachni::RPC::XML::Server::Dispatcher.new( Arachni::Options.instance )
82
- dispatcher.run
@@ -1,74 +0,0 @@
1
- #!/usr/bin/env ruby
2
- =begin
3
- Arachni
4
- Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
5
-
6
- This is free software; you can copy and distribute and modify
7
- this program under the term of the GPL v2.0 License
8
- (See LICENSE file for details)
9
-
10
- =end
11
-
12
- require 'getoptlong'
13
- require 'pp'
14
- require 'ap'
15
-
16
- cwd = File.expand_path( File.dirname( __FILE__ ) )
17
- $:.unshift( cwd )
18
-
19
- require cwd + '/../lib/options'
20
- options = Arachni::Options.instance
21
-
22
- options.dir = Hash.new
23
- options.dir['root'] = File.expand_path( cwd + '/../' ) + '/'
24
- options.dir['modules'] = options.dir['root'] + 'modules/'
25
- options.dir['reports'] = options.dir['root'] + 'reports/'
26
- options.dir['plugins'] = options.dir['root'] + 'plugins/'
27
- options.dir['lib'] = options.dir['root'] + 'lib/'
28
-
29
- # Construct getops struct
30
- opts = GetoptLong.new(
31
- [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
32
- [ '--port', GetoptLong::OPTIONAL_ARGUMENT ],
33
- [ '--debug', GetoptLong::NO_ARGUMENT ],
34
- [ '--reroute-to-logfile', GetoptLong::NO_ARGUMENT ],
35
- [ '--ssl', GetoptLong::NO_ARGUMENT ],
36
- [ '--ssl-pkey', GetoptLong::REQUIRED_ARGUMENT ],
37
- [ '--ssl-cert', GetoptLong::REQUIRED_ARGUMENT ],
38
- [ '--ssl-ca', GetoptLong::REQUIRED_ARGUMENT ],
39
- )
40
-
41
- begin
42
- opts.each {
43
- |opt, arg|
44
-
45
- case opt
46
-
47
- when '--help'
48
- options.help = true
49
-
50
- when '--debug'
51
- options.debug = true
52
-
53
- when '--ssl'
54
- options.ssl = true
55
-
56
- when '--ssl-pkey'
57
- options.ssl_pkey = arg.to_s
58
-
59
- when '--ssl-cert'
60
- options.ssl_cert = arg.to_s
61
-
62
- when '--ssl-ca'
63
- options.ssl_ca = arg.to_s
64
-
65
- end
66
- }
67
- end
68
-
69
- options.url = ARGV.shift
70
-
71
- require options.dir['lib'] + 'ui/xmlrpc/dispatcher_monitor'
72
-
73
- dispatcher = Arachni::UI::DispatcherMonitor.new( Arachni::Options.instance )
74
- dispatcher.run
@@ -1,242 +0,0 @@
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 'getoptlong'
12
-
13
- # Construct getops struct
14
- opts = GetoptLong.new(
15
- [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
16
- [ '--verbosity', '-v', GetoptLong::NO_ARGUMENT ],
17
- [ '--only-positives', '-k', GetoptLong::NO_ARGUMENT ],
18
- [ '--lsmod', GetoptLong::OPTIONAL_ARGUMENT ],
19
- [ '--lsrep', GetoptLong::OPTIONAL_ARGUMENT ],
20
- [ '--audit-links', '-g', GetoptLong::NO_ARGUMENT ],
21
- [ '--audit-forms', '-p', GetoptLong::NO_ARGUMENT ],
22
- [ '--audit-cookies', '-c', GetoptLong::NO_ARGUMENT ],
23
- [ '--audit-cookie-jar', GetoptLong::NO_ARGUMENT ],
24
- [ '--audit-headers', GetoptLong::NO_ARGUMENT ],
25
- [ '--spider-first', GetoptLong::NO_ARGUMENT ],
26
- [ '--obey-robots-txt', '-o', GetoptLong::NO_ARGUMENT ],
27
- [ '--redundant', GetoptLong::REQUIRED_ARGUMENT ],
28
- [ '--depth', '-d', GetoptLong::REQUIRED_ARGUMENT ],
29
- [ '--redirect-limit', '-q', GetoptLong::REQUIRED_ARGUMENT ],
30
- [ '--link-count', '-u', GetoptLong::REQUIRED_ARGUMENT ],
31
- [ '--mods', '-m', GetoptLong::REQUIRED_ARGUMENT ],
32
- [ '--report', GetoptLong::REQUIRED_ARGUMENT ],
33
- [ '--repload', GetoptLong::REQUIRED_ARGUMENT ],
34
- [ '--authed-by', GetoptLong::REQUIRED_ARGUMENT ],
35
- [ '--load-profile', GetoptLong::REQUIRED_ARGUMENT ],
36
- [ '--save-profile', GetoptLong::REQUIRED_ARGUMENT ],
37
- [ '--show-profile', GetoptLong::NO_ARGUMENT ],
38
- [ '--proxy', '-z', GetoptLong::REQUIRED_ARGUMENT ],
39
- [ '--proxy-auth', '-x', GetoptLong::REQUIRED_ARGUMENT ],
40
- [ '--proxy-type', '-y', GetoptLong::REQUIRED_ARGUMENT ],
41
- [ '--cookie-jar', '-j', GetoptLong::REQUIRED_ARGUMENT ],
42
- [ '--user-agent', '-b', GetoptLong::REQUIRED_ARGUMENT ],
43
- [ '--exclude', '-e', GetoptLong::REQUIRED_ARGUMENT ],
44
- [ '--include', '-i', GetoptLong::REQUIRED_ARGUMENT ],
45
- [ '--exclude-cookie', GetoptLong::REQUIRED_ARGUMENT ],
46
- [ '--http-req-limit', GetoptLong::REQUIRED_ARGUMENT ],
47
- [ '--follow-subdomains', '-f', GetoptLong::NO_ARGUMENT ],
48
- [ '--http-harvest-last', '-s', GetoptLong::NO_ARGUMENT ],
49
- [ '--debug', '-w', GetoptLong::NO_ARGUMENT ],
50
- [ '--server', GetoptLong::REQUIRED_ARGUMENT ],
51
- [ '--plugin', GetoptLong::OPTIONAL_ARGUMENT ],
52
- [ '--lsplug', GetoptLong::OPTIONAL_ARGUMENT ],
53
- [ '--ssl', GetoptLong::NO_ARGUMENT ],
54
- [ '--ssl-pkey', GetoptLong::REQUIRED_ARGUMENT ],
55
- [ '--ssl-cert', GetoptLong::REQUIRED_ARGUMENT ],
56
- [ '--ssl-ca', GetoptLong::REQUIRED_ARGUMENT ],
57
- )
58
-
59
- $:.unshift( File.expand_path( File.dirname( __FILE__ ) ) )
60
-
61
- require 'lib/options'
62
- options = Arachni::Options.instance
63
-
64
- options.dir = Hash.new
65
- options.dir['root'] = File.dirname( File.expand_path(__FILE__) ) + '/'
66
- options.dir['data'] = options.dir['root'] + 'data/'
67
- options.dir['modules'] = options.dir['root'] + 'modules/'
68
- options.dir['reports'] = options.dir['root'] + 'reports/'
69
- options.dir['plugins'] = options.dir['root'] + 'plugins/'
70
- options.dir['lib'] = options.dir['root'] + 'lib/'
71
-
72
- opts.quiet = true
73
-
74
- begin
75
- opts.each {
76
- |opt, arg|
77
-
78
- case opt
79
-
80
- when '--help'
81
- options.help = true
82
-
83
- when '--only-positives'
84
- options.only_positives = true
85
-
86
- when '--verbosity'
87
- options.arachni_verbose = true
88
-
89
- when '--debug'
90
- options.debug = true
91
-
92
- when '--spider-first'
93
- options.spider_first = true
94
-
95
- when '--plugin'
96
- plugin, opt_str = arg.split( ':', 2 )
97
-
98
- opts = {}
99
- if( opt_str )
100
- opt_arr = opt_str.split( ',' )
101
- opt_arr.each {
102
- |opt|
103
- name, val = opt.split( '=', 2 )
104
- opts[name] = val
105
- }
106
- end
107
-
108
- options.plugins[plugin] = opts
109
-
110
- when '--redundant'
111
- options.redundant << {
112
- 'regexp' => Regexp.new( arg.to_s.split( /:/ )[0] ),
113
- 'count' => Integer( arg.to_s.split( /:/ )[1] ),
114
- }
115
-
116
- when '--obey_robots_txt'
117
- options.obey_robots_txt = true
118
-
119
- when '--depth'
120
- options.depth_limit = arg.to_i
121
-
122
- when '--link-count'
123
- options.link_count_limit = arg.to_i
124
-
125
- when '--redirect-limit'
126
- options.redirect_limit = arg.to_i
127
-
128
- when '--lsmod'
129
- options.lsmod << Regexp.new( arg.to_s )
130
-
131
- when '--lsplug'
132
- options.lsplug << Regexp.new( arg.to_s )
133
-
134
- when '--lsrep'
135
- options.lsrep << Regexp.new( arg.to_s )
136
-
137
- when '--http-req-limit'
138
- options.http_req_limit = arg.to_i
139
-
140
- when '--audit-links'
141
- options.audit_links = true
142
-
143
- when '--audit-forms'
144
- options.audit_forms = true
145
-
146
- when '--audit-cookies'
147
- options.audit_cookies = true
148
-
149
- when '--audit-cookie-jar'
150
- options.audit_cookie_jar = true
151
-
152
- when '--audit-headers'
153
- options.audit_headers = true
154
-
155
- when '--mods'
156
- options.mods = arg.to_s.split( /,/ )
157
-
158
- when '--report'
159
- report, opt_str = arg.split( ':' )
160
-
161
- opts = {}
162
- if( opt_str )
163
- opt_arr = opt_str.split( ',' )
164
- opt_arr.each {
165
- |opt|
166
- name, val = opt.split( '=' )
167
- opts[name] = val
168
- }
169
- end
170
-
171
- options.reports[report] = opts
172
-
173
- when '--repload'
174
- options.repload = arg
175
-
176
- when '--save-profile'
177
- options.save_profile = arg
178
-
179
- when '--load-profile'
180
- options.load_profile << arg
181
-
182
- when '--show-profile'
183
- options.show_profile = true
184
-
185
- when '--authed-by'
186
- options.authed_by = arg
187
-
188
- when '--proxy'
189
- options.proxy_addr, options.proxy_port =
190
- arg.to_s.split( /:/ )
191
-
192
- when '--proxy-auth'
193
- options.proxy_user, options.proxy_pass =
194
- arg.to_s.split( /:/ )
195
-
196
- when '--proxy-type'
197
- options.proxy_type = arg.to_s
198
-
199
- when '--cookie-jar'
200
- options.cookie_jar = arg.to_s
201
-
202
- when '--user-agent'
203
- options.user_agent = arg.to_s
204
-
205
- when '--exclude'
206
- options.exclude << Regexp.new( arg )
207
-
208
- when '--include'
209
- options.include << Regexp.new( arg )
210
-
211
- when '--exclude-cookie'
212
- options.exclude_cookies << arg
213
-
214
- when '--follow-subdomains'
215
- options.follow_subdomains = true
216
-
217
- when '--http-harvest-last'
218
- options.http_harvest_last = true
219
-
220
- when '--ssl'
221
- options.ssl = true
222
-
223
- when '--ssl-pkey'
224
- options.ssl_pkey = arg.to_s
225
-
226
- when '--ssl-cert'
227
- options.ssl_cert = arg.to_s
228
-
229
- when '--ssl-ca'
230
- options.ssl_ca = arg.to_s
231
-
232
- when '--server'
233
- options.server = arg.to_s
234
-
235
- end
236
- }
237
- rescue Exception => e
238
- puts e.inspect
239
- exit
240
- end
241
-
242
- options.url = ARGV.shift
@@ -1,2 +0,0 @@
1
- opts = Arachni::Options.instance
2
- require opts.dir['lib'] + 'anemone/core'
@@ -1,673 +0,0 @@
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
-
12
- require 'rubygems'
13
-
14
- require File.expand_path( File.dirname( __FILE__ ) ) + '/options'
15
- opts = Arachni::Options.instance
16
-
17
- require opts.dir['lib'] + 'arachni'
18
- require opts.dir['lib'] + 'ruby'
19
- require opts.dir['lib'] + 'exceptions'
20
- require opts.dir['lib'] + 'spider'
21
- require opts.dir['lib'] + 'parser'
22
- require opts.dir['lib'] + 'audit_store'
23
- require opts.dir['lib'] + 'module'
24
- require opts.dir['lib'] + 'plugin'
25
- require opts.dir['lib'] + 'http'
26
- require opts.dir['lib'] + 'report'
27
- require opts.dir['lib'] + 'component_manager'
28
- require 'yaml'
29
- require 'ap'
30
- require 'pp'
31
-
32
-
33
- module Arachni
34
-
35
- #
36
- # Resets the Framework providing a clean slate.
37
- #
38
- # This is useful to user interfaces that require the framework to be reused.
39
- #
40
- def self.reset
41
- Element::Auditable.reset
42
- Module::Manager.reset
43
- Report::Manager.reset
44
- Arachni::HTTP.instance.reset
45
- end
46
-
47
- #
48
- # Arachni::Framework class
49
- #
50
- # The Framework class ties together all the components.<br/>
51
- # It should be wrapped by a UI class.
52
- #
53
- # It's the brains of the operation, it bosses the rest of the classes around.<br/>
54
- # It runs the audit, loads modules and reports and runs them according to
55
- # user options.
56
- #
57
- # @author: Tasos "Zapotek" Laskos
58
- # <tasos.laskos@gmail.com>
59
- # <zapotek@segfault.gr>
60
- # @version: 0.2.3
61
- #
62
- class Framework
63
-
64
- #
65
- # include the output interface but try to use it as little as possible
66
- #
67
- # the UI classes should take care of communicating with the user
68
- #
69
- include Arachni::UI::Output
70
- include Arachni::Module::Utilities
71
- include Arachni::Mixins::Observable
72
-
73
- # the version of *this* class
74
- REVISION = '0.2.3'
75
-
76
- #
77
- # Instance options
78
- #
79
- # @return [Options]
80
- #
81
- attr_reader :opts
82
-
83
- #
84
- # @return [Arachni::Report::Manager] report manager
85
- #
86
- attr_reader :reports
87
-
88
- #
89
- # @return [Arachni::Module::Manager] module manager
90
- #
91
- attr_reader :modules
92
-
93
- #
94
- # @return [Arachni::Plugin::Manager] plugin manager
95
- #
96
- attr_reader :plugins
97
-
98
- #
99
- # @return [Arachni::Spider] spider
100
- #
101
- attr_reader :spider
102
-
103
- #
104
- # @return [Arachni::HTTP]
105
- #
106
- attr_reader :http
107
-
108
- attr_reader :sitemap
109
- attr_reader :auditmap
110
-
111
- #
112
- # Holds candidate pages to be audited.
113
- #
114
- # Pages in the queue are pushed in by the trainer, the queue doesn't hold
115
- # pages returned by the spider.
116
- #
117
- # Plug-ins can push their own pages to be audited if they wish to...
118
- #
119
- # @return [Queue<Arachni::Parser::Page>] page queue
120
- #
121
- attr_reader :page_queue
122
-
123
-
124
- #
125
- # Initializes system components.
126
- #
127
- # @param [Options] opts
128
- #
129
- def initialize( opts )
130
-
131
- Encoding.default_external = "BINARY"
132
- Encoding.default_internal = "BINARY"
133
-
134
- @opts = opts
135
-
136
- @modules = Arachni::Module::Manager.new( @opts )
137
- @reports = Arachni::Report::Manager.new( @opts )
138
- @plugins = Arachni::Plugin::Manager.new( self )
139
-
140
- @page_queue = Queue.new
141
-
142
- prepare_cookie_jar( )
143
- prepare_user_agent( )
144
-
145
- # deep clone the redundancy rules to preserve their counter
146
- # for the reports
147
- @orig_redundant = @opts.redundant.deep_clone
148
-
149
- @running = false
150
- @paused = []
151
-
152
- @plugin_store = {}
153
-
154
- @current_url = ''
155
- end
156
-
157
- def http
158
- Arachni::HTTP.instance
159
- end
160
-
161
- #
162
- # Runs the system
163
- #
164
- # It parses the instanse options and runs the audit
165
- #
166
- # @param [Block] &block a block to call after the audit has finished
167
- # but before running the reports
168
- #
169
- def run( &block )
170
- @running = true
171
-
172
- @opts.start_datetime = Time.now
173
-
174
- # run all plugins
175
- @plugins.run
176
-
177
- # catch exceptions so that if something breaks down or the user opted to
178
- # exit the reports will still run with whatever results
179
- # Arachni managed to gather
180
- begin
181
- # start the audit
182
- audit( )
183
- rescue Exception
184
- end
185
-
186
- clean_up!
187
- begin
188
- block.call if block
189
- rescue Exception
190
- end
191
-
192
- # run reports
193
- if( @opts.reports && !@opts.reports.empty? )
194
- exception_jail{ @reports.run( audit_store( ) ) }
195
- end
196
-
197
- return true
198
- end
199
-
200
- def stats( refresh_time = false )
201
- req_cnt = http.request_count
202
- res_cnt = http.response_count
203
-
204
- @auditmap ||= []
205
- @sitemap ||= []
206
- if !refresh_time || @auditmap.size == @sitemap.size
207
- @opts.delta_time ||= Time.now - @opts.start_datetime
208
- else
209
- @opts.delta_time = Time.now - @opts.start_datetime
210
- end
211
-
212
- curr_avg = 0
213
- if http.curr_res_cnt > 0 && http.curr_res_time > 0
214
- curr_avg = (http.curr_res_cnt / http.curr_res_time).to_i.to_s
215
- end
216
-
217
- avg = 0
218
- if res_cnt > 0
219
- avg = ( res_cnt / @opts.delta_time ).to_i.to_s
220
- end
221
-
222
- progress = (Float( @auditmap.size ) / @sitemap.size) * 100
223
-
224
- if Arachni::Module::Auditor.timeout_loaded_modules.size > 0 &&
225
- Arachni::Module::Auditor.timeout_audit_blocks.size > 0
226
-
227
- progress /= 2
228
- progress += ( Float( Arachni::Module::Auditor.timeout_loaded_modules.size ) /
229
- Arachni::Module::Auditor.timeout_audit_blocks.size ) * 50
230
- end
231
-
232
- return {
233
- :requests => req_cnt,
234
- :responses => res_cnt,
235
- :time_out_count => http.time_out_count,
236
- :time => audit_store.delta_time,
237
- :avg => avg,
238
- :sitemap_size => @sitemap.size,
239
- :auditmap_size => @auditmap.size,
240
- :progress => progress.to_s[0...5],
241
- :curr_res_time => http.curr_res_time,
242
- :curr_res_cnt => http.curr_res_cnt,
243
- :curr_avg => curr_avg,
244
- :average_res_time => http.average_res_time,
245
- :max_concurrency => http.max_concurrency,
246
- :current_page => @current_url
247
- }
248
- end
249
-
250
- #
251
- # Audits the site.
252
- #
253
- # Runs the spider, analyzes each page as it appears and passes it
254
- # to (#run_mods} to be audited.
255
- #
256
- def audit
257
-
258
- wait_if_paused
259
-
260
- @spider = Arachni::Spider.new( @opts )
261
-
262
- @sitemap ||= []
263
- @auditmap ||= []
264
-
265
- # initiates the crawl
266
- @spider.run {
267
- |page|
268
-
269
- @sitemap |= @spider.sitemap
270
-
271
- @page_queue << page
272
- audit_queue if !@opts.spider_first
273
- }
274
-
275
- exception_jail {
276
- if !Arachni::Module::Auditor.timeout_audit_blocks.empty?
277
- print_line
278
- print_status( 'Running timing attacks.' )
279
- print_info( '---------------------------------------' )
280
- Arachni::Module::Auditor.timeout_audit_run
281
- end
282
- }
283
-
284
- audit_queue
285
-
286
- if( @opts.http_harvest_last )
287
- harvest_http_responses( )
288
- end
289
-
290
- end
291
-
292
- def audit_queue
293
-
294
- # this will run until no new elements appear for the given page
295
- while( !@page_queue.empty? && page = @page_queue.pop )
296
-
297
- # audit the page
298
- exception_jail{ run_mods( page ) }
299
-
300
- # run all the queued HTTP requests and harvest the responses
301
- http.run
302
-
303
- # check to see if the page was updated
304
- page = http.trainer.page
305
- # and push it in the queue to be audited as well
306
- @page_queue << page if page
307
-
308
- end
309
- end
310
-
311
-
312
- #
313
- # Returns the results of the audit as an {AuditStore} instance
314
- #
315
- # @see AuditStore
316
- #
317
- # @return [AuditStore]
318
- #
319
- def audit_store( fresh = false )
320
-
321
- # restore the original redundacy rules and their counters
322
- @opts.redundant = @orig_redundant
323
- opts = @opts.to_h
324
- opts['mods'] = @modules.keys
325
-
326
- if( !fresh && @store )
327
- return @store
328
- else
329
- return @store = AuditStore.new( {
330
- :version => version( ),
331
- :revision => REVISION,
332
- :options => opts,
333
- :sitemap => @sitemap ? @sitemap.sort : ['N/A'],
334
- :issues => @modules.results( ).deep_clone,
335
- :plugins => @plugin_store
336
- }, self )
337
- end
338
- end
339
-
340
- def plugin_store( plugin, obj )
341
- name = ''
342
- @plugins.each_pair {
343
- |k, v|
344
-
345
- if plugin.class.name == v.name
346
- name = k
347
- break
348
- end
349
- }
350
-
351
- return if @plugin_store[name]
352
-
353
- @plugin_store[name] = {
354
- :results => obj
355
- }.merge( plugin.class.info )
356
- end
357
-
358
- #
359
- # Returns an array of hashes with information
360
- # about all available modules
361
- #
362
- # @return [Array<Hash>]
363
- #
364
- def lsmod
365
-
366
- mod_info = []
367
- @modules.available( ).each {
368
- |name|
369
-
370
- path = @modules.name_to_path( name )
371
- next if !lsmod_match?( path )
372
-
373
- info = @modules[name].info( )
374
-
375
- info[:mod_name] = name
376
- info[:name] = info[:name].strip
377
- info[:description] = info[:description].strip
378
-
379
- if( !info[:dependencies] )
380
- info[:dependencies] = []
381
- end
382
-
383
- info[:author] = info[:author].strip
384
- info[:version] = info[:version].strip
385
- info[:path] = path.strip
386
-
387
- mod_info << info
388
- }
389
-
390
- # unload all modules
391
- @modules.clear( )
392
-
393
- return mod_info
394
-
395
- end
396
-
397
- #
398
- # Returns an array of hashes with information
399
- # about all available reports
400
- #
401
- # @return [Array<Hash>]
402
- #
403
- def lsrep
404
-
405
- rep_info = []
406
- @reports.available( ).each {
407
- |report|
408
-
409
- info = @reports[report].info
410
-
411
- info[:rep_name] = report
412
- info[:path] = @reports.name_to_path( report )
413
-
414
- rep_info << info
415
- }
416
- @reports.clear( )
417
-
418
- return rep_info
419
- end
420
-
421
- #
422
- # Returns an array of hashes with information
423
- # about all available reports
424
- #
425
- # @return [Array<Hash>]
426
- #
427
- def lsplug
428
-
429
- plug_info = []
430
-
431
- @plugins.available( ).each {
432
- |plugin|
433
-
434
- info = @plugins[plugin].info
435
-
436
- info[:plug_name] = plugin
437
- info[:path] = @plugins.name_to_path( plugin )
438
-
439
- plug_info << info
440
- }
441
-
442
- @plugins.clear( )
443
-
444
- return plug_info
445
- end
446
-
447
- def running?
448
- @running
449
- end
450
-
451
- def paused?
452
- !@paused.empty?
453
- end
454
-
455
- def pause!
456
- @spider.pause! if @spider
457
- @paused << caller
458
- return true
459
- end
460
-
461
- def resume!
462
- @paused.delete( caller )
463
- @spider.resume! if @spider
464
- return true
465
- end
466
-
467
- #
468
- # Returns the version of the framework
469
- #
470
- # @return [String]
471
- #
472
- def version
473
- Arachni::VERSION
474
- end
475
-
476
- #
477
- # Returns the revision of the {Framework} (this) class
478
- #
479
- # @return [String]
480
- #
481
- def revision
482
- REVISION
483
- end
484
-
485
- private
486
-
487
- def clean_up!( skip_audit_queue = false )
488
- @opts.finish_datetime = Time.now
489
- @opts.delta_time = @opts.finish_datetime - @opts.start_datetime
490
-
491
- # make sure this is disabled or it'll break report output
492
- @@only_positives = false
493
-
494
- @running = false
495
-
496
- # wait for the plugins to finish
497
- @plugins.block!
498
-
499
- # a plug-in may have updated the page queue, rock it!
500
- audit_queue if !skip_audit_queue
501
-
502
- # refresh the audit store
503
- audit_store( true )
504
-
505
- return true
506
- end
507
-
508
- def caller
509
- if /^(.+?):(\d+)(?::in `(.*)')?/ =~ ::Kernel.caller[1]
510
- return Regexp.last_match[1]
511
- end
512
- end
513
-
514
- def wait_if_paused
515
- while( paused? )
516
- ::IO::select( nil, nil, nil, 1 )
517
- end
518
- end
519
-
520
-
521
- #
522
- # Prepares the user agent to be used throughout the system.
523
- #
524
- def prepare_user_agent
525
- if( !@opts.user_agent )
526
- @opts.user_agent = 'Arachni/' + version( )
527
- end
528
-
529
- if( @opts.authed_by )
530
- authed_by = " (Scan authorized by: #{@opts.authed_by})"
531
- @opts.user_agent += authed_by
532
- end
533
-
534
- end
535
-
536
- def prepare_cookie_jar( )
537
- return if !@opts.cookie_jar || !@opts.cookie_jar.is_a?( String )
538
-
539
- # make sure that the provided cookie-jar file exists
540
- if !File.exist?( @opts.cookie_jar )
541
- raise( Arachni::Exceptions::NoCookieJar,
542
- 'Cookie-jar \'' + @opts.cookie_jar + '\' doesn\'t exist.' )
543
- end
544
-
545
- end
546
-
547
-
548
- #
549
- # Takes care of page audit and module execution
550
- #
551
- # It will audit one page at a time as discovered by the spider <br/>
552
- # and recursively check for new elements that may have <br/>
553
- # appeared during the audit.
554
- #
555
- # When no new elements appear the recursion will stop and a new page<br/>
556
- # will be accepted.
557
- #
558
- # @see Page
559
- #
560
- # @param [Page] page
561
- #
562
- def run_mods( page )
563
- return if !page
564
-
565
- call_on_run_mods( page.deep_clone )
566
-
567
- @current_url = page.url.to_s
568
-
569
- @modules.each_pair {
570
- |name, mod|
571
-
572
- wait_if_paused
573
- run_mod( mod, page.deep_clone )
574
- }
575
-
576
- @auditmap << page.url
577
- @auditmap.uniq!
578
- @sitemap |= @auditmap
579
- @sitemap.uniq!
580
-
581
-
582
- if( !@opts.http_harvest_last )
583
- harvest_http_responses( )
584
- end
585
-
586
- end
587
-
588
- def harvest_http_responses
589
-
590
- print_status( 'Harvesting HTTP responses...' )
591
- print_info( 'Depending on server responsiveness and network' +
592
- ' conditions this may take a while.' )
593
-
594
- # run all the queued HTTP requests and harvest the responses
595
- http.run
596
-
597
- # try to get an updated page from the Trainer
598
- page = http.trainer.page
599
-
600
- # if there was an updated page push it in the queue
601
- @page_queue << page if page
602
- audit_queue
603
- end
604
-
605
- #
606
- # Passes a page to the module and runs it.<br/>
607
- # It also handles any exceptions thrown by the module at runtime.
608
- #
609
- # @see Page
610
- #
611
- # @param [Class] mod the module to run
612
- # @param [Page] page
613
- #
614
- def run_mod( mod, page )
615
- return if !run_mod?( mod, page )
616
-
617
- begin
618
-
619
- # instantiate the module
620
- mod_new = mod.new( page )
621
- mod_new.set_framework( self )
622
-
623
- mod_new.prepare
624
- mod_new.run
625
- mod_new.clean_up
626
- rescue SystemExit
627
- raise
628
- rescue Exception => e
629
- print_error( 'Error in ' + mod.to_s + ': ' + e.to_s )
630
- print_debug_backtrace( e )
631
- end
632
- end
633
-
634
- #
635
- # Determines whether or not to run the module against the given page
636
- # depending on which elements exist in the page, which elements the module
637
- # is configured to audit and user options.
638
- #
639
- # @param [Class] mod the module to run
640
- # @param [Page] page
641
- #
642
- # @return [Bool]
643
- #
644
- def run_mod?( mod, page )
645
- return true if( !mod.info[:elements] || mod.info[:elements].empty? )
646
-
647
- elems = {
648
- Issue::Element::LINK => page.links && page.links.size > 0 && @opts.audit_links,
649
- Issue::Element::FORM => page.forms && page.forms.size > 0 && @opts.audit_forms,
650
- Issue::Element::COOKIE => page.cookies && page.cookies.size > 0 && @opts.audit_cookies,
651
- Issue::Element::HEADER => page.headers && page.headers.size > 0 && @opts.audit_headers,
652
- }
653
-
654
- elems.each_pair {
655
- |elem, expr|
656
- return true if mod.info[:elements].include?( elem ) && expr
657
- }
658
-
659
- return false
660
- end
661
-
662
- def lsmod_match?( path )
663
- cnt = 0
664
- @opts.lsmod.each {
665
- |filter|
666
- cnt += 1 if path =~ filter
667
- }
668
- return true if cnt == @opts.lsmod.size
669
- end
670
-
671
- end
672
-
673
- end