librex 0.0.68 → 0.0.70

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 (528) hide show
  1. checksums.yaml +15 -0
  2. data/README.markdown +1 -1
  3. data/Rakefile +18 -16
  4. data/lib/rex.rb +14 -10
  5. data/lib/rex/LICENSE +2 -2
  6. data/lib/rex/arch.rb +76 -76
  7. data/lib/rex/arch/sparc.rb +57 -58
  8. data/lib/rex/arch/x86.rb +506 -496
  9. data/lib/rex/assembly/nasm.rb +83 -84
  10. data/lib/rex/compat.rb +228 -173
  11. data/lib/rex/constants.rb +47 -37
  12. data/lib/rex/elfparsey.rb +0 -3
  13. data/lib/rex/elfparsey/elf.rb +107 -110
  14. data/lib/rex/elfparsey/elfbase.rb +244 -247
  15. data/lib/rex/elfparsey/exceptions.rb +0 -3
  16. data/lib/rex/elfscan.rb +0 -3
  17. data/lib/rex/elfscan/scanner.rb +184 -166
  18. data/lib/rex/elfscan/search.rb +35 -38
  19. data/lib/rex/encoder/alpha2.rb +1 -2
  20. data/lib/rex/encoder/alpha2/alpha_mixed.rb +52 -53
  21. data/lib/rex/encoder/alpha2/alpha_upper.rb +62 -63
  22. data/lib/rex/encoder/alpha2/generic.rb +77 -78
  23. data/lib/rex/encoder/alpha2/unicode_mixed.rb +101 -97
  24. data/lib/rex/encoder/alpha2/unicode_upper.rb +106 -107
  25. data/lib/rex/encoder/bloxor/bloxor.rb +326 -0
  26. data/lib/rex/encoder/ndr.rb +68 -68
  27. data/lib/rex/encoder/nonalpha.rb +50 -51
  28. data/lib/rex/encoder/nonupper.rb +50 -51
  29. data/lib/rex/encoder/xdr.rb +78 -78
  30. data/lib/rex/encoder/xor.rb +52 -53
  31. data/lib/rex/encoder/xor/dword.rb +1 -2
  32. data/lib/rex/encoder/xor/dword_additive.rb +1 -2
  33. data/lib/rex/encoders/xor_dword.rb +17 -18
  34. data/lib/rex/encoders/xor_dword_additive.rb +35 -36
  35. data/lib/rex/encoding/xor.rb +0 -1
  36. data/lib/rex/encoding/xor/byte.rb +3 -4
  37. data/lib/rex/encoding/xor/dword.rb +3 -4
  38. data/lib/rex/encoding/xor/dword_additive.rb +72 -73
  39. data/lib/rex/encoding/xor/exceptions.rb +2 -3
  40. data/lib/rex/encoding/xor/generic.rb +129 -130
  41. data/lib/rex/encoding/xor/qword.rb +3 -4
  42. data/lib/rex/encoding/xor/word.rb +3 -4
  43. data/lib/rex/exceptions.rb +100 -101
  44. data/lib/rex/exploitation/cmdstager.rb +3 -3
  45. data/lib/rex/exploitation/cmdstager/base.rb +170 -156
  46. data/lib/rex/exploitation/cmdstager/bourne.rb +105 -0
  47. data/lib/rex/exploitation/cmdstager/debug_asm.rb +110 -113
  48. data/lib/rex/exploitation/cmdstager/debug_write.rb +106 -109
  49. data/lib/rex/exploitation/cmdstager/echo.rb +164 -0
  50. data/lib/rex/exploitation/cmdstager/printf.rb +122 -0
  51. data/lib/rex/exploitation/cmdstager/tftp.rb +34 -27
  52. data/lib/rex/exploitation/cmdstager/vbs.rb +95 -98
  53. data/lib/rex/exploitation/egghunter.rb +359 -346
  54. data/lib/rex/exploitation/encryptjs.rb +60 -60
  55. data/lib/rex/exploitation/heaplib.rb +76 -76
  56. data/lib/rex/exploitation/js.rb +6 -0
  57. data/lib/rex/exploitation/js/detect.rb +69 -0
  58. data/lib/rex/exploitation/js/memory.rb +81 -0
  59. data/lib/rex/exploitation/js/network.rb +84 -0
  60. data/lib/rex/exploitation/js/utils.rb +33 -0
  61. data/lib/rex/exploitation/jsobfu.rb +448 -424
  62. data/lib/rex/exploitation/obfuscatejs.rb +301 -301
  63. data/lib/rex/exploitation/omelet.rb +257 -257
  64. data/lib/rex/exploitation/opcodedb.rb +699 -699
  65. data/lib/rex/exploitation/ropdb.rb +189 -0
  66. data/lib/rex/exploitation/seh.rb +68 -68
  67. data/lib/rex/file.rb +96 -49
  68. data/lib/rex/image_source.rb +0 -3
  69. data/lib/rex/image_source/disk.rb +45 -48
  70. data/lib/rex/image_source/image_source.rb +33 -36
  71. data/lib/rex/image_source/memory.rb +17 -20
  72. data/lib/rex/io/bidirectional_pipe.rb +118 -115
  73. data/lib/rex/io/datagram_abstraction.rb +13 -14
  74. data/lib/rex/io/ring_buffer.rb +273 -273
  75. data/lib/rex/io/stream.rb +284 -284
  76. data/lib/rex/io/stream_abstraction.rb +183 -181
  77. data/lib/rex/io/stream_server.rb +193 -193
  78. data/lib/rex/job_container.rb +167 -167
  79. data/lib/rex/logging.rb +0 -1
  80. data/lib/rex/logging/log_dispatcher.rb +113 -113
  81. data/lib/rex/logging/log_sink.rb +17 -17
  82. data/lib/rex/logging/sinks/flatfile.rb +36 -36
  83. data/lib/rex/logging/sinks/stderr.rb +27 -27
  84. data/lib/rex/mac_oui.rb +16572 -16571
  85. data/lib/rex/machparsey.rb +0 -1
  86. data/lib/rex/machparsey/exceptions.rb +0 -1
  87. data/lib/rex/machparsey/mach.rb +160 -161
  88. data/lib/rex/machparsey/machbase.rb +367 -368
  89. data/lib/rex/machscan.rb +0 -1
  90. data/lib/rex/machscan/scanner.rb +175 -176
  91. data/lib/rex/mime/encoding.rb +17 -0
  92. data/lib/rex/mime/header.rb +58 -58
  93. data/lib/rex/mime/message.rb +140 -137
  94. data/lib/rex/mime/part.rb +41 -12
  95. data/lib/rex/nop/opty2.rb +90 -90
  96. data/lib/rex/nop/opty2_tables.rb +273 -273
  97. data/lib/rex/ole.rb +0 -4
  98. data/lib/rex/ole/clsid.rb +26 -30
  99. data/lib/rex/ole/difat.rb +121 -125
  100. data/lib/rex/ole/directory.rb +205 -209
  101. data/lib/rex/ole/direntry.rb +217 -221
  102. data/lib/rex/ole/fat.rb +79 -83
  103. data/lib/rex/ole/header.rb +178 -182
  104. data/lib/rex/ole/minifat.rb +49 -53
  105. data/lib/rex/ole/propset.rb +113 -117
  106. data/lib/rex/ole/samples/create_ole.rb +8 -9
  107. data/lib/rex/ole/samples/dir.rb +10 -11
  108. data/lib/rex/ole/samples/dump_stream.rb +14 -15
  109. data/lib/rex/ole/samples/ole_info.rb +5 -6
  110. data/lib/rex/ole/storage.rb +372 -376
  111. data/lib/rex/ole/stream.rb +33 -37
  112. data/lib/rex/ole/substorage.rb +20 -24
  113. data/lib/rex/ole/util.rb +137 -141
  114. data/lib/rex/parser/acunetix_nokogiri.rb +398 -398
  115. data/lib/rex/parser/apple_backup_manifestdb.rb +116 -116
  116. data/lib/rex/parser/appscan_nokogiri.rb +359 -359
  117. data/lib/rex/parser/arguments.rb +88 -88
  118. data/lib/rex/parser/burp_session_nokogiri.rb +258 -258
  119. data/lib/rex/parser/ci_nokogiri.rb +184 -184
  120. data/lib/rex/parser/foundstone_nokogiri.rb +334 -333
  121. data/lib/rex/parser/fusionvm_nokogiri.rb +94 -94
  122. data/lib/rex/parser/ini.rb +167 -167
  123. data/lib/rex/parser/ip360_aspl_xml.rb +84 -84
  124. data/lib/rex/parser/ip360_xml.rb +77 -77
  125. data/lib/rex/parser/mbsa_nokogiri.rb +224 -224
  126. data/lib/rex/parser/nessus_xml.rb +100 -100
  127. data/lib/rex/parser/netsparker_xml.rb +89 -75
  128. data/lib/rex/parser/nexpose_raw_nokogiri.rb +677 -677
  129. data/lib/rex/parser/nexpose_simple_nokogiri.rb +322 -322
  130. data/lib/rex/parser/nexpose_xml.rb +105 -105
  131. data/lib/rex/parser/nmap_nokogiri.rb +386 -386
  132. data/lib/rex/parser/nmap_xml.rb +116 -116
  133. data/lib/rex/parser/nokogiri_doc_mixin.rb +223 -221
  134. data/lib/rex/parser/openvas_nokogiri.rb +162 -162
  135. data/lib/rex/parser/outpost24_nokogiri.rb +239 -0
  136. data/lib/rex/parser/retina_xml.rb +90 -90
  137. data/lib/rex/parser/unattend.rb +171 -0
  138. data/lib/rex/parser/wapiti_nokogiri.rb +89 -89
  139. data/lib/rex/payloads/win32/common.rb +14 -14
  140. data/lib/rex/payloads/win32/kernel.rb +36 -36
  141. data/lib/rex/payloads/win32/kernel/common.rb +32 -32
  142. data/lib/rex/payloads/win32/kernel/recovery.rb +27 -27
  143. data/lib/rex/payloads/win32/kernel/stager.rb +170 -170
  144. data/lib/rex/peparsey.rb +0 -3
  145. data/lib/rex/peparsey/exceptions.rb +0 -3
  146. data/lib/rex/peparsey/pe.rb +196 -199
  147. data/lib/rex/peparsey/pe_memdump.rb +35 -38
  148. data/lib/rex/peparsey/pebase.rb +1633 -1652
  149. data/lib/rex/peparsey/section.rb +115 -124
  150. data/lib/rex/pescan.rb +0 -3
  151. data/lib/rex/pescan/analyze.rb +351 -351
  152. data/lib/rex/pescan/scanner.rb +182 -182
  153. data/lib/rex/pescan/search.rb +59 -59
  154. data/lib/rex/platforms/windows.rb +37 -37
  155. data/lib/rex/poly.rb +111 -110
  156. data/lib/rex/poly/block.rb +419 -417
  157. data/lib/rex/poly/machine.rb +12 -0
  158. data/lib/rex/poly/machine/machine.rb +829 -0
  159. data/lib/rex/poly/machine/x86.rb +508 -0
  160. data/lib/rex/poly/register.rb +70 -70
  161. data/lib/rex/poly/register/x86.rb +22 -22
  162. data/lib/rex/post.rb +0 -1
  163. data/lib/rex/post/dir.rb +35 -36
  164. data/lib/rex/post/file.rb +140 -141
  165. data/lib/rex/post/file_stat.rb +198 -199
  166. data/lib/rex/post/io.rb +167 -168
  167. data/lib/rex/post/meterpreter.rb +1 -1
  168. data/lib/rex/post/meterpreter/channel.rb +389 -390
  169. data/lib/rex/post/meterpreter/channel_container.rb +33 -34
  170. data/lib/rex/post/meterpreter/channels/pool.rb +129 -130
  171. data/lib/rex/post/meterpreter/channels/pools/file.rb +35 -36
  172. data/lib/rex/post/meterpreter/channels/pools/stream_pool.rb +72 -73
  173. data/lib/rex/post/meterpreter/channels/stream.rb +62 -63
  174. data/lib/rex/post/meterpreter/client.rb +442 -436
  175. data/lib/rex/post/meterpreter/client_core.rb +326 -310
  176. data/lib/rex/post/meterpreter/dependencies.rb +0 -1
  177. data/lib/rex/post/meterpreter/extension.rb +12 -13
  178. data/lib/rex/post/meterpreter/extensions/espia/espia.rb +35 -36
  179. data/lib/rex/post/meterpreter/extensions/extapi/adsi/adsi.rb +71 -0
  180. data/lib/rex/post/meterpreter/extensions/extapi/clipboard/clipboard.rb +169 -0
  181. data/lib/rex/post/meterpreter/extensions/extapi/extapi.rb +45 -0
  182. data/lib/rex/post/meterpreter/extensions/extapi/service/service.rb +104 -0
  183. data/lib/rex/post/meterpreter/extensions/extapi/tlv.rb +77 -0
  184. data/lib/rex/post/meterpreter/extensions/extapi/window/window.rb +56 -0
  185. data/lib/rex/post/meterpreter/extensions/extapi/wmi/wmi.rb +75 -0
  186. data/lib/rex/post/meterpreter/extensions/incognito/incognito.rb +70 -71
  187. data/lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb +361 -0
  188. data/lib/rex/post/meterpreter/extensions/kiwi/tlv.rb +76 -0
  189. data/lib/rex/post/meterpreter/extensions/lanattacks/dhcp/dhcp.rb +78 -0
  190. data/lib/rex/post/meterpreter/extensions/lanattacks/lanattacks.rb +22 -78
  191. data/lib/rex/post/meterpreter/extensions/lanattacks/tftp/tftp.rb +49 -0
  192. data/lib/rex/post/meterpreter/extensions/lanattacks/tlv.rb +4 -4
  193. data/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb +128 -0
  194. data/lib/rex/post/meterpreter/extensions/mimikatz/tlv.rb +16 -0
  195. data/lib/rex/post/meterpreter/extensions/networkpug/networkpug.rb +38 -39
  196. data/lib/rex/post/meterpreter/extensions/networkpug/tlv.rb +1 -1
  197. data/lib/rex/post/meterpreter/extensions/priv/fs.rb +95 -96
  198. data/lib/rex/post/meterpreter/extensions/priv/passwd.rb +39 -40
  199. data/lib/rex/post/meterpreter/extensions/priv/priv.rb +80 -85
  200. data/lib/rex/post/meterpreter/extensions/sniffer/sniffer.rb +94 -95
  201. data/lib/rex/post/meterpreter/extensions/stdapi/constants.rb +207 -147
  202. data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +258 -259
  203. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +366 -301
  204. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file_stat.rb +72 -73
  205. data/lib/rex/post/meterpreter/extensions/stdapi/fs/io.rb +24 -25
  206. data/lib/rex/post/meterpreter/extensions/stdapi/net/arp.rb +59 -0
  207. data/lib/rex/post/meterpreter/extensions/stdapi/net/config.rb +227 -149
  208. data/lib/rex/post/meterpreter/extensions/stdapi/net/interface.rb +107 -108
  209. data/lib/rex/post/meterpreter/extensions/stdapi/net/netstat.rb +97 -0
  210. data/lib/rex/post/meterpreter/extensions/stdapi/net/resolve.rb +106 -0
  211. data/lib/rex/post/meterpreter/extensions/stdapi/net/route.rb +41 -42
  212. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +102 -101
  213. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +151 -152
  214. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb +142 -142
  215. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +185 -185
  216. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb +38118 -38117
  217. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb +7 -7
  218. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_advapi32.rb +2086 -2084
  219. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_crypt32.rb +15 -15
  220. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_iphlpapi.rb +80 -80
  221. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +3835 -3833
  222. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_netapi32.rb +84 -28
  223. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ntdll.rb +151 -137
  224. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_shell32.rb +15 -6
  225. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_user32.rb +3155 -3155
  226. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_version.rb +41 -0
  227. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wlanapi.rb +70 -70
  228. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb +128 -0
  229. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ws2_32.rb +596 -596
  230. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb +310 -301
  231. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb +71 -61
  232. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb +100 -100
  233. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_wrapper.rb +14 -14
  234. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/mock_magic.rb +488 -488
  235. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/multicall.rb +273 -264
  236. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/platform_util.rb +5 -5
  237. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb +240 -238
  238. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/tlv.rb +17 -15
  239. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/type/pointer_util.rb +61 -61
  240. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb +654 -635
  241. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb +49 -49
  242. data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +103 -102
  243. data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +98 -68
  244. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +165 -166
  245. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log_subsystem/event_record.rb +16 -17
  246. data/lib/rex/post/meterpreter/extensions/stdapi/sys/power.rb +34 -36
  247. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +363 -364
  248. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/image.rb +102 -103
  249. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/io.rb +28 -29
  250. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/memory.rb +303 -304
  251. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/thread.rb +113 -114
  252. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +260 -261
  253. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +165 -166
  254. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_value.rb +69 -70
  255. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/remote_registry_key.rb +160 -161
  256. data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +143 -144
  257. data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +29 -12
  258. data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +230 -231
  259. data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +181 -44
  260. data/lib/rex/post/meterpreter/inbound_packet_handler.rb +12 -13
  261. data/lib/rex/post/meterpreter/object_aliases.rb +56 -57
  262. data/lib/rex/post/meterpreter/packet.rb +591 -592
  263. data/lib/rex/post/meterpreter/packet_dispatcher.rb +506 -496
  264. data/lib/rex/post/meterpreter/packet_parser.rb +72 -73
  265. data/lib/rex/post/meterpreter/packet_response_waiter.rb +56 -57
  266. data/lib/rex/post/meterpreter/ui/console.rb +112 -112
  267. data/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb +53 -53
  268. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +911 -854
  269. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/espia.rb +86 -86
  270. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi.rb +65 -0
  271. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/adsi.rb +198 -0
  272. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/clipboard.rb +444 -0
  273. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/service.rb +199 -0
  274. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/window.rb +118 -0
  275. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/wmi.rb +108 -0
  276. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/incognito.rb +220 -220
  277. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb +509 -0
  278. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks.rb +60 -0
  279. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/dhcp.rb +254 -0
  280. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/tftp.rb +159 -0
  281. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +182 -0
  282. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/networkpug.rb +173 -173
  283. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv.rb +40 -40
  284. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +75 -77
  285. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/passwd.rb +30 -30
  286. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +105 -105
  287. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +182 -182
  288. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi.rb +37 -37
  289. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +504 -482
  290. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +401 -330
  291. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +883 -581
  292. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +296 -299
  293. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +320 -153
  294. data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +78 -78
  295. data/lib/rex/post/permission.rb +0 -1
  296. data/lib/rex/post/process.rb +39 -40
  297. data/lib/rex/post/thread.rb +41 -42
  298. data/lib/rex/post/ui.rb +35 -36
  299. data/lib/rex/proto/addp.rb +218 -0
  300. data/lib/rex/proto/dcerpc/client.rb +344 -344
  301. data/lib/rex/proto/dcerpc/exceptions.rb +128 -128
  302. data/lib/rex/proto/dcerpc/handle.rb +32 -32
  303. data/lib/rex/proto/dcerpc/ndr.rb +56 -56
  304. data/lib/rex/proto/dcerpc/packet.rb +249 -245
  305. data/lib/rex/proto/dcerpc/response.rb +170 -170
  306. data/lib/rex/proto/dcerpc/uuid.rb +65 -65
  307. data/lib/rex/proto/dcerpc/wdscp.rb +3 -0
  308. data/lib/rex/proto/dcerpc/wdscp/constants.rb +89 -0
  309. data/lib/rex/proto/dcerpc/wdscp/packet.rb +94 -0
  310. data/lib/rex/proto/dhcp.rb +0 -1
  311. data/lib/rex/proto/dhcp/constants.rb +0 -1
  312. data/lib/rex/proto/dhcp/server.rb +303 -304
  313. data/lib/rex/proto/drda/constants.rb +1 -1
  314. data/lib/rex/proto/drda/packet.rb +186 -186
  315. data/lib/rex/proto/drda/utils.rb +104 -104
  316. data/lib/rex/proto/http.rb +1 -0
  317. data/lib/rex/proto/http/client.rb +692 -820
  318. data/lib/rex/proto/http/client_request.rb +472 -0
  319. data/lib/rex/proto/http/handler.rb +25 -25
  320. data/lib/rex/proto/http/handler/erb.rb +104 -104
  321. data/lib/rex/proto/http/handler/proc.rb +37 -37
  322. data/lib/rex/proto/http/header.rb +149 -149
  323. data/lib/rex/proto/http/packet.rb +388 -382
  324. data/lib/rex/proto/http/request.rb +332 -335
  325. data/lib/rex/proto/http/response.rb +132 -72
  326. data/lib/rex/proto/http/server.rb +348 -338
  327. data/lib/rex/proto/iax2/call.rb +310 -310
  328. data/lib/rex/proto/iax2/client.rb +197 -197
  329. data/lib/rex/proto/iax2/codecs/alaw.rb +4 -4
  330. data/lib/rex/proto/iax2/codecs/mulaw.rb +4 -4
  331. data/lib/rex/proto/ipmi.rb +57 -0
  332. data/lib/rex/proto/ipmi/channel_auth_reply.rb +88 -0
  333. data/lib/rex/proto/ipmi/open_session_reply.rb +35 -0
  334. data/lib/rex/proto/ipmi/rakp2.rb +35 -0
  335. data/lib/rex/proto/ipmi/utils.rb +125 -0
  336. data/lib/rex/proto/natpmp.rb +1 -5
  337. data/lib/rex/proto/natpmp/constants.rb +4 -4
  338. data/lib/rex/proto/natpmp/packet.rb +25 -25
  339. data/lib/rex/proto/ntlm/base.rb +271 -271
  340. data/lib/rex/proto/ntlm/constants.rb +61 -61
  341. data/lib/rex/proto/ntlm/crypt.rb +348 -352
  342. data/lib/rex/proto/ntlm/exceptions.rb +3 -3
  343. data/lib/rex/proto/ntlm/message.rb +468 -471
  344. data/lib/rex/proto/ntlm/utils.rb +746 -746
  345. data/lib/rex/proto/pjl.rb +30 -0
  346. data/lib/rex/proto/pjl/client.rb +162 -0
  347. data/lib/rex/proto/proxy/socks4a.rb +440 -440
  348. data/lib/rex/proto/rfb.rb +1 -8
  349. data/lib/rex/proto/rfb/cipher.rb +46 -49
  350. data/lib/rex/proto/rfb/client.rb +179 -182
  351. data/lib/rex/proto/rfb/constants.rb +18 -21
  352. data/lib/rex/proto/smb/client.rb +1954 -1843
  353. data/lib/rex/proto/smb/constants.rb +533 -516
  354. data/lib/rex/proto/smb/crypt.rb +21 -21
  355. data/lib/rex/proto/smb/evasions.rb +43 -43
  356. data/lib/rex/proto/smb/exceptions.rb +791 -791
  357. data/lib/rex/proto/smb/simpleclient.rb +142 -286
  358. data/lib/rex/proto/smb/simpleclient/open_file.rb +106 -0
  359. data/lib/rex/proto/smb/simpleclient/open_pipe.rb +57 -0
  360. data/lib/rex/proto/smb/utils.rb +81 -81
  361. data/lib/rex/proto/sunrpc/client.rb +158 -158
  362. data/lib/rex/proto/tftp.rb +0 -1
  363. data/lib/rex/proto/tftp/client.rb +289 -289
  364. data/lib/rex/proto/tftp/constants.rb +9 -10
  365. data/lib/rex/proto/tftp/server.rb +466 -467
  366. data/lib/rex/random_identifier_generator.rb +176 -0
  367. data/lib/rex/registry.rb +1 -1
  368. data/lib/rex/registry/hive.rb +88 -88
  369. data/lib/rex/registry/lfkey.rb +25 -25
  370. data/lib/rex/registry/nodekey.rb +30 -30
  371. data/lib/rex/registry/regf.rb +10 -10
  372. data/lib/rex/registry/valuekey.rb +43 -43
  373. data/lib/rex/registry/valuelist.rb +13 -13
  374. data/lib/rex/ropbuilder/rop.rb +254 -253
  375. data/lib/rex/script.rb +21 -22
  376. data/lib/rex/script/base.rb +51 -50
  377. data/lib/rex/script/meterpreter.rb +2 -2
  378. data/lib/rex/service.rb +24 -24
  379. data/lib/rex/service_manager.rb +132 -132
  380. data/lib/rex/services/local_relay.rb +398 -398
  381. data/lib/rex/socket.rb +758 -763
  382. data/lib/rex/socket/comm.rb +95 -95
  383. data/lib/rex/socket/comm/local.rb +507 -440
  384. data/lib/rex/socket/ip.rb +118 -118
  385. data/lib/rex/socket/parameters.rb +351 -350
  386. data/lib/rex/socket/range_walker.rb +445 -368
  387. data/lib/rex/socket/ssl_tcp.rb +323 -317
  388. data/lib/rex/socket/ssl_tcp_server.rb +173 -158
  389. data/lib/rex/socket/subnet_walker.rb +48 -48
  390. data/lib/rex/socket/switch_board.rb +259 -259
  391. data/lib/rex/socket/tcp.rb +58 -56
  392. data/lib/rex/socket/tcp_server.rb +42 -42
  393. data/lib/rex/socket/udp.rb +152 -152
  394. data/lib/rex/sslscan/result.rb +200 -0
  395. data/lib/rex/sslscan/scanner.rb +205 -0
  396. data/lib/rex/struct2.rb +0 -1
  397. data/lib/rex/struct2/c_struct.rb +162 -163
  398. data/lib/rex/struct2/c_struct_template.rb +21 -22
  399. data/lib/rex/struct2/constant.rb +6 -7
  400. data/lib/rex/struct2/element.rb +30 -31
  401. data/lib/rex/struct2/generic.rb +60 -61
  402. data/lib/rex/struct2/restraint.rb +40 -41
  403. data/lib/rex/struct2/s_string.rb +60 -61
  404. data/lib/rex/struct2/s_struct.rb +97 -98
  405. data/lib/rex/sync.rb +0 -1
  406. data/lib/rex/sync/event.rb +62 -72
  407. data/lib/rex/sync/read_write_lock.rb +149 -149
  408. data/lib/rex/sync/ref.rb +42 -42
  409. data/lib/rex/sync/thread_safe.rb +59 -59
  410. data/lib/rex/text.rb +1803 -1315
  411. data/lib/rex/thread_factory.rb +25 -25
  412. data/lib/rex/time.rb +44 -44
  413. data/lib/rex/transformer.rb +91 -91
  414. data/lib/rex/ui/interactive.rb +265 -265
  415. data/lib/rex/ui/output.rb +66 -60
  416. data/lib/rex/ui/progress_tracker.rb +79 -79
  417. data/lib/rex/ui/subscriber.rb +144 -134
  418. data/lib/rex/ui/text/color.rb +76 -76
  419. data/lib/rex/ui/text/dispatcher_shell.rb +512 -505
  420. data/lib/rex/ui/text/input.rb +96 -96
  421. data/lib/rex/ui/text/input/buffer.rb +58 -58
  422. data/lib/rex/ui/text/input/readline.rb +114 -114
  423. data/lib/rex/ui/text/input/socket.rb +77 -77
  424. data/lib/rex/ui/text/input/stdio.rb +24 -24
  425. data/lib/rex/ui/text/irb_shell.rb +45 -41
  426. data/lib/rex/ui/text/output.rb +64 -60
  427. data/lib/rex/ui/text/output/buffer.rb +42 -42
  428. data/lib/rex/ui/text/output/buffer/stdout.rb +25 -0
  429. data/lib/rex/ui/text/output/file.rb +24 -24
  430. data/lib/rex/ui/text/output/socket.rb +24 -24
  431. data/lib/rex/ui/text/output/stdio.rb +29 -29
  432. data/lib/rex/ui/text/output/tee.rb +36 -36
  433. data/lib/rex/ui/text/progress_tracker.rb +37 -37
  434. data/lib/rex/ui/text/shell.rb +371 -361
  435. data/lib/rex/ui/text/table.rb +320 -284
  436. data/lib/rex/zip.rb +0 -1
  437. data/lib/rex/zip/archive.rb +115 -94
  438. data/lib/rex/zip/blocks.rb +101 -100
  439. data/lib/rex/zip/entry.rb +108 -99
  440. data/lib/rex/zip/jar.rb +261 -206
  441. data/lib/rex/zip/samples/comment.rb +1 -2
  442. data/lib/rex/zip/samples/mkwar.rb +12 -13
  443. data/lib/rex/zip/samples/mkzip.rb +1 -2
  444. data/lib/rex/zip/samples/recursive.rb +29 -30
  445. metadata +424 -446
  446. data/lib/rex/arch/sparc.rb.ut.rb +0 -19
  447. data/lib/rex/arch/x86.rb.ut.rb +0 -94
  448. data/lib/rex/assembly/nasm.rb.ut.rb +0 -23
  449. data/lib/rex/encoder/ndr.rb.ut.rb +0 -45
  450. data/lib/rex/encoder/xdr.rb.ut.rb +0 -30
  451. data/lib/rex/encoders/xor_dword_additive.rb.ut.rb +0 -13
  452. data/lib/rex/encoding/xor.rb.ts.rb +0 -15
  453. data/lib/rex/encoding/xor/byte.rb.ut.rb +0 -22
  454. data/lib/rex/encoding/xor/dword.rb.ut.rb +0 -16
  455. data/lib/rex/encoding/xor/dword_additive.rb.ut.rb +0 -16
  456. data/lib/rex/encoding/xor/generic.rb.ut.rb +0 -121
  457. data/lib/rex/encoding/xor/word.rb.ut.rb +0 -14
  458. data/lib/rex/exceptions.rb.ut.rb +0 -45
  459. data/lib/rex/exploitation/egghunter.rb.ut.rb +0 -28
  460. data/lib/rex/exploitation/javascriptosdetect.js +0 -1014
  461. data/lib/rex/exploitation/javascriptosdetect.rb +0 -43
  462. data/lib/rex/exploitation/omelet.rb.ut.rb +0 -27
  463. data/lib/rex/exploitation/opcodedb.rb.ut.rb +0 -280
  464. data/lib/rex/exploitation/seh.rb.ut.rb +0 -20
  465. data/lib/rex/file.rb.ut.rb +0 -17
  466. data/lib/rex/io/ring_buffer.rb.ut.rb +0 -135
  467. data/lib/rex/nop/opty2.rb.ut.rb +0 -24
  468. data/lib/rex/parser/arguments.rb.ut.rb +0 -68
  469. data/lib/rex/parser/ini.rb.ut.rb +0 -30
  470. data/lib/rex/post/meterpreter/extensions/stdapi/railgun.rb.ts.rb +0 -18
  471. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb.ut.rb +0 -39
  472. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb.ut.rb +0 -37
  473. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb.ut.rb +0 -52
  474. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb.ut.rb +0 -43
  475. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb.ut.rb +0 -128
  476. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_wrapper.rb.ut.rb +0 -64
  477. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/platform_util.rb.ut.rb +0 -29
  478. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb.ut.rb +0 -155
  479. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/type/pointer_util.rb.ut.rb +0 -128
  480. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb.ut.rb +0 -124
  481. data/lib/rex/proto.rb.ts.rb +0 -9
  482. data/lib/rex/proto/dcerpc.rb.ts.rb +0 -10
  483. data/lib/rex/proto/dcerpc/client.rb.ut.rb +0 -492
  484. data/lib/rex/proto/dcerpc/handle.rb.ut.rb +0 -86
  485. data/lib/rex/proto/dcerpc/ndr.rb.ut.rb +0 -42
  486. data/lib/rex/proto/dcerpc/packet.rb.ut.rb +0 -57
  487. data/lib/rex/proto/dcerpc/response.rb.ut.rb +0 -16
  488. data/lib/rex/proto/dcerpc/uuid.rb.ut.rb +0 -47
  489. data/lib/rex/proto/drda.rb.ts.rb +0 -18
  490. data/lib/rex/proto/drda/constants.rb.ut.rb +0 -24
  491. data/lib/rex/proto/drda/packet.rb.ut.rb +0 -110
  492. data/lib/rex/proto/drda/utils.rb.ut.rb +0 -85
  493. data/lib/rex/proto/http.rb.ts.rb +0 -13
  494. data/lib/rex/proto/http/client.rb.ut.rb +0 -96
  495. data/lib/rex/proto/http/handler/erb.rb.ut.rb +0 -22
  496. data/lib/rex/proto/http/handler/erb.rb.ut.rb.rhtml +0 -1
  497. data/lib/rex/proto/http/handler/proc.rb.ut.rb +0 -25
  498. data/lib/rex/proto/http/header.rb.ut.rb +0 -47
  499. data/lib/rex/proto/http/packet.rb.ut.rb +0 -166
  500. data/lib/rex/proto/http/request.rb.ut.rb +0 -215
  501. data/lib/rex/proto/http/response.rb.ut.rb +0 -150
  502. data/lib/rex/proto/http/server.rb.ut.rb +0 -80
  503. data/lib/rex/proto/ntlm.rb.ut.rb +0 -181
  504. data/lib/rex/proto/rfb.rb.ut.rb +0 -40
  505. data/lib/rex/proto/smb.rb.ts.rb +0 -9
  506. data/lib/rex/proto/smb/client.rb.ut.rb +0 -224
  507. data/lib/rex/proto/smb/constants.rb.ut.rb +0 -19
  508. data/lib/rex/proto/smb/simpleclient.rb.ut.rb +0 -129
  509. data/lib/rex/proto/smb/utils.rb.ut.rb +0 -21
  510. data/lib/rex/proto/tftp/server.rb.ut.rb +0 -29
  511. data/lib/rex/service_manager.rb.ut.rb +0 -33
  512. data/lib/rex/socket.rb.ut.rb +0 -108
  513. data/lib/rex/socket/comm/local.rb.ut.rb +0 -76
  514. data/lib/rex/socket/parameters.rb.ut.rb +0 -52
  515. data/lib/rex/socket/range_walker.rb.ut.rb +0 -56
  516. data/lib/rex/socket/ssl_tcp.rb.ut.rb +0 -40
  517. data/lib/rex/socket/ssl_tcp_server.rb.ut.rb +0 -62
  518. data/lib/rex/socket/subnet_walker.rb.ut.rb +0 -29
  519. data/lib/rex/socket/switch_board.rb.ut.rb +0 -53
  520. data/lib/rex/socket/tcp.rb.ut.rb +0 -65
  521. data/lib/rex/socket/tcp_server.rb.ut.rb +0 -45
  522. data/lib/rex/socket/udp.rb.ut.rb +0 -45
  523. data/lib/rex/test.rb +0 -36
  524. data/lib/rex/text.rb.ut.rb +0 -193
  525. data/lib/rex/transformer.rb.ut.rb +0 -39
  526. data/lib/rex/ui/text/color.rb.ut.rb +0 -19
  527. data/lib/rex/ui/text/progress_tracker.rb.ut.rb +0 -35
  528. data/lib/rex/ui/text/table.rb.ut.rb +0 -56
