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
@@ -8,123 +8,123 @@ module Rex
8
8
  module Parser
9
9
  class AppleBackupManifestDB
10
10
 
11
- attr_accessor :entry_offsets
12
- attr_accessor :entries
13
- attr_accessor :mbdb, :mbdx
14
- attr_accessor :mbdb_data, :mbdx_data
15
- attr_accessor :mbdb_offset, :mbdx_offset
16
-
17
- def initialize(mbdb_data, mbdx_data)
18
- self.entries = {}
19
- self.entry_offsets = {}
20
- self.mbdb_data = mbdb_data
21
- self.mbdx_data = mbdx_data
22
- parse_mbdb
23
- parse_mbdx
24
- end
25
-
26
- def self.from_files(mbdb_file, mbdx_file)
27
- mbdb_data = ""
28
- ::File.open(mbdb_file, "rb") {|fd| mbdb_data = fd.read(fd.stat.size) }
29
- mbdx_data = ""
30
- ::File.open(mbdx_file, "rb") {|fd| mbdx_data = fd.read(fd.stat.size) }
31
-
32
- self.new(mbdb_data, mbdx_data)
33
- end
34
-
35
- def parse_mbdb
36
- raise ArgumentError, "Not valid MBDB data" if self.mbdb_data[0,4] != "mbdb"
37
- self.mbdb_offset = 4
38
- self.mbdb_offset = self.mbdb_offset + 2 # Maps to \x05 \x00 (unknown)
39
-
40
- while self.mbdb_offset < self.mbdb_data.length
41
- info = {}
42
- info[:start_offset] = self.mbdb_offset
43
- info[:domain] = mbdb_read_string
44
- info[:filename] = mbdb_read_string
45
- info[:linktarget] = mbdb_read_string
46
- info[:datahash] = mbdb_read_string
47
- info[:unknown1] = mbdb_read_string
48
- info[:mode] = mbdb_read_int(2)
49
- info[:unknown2] = mbdb_read_int(4)
50
- info[:unknown3] = mbdb_read_int(4)
51
- info[:uid] = mbdb_read_int(4)
52
- info[:gid] = mbdb_read_int(4)
53
- info[:mtime] = Time.at(mbdb_read_int(4))
54
- info[:atime] = Time.at(mbdb_read_int(4))
55
- info[:ctime] = Time.at(mbdb_read_int(4))
56
- info[:length] = mbdb_read_int(8)
57
- info[:flag] = mbdb_read_int(1)
58
- property_count = mbdb_read_int(1)
59
- info[:properties] = {}
60
- 1.upto(property_count) do |i|
61
- k = mbdb_read_string
62
- v = mbdb_read_string
63
- info[:properties][k] = v
64
- end
65
- self.entry_offsets[ info[:start_offset] ] = info
66
- end
67
- self.mbdb_data = ""
68
- end
69
-
70
- def parse_mbdx
71
- raise ArgumentError, "Not a valid MBDX file" if self.mbdx_data[0,4] != "mbdx"
72
-
73
- self.mbdx_offset = 4
74
- self.mbdx_offset = self.mbdx_offset + 2 # Maps to \x02 \x00 (unknown)
75
-
76
- file_count = mbdx_read_int(4)
77
-
78
- while self.mbdx_offset < self.mbdx_data.length
79
- file_id = self.mbdx_data[self.mbdx_offset, 20].unpack("C*").map{|c| "%02x" % c}.join
80
- self.mbdx_offset += 20
81
- entry_offset = mbdx_read_int(4) + 6
82
- mode = mbdx_read_int(2)
83
- entry = entry_offsets[ entry_offset ]
84
- # May be corrupted if there is no matching entry, but what to do about it?
85
- next if not entry
86
- self.entries[file_id] = entry.merge({:mbdx_mode => mode, :file_id => file_id})
87
- end
88
- self.mbdx_data = ""
89
- end
90
-
91
- def mbdb_read_string
92
- raise RuntimeError, "Corrupted MBDB file" if self.mbdb_offset > self.mbdb_data.length
93
- len = self.mbdb_data[self.mbdb_offset, 2].unpack("n")[0]
94
- self.mbdb_offset += 2
95
- return '' if len == 65535
96
- val = self.mbdb_data[self.mbdb_offset, len]
97
- self.mbdb_offset += len
98
- return val
99
- end
100
-
101
- def mbdb_read_int(size)
102
- val = 0
103
- size.downto(1) do |i|
104
- val = (val << 8) + self.mbdb_data[self.mbdb_offset, 1].unpack("C")[0]
105
- self.mbdb_offset += 1
106
- end
107
- val
108
- end
109
-
110
- def mbdx_read_string
111
- raise RuntimeError, "Corrupted MBDX file" if self.mbdx_offset > self.mbdx_data.length
112
- len = self.mbdx_data[self.mbdx_offset, 2].unpack("n")[0]
113
- self.mbdx_offset += 2
114
- return '' if len == 65535
115
- val = self.mbdx_data[self.mbdx_offset, len]
116
- self.mbdx_offset += len
117
- return val
118
- end
119
-
120
- def mbdx_read_int(size)
121
- val = 0
122
- size.downto(1) do |i|
123
- val = (val << 8) + self.mbdx_data[self.mbdx_offset, 1].unpack("C")[0]
124
- self.mbdx_offset += 1
125
- end
11
+ attr_accessor :entry_offsets
12
+ attr_accessor :entries
13
+ attr_accessor :mbdb, :mbdx
14
+ attr_accessor :mbdb_data, :mbdx_data
15
+ attr_accessor :mbdb_offset, :mbdx_offset
16
+
17
+ def initialize(mbdb_data, mbdx_data)
18
+ self.entries = {}
19
+ self.entry_offsets = {}
20
+ self.mbdb_data = mbdb_data
21
+ self.mbdx_data = mbdx_data
22
+ parse_mbdb
23
+ parse_mbdx
24
+ end
25
+
26
+ def self.from_files(mbdb_file, mbdx_file)
27
+ mbdb_data = ""
28
+ ::File.open(mbdb_file, "rb") {|fd| mbdb_data = fd.read(fd.stat.size) }
29
+ mbdx_data = ""
30
+ ::File.open(mbdx_file, "rb") {|fd| mbdx_data = fd.read(fd.stat.size) }
31
+
32
+ self.new(mbdb_data, mbdx_data)
33
+ end
34
+
35
+ def parse_mbdb
36
+ raise ArgumentError, "Not valid MBDB data" if self.mbdb_data[0,4] != "mbdb"
37
+ self.mbdb_offset = 4
38
+ self.mbdb_offset = self.mbdb_offset + 2 # Maps to \x05 \x00 (unknown)
39
+
40
+ while self.mbdb_offset < self.mbdb_data.length
41
+ info = {}
42
+ info[:start_offset] = self.mbdb_offset
43
+ info[:domain] = mbdb_read_string
44
+ info[:filename] = mbdb_read_string
45
+ info[:linktarget] = mbdb_read_string
46
+ info[:datahash] = mbdb_read_string
47
+ info[:unknown1] = mbdb_read_string
48
+ info[:mode] = mbdb_read_int(2)
49
+ info[:unknown2] = mbdb_read_int(4)
50
+ info[:unknown3] = mbdb_read_int(4)
51
+ info[:uid] = mbdb_read_int(4)
52
+ info[:gid] = mbdb_read_int(4)
53
+ info[:mtime] = Time.at(mbdb_read_int(4))
54
+ info[:atime] = Time.at(mbdb_read_int(4))
55
+ info[:ctime] = Time.at(mbdb_read_int(4))
56
+ info[:length] = mbdb_read_int(8)
57
+ info[:flag] = mbdb_read_int(1)
58
+ property_count = mbdb_read_int(1)
59
+ info[:properties] = {}
60
+ 1.upto(property_count) do |i|
61
+ k = mbdb_read_string
62
+ v = mbdb_read_string
63
+ info[:properties][k] = v
64
+ end
65
+ self.entry_offsets[ info[:start_offset] ] = info
66
+ end
67
+ self.mbdb_data = ""
68
+ end
69
+
70
+ def parse_mbdx
71
+ raise ArgumentError, "Not a valid MBDX file" if self.mbdx_data[0,4] != "mbdx"
72
+
73
+ self.mbdx_offset = 4
74
+ self.mbdx_offset = self.mbdx_offset + 2 # Maps to \x02 \x00 (unknown)
75
+
76
+ file_count = mbdx_read_int(4)
77
+
78
+ while self.mbdx_offset < self.mbdx_data.length
79
+ file_id = self.mbdx_data[self.mbdx_offset, 20].unpack("C*").map{|c| "%02x" % c}.join
80
+ self.mbdx_offset += 20
81
+ entry_offset = mbdx_read_int(4) + 6
82
+ mode = mbdx_read_int(2)
83
+ entry = entry_offsets[ entry_offset ]
84
+ # May be corrupted if there is no matching entry, but what to do about it?
85
+ next if not entry
86
+ self.entries[file_id] = entry.merge({:mbdx_mode => mode, :file_id => file_id})
87
+ end
88
+ self.mbdx_data = ""
89
+ end
90
+
91
+ def mbdb_read_string
92
+ raise RuntimeError, "Corrupted MBDB file" if self.mbdb_offset > self.mbdb_data.length
93
+ len = self.mbdb_data[self.mbdb_offset, 2].unpack("n")[0]
94
+ self.mbdb_offset += 2
95
+ return '' if len == 65535
96
+ val = self.mbdb_data[self.mbdb_offset, len]
97
+ self.mbdb_offset += len
98
+ return val
99
+ end
100
+
101
+ def mbdb_read_int(size)
102
+ val = 0
103
+ size.downto(1) do |i|
104
+ val = (val << 8) + self.mbdb_data[self.mbdb_offset, 1].unpack("C")[0]
105
+ self.mbdb_offset += 1
106
+ end
107
+ val
108
+ end
109
+
110
+ def mbdx_read_string
111
+ raise RuntimeError, "Corrupted MBDX file" if self.mbdx_offset > self.mbdx_data.length
112
+ len = self.mbdx_data[self.mbdx_offset, 2].unpack("n")[0]
113
+ self.mbdx_offset += 2
114
+ return '' if len == 65535
115
+ val = self.mbdx_data[self.mbdx_offset, len]
116
+ self.mbdx_offset += len
117
+ return val
118
+ end
119
+
120
+ def mbdx_read_int(size)
121
+ val = 0
122
+ size.downto(1) do |i|
123
+ val = (val << 8) + self.mbdx_data[self.mbdx_offset, 1].unpack("C")[0]
124
+ self.mbdx_offset += 1
125
+ end
126
126
  val
