librex 0.0.20 → 0.0.21

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 (435) hide show
  1. data/Rakefile +1 -0
  2. data/lib/rex/LICENSE +29 -0
  3. data/lib/rex/arch.rb +103 -0
  4. data/lib/rex/arch/sparc.rb +75 -0
  5. data/lib/rex/arch/sparc.rb.ut.rb +18 -0
  6. data/lib/rex/arch/x86.rb +513 -0
  7. data/lib/rex/arch/x86.rb.ut.rb +93 -0
  8. data/lib/rex/assembly/nasm.rb +104 -0
  9. data/lib/rex/assembly/nasm.rb.ut.rb +22 -0
  10. data/lib/rex/codepage.map +104 -0
  11. data/lib/rex/compat.rb +311 -0
  12. data/lib/rex/constants.rb +113 -0
  13. data/lib/rex/elfparsey.rb +11 -0
  14. data/lib/rex/elfparsey/elf.rb +123 -0
  15. data/lib/rex/elfparsey/elfbase.rb +258 -0
  16. data/lib/rex/elfparsey/exceptions.rb +27 -0
  17. data/lib/rex/elfscan.rb +12 -0
  18. data/lib/rex/elfscan/scanner.rb +207 -0
  19. data/lib/rex/elfscan/search.rb +46 -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 +114 -0
  24. data/lib/rex/encoder/alpha2/unicode_mixed.rb +117 -0
  25. data/lib/rex/encoder/alpha2/unicode_upper.rb +129 -0
  26. data/lib/rex/encoder/ndr.rb +89 -0
  27. data/lib/rex/encoder/ndr.rb.ut.rb +44 -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 +106 -0
  31. data/lib/rex/encoder/xdr.rb.ut.rb +29 -0
  32. data/lib/rex/encoder/xor.rb +69 -0
  33. data/lib/rex/encoder/xor/dword.rb +13 -0
  34. data/lib/rex/encoder/xor/dword_additive.rb +13 -0
  35. data/lib/rex/encoders/xor_dword.rb +35 -0
  36. data/lib/rex/encoders/xor_dword_additive.rb +53 -0
  37. data/lib/rex/encoders/xor_dword_additive.rb.ut.rb +12 -0
  38. data/lib/rex/encoding/xor.rb +20 -0
  39. data/lib/rex/encoding/xor.rb.ts.rb +14 -0
  40. data/lib/rex/encoding/xor/byte.rb +15 -0
  41. data/lib/rex/encoding/xor/byte.rb.ut.rb +21 -0
  42. data/lib/rex/encoding/xor/dword.rb +21 -0
  43. data/lib/rex/encoding/xor/dword.rb.ut.rb +15 -0
  44. data/lib/rex/encoding/xor/dword_additive.rb +92 -0
  45. data/lib/rex/encoding/xor/dword_additive.rb.ut.rb +15 -0
  46. data/lib/rex/encoding/xor/exceptions.rb +17 -0
  47. data/lib/rex/encoding/xor/generic.rb +146 -0
  48. data/lib/rex/encoding/xor/generic.rb.ut.rb +120 -0
  49. data/lib/rex/encoding/xor/qword.rb +15 -0
  50. data/lib/rex/encoding/xor/word.rb +21 -0
  51. data/lib/rex/encoding/xor/word.rb.ut.rb +13 -0
  52. data/lib/rex/exceptions.rb +275 -0
  53. data/lib/rex/exceptions.rb.ut.rb +44 -0
  54. data/lib/rex/exploitation/cmdstager.rb +9 -0
  55. data/lib/rex/exploitation/cmdstager/base.rb +175 -0
  56. data/lib/rex/exploitation/cmdstager/debug_asm.rb +142 -0
  57. data/lib/rex/exploitation/cmdstager/debug_write.rb +136 -0
  58. data/lib/rex/exploitation/cmdstager/tftp.rb +63 -0
  59. data/lib/rex/exploitation/cmdstager/vbs.rb +128 -0
  60. data/lib/rex/exploitation/egghunter.rb +277 -0
  61. data/lib/rex/exploitation/egghunter.rb.ut.rb +25 -0
  62. data/lib/rex/exploitation/encryptjs.rb +77 -0
  63. data/lib/rex/exploitation/heaplib.js.b64 +331 -0
  64. data/lib/rex/exploitation/heaplib.rb +94 -0
  65. data/lib/rex/exploitation/javascriptosdetect.rb +897 -0
  66. data/lib/rex/exploitation/obfuscatejs.rb +335 -0
  67. data/lib/rex/exploitation/omelet.rb +320 -0
  68. data/lib/rex/exploitation/omelet.rb.ut.rb +13 -0
  69. data/lib/rex/exploitation/opcodedb.rb +818 -0
  70. data/lib/rex/exploitation/opcodedb.rb.ut.rb +279 -0
  71. data/lib/rex/exploitation/seh.rb +92 -0
  72. data/lib/rex/exploitation/seh.rb.ut.rb +19 -0
  73. data/lib/rex/file.rb +112 -0
  74. data/lib/rex/file.rb.ut.rb +16 -0
  75. data/lib/rex/image_source.rb +12 -0
  76. data/lib/rex/image_source/disk.rb +60 -0
  77. data/lib/rex/image_source/image_source.rb +46 -0
  78. data/lib/rex/image_source/memory.rb +37 -0
  79. data/lib/rex/io/bidirectional_pipe.rb +157 -0
  80. data/lib/rex/io/datagram_abstraction.rb +35 -0
  81. data/lib/rex/io/ring_buffer.rb +364 -0
  82. data/lib/rex/io/stream.rb +319 -0
  83. data/lib/rex/io/stream_abstraction.rb +197 -0
  84. data/lib/rex/io/stream_server.rb +211 -0
  85. data/lib/rex/job_container.rb +187 -0
  86. data/lib/rex/logging.rb +4 -0
  87. data/lib/rex/logging/log_dispatcher.rb +179 -0
  88. data/lib/rex/logging/log_sink.rb +42 -0
  89. data/lib/rex/logging/sinks/flatfile.rb +55 -0
  90. data/lib/rex/logging/sinks/stderr.rb +43 -0
  91. data/lib/rex/machparsey.rb +9 -0
  92. data/lib/rex/machparsey/exceptions.rb +34 -0
  93. data/lib/rex/machparsey/mach.rb +209 -0
  94. data/lib/rex/machparsey/machbase.rb +408 -0
  95. data/lib/rex/machscan.rb +9 -0
  96. data/lib/rex/machscan/scanner.rb +217 -0
  97. data/lib/rex/mime.rb +9 -0
  98. data/lib/rex/mime/header.rb +77 -0
  99. data/lib/rex/mime/message.rb +144 -0
  100. data/lib/rex/mime/part.rb +20 -0
  101. data/lib/rex/nop/opty2.rb +108 -0
  102. data/lib/rex/nop/opty2.rb.ut.rb +23 -0
  103. data/lib/rex/nop/opty2_tables.rb +300 -0
  104. data/lib/rex/ole.rb +205 -0
  105. data/lib/rex/ole/clsid.rb +47 -0
  106. data/lib/rex/ole/difat.rb +141 -0
  107. data/lib/rex/ole/directory.rb +231 -0
  108. data/lib/rex/ole/direntry.rb +240 -0
  109. data/lib/rex/ole/docs/dependencies.txt +8 -0
  110. data/lib/rex/ole/docs/references.txt +1 -0
  111. data/lib/rex/ole/fat.rb +99 -0
  112. data/lib/rex/ole/header.rb +204 -0
  113. data/lib/rex/ole/minifat.rb +77 -0
  114. data/lib/rex/ole/propset.rb +144 -0
  115. data/lib/rex/ole/samples/create_ole.rb +27 -0
  116. data/lib/rex/ole/samples/dir.rb +35 -0
  117. data/lib/rex/ole/samples/dump_stream.rb +34 -0
  118. data/lib/rex/ole/samples/ole_info.rb +23 -0
  119. data/lib/rex/ole/storage.rb +395 -0
  120. data/lib/rex/ole/stream.rb +53 -0
  121. data/lib/rex/ole/substorage.rb +49 -0
  122. data/lib/rex/ole/util.rb +157 -0
  123. data/lib/rex/parser/arguments.rb +97 -0
  124. data/lib/rex/parser/arguments.rb.ut.rb +67 -0
  125. data/lib/rex/parser/ini.rb +185 -0
  126. data/lib/rex/parser/ini.rb.ut.rb +29 -0
  127. data/lib/rex/parser/ip360_aspl_xml.rb +102 -0
  128. data/lib/rex/parser/ip360_xml.rb +97 -0
  129. data/lib/rex/parser/nessus_xml.rb +118 -0
  130. data/lib/rex/parser/netsparker_xml.rb +94 -0
  131. data/lib/rex/parser/nexpose_xml.rb +136 -0
  132. data/lib/rex/parser/nmap_xml.rb +137 -0
  133. data/lib/rex/parser/retina_xml.rb +109 -0
  134. data/lib/rex/payloads.rb +1 -0
  135. data/lib/rex/payloads/win32.rb +2 -0
  136. data/lib/rex/payloads/win32/common.rb +26 -0
  137. data/lib/rex/payloads/win32/kernel.rb +53 -0
  138. data/lib/rex/payloads/win32/kernel/common.rb +54 -0
  139. data/lib/rex/payloads/win32/kernel/migration.rb +12 -0
  140. data/lib/rex/payloads/win32/kernel/recovery.rb +50 -0
  141. data/lib/rex/payloads/win32/kernel/stager.rb +194 -0
  142. data/lib/rex/peparsey.rb +12 -0
  143. data/lib/rex/peparsey/exceptions.rb +32 -0
  144. data/lib/rex/peparsey/pe.rb +212 -0
  145. data/lib/rex/peparsey/pe_memdump.rb +63 -0
  146. data/lib/rex/peparsey/pebase.rb +1680 -0
  147. data/lib/rex/peparsey/section.rb +136 -0
  148. data/lib/rex/pescan.rb +13 -0
  149. data/lib/rex/pescan/analyze.rb +309 -0
  150. data/lib/rex/pescan/scanner.rb +206 -0
  151. data/lib/rex/pescan/search.rb +56 -0
  152. data/lib/rex/platforms.rb +1 -0
  153. data/lib/rex/platforms/windows.rb +51 -0
  154. data/lib/rex/poly.rb +132 -0
  155. data/lib/rex/poly/block.rb +477 -0
  156. data/lib/rex/poly/register.rb +100 -0
  157. data/lib/rex/poly/register/x86.rb +40 -0
  158. data/lib/rex/post.rb +8 -0
  159. data/lib/rex/post/dir.rb +51 -0
  160. data/lib/rex/post/file.rb +172 -0
  161. data/lib/rex/post/file_stat.rb +220 -0
  162. data/lib/rex/post/gen.pl +13 -0
  163. data/lib/rex/post/io.rb +182 -0
  164. data/lib/rex/post/meterpreter.rb +4 -0
  165. data/lib/rex/post/meterpreter/channel.rb +445 -0
  166. data/lib/rex/post/meterpreter/channel_container.rb +54 -0
  167. data/lib/rex/post/meterpreter/channels/pool.rb +160 -0
  168. data/lib/rex/post/meterpreter/channels/pools/file.rb +62 -0
  169. data/lib/rex/post/meterpreter/channels/pools/stream_pool.rb +103 -0
  170. data/lib/rex/post/meterpreter/channels/stream.rb +87 -0
  171. data/lib/rex/post/meterpreter/client.rb +364 -0
  172. data/lib/rex/post/meterpreter/client_core.rb +274 -0
  173. data/lib/rex/post/meterpreter/dependencies.rb +3 -0
  174. data/lib/rex/post/meterpreter/extension.rb +32 -0
  175. data/lib/rex/post/meterpreter/extensions/espia/espia.rb +58 -0
  176. data/lib/rex/post/meterpreter/extensions/espia/tlv.rb +16 -0
  177. data/lib/rex/post/meterpreter/extensions/incognito/incognito.rb +94 -0
  178. data/lib/rex/post/meterpreter/extensions/incognito/tlv.rb +21 -0
  179. data/lib/rex/post/meterpreter/extensions/networkpug/networkpug.rb +57 -0
  180. data/lib/rex/post/meterpreter/extensions/networkpug/tlv.rb +15 -0
  181. data/lib/rex/post/meterpreter/extensions/priv/fs.rb +118 -0
  182. data/lib/rex/post/meterpreter/extensions/priv/passwd.rb +61 -0
  183. data/lib/rex/post/meterpreter/extensions/priv/priv.rb +111 -0
  184. data/lib/rex/post/meterpreter/extensions/priv/tlv.rb +28 -0
  185. data/lib/rex/post/meterpreter/extensions/sniffer/sniffer.rb +101 -0
  186. data/lib/rex/post/meterpreter/extensions/sniffer/tlv.rb +26 -0
  187. data/lib/rex/post/meterpreter/extensions/stdapi/constants.rb +333 -0
  188. data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +282 -0
  189. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +266 -0
  190. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file_stat.rb +103 -0
  191. data/lib/rex/post/meterpreter/extensions/stdapi/fs/io.rb +48 -0
  192. data/lib/rex/post/meterpreter/extensions/stdapi/net/config.rb +144 -0
  193. data/lib/rex/post/meterpreter/extensions/stdapi/net/interface.rb +73 -0
  194. data/lib/rex/post/meterpreter/extensions/stdapi/net/route.rb +56 -0
  195. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +137 -0
  196. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +180 -0
  197. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb +167 -0
  198. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +208 -0
  199. data/lib/rex/post/meterpreter/extensions/stdapi/railgun.rb.ts.rb +6 -0
  200. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb +38106 -0
  201. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb.ut.rb +31 -0
  202. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb +47 -0
  203. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb.ut.rb +36 -0
  204. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_advapi32.rb +1818 -0
  205. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_iphlpapi.rb +96 -0
  206. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +3848 -0
  207. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_netapi32.rb +26 -0
  208. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ntdll.rb +153 -0
  209. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_shell32.rb +21 -0
  210. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_user32.rb +3169 -0
  211. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ws2_32.rb +599 -0
  212. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb +318 -0
  213. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb +100 -0
  214. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb.ut.rb +42 -0
  215. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb +148 -0
  216. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb.ut.rb +127 -0
  217. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/multicall.rb +309 -0
  218. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb +204 -0
  219. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/tlv.rb +51 -0
  220. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb +630 -0
  221. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb +75 -0
  222. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb.ut.rb +103 -0
  223. data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +149 -0
  224. data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +97 -0
  225. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +192 -0
  226. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log_subsystem/event_record.rb +41 -0
  227. data/lib/rex/post/meterpreter/extensions/stdapi/sys/power.rb +61 -0
  228. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +370 -0
  229. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/image.rb +129 -0
  230. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/io.rb +55 -0
  231. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/memory.rb +336 -0
  232. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/thread.rb +141 -0
  233. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +279 -0
  234. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +193 -0
  235. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_value.rb +102 -0
  236. data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +180 -0
  237. data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +211 -0
  238. data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +227 -0
  239. data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +63 -0
  240. data/lib/rex/post/meterpreter/inbound_packet_handler.rb +30 -0
  241. data/lib/rex/post/meterpreter/object_aliases.rb +83 -0
  242. data/lib/rex/post/meterpreter/packet.rb +688 -0
  243. data/lib/rex/post/meterpreter/packet_dispatcher.rb +431 -0
  244. data/lib/rex/post/meterpreter/packet_parser.rb +94 -0
  245. data/lib/rex/post/meterpreter/packet_response_waiter.rb +83 -0
  246. data/lib/rex/post/meterpreter/ui/console.rb +137 -0
  247. data/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb +62 -0
  248. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +730 -0
  249. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/espia.rb +108 -0
  250. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/incognito.rb +241 -0
  251. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/networkpug.rb +231 -0
  252. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv.rb +61 -0
  253. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +98 -0
  254. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/passwd.rb +51 -0
  255. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +132 -0
  256. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +187 -0
  257. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi.rb +65 -0
  258. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +442 -0
  259. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +298 -0
  260. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +486 -0
  261. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +315 -0
  262. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +157 -0
  263. data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +95 -0
  264. data/lib/rex/post/permission.rb +26 -0
  265. data/lib/rex/post/process.rb +57 -0
  266. data/lib/rex/post/thread.rb +57 -0
  267. data/lib/rex/post/ui.rb +52 -0
  268. data/lib/rex/proto.rb +13 -0
  269. data/lib/rex/proto.rb.ts.rb +8 -0
  270. data/lib/rex/proto/dcerpc.rb +6 -0
  271. data/lib/rex/proto/dcerpc.rb.ts.rb +9 -0
  272. data/lib/rex/proto/dcerpc/client.rb +361 -0
  273. data/lib/rex/proto/dcerpc/client.rb.ut.rb +491 -0
  274. data/lib/rex/proto/dcerpc/exceptions.rb +150 -0
  275. data/lib/rex/proto/dcerpc/handle.rb +47 -0
  276. data/lib/rex/proto/dcerpc/handle.rb.ut.rb +85 -0
  277. data/lib/rex/proto/dcerpc/ndr.rb +72 -0
  278. data/lib/rex/proto/dcerpc/ndr.rb.ut.rb +41 -0
  279. data/lib/rex/proto/dcerpc/packet.rb +253 -0
  280. data/lib/rex/proto/dcerpc/packet.rb.ut.rb +56 -0
  281. data/lib/rex/proto/dcerpc/response.rb +187 -0
  282. data/lib/rex/proto/dcerpc/response.rb.ut.rb +15 -0
  283. data/lib/rex/proto/dcerpc/uuid.rb +84 -0
  284. data/lib/rex/proto/dcerpc/uuid.rb.ut.rb +46 -0
  285. data/lib/rex/proto/dhcp.rb +7 -0
  286. data/lib/rex/proto/dhcp/constants.rb +33 -0
  287. data/lib/rex/proto/dhcp/server.rb +292 -0
  288. data/lib/rex/proto/drda.rb +5 -0
  289. data/lib/rex/proto/drda.rb.ts.rb +17 -0
  290. data/lib/rex/proto/drda/constants.rb +49 -0
  291. data/lib/rex/proto/drda/constants.rb.ut.rb +23 -0
  292. data/lib/rex/proto/drda/packet.rb +252 -0
  293. data/lib/rex/proto/drda/packet.rb.ut.rb +109 -0
  294. data/lib/rex/proto/drda/utils.rb +123 -0
  295. data/lib/rex/proto/drda/utils.rb.ut.rb +84 -0
  296. data/lib/rex/proto/http.rb +5 -0
  297. data/lib/rex/proto/http.rb.ts.rb +12 -0
  298. data/lib/rex/proto/http/client.rb +821 -0
  299. data/lib/rex/proto/http/client.rb.ut.rb +95 -0
  300. data/lib/rex/proto/http/handler.rb +46 -0
  301. data/lib/rex/proto/http/handler/erb.rb +128 -0
  302. data/lib/rex/proto/http/handler/erb.rb.ut.rb +21 -0
  303. data/lib/rex/proto/http/handler/erb.rb.ut.rb.rhtml +1 -0
  304. data/lib/rex/proto/http/handler/proc.rb +60 -0
  305. data/lib/rex/proto/http/handler/proc.rb.ut.rb +24 -0
  306. data/lib/rex/proto/http/header.rb +161 -0
  307. data/lib/rex/proto/http/header.rb.ut.rb +46 -0
  308. data/lib/rex/proto/http/packet.rb +407 -0
  309. data/lib/rex/proto/http/packet.rb.ut.rb +165 -0
  310. data/lib/rex/proto/http/request.rb +356 -0
  311. data/lib/rex/proto/http/request.rb.ut.rb +214 -0
  312. data/lib/rex/proto/http/response.rb +90 -0
  313. data/lib/rex/proto/http/response.rb.ut.rb +149 -0
  314. data/lib/rex/proto/http/server.rb +369 -0
  315. data/lib/rex/proto/http/server.rb.ut.rb +79 -0
  316. data/lib/rex/proto/ntlm.rb +7 -0
  317. data/lib/rex/proto/ntlm.rb.ut.rb +177 -0
  318. data/lib/rex/proto/ntlm/base.rb +326 -0
  319. data/lib/rex/proto/ntlm/constants.rb +74 -0
  320. data/lib/rex/proto/ntlm/crypt.rb +415 -0
  321. data/lib/rex/proto/ntlm/exceptions.rb +16 -0
  322. data/lib/rex/proto/ntlm/message.rb +536 -0
  323. data/lib/rex/proto/ntlm/utils.rb +764 -0
  324. data/lib/rex/proto/proxy/socks4a.rb +440 -0
  325. data/lib/rex/proto/rfb.rb +19 -0
  326. data/lib/rex/proto/rfb.rb.ut.rb +37 -0
  327. data/lib/rex/proto/rfb/cipher.rb +84 -0
  328. data/lib/rex/proto/rfb/client.rb +207 -0
  329. data/lib/rex/proto/rfb/constants.rb +52 -0
  330. data/lib/rex/proto/smb.rb +7 -0
  331. data/lib/rex/proto/smb.rb.ts.rb +8 -0
  332. data/lib/rex/proto/smb/client.rb +1952 -0
  333. data/lib/rex/proto/smb/client.rb.ut.rb +223 -0
  334. data/lib/rex/proto/smb/constants.rb +1047 -0
  335. data/lib/rex/proto/smb/constants.rb.ut.rb +18 -0
  336. data/lib/rex/proto/smb/crypt.rb +36 -0
  337. data/lib/rex/proto/smb/evasions.rb +66 -0
  338. data/lib/rex/proto/smb/exceptions.rb +858 -0
  339. data/lib/rex/proto/smb/simpleclient.rb +306 -0
  340. data/lib/rex/proto/smb/simpleclient.rb.ut.rb +128 -0
  341. data/lib/rex/proto/smb/utils.rb +103 -0
  342. data/lib/rex/proto/smb/utils.rb.ut.rb +20 -0
  343. data/lib/rex/proto/sunrpc.rb +1 -0
  344. data/lib/rex/proto/sunrpc/client.rb +195 -0
  345. data/lib/rex/proto/tftp.rb +12 -0
  346. data/lib/rex/proto/tftp/constants.rb +39 -0
  347. data/lib/rex/proto/tftp/server.rb +497 -0
  348. data/lib/rex/proto/tftp/server.rb.ut.rb +28 -0
  349. data/lib/rex/script.rb +42 -0
  350. data/lib/rex/script/base.rb +59 -0
  351. data/lib/rex/script/meterpreter.rb +15 -0
  352. data/lib/rex/script/shell.rb +9 -0
  353. data/lib/rex/service.rb +48 -0
  354. data/lib/rex/service_manager.rb +141 -0
  355. data/lib/rex/service_manager.rb.ut.rb +32 -0
  356. data/lib/rex/services/local_relay.rb +423 -0
  357. data/lib/rex/socket.rb +684 -0
  358. data/lib/rex/socket.rb.ut.rb +107 -0
  359. data/lib/rex/socket/comm.rb +119 -0
  360. data/lib/rex/socket/comm/local.rb +412 -0
  361. data/lib/rex/socket/comm/local.rb.ut.rb +75 -0
  362. data/lib/rex/socket/ip.rb +130 -0
  363. data/lib/rex/socket/parameters.rb +345 -0
  364. data/lib/rex/socket/parameters.rb.ut.rb +51 -0
  365. data/lib/rex/socket/range_walker.rb +346 -0
  366. data/lib/rex/socket/range_walker.rb.ut.rb +55 -0
  367. data/lib/rex/socket/ssl_tcp.rb +184 -0
  368. data/lib/rex/socket/ssl_tcp.rb.ut.rb +39 -0
  369. data/lib/rex/socket/ssl_tcp_server.rb +122 -0
  370. data/lib/rex/socket/ssl_tcp_server.rb.ut.rb +61 -0
  371. data/lib/rex/socket/subnet_walker.rb +75 -0
  372. data/lib/rex/socket/subnet_walker.rb.ut.rb +28 -0
  373. data/lib/rex/socket/switch_board.rb +278 -0
  374. data/lib/rex/socket/switch_board.rb.ut.rb +52 -0
  375. data/lib/rex/socket/tcp.rb +76 -0
  376. data/lib/rex/socket/tcp.rb.ut.rb +64 -0
  377. data/lib/rex/socket/tcp_server.rb +66 -0
  378. data/lib/rex/socket/tcp_server.rb.ut.rb +44 -0
  379. data/lib/rex/socket/udp.rb +164 -0
  380. data/lib/rex/socket/udp.rb.ut.rb +44 -0
  381. data/lib/rex/struct2.rb +5 -0
  382. data/lib/rex/struct2/c_struct.rb +181 -0
  383. data/lib/rex/struct2/c_struct_template.rb +39 -0
  384. data/lib/rex/struct2/constant.rb +26 -0
  385. data/lib/rex/struct2/element.rb +44 -0
  386. data/lib/rex/struct2/generic.rb +73 -0
  387. data/lib/rex/struct2/restraint.rb +54 -0
  388. data/lib/rex/struct2/s_string.rb +72 -0
  389. data/lib/rex/struct2/s_struct.rb +111 -0
  390. data/lib/rex/sync.rb +6 -0
  391. data/lib/rex/sync/event.rb +94 -0
  392. data/lib/rex/sync/read_write_lock.rb +176 -0
  393. data/lib/rex/sync/ref.rb +57 -0
  394. data/lib/rex/sync/thread_safe.rb +82 -0
  395. data/lib/rex/test.rb +35 -0
  396. data/lib/rex/text.rb +1163 -0
  397. data/lib/rex/text.rb.ut.rb +190 -0
  398. data/lib/rex/thread_factory.rb +42 -0
  399. data/lib/rex/time.rb +65 -0
  400. data/lib/rex/transformer.rb +115 -0
  401. data/lib/rex/transformer.rb.ut.rb +38 -0
  402. data/lib/rex/ui.rb +21 -0
  403. data/lib/rex/ui/interactive.rb +298 -0
  404. data/lib/rex/ui/output.rb +78 -0
  405. data/lib/rex/ui/output/none.rb +18 -0
  406. data/lib/rex/ui/progress_tracker.rb +96 -0
  407. data/lib/rex/ui/subscriber.rb +149 -0
  408. data/lib/rex/ui/text/color.rb +97 -0
  409. data/lib/rex/ui/text/color.rb.ut.rb +18 -0
  410. data/lib/rex/ui/text/dispatcher_shell.rb +467 -0
  411. data/lib/rex/ui/text/input.rb +117 -0
  412. data/lib/rex/ui/text/input/buffer.rb +75 -0
  413. data/lib/rex/ui/text/input/readline.rb +129 -0
  414. data/lib/rex/ui/text/input/socket.rb +95 -0
  415. data/lib/rex/ui/text/input/stdio.rb +45 -0
  416. data/lib/rex/ui/text/irb_shell.rb +57 -0
  417. data/lib/rex/ui/text/output.rb +80 -0
  418. data/lib/rex/ui/text/output/buffer.rb +61 -0
  419. data/lib/rex/ui/text/output/file.rb +43 -0
  420. data/lib/rex/ui/text/output/socket.rb +43 -0
  421. data/lib/rex/ui/text/output/stdio.rb +40 -0
  422. data/lib/rex/ui/text/progress_tracker.rb +56 -0
  423. data/lib/rex/ui/text/progress_tracker.rb.ut.rb +34 -0
  424. data/lib/rex/ui/text/shell.rb +328 -0
  425. data/lib/rex/ui/text/table.rb +279 -0
  426. data/lib/rex/ui/text/table.rb.ut.rb +55 -0
  427. data/lib/rex/zip.rb +93 -0
  428. data/lib/rex/zip/archive.rb +184 -0
  429. data/lib/rex/zip/blocks.rb +182 -0
  430. data/lib/rex/zip/entry.rb +104 -0
  431. data/lib/rex/zip/samples/comment.rb +32 -0
  432. data/lib/rex/zip/samples/mkwar.rb +138 -0
  433. data/lib/rex/zip/samples/mkzip.rb +19 -0
  434. data/lib/rex/zip/samples/recursive.rb +58 -0
  435. metadata +434 -1
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'timeout'
4
+ require 'thread'
5
+
6
+ module Rex
7
+ module Post
8
+ module Meterpreter
9
+
10
+ ###
11
+ #
12
+ # This class handles waiting for a response to a given request
13
+ # and the subsequent response association.
14
+ #
15
+ ###
16
+ class PacketResponseWaiter
17
+
18
+ #
19
+ # Initializes a response waiter instance for the supplied request
20
+ # identifier.
21
+ #
22
+ def initialize(rid, completion_routine = nil, completion_param = nil)
23
+ self.rid = rid.dup
24
+ self.response = nil
25
+
26
+ if (completion_routine)
27
+ self.completion_routine = completion_routine
28
+ self.completion_param = completion_param
29
+ else
30
+ self.done = false
31
+ end
32
+ end
33
+
34
+ #
35
+ # Checks to see if this waiter instance is waiting for the supplied
36
+ # packet based on its request identifier.
37
+ #
38
+ def waiting_for?(packet)
39
+ return (packet.rid == rid)
40
+ end
41
+
42
+ #
43
+ # Notifies the waiter that the supplied response packet has arrived.
44
+ #
45
+ def notify(response)
46
+ self.response = response
47
+
48
+ if (self.completion_routine)
49
+ self.completion_routine.call(response, self.completion_param)
50
+ else
51
+ self.done = true
52
+ end
53
+ end
54
+
55
+ #
56
+ # Waits for a given time interval for the response packet to arrive.
57
+ # If the interval is -1 we can wait forever.
58
+ #
59
+ def wait(interval)
60
+ if( interval and interval == -1 )
61
+ while(not self.done)
62
+ ::IO.select(nil, nil, nil, 0.1)
63
+ end
64
+ else
65
+ begin
66
+ Timeout.timeout(interval) {
67
+ while(not self.done)
68
+ ::IO.select(nil, nil, nil, 0.1)
69
+ end
70
+ }
71
+ rescue Timeout::Error
72
+ self.response = nil
73
+ end
74
+ end
75
+ return self.response
76
+ end
77
+
78
+ attr_accessor :rid, :done, :response # :nodoc:
79
+ attr_accessor :completion_routine, :completion_param # :nodoc:
80
+ end
81
+
82
+ end; end; end
83
+
@@ -0,0 +1,137 @@
1
+ require 'rex/ui'
2
+ require 'rex/post/meterpreter'
3
+ require 'rex/logging'
4
+
5
+ module Rex
6
+ module Post
7
+ module Meterpreter
8
+ module Ui
9
+
10
+ ###
11
+ #
12
+ # This class provides a shell driven interface to the meterpreter client API.
13
+ #
14
+ ###
15
+ class Console
16
+
17
+ include Rex::Ui::Text::DispatcherShell
18
+
19
+ # Dispatchers
20
+ require 'rex/post/meterpreter/ui/console/interactive_channel'
21
+ require 'rex/post/meterpreter/ui/console/command_dispatcher'
22
+ require 'rex/post/meterpreter/ui/console/command_dispatcher/core'
23
+
24
+ #
25
+ # Initialize the meterpreter console.
26
+ #
27
+ def initialize(client)
28
+ if (Rex::Compat.is_windows())
29
+ super("meterpreter")
30
+ else
31
+ super("%undmeterpreter%clr")
32
+ end
33
+
34
+ # The meterpreter client context
35
+ self.client = client
36
+
37
+ # Queued commands array
38
+ self.commands = []
39
+
40
+ # Point the input/output handles elsewhere
41
+ reset_ui
42
+
43
+ enstack_dispatcher(Console::CommandDispatcher::Core)
44
+
45
+ # Set up logging to whatever logsink 'core' is using
46
+ if ! $dispatcher['meterpreter']
47
+ $dispatcher['meterpreter'] = $dispatcher['core']
48
+ end
49
+ end
50
+
51
+ #
52
+ # Called when someone wants to interact with the meterpreter client. It's
53
+ # assumed that init_ui has been called prior.
54
+ #
55
+ def interact(&block)
56
+ init_tab_complete
57
+
58
+ # Run queued commands
59
+ commands.delete_if { |ent|
60
+ run_single(ent)
61
+ true
62
+ }
63
+
64
+ # Run the interactive loop
65
+ run { |line|
66
+ # Run the command
67
+ run_single(line)
68
+
69
+ # If a block was supplied, call it, otherwise return false
70
+ if (block)
71
+ block.call
72
+ else
73
+ false
74
+ end
75
+ }
76
+ end
77
+
78
+ #
79
+ # Interacts with the supplied channel.
80
+ #
81
+ def interact_with_channel(channel)
82
+ channel.extend(InteractiveChannel) unless (channel.kind_of?(InteractiveChannel) == true)
83
+
84
+ channel.interact(input, output)
85
+ channel.reset_ui
86
+ end
87
+
88
+ #
89
+ # Queues a command to be run when the interactive loop is entered.
90
+ #
91
+ def queue_cmd(cmd)
92
+ self.commands << cmd
93
+ end
94
+
95
+ #
96
+ # Runs the specified command wrapper in something to catch meterpreter
97
+ # exceptions.
98
+ #
99
+ def run_command(dispatcher, method, arguments)
100
+ begin
101
+ super
102
+ rescue Timeout::Error
103
+ log_error("Operation timed out.")
104
+ rescue RequestError => info
105
+ log_error(info.to_s)
106
+ rescue ::Errno::EPIPE, ::OpenSSL::SSL::SSLError, ::IOError
107
+ self.client.kill
108
+ rescue ::Exception => e
109
+ log_error("Error running command #{method}: #{e.class} #{e}")
110
+ end
111
+ end
112
+
113
+ #
114
+ # Logs that an error occurred and persists the callstack.
115
+ #
116
+ def log_error(msg)
117
+ print_error(msg)
118
+
119
+ elog(msg, 'meterpreter')
120
+
121
+ dlog("Call stack:\n#{$@.join("\n")}", 'meterpreter')
122
+ end
123
+
124
+ attr_reader :client # :nodoc:
125
+
126
+ protected
127
+
128
+ attr_writer :client # :nodoc:
129
+ attr_accessor :commands # :nodoc:
130
+
131
+ end
132
+
133
+ end
134
+ end
135
+ end
136
+ end
137
+
@@ -0,0 +1,62 @@
1
+ require 'rex/logging'
2
+
3
+ module Rex
4
+ module Post
5
+ module Meterpreter
6
+ module Ui
7
+
8
+ ###
9
+ #
10
+ # Base class for all command dispatchers within the meterpreter console user
11
+ # interface.
12
+ #
13
+ ###
14
+ module Console::CommandDispatcher
15
+
16
+ include Rex::Ui::Text::DispatcherShell::CommandDispatcher
17
+
18
+ #
19
+ # The hash of file names to class names after a module has already been
20
+ # loaded once on the client side.
21
+ #
22
+ @@file_hash = {}
23
+
24
+ #
25
+ # Checks the file name to hash association to see if the module being
26
+ # requested has already been loaded once.
27
+ #
28
+ def self.check_hash(name)
29
+ @@file_hash[name]
30
+ end
31
+
32
+ #
33
+ # Sets the file path to class name association for future reference.
34
+ #
35
+ def self.set_hash(name, klass)
36
+ @@file_hash[name] = klass
37
+ end
38
+
39
+ #
40
+ # Returns the meterpreter client context.
41
+ #
42
+ def client
43
+ shell.client
44
+ end
45
+
46
+ #
47
+ # Log that an error occurred.
48
+ #
49
+ def log_error(msg)
50
+ print_error(msg)
51
+
52
+ elog(msg, 'meterpreter')
53
+
54
+ dlog("Call stack:\n#{$@.join("\n")}", 'meterpreter')
55
+ end
56
+
57
+ end
58
+
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,730 @@
1
+ require 'rex/post/meterpreter'
2
+ require 'rex/parser/arguments'
3
+
4
+ module Rex
5
+ module Post
6
+ module Meterpreter
7
+ module Ui
8
+
9
+ ###
10
+ #
11
+ # Core meterpreter client commands that provide only the required set of
12
+ # commands for having a functional meterpreter client<->server instance.
13
+ #
14
+ ###
15
+ class Console::CommandDispatcher::Core
16
+
17
+ include Console::CommandDispatcher
18
+
19
+ #
20
+ # Initializes an instance of the core command set using the supplied shell
21
+ # for interactivity.
22
+ #
23
+ def initialize(shell)
24
+ super
25
+
26
+ self.extensions = []
27
+ self.bgjobs = []
28
+ self.bgjob_id = 0
29
+
30
+ @msf_loaded = nil
31
+ end
32
+
33
+ def msf_loaded?
34
+ return @msf_loaded unless @msf_loaded.nil?
35
+ # if we get here we must not have initialized yet
36
+
37
+ if client.framework
38
+ # We have a framework instance so the msf libraries should be
39
+ # available. Load up the ones we're going to use
40
+ require 'msf/base/serializer/readable_text'
41
+ end
42
+ @msf_loaded = !!(client.framework)
43
+ @msf_loaded
44
+ end
45
+
46
+ @@use_opts = Rex::Parser::Arguments.new(
47
+ "-l" => [ false, "List all available extensions" ],
48
+ "-h" => [ false, "Help menu." ])
49
+
50
+ #
51
+ # List of supported commands.
52
+ #
53
+ def commands
54
+ c = {
55
+ "?" => "Help menu",
56
+ "background" => "Backgrounds the current session",
57
+ "close" => "Closes a channel",
58
+ "channel" => "Displays information about active channels",
59
+ "exit" => "Terminate the meterpreter session",
60
+ "help" => "Help menu",
61
+ "interact" => "Interacts with a channel",
62
+ "irb" => "Drop into irb scripting mode",
63
+ "migrate" => "Migrate the server to another process",
64
+ "use" => "Load a one or more meterpreter extensions",
65
+ "quit" => "Terminate the meterpreter session",
66
+ "resource" => "Run the commands stored in a file",
67
+ "read" => "Reads data from a channel",
68
+ "run" => "Executes a meterpreter script or Post module",
69
+ "bgrun" => "Executes a meterpreter script as a background thread",
70
+ "bgkill" => "Kills a background meterpreter script",
71
+ "bglist" => "Lists running background scripts",
72
+ "write" => "Writes data to a channel",
73
+ }
74
+ if (msf_loaded?)
75
+ c["info"] = "Displays information about a Post module"
76
+ end
77
+
78
+ c
79
+ end
80
+
81
+ #
82
+ # Core baby.
83
+ #
84
+ def name
85
+ "Core"
86
+ end
87
+
88
+ def cmd_background
89
+ client.interacting = false
90
+ end
91
+
92
+ #
93
+ # Displays information about active channels
94
+ #
95
+ @@channel_opts = Rex::Parser::Arguments.new(
96
+ "-l" => [ false, "List active channels." ],
97
+ "-h" => [ false, "Help menu." ])
98
+
99
+ #
100
+ # Performs operations on the supplied channel.
101
+ #
102
+ def cmd_channel(*args)
103
+ if (args.length == 0)
104
+ args.unshift("-h")
105
+ end
106
+
107
+ mode = nil
108
+
109
+ # Parse options
110
+ @@channel_opts.parse(args) { |opt, idx, val|
111
+ case opt
112
+ when "-h"
113
+ print(
114
+ "Usage: channel [options]\n\n" +
115
+ "Displays information about active channels.\n" +
116
+ @@channel_opts.usage)
117
+ return true
118
+ when "-l"
119
+ mode = 'list'
120
+ end
121
+ }
122
+
123
+ # No mode, no service.
124
+ if (mode == nil)
125
+ return true
126
+ elsif (mode == 'list')
127
+ tbl = Rex::Ui::Text::Table.new(
128
+ 'Indent' => 4,
129
+ 'Columns' =>
130
+ [
131
+ 'Id',
132
+ 'Class',
133
+ 'Type'
134
+ ])
135
+ items = 0
136
+
137
+ client.channels.each_pair { |cid, channel|
138
+ tbl << [ cid, channel.class.cls, channel.type ]
139
+ items += 1
140
+ }
141
+
142
+ if (items == 0)
143
+ print_line("No active channels.")
144
+ else
145
+ print("\n" + tbl.to_s + "\n")
146
+ end
147
+ end
148
+ end
149
+
150
+ #
151
+ # Closes a supplied channel.
152
+ #
153
+ def cmd_close(*args)
154
+ if (args.length == 0)
155
+ print_line(
156
+ "Usage: close channel_id\n\n" +
157
+ "Closes the supplied channel.")
158
+ return true
159
+ end
160
+
161
+ cid = args[0].to_i
162
+ channel = client.find_channel(cid)
163
+
164
+ if (!channel)
165
+ print_error("Invalid channel identifier specified.")
166
+ return true
167
+ else
168
+ channel._close # Issue #410
169
+
170
+ print_status("Closed channel #{cid}.")
171
+ end
172
+ end
173
+
174
+ #
175
+ # Terminates the meterpreter session.
176
+ #
177
+ def cmd_exit(*args)
178
+ shell.stop
179
+ end
180
+
181
+ alias cmd_quit cmd_exit
182
+
183
+ #
184
+ # Interacts with a channel.
185
+ #
186
+ def cmd_interact(*args)
187
+ if (args.length == 0)
188
+ print_line(
189
+ "Usage: interact channel_id\n\n" +
190
+ "Interacts with the supplied channel.")
191
+ return true
192
+ end
193
+
194
+ cid = args[0].to_i
195
+ channel = client.find_channel(cid)
196
+
197
+ if (channel)
198
+ print_line("Interacting with channel #{cid}...\n")
199
+
200
+ shell.interact_with_channel(channel)
201
+ else
202
+ print_error("Invalid channel identifier specified.")
203
+ end
204
+ end
205
+
206
+ #
207
+ # Runs the IRB scripting shell
208
+ #
209
+ def cmd_irb(*args)
210
+ print_status("Starting IRB shell")
211
+ print_status("The 'client' variable holds the meterpreter client\n")
212
+
213
+ Rex::Ui::Text::IrbShell.new(binding).run
214
+ end
215
+
216
+ #
217
+ # Migrates the server to the supplied process identifier.
218
+ #
219
+ def cmd_migrate(*args)
220
+ if (args.length == 0)
221
+ print_line(
222
+ "Usage: migrate pid\n\n" +
223
+ "Migrates the server instance to another process.\n" +
224
+ "Note: Any open channels or other dynamic state will be lost.")
225
+ return true
226
+ end
227
+
228
+ pid = args[0].to_i
229
+ if(pid == 0)
230
+ print_error("A process ID must be specified, not a process name")
231
+ return
232
+ end
233
+
234
+ print_status("Migrating to #{pid}...")
235
+
236
+ # Do this thang.
237
+ client.core.migrate(pid)
238
+
239
+ print_status("Migration completed successfully.")
240
+ end
241
+
242
+ #
243
+ # Loads one or more meterpreter extensions.
244
+ #
245
+ def cmd_use(*args)
246
+ if (args.length == 0)
247
+ args.unshift("-h")
248
+ end
249
+
250
+ modules = nil
251
+
252
+ @@use_opts.parse(args) { |opt, idx, val|
253
+ case opt
254
+ when "-l"
255
+ exts = []
256
+ path = ::File.join(Msf::Config.install_root, 'data', 'meterpreter')
257
+ ::Dir.entries(path).each { |f|
258
+ if (::File.file?(::File.join(path, f)) && f =~ /ext_server_(.*)\.#{client.binary_suffix}/ )
259
+ exts.push($1)
260
+ end
261
+ }
262
+ print(exts.sort.join("\n") + "\n")
263
+
264
+ return true
265
+ when "-h"
266
+ print(
267
+ "Usage: use ext1 ext2 ext3 ...\n\n" +
268
+ "Loads a meterpreter extension module or modules.\n" +
269
+ @@use_opts.usage)
270
+ return true
271
+ end
272
+ }
273
+
274
+ # Load each of the modules
275
+ args.each { |m|
276
+ md = m.downcase
277
+
278
+ if (extensions.include?(md))
279
+ print_error("The '#{md}' extension has already been loaded.")
280
+ next
281
+ end
282
+
283
+ print("Loading extension #{md}...")
284
+
285
+ begin
286
+ # Use the remote side, then load the client-side
287
+ if (client.core.use(md) == true)
288
+ add_extension_client(md)
289
+ end
290
+ rescue
291
+ print_line
292
+ log_error("Failed to load extension: #{$!}")
293
+ next
294
+ end
295
+
296
+ print_line("success.")
297
+ }
298
+
299
+ return true
300
+ end
301
+
302
+ def cmd_use_tabs(str, words)
303
+ tabs = []
304
+ path = ::File.join(Msf::Config.install_root, 'data', 'meterpreter')
305
+ ::Dir.entries(path).each { |f|
306
+ if (::File.file?(::File.join(path, f)) && f =~ /ext_server_(.*)\.#{client.binary_suffix}/ )
307
+ if (not extensions.include?($1))
308
+ tabs.push($1)
309
+ end
310
+ end
311
+ }
312
+ return tabs
313
+ end
314
+
315
+ #
316
+ # Reads data from a channel.
317
+ #
318
+ def cmd_read(*args)
319
+ if (args.length == 0)
320
+ print_line(
321
+ "Usage: read channel_id [length]\n\n" +
322
+ "Reads data from the supplied channel.")
323
+ return true
324
+ end
325
+
326
+ cid = args[0].to_i
327
+ length = (args.length >= 2) ? args[1].to_i : 16384
328
+ channel = client.find_channel(cid)
329
+
330
+ if (!channel)
331
+ print_error("Channel #{cid} is not valid.")
332
+ return true
333
+ end
334
+
335
+ data = channel.read(length)
336
+
337
+ if (data and data.length)
338
+ print("Read #{data.length} bytes from #{cid}:\n\n#{data}\n")
339
+ else
340
+ print_error("No data was returned.")
341
+ end
342
+
343
+ return true
344
+ end
345
+
346
+ def cmd_run_help
347
+ print_line "Usage: run <script> [arguments]"
348
+ print_line
349
+ print_line "Executes a ruby script or Metasploit Post module in the context of the"
350
+ print_line "meterpreter session. Post modules can take arguments in var=val format."
351
+ print_line "Example: run post/foo/bar BAZ=abcd"
352
+ print_line
353
+ end
354
+
355
+ #
356
+ # Executes a script in the context of the meterpreter session.
357
+ #
358
+ def cmd_run(*args)
359
+ if args.length == 0
360
+ cmd_run_help
361
+ return true
362
+ end
363
+
364
+ # Get the script name
365
+ begin
366
+ script_name = args.shift
367
+ # First try it as a Post module if we have access to the Metasploit
368
+ # Framework instance. If we don't, or if no such module exists,
369
+ # fall back to using the scripting interface.
370
+ if (msf_loaded? and mod = client.framework.modules.create(script_name))
371
+ omod = mod
372
+ mod = client.framework.modules.reload_module(mod)
373
+ if (not mod)
374
+ print_error("Failed to reload module: #{client.framework.modules.failed[omod.file_path]}")
375
+ return
376
+ end
377
+ opts = (args + [ "SESSION=#{client.sid}" ]).join(',')
378
+ mod.run_simple(
379
+ #'RunAsJob' => true,
380
+ 'LocalInput' => shell.input,
381
+ 'LocalOutput' => shell.output,
382
+ 'OptionStr' => opts
383
+ )
384
+ else
385
+ # the rest of the arguments get passed in through the binding
386
+ client.execute_script(script_name, args)
387
+ end
388
+ rescue
389
+ print_error("Error in script: #{$!.class} #{$!}")
390
+ elog("Error in script: #{$!.class} #{$!}")
391
+ dlog("Callstack: #{$@.join("\n")}")
392
+ end
393
+ end
394
+
395
+ def cmd_run_tabs(str, words)
396
+ tabs = []
397
+ if(not words[1] or not words[1].match(/^\//))
398
+ begin
399
+ if (msf_loaded?)
400
+ tabs += tab_complete_postmods
401
+ end
402
+ [
403
+ ::Msf::Sessions::Meterpreter.script_base,
404
+ ::Msf::Sessions::Meterpreter.user_script_base
405
+ ].each do |dir|
406
+ next if not ::File.exist? dir
407
+ tabs += ::Dir.new(dir).find_all { |e|
408
+ path = dir + ::File::SEPARATOR + e
409
+ ::File.file?(path) and ::File.readable?(path)
410
+ }
411
+ end
412
+ rescue Exception
413
+ end
414
+ end
415
+ return tabs.map { |e| e.sub(/\.rb$/, '') }
416
+ end
417
+
418
+
419
+ #
420
+ # Executes a script in the context of the meterpreter session in the background
421
+ #
422
+ def cmd_bgrun(*args)
423
+ if args.length == 0
424
+ print_line(
425
+ "Usage: bgrun <script> [arguments]\n\n" +
426
+ "Executes a ruby script in the context of the meterpreter session.")
427
+ return true
428
+ end
429
+
430
+ jid = self.bgjob_id
431
+ self.bgjob_id += 1
432
+
433
+ # Get the script name
434
+ self.bgjobs[jid] = Rex::ThreadFactory.spawn("MeterpreterBGRun(#{args[0]})-#{jid}", false, jid, args) do |myjid,xargs|
435
+ ::Thread.current[:args] = xargs.dup
436
+ begin
437
+ # the rest of the arguments get passed in through the binding
438
+ client.execute_script(args.shift, args)
439
+ rescue ::Exception
440
+ print_error("Error in script: #{$!.class} #{$!}")
441
+ elog("Error in script: #{$!.class} #{$!}")
442
+ dlog("Callstack: #{$@.join("\n")}")
443
+ end
444
+ self.bgjobs[myjid] = nil
445
+ print_status("Background script with Job ID #{myjid} has completed (#{::Thread.current[:args].inspect})")
446
+ end
447
+
448
+ print_status("Executed Meterpreter with Job ID #{jid}")
449
+ end
450
+
451
+ #
452
+ # Map this to the normal run command tab completion
453
+ #
454
+ def cmd_bgrun_tabs(*args)
455
+ cmd_run_tabs(*args)
456
+ end
457
+
458
+ #
459
+ # Kill a background job
460
+ #
461
+ def cmd_bgkill(*args)
462
+ if args.length == 0
463
+ print_line("Usage: bgkill [id]")
464
+ return
465
+ end
466
+
467
+ args.each do |jid|
468
+ jid = jid.to_i
469
+ if self.bgjobs[jid]
470
+ print_status("Killing background job #{jid}...")
471
+ self.bgjobs[jid].kill
472
+ self.bgjobs[jid] = nil
473
+ else
474
+ print_error("Job #{jid} was not running")
475
+ end
476
+ end
477
+ end
478
+
479
+ #
480
+ # List background jobs
481
+ #
482
+ def cmd_bglist(*args)
483
+ self.bgjobs.each_index do |jid|
484
+ if self.bgjobs[jid]
485
+ print_status("Job #{jid}: #{self.bgjobs[jid][:args].inspect}")
486
+ end
487
+ end
488
+ end
489
+
490
+ #
491
+ # Show info for a given Post module.
492
+ #
493
+ # See also +cmd_info+ in lib/msf/ui/console/command_dispatcher/core.rb
494
+ #
495
+ def cmd_info(*args)
496
+ return unless msf_loaded?
497
+
498
+ if args.length != 1
499
+ print_error 'Usage: info <module>'
500
+ return
501
+ end
502
+
503
+ module_name = args.shift
504
+ mod = client.framework.modules.create(module_name);
505
+
506
+ if mod.nil?
507
+ print_error 'Invalid module: ' << module_name
508
+ end
509
+
510
+ if (mod)
511
+ print_line ::Msf::Serializer::ReadableText.dump_module(mod)
512
+ end
513
+ end
514
+
515
+ def cmd_info_tabs(*args)
516
+ return unless msf_loaded?
517
+ tab_complete_postmods
518
+ end
519
+
520
+ #
521
+ # Writes data to a channel.
522
+ #
523
+ @@write_opts = Rex::Parser::Arguments.new(
524
+ "-f" => [ true, "Write the contents of a file on disk" ],
525
+ "-h" => [ false, "Help menu." ])
526
+
527
+ def cmd_write(*args)
528
+ if (args.length == 0)
529
+ args.unshift("-h")
530
+ end
531
+
532
+ src_file = nil
533
+ cid = nil
534
+
535
+ @@write_opts.parse(args) { |opt, idx, val|
536
+ case opt
537
+ when "-h"
538
+ print(
539
+ "Usage: write [options] channel_id\n\n" +
540
+ "Writes data to the supplied channel.\n" +
541
+ @@write_opts.usage)
542
+ return true
543
+ when "-f"
544
+ src_file = val
545
+ else
546
+ cid = val.to_i
547
+ end
548
+ }
549
+
550
+ # Find the channel associated with this cid, assuming the cid is valid.
551
+ if ((!cid) or
552
+ (!(channel = client.find_channel(cid))))
553
+ print_error("Invalid channel identifier specified.")
554
+ return true
555
+ end
556
+
557
+ # If they supplied a source file, read in its contents and write it to
558
+ # the channel
559
+ if (src_file)
560
+ begin
561
+ data = ''
562
+
563
+ ::File.open(src_file, 'rb') { |f|
564
+ data = f.read(f.stat.size)
565
+ }
566
+
567
+ rescue Errno::ENOENT
568
+ print_error("Invalid source file specified: #{src_file}")
569
+ return true
570
+ end
571
+
572
+ if (data and data.length > 0)
573
+ channel.write(data)
574
+ print_status("Wrote #{data.length} bytes to channel #{cid}.")
575
+ else
576
+ print_error("No data to send from file #{src_file}")
577
+ return true
578
+ end
579
+ # Otherwise, read from the input descriptor until we're good to go.
580
+ else
581
+ print("Enter data followed by a '.' on an empty line:\n\n")
582
+
583
+ data = ''
584
+
585
+ # Keep truckin'
586
+ while (s = shell.input.gets)
587
+ break if (s =~ /^\.\r?\n?$/)
588
+ data += s
589
+ end
590
+
591
+ if (!data or data.length == 0)
592
+ print_error("No data to send.")
593
+ else
594
+ channel.write(data)
595
+ print_status("Wrote #{data.length} bytes to channel #{cid}.")
596
+ end
597
+ end
598
+
599
+ return true
600
+ end
601
+
602
+ def cmd_resource_tabs(str, words)
603
+ return [] if words.length > 1
604
+
605
+ tab_complete_filenames(str, words)
606
+ end
607
+
608
+ def cmd_resource(*args)
609
+ if args.empty?
610
+ print(
611
+ "Usage: resource path1 path2" +
612
+ "Run the commands stored in the supplied files.\n")
613
+ return false
614
+ end
615
+ args.each do |glob|
616
+ files = ::Dir.glob(::File.expand_path(glob))
617
+ if files.empty?
618
+ print_error("No such file #{glob}")
619
+ next
620
+ end
621
+ files.each do |filename|
622
+ print_status("Reading #{filename}")
623
+ if (not ::File.readable?(filename))
624
+ print_error("Could not read file #{filename}")
625
+ next
626
+ else
627
+ ::File.open(filename, "r").each_line do |line|
628
+ next if line.strip.length < 1
629
+ next if line[0,1] == "#"
630
+ begin
631
+ print_status("Running #{line}")
632
+ client.console.run_single(line)
633
+ rescue ::Exception => e
634
+ print_error("Error Running Command #{line}: #{e.class} #{e}")
635
+ end
636
+
637
+ end
638
+ end
639
+ end
640
+ end
641
+ end
642
+
643
+
644
+
645
+ @@client_extension_search_paths = [ ::File.join(Rex::Root, "post", "meterpreter", "ui", "console", "command_dispatcher") ]
646
+
647
+ def self.add_client_extension_search_path(path)
648
+ @@client_extension_search_paths << path unless @@client_extension_search_paths.include?(path)
649
+ end
650
+ def self.client_extension_search_paths
651
+ @@client_extension_search_paths
652
+ end
653
+
654
+ protected
655
+
656
+ attr_accessor :extensions # :nodoc:
657
+ attr_accessor :bgjobs, :bgjob_id # :nodoc:
658
+
659
+ CommDispatcher = Console::CommandDispatcher
660
+
661
+ #
662
+ # Loads the client extension specified in mod
663
+ #
664
+ def add_extension_client(mod)
665
+ loaded = false
666
+ klass = nil
667
+ self.class.client_extension_search_paths.each do |path|
668
+ path = ::File.join(path, "#{mod}.rb")
669
+ klass = CommDispatcher.check_hash(path)
670
+ if (klass == nil)
671
+ old = CommDispatcher.constants
672
+ next unless ::File.exist? path
673
+
674
+ if (require(path))
675
+ new = CommDispatcher.constants
676
+ diff = new - old
677
+
678
+ next if (diff.empty?)
679
+
680
+ klass = CommDispatcher.const_get(diff[0])
681
+
682
+ CommDispatcher.set_hash(path, klass)
683
+ loaded = true
684
+ break
685
+ else
686
+ print_error("Failed to load client script file: #{path}")
687
+ return false
688
+ end
689
+ else
690
+ # the klass is already loaded, from a previous invocation
691
+ loaded = true
692
+ break
693
+ end
694
+ end
695
+ unless loaded
696
+ print_error("Failed to load client portion of #{mod}.")
697
+ return false
698
+ end
699
+
700
+ # Enstack the dispatcher
701
+ self.shell.enstack_dispatcher(klass)
702
+
703
+ # Insert the module into the list of extensions
704
+ self.extensions << mod
705
+ end
706
+
707
+ def tab_complete_postmods
708
+ # XXX This might get slow with a large number of post
709
+ # modules. The proper solution is probably to implement a
710
+ # Module::Post#session_compatible?(session_object_or_int) method
711
+ tabs = client.framework.modules.post.map { |name,klass|
712
+ mod = klass.new
713
+ if mod.compatible_sessions.include?(client.sid)
714
+ mod.fullname.dup
715
+ else
716
+ nil
717
+ end
718
+ }
719
+
720
+ # nils confuse readline
721
+ tabs.compact
722
+ end
723
+
724
+ end
725
+
726
+ end
727
+ end
728
+ end
729
+ end
730
+