@@ -1,8 +1,4 @@
1
1
  # -*- coding: binary -*-
2
- ##
3
- # $Id: stream.rb 15548 2012-06-29 06:08:20Z rapid7 $
4
- # Version: $Revision: 15548 $
5
- ##
6
2
 
7
3
  ##
8
4
  # Rex::OLE - an OLE implementation
@@ -14,39 +10,39 @@ module OLE
14
10
 
15
11
  class Stream < DirEntry
16
12
 
17
- def initialize(stg)
18
- super
19
-
20
- # for reading/writing from this
21
- @offset = 0
22
- @_mse = STGTY_STREAM
23
- end
24
-
25
- def close
26
- @mode = nil
27
- @offset = nil
28
- end
29
-
30
- def seek(offset)
31
- @offset = offset
32
- end
33
-
34
- def read(len)
35
- return nil if (not @data)
36
-
37
- ret = @data[@offset, len]
38
- @offset += len
39
- ret
40
- end
41
-
42
- def <<(expr)
43
- if (not @data)
44
- @data = expr.dup
45
- else
46
- @data << expr
47
- end
48
- @_ulSize = @data.length
49
- end
13
+ def initialize(stg)
14
+ super
15
+
16
+ # for reading/writing from this
17
+ @offset = 0
18
+ @_mse = STGTY_STREAM
19
+ end
20
+
21
+ def close
22
+ @mode = nil
23
+ @offset = nil
24
+ end
25
+
26
+ def seek(offset)
27
+ @offset = offset
28
+ end
29
+
30
+ def read(len)
31
+ return nil if (not @data)
32
+
33
+ ret = @data[@offset, len]
34
+ @offset += len
35
+ ret
36
+ end
37
+
38
+ def <<(expr)
39
+ if (not @data)
40
+ @data = expr.dup
41
+ else
42
+ @data << expr
43
+ end
44
+ @_ulSize = @data.length
45
+ end
50
46
 