127
- end
127
+ end
128
128
  end
129
129
 
130
130
 
@@ -2,365 +2,365 @@
2
2
  require "rex/parser/nokogiri_doc_mixin"
3
3
 
4
4
  module Rex
5
- module Parser
6
-
7
- # If Nokogiri is available, define AppScan document class.
8
- load_nokogiri && class AppscanDocument < Nokogiri::XML::SAX::Document
9
-
10
- include NokogiriDocMixin
11
-
12
- # The resolver prefers your local /etc/hosts (or windows equiv), but will
13
- # fall back to regular DNS. It retains a cache for the import to avoid
14
- # spamming your network with DNS requests.
15
- attr_reader :resolv_cache
16
-
17
- # If name resolution of the host fails out completely, you will not be
18
- # able to import that Scan task. Other scan tasks in the same report
19
- # should be unaffected.
20
- attr_reader :parse_warning
21
-
22
- def start_document
23
- @parse_warnings = []
24
- @resolv_cache = {}
25
- end
26
-
27
- def start_element(name=nil,attrs=[])
28
- attrs = normalize_attrs(attrs)
29
- block = @block
30
- @state[:current_tag][name] = true
31
- case name
32
- when "Issue" # Start of the stuff we want
33
- collect_issue(attrs)
34
- when "Entity" # Start of the stuff we want
35
- collect_entity(attrs)
36
- when "Severity", "Url", "OriginalHttpTraffic"
37
- @state[:has_text] = true
38
- end
39
- end
40
-
41
- def end_element(name=nil)
42
- block = @block
43
- case name
44
- when "Issue" # Wrap it up
45
- record_issue
46
- # Reset the state once we close an issue
47
- @state = @state.select do
48
- |k| [:current_tag, :web_sites].include? k
49
- end
50
- when "Url" # Populates @state[:web_site]
51
- @state[:has_text] = false
52
- record_url
53
- @text = nil
54
- report_web_site(&block)
55
- handle_parse_warnings(&block)
56
- when "Severity"
57
- @state[:has_text] = false
58
- record_risk
59
- @text = nil
60
- when "OriginalHttpTraffic" # Request and response
61
- @state[:has_text] = false
62
- record_request_and_response
63
- report_service_info
64
- page_info = report_web_page(&block)
65
- if page_info
66
- form_info = report_web_form(page_info,&block)
67
- if form_info
68
- report_web_vuln(form_info,&block)
69
- end
70
- end
71
- @text = nil
72
- end
73
- @state[:current_tag].delete name
74
- end
75
-
76
- def report_web_vuln(form_info,&block)
77
- return unless(in_issue && has_text)
78
- return unless form_info.kind_of? Hash
79
- return unless @state[:issue]
80
- return unless @state[:issue]["Noise"]
81
- return unless @state[:issue]["Noise"].to_s.downcase == "false"
82
- return unless @state[:issue][:vuln_param]
83
- web_vuln_info = {}
84
- web_vuln_info[:web_site] = form_info[:web_site]
85
- web_vuln_info[:path] = form_info[:path]
86
- web_vuln_info[:query] = form_info[:query]
87
- web_vuln_info[:method] = form_info[:method]
88
- web_vuln_info[:params] = form_info[:params]
89
- web_vuln_info[:pname] = @state[:issue][:vuln_param]
90
- web_vuln_info[:proof] = "" # TODO: pick this up from <Difference> maybe?
91
- web_vuln_info[:risk] = @state[:issue][:risk]
92
- web_vuln_info[:name] = @state[:issue]["IssueTypeID"]
93
- web_vuln_info[:category] = "imported"
94
- web_vuln_info[:confidence] = 100 # Seems pretty binary, noise or not
95
- db.emit(:web_vuln, web_vuln_info[:name], &block) if block
96
- web_vuln = db_report(:web_vuln, web_vuln_info)
97
- end
98
-
99
- def collect_entity(attrs)
100
- return unless in_issue
101
- return unless @state[:issue].kind_of? Hash
102
- ent_hash = attr_hash(attrs)
103
- return unless ent_hash
104
- return unless ent_hash["Type"].to_s.downcase == "parameter"
105
- @state[:issue][:vuln_param] = ent_hash["Name"]
106
- end
107
-
108
- def report_web_form(page_info,&block)
109
- return unless(in_issue && has_text)
110
- return unless page_info.kind_of? Hash
111
- return unless @state[:request_body]
112
- return if @state[:request_body].strip.empty?
113
- web_form_info = {}
114
- web_form_info[:web_site] = page_info[:web_site]
115
- web_form_info[:path] = page_info[:path]
116
- web_form_info[:query] = page_info[:query]
117
- web_form_info[:method] = @state[:request_headers].cmd_string.split(/\s+/)[0]
118
- parsed_params = parse_params(@state[:request_body])
119
- return unless parsed_params
120
- return if parsed_params.empty?
121
- web_form_info[:params] = parsed_params
122
- web_form = db_report(:web_form, web_form_info)
123
- @state[:web_forms] ||= []
124
- unless @state[:web_forms].include? web_form
125
- db.emit(:web_form, @state[:uri].to_s, &block) if block
126
- @state[:web_forms] << web_form
127
- end
128
- web_form_info
129
- end
130
-
131
- def parse_params(request_body)
132
- return unless request_body
133
- pairs = request_body.split(/&/)
134
- params = []
135
- pairs.each do |pair|
136
- param,value = pair.split("=",2)
137
- params << [param,""] # Can't tell what's default
138
- end
139
- params
140
- end
141
-
142
- def report_web_page(&block)
143
- return unless(in_issue && has_text)
144
- return unless @state[:web_site]
145
- return unless @state[:response_headers]
146
- return unless @state[:uri]
147
- web_page_info = {}
148
- web_page_info[:web_site] = @state[:web_site]
149
- web_page_info[:path] = @state[:uri].path
150
- web_page_info[:body] = @state[:response_body].to_s
151
- web_page_info[:query] = @state[:uri].query
152
- code = @state[:response_headers].cmd_string.split(/\s+/)[1]
153
- return unless code
154
- web_page_info[:code] = code
155
- parsed_headers = {}
156
- @state[:response_headers].each do |k,v|
157
- parsed_headers[k.to_s.downcase] ||= []
158
- parsed_headers[k.to_s.downcase] << v
159
- end
160
- return if parsed_headers.empty?
161
- web_page_info[:headers] = parsed_headers
162
- web_page = db_report(:web_page, web_page_info)
163
- @state[:web_pages] ||= []
164
- unless @state[:web_pages].include? web_page
165
- db.emit(:web_page, @state[:uri].to_s, &block) if block
166
- @state[:web_pages] << web_page
167
- end
168
- web_page_info
169
- end
170
-
171
- def report_service_info
172
- return unless(in_issue && has_text)
173
- return unless @state[:web_site]
174
- return unless @state[:response_headers]
175
- banner = @state[:response_headers]["server"]
176
- return unless banner
177
- service = @state[:web_site].service
178
- return unless service.info.to_s.empty?
179
- service_info = {
180
- :host => service.host,
181
- :port => service.port,
182
- :proto => service.proto,
183
- :info => banner
184
- }
185
- db_report(:service, service_info)
186
- end
187
-
188
- def record_request_and_response
189
- return unless(in_issue && has_text)
190
- return unless @state[:web_site]
191
- really_original_traffic = unindent_and_crlf(@text)
192
- split_traffic = really_original_traffic.split(/\r\n\r\n/)
193
- request_headers_text = split_traffic.first
194
- content_length = 0
195
- if request_headers_text =~ /\ncontent-length:\s+([0-9]+)/mni
196
- content_length = $1.to_i
197
- end
198
- if(content_length > 0) and (split_traffic[1].to_s.size >= content_length)
199
- request_body_text = split_traffic[1].to_s[0,content_length]
200
- else
201
- request_body_text = nil
202
- end
203
- response_headers_text = split_traffic[1].to_s[content_length,split_traffic[1].to_s.size].lstrip
204
- request = request_headers_text
205
- return unless(request && response_headers_text)
206
- response_body_text = split_traffic[2]
207
- req_header = Rex::Proto::Http::Packet::Header.new
208
- res_header = Rex::Proto::Http::Packet::Header.new
209
- req_header.from_s request_headers_text.dup
210
- res_header.from_s response_headers_text.dup
211
- @state[:request_headers] = req_header
212
- @state[:request_body] = request_body_text
213
- @state[:response_headers] = res_header
214
- @state[:response_body] = response_body_text
215
- end
216
-
217
- # Appscan tab-indents which makes parsing a little difficult. They
218
- # also don't record CRLFs, just LFs.
219
- def unindent_and_crlf(text)
220
- second_line = text.split(/\r*\n/)[1]
221
- indent_level = second_line.size - second_line.lstrip.size
222
- unindented_text_lines = []
223
- text.split(/\r*\n/).each do |line|
224
- if line =~ /^\t{#{indent_level}}/
225
- unindented_line = line[indent_level,line.size]
226
- unindented_text_lines << unindented_line
227
- else
228
- unindented_text_lines << line
229
- end
230
- end
231
- unindented_text_lines.join("\r\n")
232
- end
233
-
234
- def record_risk
235
- return unless(in_issue && has_text)
236
- @state[:issue] ||= {}
237
- @state[:issue][:risk] = map_severity_to_risk
238
- end
239
-
240
- def map_severity_to_risk
241
- case @text.to_s.downcase
242
- when "high" ; 5
243
- when "medium" ; 3
244
- when "low" ; 1
245
- else ; 0
246
- end
247
- end
248
-
249
- # TODO
250
- def record_issue
251
- return unless in_issue
252
- return unless @report_data[:issue].kind_of? Hash
253
- return unless @state[:web_site]
254
- return if @state[:issue]["Noise"].to_s.downcase == "true"
255
- end
256
-
257
- def collect_issue(attrs)
258
- return unless in_issue
259
- @state[:issue] = {}
260
- @state[:issue].merge! attr_hash(attrs)
261
- end
262
-
263
- def report_web_site(&block)
264
- return unless @state[:uri]
265
- uri = @state[:uri]
266
- hostname = uri.host # Assume the first one is the real hostname
267
- address = resolve_issue_url_address(uri)
268
- return unless address
269
- unless @resolv_cache.values.include? address
270
- db.emit(:address, address, &block) if block
271
- end
272
- port = resolve_port(uri)
273
- return unless port
274
- scheme = uri.scheme
275
- return unless scheme
276
- web_site_info = {:workspace => @args[:wspace]}
277
- web_site_info[:vhost] = hostname
278
- service_obj = check_for_existing_service(address,port)
279
- if service_obj
280
- web_site_info[:service] = service_obj
281
- else
282
- web_site_info[:host] = address
283
- web_site_info[:port] = port
284
- web_site_info[:ssl] = scheme == "https"
285
- end
286
- web_site_obj = db_report(:web_site, web_site_info)
287
- @state[:web_sites] ||= []
288
- unless @state[:web_sites].include? web_site_obj
289
- url = "#{uri.scheme}://#{uri.host}:#{uri.port}"
290
- db.emit(:web_site, url, &block) if block
291
- db.report_import_note(@args[:wspace], web_site_obj.service.host)
292
- @state[:web_sites] << web_site_obj
293
- end
294
- @state[:service] = service_obj || web_site_obj.service
295
- @state[:host] = (service_obj || web_site_obj.service).host
296
- @state[:web_site] = web_site_obj
297
- end
298
-
299
- def check_for_existing_service(address,port)
300
- db.get_service(@args[:wspace],address,"tcp",port)
301
- end
302
-
303
- def resolve_port(uri)
304
- @state[:port] = uri.port
305
- unless @state[:port]
306
- @parse_warnings << "Could not determine a port for '#{@state[:scan_name]}'"
307
- end
308
- return @state[:port]
309
- end
310
-
311
- def resolve_address(host)
312
- return @resolv_cache[host] if @resolv_cache[host]
313
- address = Rex::Socket.resolv_to_dotted(host) rescue nil
314
- @resolv_cache[host] = address
315
- if address
316
- block = @block
317
- db.emit(:address, address, &block) if block
318
- end
319
- return address
320
- end
321
-
322
- # Alias this
323
- def resolve_issue_url_address(uri)
324
- if uri.host
325
- address = resolve_address(uri.host)
326
- unless address
327
- @parse_warnings << "Could not resolve address for '#{uri.host}', skipping."
328
- end
329
- else
330
- @parse_warnings << "Could not determine a host for this import."
331
- end
332
- address
333
- end
334
-
335
- def handle_parse_warnings(&block)
336
- return if @parse_warnings.empty?
337
- @parse_warnings.each do |pwarn|
338
- db.emit(:warning, pwarn, &block) if block
339
- end
340
- end
341
-
342
- def record_url
343
- return unless in_issue
344
- return unless has_text
345
- uri = URI.parse(@text) rescue nil
346
- return unless uri
347
- @state[:uri] = uri
348
- end
349
-
350
- def in_issue
351
- return false unless in_tag("Issue")
352
- return false unless in_tag("Issues")
353
- return false unless in_tag("XmlReport")
354
- return true
355
- end
356
-
357
- def has_text
358
- return false unless @text
359
- return false if @text.strip.empty?
360
- @text = @text.strip
361
- end
362
-
363
- end
5
+ module Parser
6
+
7
+ # If Nokogiri is available, define AppScan document class.
8
+ load_nokogiri && class AppscanDocument < Nokogiri::XML::SAX::Document
9
+
10
+ include NokogiriDocMixin
11
+
12
+ # The resolver prefers your local /etc/hosts (or windows equiv), but will
13
+ # fall back to regular DNS. It retains a cache for the import to avoid
14
+ # spamming your network with DNS requests.
15
+ attr_reader :resolv_cache
16
+
17
+ # If name resolution of the host fails out completely, you will not be
18
+ # able to import that Scan task. Other scan tasks in the same report
19
+ # should be unaffected.
20
+ attr_reader :parse_warning
21
+
22
+ def start_document
23
+ @parse_warnings = []
24
+ @resolv_cache = {}
25
+ end
26
+
27
+ def start_element(name=nil,attrs=[])
28
+ attrs = normalize_attrs(attrs)
29
+ block = @block
30
+ @state[:current_tag][name] = true
31
+ case name
32
+ when "Issue" # Start of the stuff we want
33
+ collect_issue(attrs)
34
+ when "Entity" # Start of the stuff we want
35
+ collect_entity(attrs)
36
+ when "Severity", "Url", "OriginalHttpTraffic"
37
+ @state[:has_text] = true
38
+ end
39
+ end
40
+
41
+ def end_element(name=nil)
42
+ block = @block
43
+ case name
44
+ when "Issue" # Wrap it up
45
+ record_issue
46
+ # Reset the state once we close an issue
47
+ @state = @state.select do
48
+ |k| [:current_tag, :web_sites].include? k
49
+ end
50
+ when "Url" # Populates @state[:web_site]
51
+ @state[:has_text] = false
52
+ record_url
53
+ @text = nil
54
+ report_web_site(&block)
55
+ handle_parse_warnings(&block)
56
+ when "Severity"
57
+ @state[:has_text] = false
58
+ record_risk
59
+ @text = nil
60
+ when "OriginalHttpTraffic" # Request and response
61
+ @state[:has_text] = false
62
+ record_request_and_response
63
+ report_service_info
64
+ page_info = report_web_page(&block)
65
+ if page_info
66
+ form_info = report_web_form(page_info,&block)
67
+ if form_info
68
+ report_web_vuln(form_info,&block)
69
+ end
70
+ end
71
+ @text = nil
72
+ end
73
+ @state[:current_tag].delete name
74
+ end
75
+
76
+ def report_web_vuln(form_info,&block)
77
+ return unless(in_issue && has_text)
78
+ return unless form_info.kind_of? Hash
79
+ return unless @state[:issue]
80
+ return unless @state[:issue]["Noise"]
81
+ return unless @state[:issue]["Noise"].to_s.downcase == "false"
82
+ return unless @state[:issue][:vuln_param]
83
+ web_vuln_info = {}
84
+ web_vuln_info[:web_site] = form_info[:web_site]
85
+ web_vuln_info[:path] = form_info[:path]
86
+ web_vuln_info[:query] = form_info[:query]
87
+ web_vuln_info[:method] = form_info[:method]
88
+ web_vuln_info[:params] = form_info[:params]
89
+ web_vuln_info[:pname] = @state[:issue][:vuln_param]
90
+ web_vuln_info[:proof] = "" # TODO: pick this up from <Difference> maybe?
91
+ web_vuln_info[:risk] = @state[:issue][:risk]
92
+ web_vuln_info[:name] = @state[:issue]["IssueTypeID"]
93
+ web_vuln_info[:category] = "imported"
94
+ web_vuln_info[:confidence] = 100 # Seems pretty binary, noise or not
95
+ db.emit(:web_vuln, web_vuln_info[:name], &block) if block
96
+ web_vuln = db_report(:web_vuln, web_vuln_info)
97
+ end
98
+
99
+ def collect_entity(attrs)
100
+ return unless in_issue
101
+ return unless @state[:issue].kind_of? Hash
102
+ ent_hash = attr_hash(attrs)
103
+ return unless ent_hash
104
+ return unless ent_hash["Type"].to_s.downcase == "parameter"
105
+ @state[:issue][:vuln_param] = ent_hash["Name"]
106
+ end
107
+
108
+ def report_web_form(page_info,&block)
109
+ return unless(in_issue && has_text)
110
+ return unless page_info.kind_of? Hash
111
+ return unless @state[:request_body]
112
+ return if @state[:request_body].strip.empty?
113
+ web_form_info = {}
114
+ web_form_info[:web_site] = page_info[:web_site]
115
+ web_form_info[:path] = page_info[:path]
116
+ web_form_info[:query] = page_info[:query]
117
+ web_form_info[:method] = @state[:request_headers].cmd_string.split(/\s+/)[0]
118
+ parsed_params = parse_params(@state[:request_body])
119
+ return unless parsed_params
120
+ return if parsed_params.empty?
121
+ web_form_info[:params] = parsed_params
122
+ web_form = db_report(:web_form, web_form_info)
123
+ @state[:web_forms] ||= []
124
+ unless @state[:web_forms].include? web_form
125
+ db.emit(:web_form, @state[:uri].to_s, &block) if block
126
+ @state[:web_forms] << web_form
127
+ end
128
+ web_form_info
129
+ end
130
+
131
+ def parse_params(request_body)
132
+ return unless request_body
133
+ pairs = request_body.split(/&/)
134
+ params = []
135
+ pairs.each do |pair|
136
+ param,value = pair.split("=",2)
137
+ params << [param,""] # Can't tell what's default
138
+ end
139
+ params
140
+ end
141
+
142
+ def report_web_page(&block)
143
+ return unless(in_issue && has_text)
144
+ return unless @state[:web_site]
145
+ return unless @state[:response_headers]
146
+ return unless @state[:uri]
147
+ web_page_info = {}
148
+ web_page_info[:web_site] = @state[:web_site]
149
+ web_page_info[:path] = @state[:uri].path
150
+ web_page_info[:body] = @state[:response_body].to_s
151
+ web_page_info[:query] = @state[:uri].query
152
+ code = @state[:response_headers].cmd_string.split(/\s+/)[1]
153
+ return unless code
154
+ web_page_info[:code] = code
155
+ parsed_headers = {}
156
+ @state[:response_headers].each do |k,v|
157
+ parsed_headers[k.to_s.downcase] ||= []
158
+ parsed_headers[k.to_s.downcase] << v
159
+ end
160
+ return if parsed_headers.empty?
161
+ web_page_info[:headers] = parsed_headers
162
+ web_page = db_report(:web_page, web_page_info)
163
+ @state[:web_pages] ||= []
164
+ unless @state[:web_pages].include? web_page
165
+ db.emit(:web_page, @state[:uri].to_s, &block) if block
166
+ @state[:web_pages] << web_page
167
+ end
168
+ web_page_info
169
+ end
170
+
171
+ def report_service_info
172
+ return unless(in_issue && has_text)
173
+ return unless @state[:web_site]
174
+ return unless @state[:response_headers]
175
+ banner = @state[:response_headers]["server"]
176
+ return unless banner
177
+ service = @state[:web_site].service
178
+ return unless service.info.to_s.empty?
179
+ service_info = {
180
+ :host => service.host,
181
+ :port => service.port,
182
+ :proto => service.proto,
183
+ :info => banner
184
+ }
185
+ db_report(:service, service_info)
186
+ end
187
+
188
+ def record_request_and_response
189
+ return unless(in_issue && has_text)
190
+ return unless @state[:web_site]
191
+ really_original_traffic = unindent_and_crlf(@text)
192
+ split_traffic = really_original_traffic.split(/\r\n\r\n/)
193
+ request_headers_text = split_traffic.first
194
+ content_length = 0
195
+ if request_headers_text =~ /\ncontent-length:\s+([0-9]+)/mni
196
+ content_length = $1.to_i
197
+ end
198
+ if(content_length > 0) and (split_traffic[1].to_s.size >= content_length)
199
+ request_body_text = split_traffic[1].to_s[0,content_length]
200
+ else
201
+ request_body_text = nil
202
+ end
203
+ response_headers_text = split_traffic[1].to_s[content_length,split_traffic[1].to_s.size].lstrip
204
+ request = request_headers_text
205
+ return unless(request && response_headers_text)
206
+ response_body_text = split_traffic[2]
207
+ req_header = Rex::Proto::Http::Packet::Header.new
208
+ res_header = Rex::Proto::Http::Packet::Header.new
209
+ req_header.from_s request_headers_text.dup
210
+ res_header.from_s response_headers_text.dup
211
+ @state[:request_headers] = req_header
212
+ @state[:request_body] = request_body_text
213
+ @state[:response_headers] = res_header
214
+ @state[:response_body] = response_body_text
215
+ end
216
+
217
+ # Appscan tab-indents which makes parsing a little difficult. They
218
+ # also don't record CRLFs, just LFs.
219
+ def unindent_and_crlf(text)
220
+ second_line = text.split(/\r*\n/)[1]
221
+ indent_level = second_line.size - second_line.lstrip.size
222
+ unindented_text_lines = []
223
+ text.split(/\r*\n/).each do |line|
224
+ if line =~ /^\t{#{indent_level}}/
225
+ unindented_line = line[indent_level,line.size]
226
+ unindented_text_lines << unindented_line
227
+ else
228
+ unindented_text_lines << line
229
+ end
230
+ end
231
+ unindented_text_lines.join("\r\n")
232
+ end
233
+
234
+ def record_risk
235
+ return unless(in_issue && has_text)
236
+ @state[:issue] ||= {}
237
+ @state[:issue][:risk] = map_severity_to_risk
238
+ end
239
+
240
+ def map_severity_to_risk
241
+ case @text.to_s.downcase
242
+ when "high" ; 5
243
+ when "medium" ; 3
244
+ when "low" ; 1
245
+ else ; 0
246
+ end
247
+ end
248
+
249
+ # TODO
250
+ def record_issue
251
+ return unless in_issue
252
+ return unless @report_data[:issue].kind_of? Hash
253
+ return unless @state[:web_site]
254
+ return if @state[:issue]["Noise"].to_s.downcase == "true"
255
+ end
256
+
257
+ def collect_issue(attrs)
258
+ return unless in_issue
259
+ @state[:issue] = {}
260
+ @state[:issue].merge! attr_hash(attrs)
261
+ end
262
+
263
+ def report_web_site(&block)
264
+ return unless @state[:uri]
265
+ uri = @state[:uri]
266
+ hostname = uri.host # Assume the first one is the real hostname
267
+ address = resolve_issue_url_address(uri)
268
+ return unless address
269
+ unless @resolv_cache.values.include? address
270
+ db.emit(:address, address, &block) if block
271
+ end
272
+ port = resolve_port(uri)
273
+ return unless port
274
+ scheme = uri.scheme
275
+ return unless scheme
276
+ web_site_info = {:workspace => @args[:wspace]}
277
+ web_site_info[:vhost] = hostname
278
+ service_obj = check_for_existing_service(address,port)
279
+ if service_obj
280
+ web_site_info[:service] = service_obj
281
+ else
282
+ web_site_info[:host] = address
283
+ web_site_info[:port] = port
284
+ web_site_info[:ssl] = scheme == "https"
285
+ end
286
+ web_site_obj = db_report(:web_site, web_site_info)
287
+ @state[:web_sites] ||= []
288
+ unless @state[:web_sites].include? web_site_obj
289
+ url = "#{uri.scheme}://#{uri.host}:#{uri.port}"
290
+ db.emit(:web_site, url, &block) if block
291
+ db.report_import_note(@args[:wspace], web_site_obj.service.host)
292
+ @state[:web_sites] << web_site_obj
293
+ end
294
+ @state[:service] = service_obj || web_site_obj.service
295
+ @state[:host] = (service_obj || web_site_obj.service).host
296
+ @state[:web_site] = web_site_obj
297
+ end
298
+
299
+ def check_for_existing_service(address,port)
300
+ db.get_service(@args[:wspace],address,"tcp",port)
301
+ end
302
+
303
+ def resolve_port(uri)
304
+ @state[:port] = uri.port
305
+ unless @state[:port]
306
+ @parse_warnings << "Could not determine a port for '#{@state[:scan_name]}'"
307
+ end
308
+ return @state[:port]
309
+ end
310
+
311
+ def resolve_address(host)
312
+ return @resolv_cache[host] if @resolv_cache[host]
313
+ address = Rex::Socket.resolv_to_dotted(host) rescue nil
314
+ @resolv_cache[host] = address
315
+ if address
316
+ block = @block
317
+ db.emit(:address, address, &block) if block
318
+ end
319
+ return address
320
+ end
321
+
322
+ # Alias this
323
+ def resolve_issue_url_address(uri)
324
+ if uri.host
325
+ address = resolve_address(uri.host)
326
+ unless address
327
+ @parse_warnings << "Could not resolve address for '#{uri.host}', skipping."
328
+ end
329
+ else
330
+ @parse_warnings << "Could not determine a host for this import."
331
+ end
332
+ address
333
+ end
334
+
335
+ def handle_parse_warnings(&block)
336
+ return if @parse_warnings.empty?
337
+ @parse_warnings.each do |pwarn|
338
+ db.emit(:warning, pwarn, &block) if block
339
+ end
340
+ end
341
+
342
+ def record_url
343
+ return unless in_issue
344
+ return unless has_text
345
+ uri = URI.parse(@text) rescue nil
346
+ return unless uri
347
+ @state[:uri] = uri
348
+ end
349
+
350
+ def in_issue
351
+ return false unless in_tag("Issue")
352
+ return false unless in_tag("Issues")
353
+ return false unless in_tag("XmlReport")
354
+ return true
355
+ end
356
+
357
+ def has_text
358
+ return false unless @text
359
+ return false if @text.strip.empty?
360
+ @text = @text.strip
361
+ end
362
+
363
+ end
364
364
 
365
365
  end
366
366
  end