51
47
  end
52
48
 
@@ -1,8 +1,4 @@
1
1
  # -*- coding: binary -*-
2
- ##
3
- # $Id: substorage.rb 15548 2012-06-29 06:08:20Z rapid7 $
4
- # Version: $Revision: 15548 $
5
- ##
6
2
 
7
3
  ##
8
4
  # Rex::OLE - an OLE implementation
@@ -14,35 +10,35 @@ module OLE
14
10
 
15
11
  class SubStorage < DirEntry
16
12
 
17
- def initialize(stg)
18
- super
13
+ def initialize(stg)
14
+ super
19
15
 
20
- @_mse = STGTY_STORAGE
21
- end
16
+ @_mse = STGTY_STORAGE
17
+ end
22
18
 
23
19
 
24
- def close
25
- end
20
+ def close
21
+ end
26
22
 
27
23
 
28
- # stream handling stuff
29
- def create_stream(name, mode=STGM_WRITE)
30
- @stg.create_stream(name, mode, self)
31
- end
24
+ # stream handling stuff
25
+ def create_stream(name, mode=STGM_WRITE)
26
+ @stg.create_stream(name, mode, self)
27
+ end
32
28
 
33
- def open_stream(name, mode=STGM_READ)
34
- @stg.open_stream(name, mode, self)
35
- end
29
+ def open_stream(name, mode=STGM_READ)
30
+ @stg.open_stream(name, mode, self)
31
+ end
36
32
 
37
33
 
38
- # storage handling stuff
39
- def create_storage(name, mode=STGM_WRITE)
40
- @stg.create_storage(name, mode, self)
41
- end
34
+ # storage handling stuff
35
+ def create_storage(name, mode=STGM_WRITE)
36
+ @stg.create_storage(name, mode, self)
37
+ end
42
38
 
43
- def open_storage(name, mode=STGM_WRITE)
44
- @stg.open_storage(name, mode, self)
45
- end
39
+ def open_storage(name, mode=STGM_WRITE)
40
+ @stg.open_storage(name, mode, self)
41
+ end
46
42
 
47
43
  end
48
44
 
@@ -1,8 +1,4 @@
1
1
  # -*- coding: binary -*-
2
- ##
3
- # $Id: util.rb 15548 2012-06-29 06:08:20Z rapid7 $
4
- # Version: $Revision: 15548 $
5
- ##
6
2
 
7
3
  ##
8
4
  # Rex::OLE - an OLE implementation
@@ -14,143 +10,143 @@ module OLE
14
10
 
15
11
  class Util
16
12
 
17
- def self.Hexify32array(arr)
18
- ret = ""
19
- arr.each { |dw|
20
- ret << " " if ret.length > 0
21
- ret << "0x%08x" % dw
22
- }
23
- ret
24
- end
25
-
26
- def self.Printable(buf)
27
- ret = ""
28
- buf.unpack('C*').each { |byte|
29
- ch = byte.chr
30
- if (byte < 0x20 || byte > 0x7e)
31
- ret << "\\x" + ch.unpack('H*')[0]
32
- else
33
- ret << ch
34
- end
35
- }
36
- ret
37
- end
38
-
39
-
40
- def self.set_endian(endian)
41
- @endian = endian
42
- end
43
-
44
- def self.get64(buf, offset)
45
- @endian = LITTLE_ENDIAN if not @endian
46
- if (@endian == LITTLE_ENDIAN)
47
- arr = buf[offset,8].unpack('VV')
48
- return (arr[0] + (arr[1] << 32))
49
- else
50
- arr = buf[offset,8].unpack('NN')
51
- return ((arr[0] << 32) + arr[1])
52
- end
53
- end
54
-
55
- def self.pack64(value)
56
- @endian = LITTLE_ENDIAN if not @endian
57
- arr = []
58
- arr << (value & 0xffffffff)
59
- arr << (value >> 32)
60
- if (@endian == LITTLE_ENDIAN)
61
- arr.pack('VV')
62
- else
63
- arr.reverse.pack('NN')
64
- end
65
- end
66
-
67
- def self.get32(buf, offset)
68
- @endian = LITTLE_ENDIAN if not @endian
69
- if (@endian == LITTLE_ENDIAN)
70
- buf[offset,4].unpack('V')[0]
71
- else
72
- buf[offset,4].unpack('N')[0]
73
- end
74
- end
75
-
76
- def self.pack32(value)
77
- @endian = LITTLE_ENDIAN if not @endian
78
- if (@endian == LITTLE_ENDIAN)
79
- [value].pack('V')
80
- else
81
- [value].pack('N')
82
- end
83
- end
84
-
85
- def self.get32array(buf)
86
- @endian = LITTLE_ENDIAN if not @endian
87
- if (@endian == LITTLE_ENDIAN)
88
- buf.unpack('V*')
89
- else
90
- buf.unpack('N*')
91
- end
92
- end
93
-
94
- def self.pack32array(arr)
95
- @endian = LITTLE_ENDIAN if not @endian
96
- if (@endian == LITTLE_ENDIAN)
97
- arr.pack('V*')
98
- else
99
- arr.pack('N*')
100
- end
101
- end
102
-
103
- def self.get16(buf, offset)
104
- @endian = LITTLE_ENDIAN if not @endian
105
- if (@endian == LITTLE_ENDIAN)
106
- buf[offset,2].unpack('v')[0]
107
- else
108
- buf[offset,2].unpack('n')[0]
109
- end
110
- end
111
-
112
- def self.pack16(value)
113
- @endian = LITTLE_ENDIAN if not @endian
114
- if (@endian == LITTLE_ENDIAN)
115
- [value].pack('v')
116
- else
117
- [value].pack('n')
118
- end
119
- end
120
-
121
- def self.get8(buf, offset)
122
- buf[offset,1].unpack('C')[0]
123
- end
124
-
125
- def self.pack8(value)
126
- [value].pack('C')
127
- end
128
-
129
-
130
- def self.getUnicodeString(buf)
131
- buf = buf.unpack('S*').pack('C*')
132
- if (idx = buf.index(0x00.chr))
133
- buf.slice!(idx, buf.length)
134
- end
135
- buf
136
- end
137
-
138
- def self.putUnicodeString(buf)
139
- buf = buf.unpack('C*').pack('S*')
140
- if (buf.length < 0x40)
141
- buf << "\x00" * (0x40 - buf.length)
142
- end
143
- buf
144
- end
145
-
146
-
147
- def self.name_is_valid(name)
148
- return nil if (name.length > 31)
149
- (0..0x1f).to_a.each { |x|
150
- return nil if (name.include?(x.chr))
151
- }
152
- return true
153
- end
13
+ def self.Hexify32array(arr)
14
+ ret = ""
15
+ arr.each { |dw|
16
+ ret << " " if ret.length > 0
17
+ ret << "0x%08x" % dw
18
+ }
19
+ ret
20
+ end
21
+
22
+ def self.Printable(buf)
23
+ ret = ""
24
+ buf.unpack('C*').each { |byte|
25
+ ch = byte.chr
26
+ if (byte < 0x20 || byte > 0x7e)
27
+ ret << "\\x" + ch.unpack('H*')[0]
28
+ else
29
+ ret << ch
30
+ end
31
+ }
32
+ ret
33
+ end
34
+
35
+
36
+ def self.set_endian(endian)
37
+ @endian = endian
38
+ end
39
+
40
+ def self.get64(buf, offset)
41
+ @endian = LITTLE_ENDIAN if not @endian
42
+ if (@endian == LITTLE_ENDIAN)
43
+ arr = buf[offset,8].unpack('VV')
44
+ return (arr[0] + (arr[1] << 32))
45
+ else
46
+ arr = buf[offset,8].unpack('NN')
47
+ return ((arr[0] << 32) + arr[1])
48
+ end
49
+ end
50
+
51
+ def self.pack64(value)
52
+ @endian = LITTLE_ENDIAN if not @endian
53
+ arr = []
54
+ arr << (value & 0xffffffff)
55
+ arr << (value >> 32)
56
+ if (@endian == LITTLE_ENDIAN)
57
+ arr.pack('VV')
58
+ else
59
+ arr.reverse.pack('NN')
60
+ end
61
+ end
62
+
63
+ def self.get32(buf, offset)
64
+ @endian = LITTLE_ENDIAN if not @endian
65
+ if (@endian == LITTLE_ENDIAN)
66
+ buf[offset,4].unpack('V')[0]
67
+ else
68
+ buf[offset,4].unpack('N')[0]
69
+ end
70
+ end
71
+
72
+ def self.pack32(value)
73
+ @endian = LITTLE_ENDIAN if not @endian
74
+ if (@endian == LITTLE_ENDIAN)
75
+ [value].pack('V')
76
+ else
77
+ [value].pack('N')
78
+ end
79
+ end
80
+
81
+ def self.get32array(buf)
82
+ @endian = LITTLE_ENDIAN if not @endian
83
+ if (@endian == LITTLE_ENDIAN)
84
+ buf.unpack('V*')
85
+ else
86
+ buf.unpack('N*')
87
+ end
88
+ end
89
+
90
+ def self.pack32array(arr)
91
+ @endian = LITTLE_ENDIAN if not @endian
92
+ if (@endian == LITTLE_ENDIAN)
93
+ arr.pack('V*')
94
+ else
95
+ arr.pack('N*')
96
+ end
97
+ end
98
+
99
+ def self.get16(buf, offset)
100
+ @endian = LITTLE_ENDIAN if not @endian
101
+ if (@endian == LITTLE_ENDIAN)
102
+ buf[offset,2].unpack('v')[0]
103
+ else
104
+ buf[offset,2].unpack('n')[0]
105
+ end
106
+ end
107
+
108
+ def self.pack16(value)
109
+ @endian = LITTLE_ENDIAN if not @endian
110
+ if (@endian == LITTLE_ENDIAN)
111
+ [value].pack('v')
112
+ else
113
+ [value].pack('n')
114
+ end
115
+ end
116
+
117
+ def self.get8(buf, offset)
118
+ buf[offset,1].unpack('C')[0]
119
+ end
120
+
121
+ def self.pack8(value)
122
+ [value].pack('C')
123
+ end
124
+
125
+
126
+ def self.getUnicodeString(buf)
127
+ buf = buf.unpack('S*').pack('C*')
128
+ if (idx = buf.index(0x00.chr))
129
+ buf.slice!(idx, buf.length)
130
+ end
131
+ buf
132
+ end
133
+
134
+ def self.putUnicodeString(buf)
135
+ buf = buf.unpack('C*').pack('S*')
136
+ if (buf.length < 0x40)
137
+ buf << "\x00" * (0x40 - buf.length)
138
+ end
139
+ buf
140
+ end
141
+
142
+
143
+ def self.name_is_valid(name)
144
+ return nil if (name.length > 31)
145
+ (0..0x1f).to_a.each { |x|
146
+ return nil if (name.include?(x.chr))
147
+ }
148
+ return true
149
+ end
154
150
 
155
151
  end
156
152
 
@@ -4,403 +4,403 @@ require 'rex'
4
4
  require 'uri'
5
5
 
6
6
  module Rex
7
- module Parser
8
-
9
- # If Nokogiri is available, define the Acunetix document class.
10
- load_nokogiri && class AcunetixDocument < Nokogiri::XML::SAX::Document
11
-
12
- include NokogiriDocMixin
13
-
14
- # The resolver prefers your local /etc/hosts (or windows equiv), but will
15
- # fall back to regular DNS. It retains a cache for the import to avoid
16
- # spamming your network with DNS requests.
17
- attr_reader :resolv_cache
18
-
19
- # If name resolution of the host fails out completely, you will not be
20
- # able to import that Scan task. Other scan tasks in the same report
21
- # should be unaffected.
22
- attr_reader :parse_warnings
23
-
24
- def start_document
25
- @parse_warnings = []
26
- @resolv_cache = {}
27
- end
28
-
29
- def start_element(name=nil,attrs=[])
30
- attrs = normalize_attrs(attrs)
31
- block = @block
32
- @state[:current_tag][name] = true
33
- case name
34
- when "Scan" # Start of the thing.
35
- when "Name", "StartURL", "Banner", "Os"
36
- @state[:has_text] = true
37
- when "LoginSequence" # Skipping for now
38
- when "Crawler"
39
- record_crawler(attrs)
40
- when "FullURL"
41
- @state[:has_text] = true
42
- when "Variable"
43
- record_variable(attrs)
44
- when "Request", "Response"
45
- @state[:has_text] = true
46
- end
47
- end
48
-
49
- def end_element(name=nil)
50
- block = @block
51
- case name
52
- when "Scan"
53
- # Clears most of the @state out, we're done with this web site.
54
- @state.delete_if {|k| k != :current_tag}
55
- when "Name"
56
- @state[:has_text] = false
57
- collect_scan_name
58
- collect_report_item_name
59
- @text = nil
60
- when "StartURL" # Populates @state[:starturl_uri], we use this a lot
61
- @state[:has_text] = false
62
- collect_host
63
- collect_service
64
- @text = nil
65
- handle_parse_warnings &block
66
- host_object = report_host &block
67
- if host_object
68
- report_starturl_service(host_object,&block)
69
- db.report_import_note(@args[:wspace],host_object)
70
- end
71
- when "Banner"
72
- @state[:has_text] = false
73
- collect_and_report_banner
74
- when "Os"
75
- @state[:has_text] = false
76
- report_os_fingerprint
77
- when "LoginSequence" # This comes up later in the report anyway
78
- when "Crawler"
79
- report_starturl_web_site(&block)
80
- when "FullURL"
81
- @state[:has_text] = false
82
- report_web_site(@text,&block)
83
- @text = nil
84
- when "Inputs"
85
- report_web_form(&block)
86
- when "Request"
87
- @state[:has_text] = false
88
- collect_page_request
89
- @text = nil
90
- when "Response"
91
- @state[:has_text] = false
92
- collect_page_response
93
- @text = nil
94
- report_web_page(&block)
95
- end
96
- @state[:current_tag].delete name
97
- end
98
-
99
- def collect_page_response
100
- return unless in_tag("TechnicalDetails")
101
- return unless in_tag("ReportItem")
102
- return unless @text
103
- return if @text.to_s.empty?
104
- @state[:page_response] = @text
105
- end
106
-
107
- def collect_page_request
108
- return unless in_tag("TechnicalDetails")
109
- return unless in_tag("ReportItem")
110
- return unless @text
111
- return if @text.to_s.empty?
112
- @state[:page_request] = @text
113
- end
114
-
115
- def collect_scan_name
116
- return unless in_tag("Scan")
117
- return if in_tag("ReportItems")
118
- return if in_tag("Crawler")
119
- return unless @text
120
- return if @text.strip.empty?
121
- @state[:scan_name] = @text.strip
122
- end
123
-
124
- def collect_host
125
- return unless in_tag("Scan")
126
- return unless @text
127
- return if @text.strip.empty?
128
- uri = URI.parse(@text) rescue nil
129
- return unless uri
130
- address = resolve_scan_starturl_address(uri)
131
- @report_data[:host] = address
132
- @report_data[:state] = Msf::HostState::Alive
133
- end
134
-
135
- def collect_service
136
- return unless @report_data[:host]
137
- return unless in_tag("Scan")
138
- return unless @text
139
- return if @text.strip.empty?
140
- uri = URI.parse(@text) rescue nil
141
- return unless uri
142
- @state[:starturl_uri] = uri
143
- @report_data[:ports] ||= []
144
- @report_data[:ports] << @state[:starturl_port]
145
- end
146
-
147
- def collect_and_report_banner
148
- return unless (svc = @state[:starturl_service_object]) # Yes i want assignment
149
- return unless @text
150
- return if @text.strip.empty?
151
- return unless in_tag("Scan")
152
- svc_info = {
153
- :host => svc.host,
154
- :port => svc.port,
155
- :proto => svc.proto,
156
- :info => @text.strip
157
- }
158
- db_report(:service, svc_info)
159
- @text = nil
160
- end
161
-
162
- def collect_report_item_name
163
- return unless in_tag("ReportItem")
164
- return unless @text
165
- return if @text.strip.empty?
166
- @state[:report_item] = @text
167
- end
168
-
169
- # @state[:fullurl] is set by report_web_site
170
- def record_variable(attrs)
171
- return unless in_tag("Inputs")
172
- return unless @state[:fullurl].kind_of? URI
173
- method = attr_hash(attrs)["Type"]
174
- return unless method
175
- return if method.strip.empty?
176
- @state[:form_variables] ||= []
177
- @state[:form_variables] << [attr_hash(attrs)["Name"],method]
178
- end
179
-
180
- def record_crawler(attrs)
181
- return unless in_tag("Scan")
182
- return unless @state[:starturl_service_object]
183
- starturl = attr_hash(attrs)["StartUrl"]
184
- return unless starturl
185
- @state[:crawler_starturl] = starturl
186
- end
187
-
188
- def report_web_form(&block)
189
- return unless in_tag("SiteFiles")
190
- return unless @state[:web_site]
191
- return unless @state[:fullurl].kind_of? URI
192
- return unless @state[:form_variables].kind_of? Array
193
- return if @state[:form_variables].empty?
194
- method = parse_method(@state[:form_variables].first[1])
195
- vars = @state[:form_variables].map {|x| x[0]}
196
- form_info = {}
197
- form_info[:web_site] = @state[:web_site]
198
- form_info[:path] = @state[:fullurl].path
199
- form_info[:query] = @state[:fullurl].query
200
- form_info[:method] = method
201
- form_info[:params] = vars
202
- url = @state[:fullurl].to_s
203
- db.emit(:web_form,url,&block) if block
204
- db_report(:web_form,form_info)
205
- @state[:fullurl] = nil
206
- @state[:form_variables] = nil
207
- end
208
-
209
- def report_web_page(&block)
210
- return if should_skip_this_page
211
- return unless @state[:web_site]
212
- return unless @state[:page_request]
213
- return if @state[:page_request].strip.empty?
214
- return unless @state[:page_response]
215
- return if @state[:page_response].strip.empty?
216
- path,query_string = parse_request(@state[:page_request])
217
- return unless path
218
- parsed_response = parse_response(@state[:page_response])
219
- return unless parsed_response
220
- web_page_info = {}
221
- web_page_info[:web_site] = @state[:web_site]
222
- web_page_info[:path] = path
223
- web_page_info[:code] = parsed_response[:code].to_i
224
- web_page_info[:headers] = parsed_response[:headers]
225
- web_page_info[:body] = parsed_response[:body]
226
- web_page_info[:query] = query_string || ""
227
- url = ""
228
- url << @state[:web_site].service.name.to_s << "://"
229
- url << @state[:web_site].vhost.to_s << ":"
230
- url << path
231
- uri = URI.parse(url) rescue nil
232
- return unless uri # Sanity checker
233
- db.emit(:web_page, url, &block) if block
234
- web_page_object = db_report(:web_page,web_page_info)
235
- @state[:page_request] = @state[:page_response] = nil
236
- @state[:web_page] = web_page_object
237
- end
238
-
239
- # Reasons why we shouldn't collect a particular web page.
240
- def should_skip_this_page
241
- if @state[:report_item] =~ /Unrestricted File Upload/
242
- # This means that the page being collected is something the
243
- # auditor put there, so it's not useful to report on.
244
- return true
245
- end
246
- return false
247
- end
248
-
249
- # XXX Rex::Proto::Http::Packet seems broken for
250
- # actually parsing requests and responses, but all I
251
- # need are the headers anyway
252
- def parse_request(request)
253
- headers = Rex::Proto::Http::Packet::Header.new
254
- headers.from_s request.dup # It's destructive.
255
- return unless headers.cmd_string
256
- verb,req = headers.cmd_string.split(/\s+/)
257
- return unless verb
258
- return unless req
259
- path,query_string = req.split(/\?/)[0,2]
260
- end
261
-
262
- def parse_response(response)
263
- headers = Rex::Proto::Http::Packet::Header.new
264
- headers.from_s response.dup # It's destructive.
265
- return unless headers.cmd_string
266
- http,code,msg = headers.cmd_string.split(/\s+/)
267
- return unless code
268
- return unless code.to_i.to_s == code
269
- parsed = {}
270
- parsed[:code] = code
271
- parsed[:headers] = {}
272
- headers.each do |k,v|
273
- parsed[:headers][k.to_s.downcase] = []
274
- parsed[:headers][k.to_s.downcase] << v
275
- end
276
- parsed[:body] = "" # We never seem to get this from Acunetix
277
- parsed
278
- end
279
-
280
- # Don't cause the web report to die just because we can't tell
281
- # what method was used -- default to GET. Sometimes it's just "POST," and
282
- # sometimes it's "URL encoded POST," and sometimes it might be something
283
- # else.
284
- def parse_method(meth)
285
- verbs = "(GET|POST|PATH)"
286
- real_method = meth.match(/^\s*#{verbs}/)
287
- real_method ||= meth.match(/\s*#{verbs}\s*$/)
288
- ( real_method && real_method[1] ) ? real_method[1] : "GET"
289
- end
290
-
291
- def report_host(&block)
292
- return unless @report_data[:host]
293
- return unless in_tag("Scan")
294
- if host_is_okay
295
- db.emit(:address,@report_data[:host],&block) if block
296
- host_info = @report_data.merge(:workspace => @args[:wspace])
297
- db_report(:host,host_info)
298
- end
299
- end
300
-
301
- # The service is super important, so we hang on to it for the
302
- # rest of the scan.
303
- def report_starturl_service(host_object,&block)
304
- return unless host_object
305
- return unless @state[:starturl_uri]
306
- name = @state[:starturl_uri].scheme
307
- port = @state[:starturl_uri].port
308
- addr = host_object.address
309
- svc = {
310
- :host => host_object,
311
- :port => port,
312
- :name => name.dup,
313
- :proto => "tcp"
314
- }
315
- if name and port
316
- db.emit(:service,[addr,port].join(":"),&block) if block
317
- @state[:starturl_service_object] = db_report(:service,svc)
318
- end
319
- end
320
-
321
- def report_web_site(url,&block)
322
- return unless in_tag("Crawler")
323
- return unless url
324
- return if url.strip.empty?
325
- uri = URI.parse(url) rescue nil
326
- return unless uri
327
- host = uri.host
328
- port = uri.port
329
- scheme = uri.scheme
330
- return unless scheme[/^https?/]
331
- return unless (host && port && scheme)
332
- address = resolve_address(host)
333
- return unless address
334
- service_info = [ @args[:wspace], address, "tcp", port ]
335
- service_object = db.get_service(*service_info)
336
- service_object = db_report(:service,service_info) unless service_object
337
- web_site_info = {
338
- :workspace => @args[:wspace],
339
- :service => service_object,
340
- :vhost => host,
341
- :ssl => (scheme == "https")
342
- }
343
- @state[:web_site] = db_report(:web_site,web_site_info)
344
- @state[:fullurl] = uri
345
- end
346
-
347
- def report_starturl_web_site(&block)
348
- return unless @state[:crawler_starturl]
349
- starturl = @state[:crawler_starturl].dup
350
- report_web_site(starturl,&block)
351
- end
352
-
353
- def report_os_fingerprint
354
- return unless @state[:starturl_service_object]
355
- return unless @text
356
- return if @text.strip.empty?
357
- return unless in_tag("Scan")
358
- host = @state[:starturl_service_object].host
359
- fp_note = {
360
- :workspace => host.workspace,
361
- :host => host,
362
- :type => 'host.os.acunetix_fingerprint',
363
- :data => {:os => @text}
364
- }
365
- db_report(:note, fp_note)
366
- @text = nil
367
- end
368
-
369
- def resolve_port(uri)
370
- @state[:port] = uri.port
371
- unless @state[:port]
372
- @parse_warnings << "Could not determine a port for '#{@state[:scan_name]}'"
373
- end
374
- @state[:port] = uri.port
375
- end
376
-
377
- def resolve_address(host)
378
- return @resolv_cache[host] if @resolv_cache[host]
379
- address = Rex::Socket.resolv_to_dotted(host) rescue nil
380
- @resolv_cache[host] = address
381
- return address
382
- end
383
-
384
- def resolve_scan_starturl_address(uri)
385
- if uri.host
386
- address = resolve_address(uri.host)
387
- unless address
388
- @parse_warnings << "Could not resolve address for '#{uri.host}', skipping '#{@state[:scan_name]}'"
389
- end
390
- else
391
- @parse_warnings << "Could not determine a host for '#{@state[:scan_name]}'"
392
- end
393
- address
394
- end
395
-
396
- def handle_parse_warnings(&block)
397
- return if @parse_warnings.empty?
398
- @parse_warnings.each do |pwarn|
399
- db.emit(:warning, pwarn, &block) if block
400
- end
401
- end
402
-
403
- end
404
- end
7
+ module Parser
8
+
9
+ # If Nokogiri is available, define the Acunetix document class.
10
+ load_nokogiri && class AcunetixDocument < Nokogiri::XML::SAX::Document
11
+
12
+ include NokogiriDocMixin
13
+
14
+ # The resolver prefers your local /etc/hosts (or windows equiv), but will
15
+ # fall back to regular DNS. It retains a cache for the import to avoid
16
+ # spamming your network with DNS requests.
17
+ attr_reader :resolv_cache
18
+
19
+ # If name resolution of the host fails out completely, you will not be
20
+ # able to import that Scan task. Other scan tasks in the same report
21
+ # should be unaffected.
22
+ attr_reader :parse_warnings
23
+
24
+ def start_document
25
+ @parse_warnings = []
26
+ @resolv_cache = {}
27
+ end
28
+
29
+ def start_element(name=nil,attrs=[])
30
+ attrs = normalize_attrs(attrs)
31
+ block = @block
32
+ @state[:current_tag][name] = true
33
+ case name
34
+ when "Scan" # Start of the thing.
35
+ when "Name", "StartURL", "Banner", "Os"
36
+ @state[:has_text] = true
37
+ when "LoginSequence" # Skipping for now
38
+ when "Crawler"
39
+ record_crawler(attrs)
40
+ when "FullURL"
41
+ @state[:has_text] = true
42
+ when "Variable"
43
+ record_variable(attrs)
44
+ when "Request", "Response"
45
+ @state[:has_text] = true
46
+ end
47
+ end
48
+
49
+ def end_element(name=nil)
50
+ block = @block
51
+ case name
52
+ when "Scan"
53
+ # Clears most of the @state out, we're done with this web site.
54
+ @state.delete_if {|k| k != :current_tag}
55
+ when "Name"
56
+ @state[:has_text] = false
57
+ collect_scan_name
58
+ collect_report_item_name
59
+ @text = nil
60
+ when "StartURL" # Populates @state[:starturl_uri], we use this a lot
61
+ @state[:has_text] = false
62
+ collect_host
63
+ collect_service
64
+ @text = nil
65
+ handle_parse_warnings &block
66
+ host_object = report_host &block
67
+ if host_object
68
+ report_starturl_service(host_object,&block)
69
+ db.report_import_note(@args[:wspace],host_object)
70
+ end
71
+ when "Banner"
72
+ @state[:has_text] = false
73
+ collect_and_report_banner
74
+ when "Os"
75
+ @state[:has_text] = false
76
+ report_os_fingerprint
77
+ when "LoginSequence" # This comes up later in the report anyway
78
+ when "Crawler"
79
+ report_starturl_web_site(&block)
80
+ when "FullURL"
81
+ @state[:has_text] = false
82
+ report_web_site(@text,&block)
83
+ @text = nil
84
+ when "Inputs"
85
+ report_web_form(&block)
86
+ when "Request"
87
+ @state[:has_text] = false
88
+ collect_page_request
89
+ @text = nil
90
+ when "Response"
91
+ @state[:has_text] = false
92
+ collect_page_response
93
+ @text = nil
94
+ report_web_page(&block)
95
+ end
96
+ @state[:current_tag].delete name
97
+ end
98
+
99
+ def collect_page_response
100
+ return unless in_tag("TechnicalDetails")
101
+ return unless in_tag("ReportItem")
102
+ return unless @text
103
+ return if @text.to_s.empty?
104
+ @state[:page_response] = @text
105
+ end
106
+
107
+ def collect_page_request
108
+ return unless in_tag("TechnicalDetails")
109
+ return unless in_tag("ReportItem")
110
+ return unless @text
111
+ return if @text.to_s.empty?
112
+ @state[:page_request] = @text
113
+ end
114
+
115
+ def collect_scan_name
116
+ return unless in_tag("Scan")
117
+ return if in_tag("ReportItems")
118
+ return if in_tag("Crawler")
119
+ return unless @text
120
+ return if @text.strip.empty?
121
+ @state[:scan_name] = @text.strip
122
+ end
123
+
124
+ def collect_host
125
+ return unless in_tag("Scan")
126
+ return unless @text
127
+ return if @text.strip.empty?
128
+ uri = URI.parse(@text) rescue nil
129
+ return unless uri
130
+ address = resolve_scan_starturl_address(uri)
131
+ @report_data[:host] = address
132
+ @report_data[:state] = Msf::HostState::Alive
133
+ end
134
+
135
+ def collect_service
136
+ return unless @report_data[:host]
137
+ return unless in_tag("Scan")
138
+ return unless @text
139
+ return if @text.strip.empty?
140
+ uri = URI.parse(@text) rescue nil
141
+ return unless uri
142
+ @state[:starturl_uri] = uri
143
+ @report_data[:ports] ||= []
144
+ @report_data[:ports] << @state[:starturl_port]
145
+ end
146
+
147
+ def collect_and_report_banner
148
+ return unless (svc = @state[:starturl_service_object]) # Yes i want assignment
149
+ return unless @text
150
+ return if @text.strip.empty?
151
+ return unless in_tag("Scan")
152
+ svc_info = {
153
+ :host => svc.host,
154
+ :port => svc.port,
155
+ :proto => svc.proto,
156
+ :info => @text.strip
157
+ }
158
+ db_report(:service, svc_info)
159
+ @text = nil
160
+ end
161
+
162
+ def collect_report_item_name
163
+ return unless in_tag("ReportItem")
164
+ return unless @text
165
+ return if @text.strip.empty?
166
+ @state[:report_item] = @text
167
+ end
168
+
169
+ # @state[:fullurl] is set by report_web_site
170
+ def record_variable(attrs)
171
+ return unless in_tag("Inputs")
172
+ return unless @state[:fullurl].kind_of? URI
173
+ method = attr_hash(attrs)["Type"]
174
+ return unless method
175
+ return if method.strip.empty?
176
+ @state[:form_variables] ||= []
177
+ @state[:form_variables] << [attr_hash(attrs)["Name"],method]
178
+ end
179
+
180
+ def record_crawler(attrs)
181
+ return unless in_tag("Scan")
182
+ return unless @state[:starturl_service_object]
183
+ starturl = attr_hash(attrs)["StartUrl"]
184
+ return unless starturl
185
+ @state[:crawler_starturl] = starturl
186
+ end
187
+
188
+ def report_web_form(&block)
189
+ return unless in_tag("SiteFiles")
190
+ return unless @state[:web_site]
191
+ return unless @state[:fullurl].kind_of? URI
192
+ return unless @state[:form_variables].kind_of? Array
193
+ return if @state[:form_variables].empty?
194
+ method = parse_method(@state[:form_variables].first[1])
195
+ vars = @state[:form_variables].map {|x| x[0]}
196
+ form_info = {}
197
+ form_info[:web_site] = @state[:web_site]
198
+ form_info[:path] = @state[:fullurl].path
199
+ form_info[:query] = @state[:fullurl].query
200
+ form_info[:method] = method
201
+ form_info[:params] = vars
202
+ url = @state[:fullurl].to_s
203
+ db.emit(:web_form,url,&block) if block
204
+ db_report(:web_form,form_info)
205
+ @state[:fullurl] = nil
206
+ @state[:form_variables] = nil
207
+ end
208
+
209
+ def report_web_page(&block)
210
+ return if should_skip_this_page
211
+ return unless @state[:web_site]
212
+ return unless @state[:page_request]
213
+ return if @state[:page_request].strip.empty?
214
+ return unless @state[:page_response]
215
+ return if @state[:page_response].strip.empty?
216
+ path,query_string = parse_request(@state[:page_request])
217
+ return unless path
218
+ parsed_response = parse_response(@state[:page_response])
219
+ return unless parsed_response
220
+ web_page_info = {}
221
+ web_page_info[:web_site] = @state[:web_site]
222
+ web_page_info[:path] = path
223
+ web_page_info[:code] = parsed_response[:code].to_i
224
+ web_page_info[:headers] = parsed_response[:headers]
225
+ web_page_info[:body] = parsed_response[:body]
226
+ web_page_info[:query] = query_string || ""
227
+ url = ""
228
+ url << @state[:web_site].service.name.to_s << "://"
229
+ url << @state[:web_site].vhost.to_s << ":"
230
+ url << path
231
+ uri = URI.parse(url) rescue nil
232
+ return unless uri # Sanity checker
233
+ db.emit(:web_page, url, &block) if block
234
+ web_page_object = db_report(:web_page,web_page_info)
235
+ @state[:page_request] = @state[:page_response] = nil
236
+ @state[:web_page] = web_page_object
237
+ end
238
+
239
+ # Reasons why we shouldn't collect a particular web page.
240
+ def should_skip_this_page
241
+ if @state[:report_item] =~ /Unrestricted File Upload/
242
+ # This means that the page being collected is something the
243
+ # auditor put there, so it's not useful to report on.
244
+ return true
245
+ end
246
+ return false
247
+ end
248
+
249
+ # XXX Rex::Proto::Http::Packet seems broken for
250
+ # actually parsing requests and responses, but all I
251
+ # need are the headers anyway
252
+ def parse_request(request)
253
+ headers = Rex::Proto::Http::Packet::Header.new
254
+ headers.from_s request.dup # It's destructive.
255
+ return unless headers.cmd_string
256
+ verb,req = headers.cmd_string.split(/\s+/)
257
+ return unless verb
258
+ return unless req
259
+ path,query_string = req.split(/\?/)[0,2]
260
+ end
261
+
262
+ def parse_response(response)
263
+ headers = Rex::Proto::Http::Packet::Header.new
264
+ headers.from_s response.dup # It's destructive.
265
+ return unless headers.cmd_string
266
+ http,code,msg = headers.cmd_string.split(/\s+/)
267
+ return unless code
268
+ return unless code.to_i.to_s == code
269
+ parsed = {}
270
+ parsed[:code] = code
271
+ parsed[:headers] = {}
272
+ headers.each do |k,v|
273
+ parsed[:headers][k.to_s.downcase] = []
274
+ parsed[:headers][k.to_s.downcase] << v
275
+ end
276
+ parsed[:body] = "" # We never seem to get this from Acunetix
277
+ parsed
278
+ end
279
+
280
+ # Don't cause the web report to die just because we can't tell
281
+ # what method was used -- default to GET. Sometimes it's just "POST," and
282
+ # sometimes it's "URL encoded POST," and sometimes it might be something
283
+ # else.
284
+ def parse_method(meth)
285
+ verbs = "(GET|POST|PATH)"
286
+ real_method = meth.match(/^\s*#{verbs}/)
287
+ real_method ||= meth.match(/\s*#{verbs}\s*$/)
288
+ ( real_method && real_method[1] ) ? real_method[1] : "GET"
289
+ end
290
+
291
+ def report_host(&block)
292
+ return unless @report_data[:host]
293
+ return unless in_tag("Scan")
294
+ if host_is_okay
295
+ db.emit(:address,@report_data[:host],&block) if block
296
+ host_info = @report_data.merge(:workspace => @args[:wspace])
297
+ db_report(:host,host_info)
298
+ end
299
+ end
300
+
301
+ # The service is super important, so we hang on to it for the
302
+ # rest of the scan.
303
+ def report_starturl_service(host_object,&block)
304
+ return unless host_object
305
+ return unless @state[:starturl_uri]
306
+ name = @state[:starturl_uri].scheme
307
+ port = @state[:starturl_uri].port
308
+ addr = host_object.address
309
+ svc = {
310
+ :host => host_object,
311
+ :port => port,
312
+ :name => name.dup,
313
+ :proto => "tcp"
314
+ }
315
+ if name and port
316
+ db.emit(:service,[addr,port].join(":"),&block) if block
317
+ @state[:starturl_service_object] = db_report(:service,svc)
318
+ end
319
+ end
320
+
321
+ def report_web_site(url,&block)
322
+ return unless in_tag("Crawler")
323
+ return unless url
324
+ return if url.strip.empty?
325
+ uri = URI.parse(url) rescue nil
326
+ return unless uri
327
+ host = uri.host
328
+ port = uri.port
329
+ scheme = uri.scheme
330
+ return unless scheme[/^https?/]
331
+ return unless (host && port && scheme)
332
+ address = resolve_address(host)
333
+ return unless address
334
+ service_info = [ @args[:wspace], address, "tcp", port ]
335
+ service_object = db.get_service(*service_info)
336
+ service_object = db_report(:service,service_info) unless service_object
337
+ web_site_info = {
338
+ :workspace => @args[:wspace],
339
+ :service => service_object,
340
+ :vhost => host,
341
+ :ssl => (scheme == "https")
342
+ }
343
+ @state[:web_site] = db_report(:web_site,web_site_info)
344
+ @state[:fullurl] = uri
345
+ end
346
+
347
+ def report_starturl_web_site(&block)
348
+ return unless @state[:crawler_starturl]
349
+ starturl = @state[:crawler_starturl].dup
350
+ report_web_site(starturl,&block)
351
+ end
352
+
353
+ def report_os_fingerprint
354
+ return unless @state[:starturl_service_object]
355
+ return unless @text
356
+ return if @text.strip.empty?
357
+ return unless in_tag("Scan")
358
+ host = @state[:starturl_service_object].host
359
+ fp_note = {
360
+ :workspace => host.workspace,
361
+ :host => host,
362
+ :type => 'host.os.acunetix_fingerprint',
363
+ :data => {:os => @text}
364
+ }
365
+ db_report(:note, fp_note)
366
+ @text = nil
367
+ end
368
+
369
+ def resolve_port(uri)
370
+ @state[:port] = uri.port
371
+ unless @state[:port]
372
+ @parse_warnings << "Could not determine a port for '#{@state[:scan_name]}'"
373
+ end
374
+ @state[:port] = uri.port
375
+ end
376
+
377
+ def resolve_address(host)
378
+ return @resolv_cache[host] if @resolv_cache[host]
379
+ address = Rex::Socket.resolv_to_dotted(host) rescue nil
380
+ @resolv_cache[host] = address
381
+ return address
382
+ end
383
+
384
+ def resolve_scan_starturl_address(uri)
385
+ if uri.host
386
+ address = resolve_address(uri.host)
387
+ unless address
388
+ @parse_warnings << "Could not resolve address for '#{uri.host}', skipping '#{@state[:scan_name]}'"
389
+ end
390
+ else
391
+ @parse_warnings << "Could not determine a host for '#{@state[:scan_name]}'"
392
+ end
393
+ address
394
+ end
395
+
396
+ def handle_parse_warnings(&block)
397
+ return if @parse_warnings.empty?
398
+ @parse_warnings.each do |pwarn|
399
+ db.emit(:warning, pwarn, &block) if block
400
+ end
401
+ end
402
+
403
+ end
404
+ end
405
405
  end
406
406