librex 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 (370) hide show
  1. data/README +4 -0
  2. data/lib/rex.rb +101 -0
  3. data/lib/rex.rb.ts.rb +70 -0
  4. data/lib/rex/LICENSE +29 -0
  5. data/lib/rex/arch.rb +103 -0
  6. data/lib/rex/arch/sparc.rb +75 -0
  7. data/lib/rex/arch/sparc.rb.ut.rb +18 -0
  8. data/lib/rex/arch/x86.rb +513 -0
  9. data/lib/rex/arch/x86.rb.ut.rb +93 -0
  10. data/lib/rex/assembly/nasm.rb +100 -0
  11. data/lib/rex/assembly/nasm.rb.ut.rb +22 -0
  12. data/lib/rex/codepage.map +104 -0
  13. data/lib/rex/compat.rb +281 -0
  14. data/lib/rex/constants.rb +113 -0
  15. data/lib/rex/elfparsey.rb +11 -0
  16. data/lib/rex/elfparsey/elf.rb +123 -0
  17. data/lib/rex/elfparsey/elfbase.rb +260 -0
  18. data/lib/rex/elfparsey/exceptions.rb +27 -0
  19. data/lib/rex/elfscan.rb +12 -0
  20. data/lib/rex/elfscan/scanner.rb +207 -0
  21. data/lib/rex/elfscan/search.rb +46 -0
  22. data/lib/rex/encoder/alpha2.rb +31 -0
  23. data/lib/rex/encoder/alpha2/alpha_mixed.rb +68 -0
  24. data/lib/rex/encoder/alpha2/alpha_upper.rb +79 -0
  25. data/lib/rex/encoder/alpha2/generic.rb +113 -0
  26. data/lib/rex/encoder/alpha2/unicode_mixed.rb +117 -0
  27. data/lib/rex/encoder/alpha2/unicode_upper.rb +129 -0
  28. data/lib/rex/encoder/ndr.rb +89 -0
  29. data/lib/rex/encoder/ndr.rb.ut.rb +44 -0
  30. data/lib/rex/encoder/nonalpha.rb +61 -0
  31. data/lib/rex/encoder/nonupper.rb +64 -0
  32. data/lib/rex/encoder/xdr.rb +106 -0
  33. data/lib/rex/encoder/xdr.rb.ut.rb +29 -0
  34. data/lib/rex/encoder/xor.rb +69 -0
  35. data/lib/rex/encoder/xor/dword.rb +13 -0
  36. data/lib/rex/encoder/xor/dword_additive.rb +13 -0
  37. data/lib/rex/encoders/xor_dword.rb +35 -0
  38. data/lib/rex/encoders/xor_dword_additive.rb +53 -0
  39. data/lib/rex/encoders/xor_dword_additive.rb.ut.rb +12 -0
  40. data/lib/rex/encoding/xor.rb +20 -0
  41. data/lib/rex/encoding/xor.rb.ts.rb +14 -0
  42. data/lib/rex/encoding/xor/byte.rb +15 -0
  43. data/lib/rex/encoding/xor/byte.rb.ut.rb +21 -0
  44. data/lib/rex/encoding/xor/dword.rb +21 -0
  45. data/lib/rex/encoding/xor/dword.rb.ut.rb +15 -0
  46. data/lib/rex/encoding/xor/dword_additive.rb +92 -0
  47. data/lib/rex/encoding/xor/dword_additive.rb.ut.rb +15 -0
  48. data/lib/rex/encoding/xor/exceptions.rb +17 -0
  49. data/lib/rex/encoding/xor/generic.rb +146 -0
  50. data/lib/rex/encoding/xor/generic.rb.ut.rb +120 -0
  51. data/lib/rex/encoding/xor/qword.rb +15 -0
  52. data/lib/rex/encoding/xor/word.rb +21 -0
  53. data/lib/rex/encoding/xor/word.rb.ut.rb +13 -0
  54. data/lib/rex/exceptions.rb +275 -0
  55. data/lib/rex/exceptions.rb.ut.rb +44 -0
  56. data/lib/rex/exploitation/cmdstager.rb +133 -0
  57. data/lib/rex/exploitation/egghunter.rb +143 -0
  58. data/lib/rex/exploitation/egghunter.rb.ut.rb +25 -0
  59. data/lib/rex/exploitation/encryptjs.rb +77 -0
  60. data/lib/rex/exploitation/heaplib.js.b64 +331 -0
  61. data/lib/rex/exploitation/heaplib.rb +94 -0
  62. data/lib/rex/exploitation/javascriptosdetect.rb +735 -0
  63. data/lib/rex/exploitation/obfuscatejs.rb +335 -0
  64. data/lib/rex/exploitation/opcodedb.rb +818 -0
  65. data/lib/rex/exploitation/opcodedb.rb.ut.rb +279 -0
  66. data/lib/rex/exploitation/seh.rb +92 -0
  67. data/lib/rex/exploitation/seh.rb.ut.rb +19 -0
  68. data/lib/rex/file.rb +84 -0
  69. data/lib/rex/file.rb.ut.rb +16 -0
  70. data/lib/rex/image_source.rb +12 -0
  71. data/lib/rex/image_source/disk.rb +60 -0
  72. data/lib/rex/image_source/image_source.rb +46 -0
  73. data/lib/rex/image_source/memory.rb +37 -0
  74. data/lib/rex/io/bidirectional_pipe.rb +157 -0
  75. data/lib/rex/io/datagram_abstraction.rb +35 -0
  76. data/lib/rex/io/stream.rb +313 -0
  77. data/lib/rex/io/stream_abstraction.rb +186 -0
  78. data/lib/rex/io/stream_server.rb +211 -0
  79. data/lib/rex/job_container.rb +202 -0
  80. data/lib/rex/logging.rb +4 -0
  81. data/lib/rex/logging/log_dispatcher.rb +179 -0
  82. data/lib/rex/logging/log_sink.rb +42 -0
  83. data/lib/rex/logging/sinks/flatfile.rb +55 -0
  84. data/lib/rex/logging/sinks/stderr.rb +43 -0
  85. data/lib/rex/machparsey.rb +9 -0
  86. data/lib/rex/machparsey/exceptions.rb +34 -0
  87. data/lib/rex/machparsey/mach.rb +209 -0
  88. data/lib/rex/machparsey/machbase.rb +408 -0
  89. data/lib/rex/machscan.rb +9 -0
  90. data/lib/rex/machscan/scanner.rb +217 -0
  91. data/lib/rex/mime.rb +9 -0
  92. data/lib/rex/mime/header.rb +75 -0
  93. data/lib/rex/mime/message.rb +112 -0
  94. data/lib/rex/mime/part.rb +20 -0
  95. data/lib/rex/nop/opty2.rb +108 -0
  96. data/lib/rex/nop/opty2.rb.ut.rb +23 -0
  97. data/lib/rex/nop/opty2_tables.rb +300 -0
  98. data/lib/rex/ole.rb +128 -0
  99. data/lib/rex/ole/clsid.rb +47 -0
  100. data/lib/rex/ole/difat.rb +141 -0
  101. data/lib/rex/ole/directory.rb +230 -0
  102. data/lib/rex/ole/direntry.rb +240 -0
  103. data/lib/rex/ole/fat.rb +99 -0
  104. data/lib/rex/ole/header.rb +204 -0
  105. data/lib/rex/ole/minifat.rb +77 -0
  106. data/lib/rex/ole/samples/create_ole.rb +27 -0
  107. data/lib/rex/ole/samples/dir.rb +35 -0
  108. data/lib/rex/ole/samples/dump_stream.rb +34 -0
  109. data/lib/rex/ole/samples/ole_info.rb +23 -0
  110. data/lib/rex/ole/storage.rb +395 -0
  111. data/lib/rex/ole/stream.rb +53 -0
  112. data/lib/rex/ole/substorage.rb +49 -0
  113. data/lib/rex/ole/util.rb +157 -0
  114. data/lib/rex/parser/arguments.rb +97 -0
  115. data/lib/rex/parser/arguments.rb.ut.rb +67 -0
  116. data/lib/rex/parser/ini.rb +185 -0
  117. data/lib/rex/parser/ini.rb.ut.rb +29 -0
  118. data/lib/rex/parser/nmap_xml.rb +111 -0
  119. data/lib/rex/payloads.rb +1 -0
  120. data/lib/rex/payloads/win32.rb +2 -0
  121. data/lib/rex/payloads/win32/common.rb +26 -0
  122. data/lib/rex/payloads/win32/kernel.rb +53 -0
  123. data/lib/rex/payloads/win32/kernel/common.rb +54 -0
  124. data/lib/rex/payloads/win32/kernel/migration.rb +12 -0
  125. data/lib/rex/payloads/win32/kernel/recovery.rb +50 -0
  126. data/lib/rex/payloads/win32/kernel/stager.rb +171 -0
  127. data/lib/rex/peparsey.rb +12 -0
  128. data/lib/rex/peparsey/exceptions.rb +32 -0
  129. data/lib/rex/peparsey/pe.rb +188 -0
  130. data/lib/rex/peparsey/pe_memdump.rb +63 -0
  131. data/lib/rex/peparsey/pebase.rb +1655 -0
  132. data/lib/rex/peparsey/section.rb +136 -0
  133. data/lib/rex/pescan.rb +13 -0
  134. data/lib/rex/pescan/analyze.rb +309 -0
  135. data/lib/rex/pescan/scanner.rb +206 -0
  136. data/lib/rex/pescan/search.rb +56 -0
  137. data/lib/rex/platforms.rb +1 -0
  138. data/lib/rex/platforms/windows.rb +51 -0
  139. data/lib/rex/poly.rb +132 -0
  140. data/lib/rex/poly/block.rb +468 -0
  141. data/lib/rex/poly/register.rb +100 -0
  142. data/lib/rex/poly/register/x86.rb +40 -0
  143. data/lib/rex/post.rb +8 -0
  144. data/lib/rex/post/dir.rb +51 -0
  145. data/lib/rex/post/file.rb +172 -0
  146. data/lib/rex/post/file_stat.rb +220 -0
  147. data/lib/rex/post/gen.pl +13 -0
  148. data/lib/rex/post/io.rb +182 -0
  149. data/lib/rex/post/meterpreter.rb +4 -0
  150. data/lib/rex/post/meterpreter/channel.rb +438 -0
  151. data/lib/rex/post/meterpreter/channel_container.rb +54 -0
  152. data/lib/rex/post/meterpreter/channels/pool.rb +160 -0
  153. data/lib/rex/post/meterpreter/channels/pools/file.rb +62 -0
  154. data/lib/rex/post/meterpreter/channels/pools/stream_pool.rb +103 -0
  155. data/lib/rex/post/meterpreter/channels/stream.rb +87 -0
  156. data/lib/rex/post/meterpreter/client.rb +335 -0
  157. data/lib/rex/post/meterpreter/client_core.rb +274 -0
  158. data/lib/rex/post/meterpreter/dependencies.rb +3 -0
  159. data/lib/rex/post/meterpreter/extension.rb +32 -0
  160. data/lib/rex/post/meterpreter/extensions/espia/espia.rb +58 -0
  161. data/lib/rex/post/meterpreter/extensions/espia/tlv.rb +16 -0
  162. data/lib/rex/post/meterpreter/extensions/incognito/incognito.rb +94 -0
  163. data/lib/rex/post/meterpreter/extensions/incognito/tlv.rb +21 -0
  164. data/lib/rex/post/meterpreter/extensions/priv/fs.rb +118 -0
  165. data/lib/rex/post/meterpreter/extensions/priv/passwd.rb +61 -0
  166. data/lib/rex/post/meterpreter/extensions/priv/priv.rb +104 -0
  167. data/lib/rex/post/meterpreter/extensions/priv/tlv.rb +28 -0
  168. data/lib/rex/post/meterpreter/extensions/sniffer/sniffer.rb +100 -0
  169. data/lib/rex/post/meterpreter/extensions/sniffer/tlv.rb +24 -0
  170. data/lib/rex/post/meterpreter/extensions/stdapi/constants.rb +333 -0
  171. data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +273 -0
  172. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +235 -0
  173. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file_stat.rb +103 -0
  174. data/lib/rex/post/meterpreter/extensions/stdapi/fs/io.rb +48 -0
  175. data/lib/rex/post/meterpreter/extensions/stdapi/net/config.rb +144 -0
  176. data/lib/rex/post/meterpreter/extensions/stdapi/net/interface.rb +73 -0
  177. data/lib/rex/post/meterpreter/extensions/stdapi/net/route.rb +56 -0
  178. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +137 -0
  179. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +167 -0
  180. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb +167 -0
  181. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +192 -0
  182. data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +139 -0
  183. data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +97 -0
  184. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +184 -0
  185. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log_subsystem/event_record.rb +41 -0
  186. data/lib/rex/post/meterpreter/extensions/stdapi/sys/power.rb +61 -0
  187. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +361 -0
  188. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/image.rb +129 -0
  189. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/io.rb +55 -0
  190. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/memory.rb +336 -0
  191. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/thread.rb +141 -0
  192. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +279 -0
  193. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +182 -0
  194. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_value.rb +102 -0
  195. data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +174 -0
  196. data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +185 -0
  197. data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +227 -0
  198. data/lib/rex/post/meterpreter/inbound_packet_handler.rb +30 -0
  199. data/lib/rex/post/meterpreter/object_aliases.rb +83 -0
  200. data/lib/rex/post/meterpreter/packet.rb +596 -0
  201. data/lib/rex/post/meterpreter/packet_dispatcher.rb +409 -0
  202. data/lib/rex/post/meterpreter/packet_parser.rb +94 -0
  203. data/lib/rex/post/meterpreter/packet_response_waiter.rb +83 -0
  204. data/lib/rex/post/meterpreter/ui/console.rb +135 -0
  205. data/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb +62 -0
  206. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +595 -0
  207. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/espia.rb +108 -0
  208. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/incognito.rb +241 -0
  209. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv.rb +61 -0
  210. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +98 -0
  211. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/passwd.rb +51 -0
  212. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +132 -0
  213. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +187 -0
  214. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi.rb +63 -0
  215. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +376 -0
  216. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +270 -0
  217. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +484 -0
  218. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +315 -0
  219. data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +95 -0
  220. data/lib/rex/post/permission.rb +26 -0
  221. data/lib/rex/post/process.rb +57 -0
  222. data/lib/rex/post/thread.rb +57 -0
  223. data/lib/rex/post/ui.rb +52 -0
  224. data/lib/rex/proto.rb +12 -0
  225. data/lib/rex/proto.rb.ts.rb +8 -0
  226. data/lib/rex/proto/dcerpc.rb +6 -0
  227. data/lib/rex/proto/dcerpc.rb.ts.rb +9 -0
  228. data/lib/rex/proto/dcerpc/client.rb +358 -0
  229. data/lib/rex/proto/dcerpc/client.rb.ut.rb +491 -0
  230. data/lib/rex/proto/dcerpc/exceptions.rb +150 -0
  231. data/lib/rex/proto/dcerpc/handle.rb +47 -0
  232. data/lib/rex/proto/dcerpc/handle.rb.ut.rb +85 -0
  233. data/lib/rex/proto/dcerpc/ndr.rb +72 -0
  234. data/lib/rex/proto/dcerpc/ndr.rb.ut.rb +41 -0
  235. data/lib/rex/proto/dcerpc/packet.rb +253 -0
  236. data/lib/rex/proto/dcerpc/packet.rb.ut.rb +56 -0
  237. data/lib/rex/proto/dcerpc/response.rb +186 -0
  238. data/lib/rex/proto/dcerpc/response.rb.ut.rb +15 -0
  239. data/lib/rex/proto/dcerpc/uuid.rb +84 -0
  240. data/lib/rex/proto/dcerpc/uuid.rb.ut.rb +46 -0
  241. data/lib/rex/proto/drda.rb +5 -0
  242. data/lib/rex/proto/drda.rb.ts.rb +17 -0
  243. data/lib/rex/proto/drda/constants.rb +49 -0
  244. data/lib/rex/proto/drda/constants.rb.ut.rb +23 -0
  245. data/lib/rex/proto/drda/packet.rb +252 -0
  246. data/lib/rex/proto/drda/packet.rb.ut.rb +109 -0
  247. data/lib/rex/proto/drda/utils.rb +123 -0
  248. data/lib/rex/proto/drda/utils.rb.ut.rb +84 -0
  249. data/lib/rex/proto/http.rb +5 -0
  250. data/lib/rex/proto/http.rb.ts.rb +12 -0
  251. data/lib/rex/proto/http/client.rb +817 -0
  252. data/lib/rex/proto/http/client.rb.ut.rb +93 -0
  253. data/lib/rex/proto/http/handler.rb +46 -0
  254. data/lib/rex/proto/http/handler/erb.rb +128 -0
  255. data/lib/rex/proto/http/handler/erb.rb.ut.rb +21 -0
  256. data/lib/rex/proto/http/handler/erb.rb.ut.rb.rhtml +1 -0
  257. data/lib/rex/proto/http/handler/proc.rb +54 -0
  258. data/lib/rex/proto/http/handler/proc.rb.ut.rb +24 -0
  259. data/lib/rex/proto/http/header.rb +161 -0
  260. data/lib/rex/proto/http/header.rb.ut.rb +46 -0
  261. data/lib/rex/proto/http/packet.rb +394 -0
  262. data/lib/rex/proto/http/packet.rb.ut.rb +165 -0
  263. data/lib/rex/proto/http/request.rb +356 -0
  264. data/lib/rex/proto/http/request.rb.ut.rb +214 -0
  265. data/lib/rex/proto/http/response.rb +85 -0
  266. data/lib/rex/proto/http/response.rb.ut.rb +149 -0
  267. data/lib/rex/proto/http/server.rb +367 -0
  268. data/lib/rex/proto/http/server.rb.ut.rb +79 -0
  269. data/lib/rex/proto/smb.rb +7 -0
  270. data/lib/rex/proto/smb.rb.ts.rb +8 -0
  271. data/lib/rex/proto/smb/client.rb +1733 -0
  272. data/lib/rex/proto/smb/client.rb.ut.rb +223 -0
  273. data/lib/rex/proto/smb/constants.rb +1062 -0
  274. data/lib/rex/proto/smb/constants.rb.ut.rb +18 -0
  275. data/lib/rex/proto/smb/crypt.rb +95 -0
  276. data/lib/rex/proto/smb/crypt.rb.ut.rb +20 -0
  277. data/lib/rex/proto/smb/evasions.rb +65 -0
  278. data/lib/rex/proto/smb/exceptions.rb +846 -0
  279. data/lib/rex/proto/smb/simpleclient.rb +292 -0
  280. data/lib/rex/proto/smb/simpleclient.rb.ut.rb +128 -0
  281. data/lib/rex/proto/smb/utils.rb +514 -0
  282. data/lib/rex/proto/smb/utils.rb.ut.rb +20 -0
  283. data/lib/rex/proto/sunrpc.rb +1 -0
  284. data/lib/rex/proto/sunrpc/client.rb +195 -0
  285. data/lib/rex/script.rb +42 -0
  286. data/lib/rex/script/base.rb +59 -0
  287. data/lib/rex/script/meterpreter.rb +9 -0
  288. data/lib/rex/script/shell.rb +9 -0
  289. data/lib/rex/service.rb +48 -0
  290. data/lib/rex/service_manager.rb +141 -0
  291. data/lib/rex/service_manager.rb.ut.rb +32 -0
  292. data/lib/rex/services/local_relay.rb +423 -0
  293. data/lib/rex/socket.rb +586 -0
  294. data/lib/rex/socket.rb.ut.rb +86 -0
  295. data/lib/rex/socket/comm.rb +119 -0
  296. data/lib/rex/socket/comm/local.rb +409 -0
  297. data/lib/rex/socket/comm/local.rb.ut.rb +75 -0
  298. data/lib/rex/socket/ip.rb +129 -0
  299. data/lib/rex/socket/parameters.rb +345 -0
  300. data/lib/rex/socket/parameters.rb.ut.rb +51 -0
  301. data/lib/rex/socket/range_walker.rb +295 -0
  302. data/lib/rex/socket/range_walker.rb.ut.rb +55 -0
  303. data/lib/rex/socket/ssl_tcp.rb +184 -0
  304. data/lib/rex/socket/ssl_tcp.rb.ut.rb +39 -0
  305. data/lib/rex/socket/ssl_tcp_server.rb +122 -0
  306. data/lib/rex/socket/ssl_tcp_server.rb.ut.rb +51 -0
  307. data/lib/rex/socket/subnet_walker.rb +75 -0
  308. data/lib/rex/socket/subnet_walker.rb.ut.rb +28 -0
  309. data/lib/rex/socket/switch_board.rb +272 -0
  310. data/lib/rex/socket/switch_board.rb.ut.rb +52 -0
  311. data/lib/rex/socket/tcp.rb +76 -0
  312. data/lib/rex/socket/tcp.rb.ut.rb +64 -0
  313. data/lib/rex/socket/tcp_server.rb +67 -0
  314. data/lib/rex/socket/tcp_server.rb.ut.rb +44 -0
  315. data/lib/rex/socket/udp.rb +157 -0
  316. data/lib/rex/socket/udp.rb.ut.rb +44 -0
  317. data/lib/rex/struct2.rb +5 -0
  318. data/lib/rex/struct2/c_struct.rb +181 -0
  319. data/lib/rex/struct2/c_struct_template.rb +39 -0
  320. data/lib/rex/struct2/constant.rb +26 -0
  321. data/lib/rex/struct2/element.rb +44 -0
  322. data/lib/rex/struct2/generic.rb +73 -0
  323. data/lib/rex/struct2/restraint.rb +54 -0
  324. data/lib/rex/struct2/s_string.rb +72 -0
  325. data/lib/rex/struct2/s_struct.rb +111 -0
  326. data/lib/rex/sync.rb +6 -0
  327. data/lib/rex/sync/event.rb +94 -0
  328. data/lib/rex/sync/read_write_lock.rb +176 -0
  329. data/lib/rex/sync/ref.rb +57 -0
  330. data/lib/rex/sync/thread_safe.rb +82 -0
  331. data/lib/rex/test.rb +35 -0
  332. data/lib/rex/text.rb +1029 -0
  333. data/lib/rex/text.rb.ut.rb +168 -0
  334. data/lib/rex/time.rb +65 -0
  335. data/lib/rex/transformer.rb +115 -0
  336. data/lib/rex/transformer.rb.ut.rb +38 -0
  337. data/lib/rex/ui.rb +21 -0
  338. data/lib/rex/ui/interactive.rb +252 -0
  339. data/lib/rex/ui/output.rb +80 -0
  340. data/lib/rex/ui/output/none.rb +18 -0
  341. data/lib/rex/ui/progress_tracker.rb +96 -0
  342. data/lib/rex/ui/subscriber.rb +149 -0
  343. data/lib/rex/ui/text/color.rb +97 -0
  344. data/lib/rex/ui/text/color.rb.ut.rb +18 -0
  345. data/lib/rex/ui/text/dispatcher_shell.rb +382 -0
  346. data/lib/rex/ui/text/input.rb +117 -0
  347. data/lib/rex/ui/text/input/buffer.rb +75 -0
  348. data/lib/rex/ui/text/input/readline.rb +129 -0
  349. data/lib/rex/ui/text/input/socket.rb +95 -0
  350. data/lib/rex/ui/text/input/stdio.rb +45 -0
  351. data/lib/rex/ui/text/irb_shell.rb +55 -0
  352. data/lib/rex/ui/text/output.rb +80 -0
  353. data/lib/rex/ui/text/output/buffer.rb +65 -0
  354. data/lib/rex/ui/text/output/file.rb +37 -0
  355. data/lib/rex/ui/text/output/socket.rb +43 -0
  356. data/lib/rex/ui/text/output/stdio.rb +40 -0
  357. data/lib/rex/ui/text/progress_tracker.rb +56 -0
  358. data/lib/rex/ui/text/progress_tracker.rb.ut.rb +34 -0
  359. data/lib/rex/ui/text/shell.rb +321 -0
  360. data/lib/rex/ui/text/table.rb +254 -0
  361. data/lib/rex/ui/text/table.rb.ut.rb +55 -0
  362. data/lib/rex/zip.rb +93 -0
  363. data/lib/rex/zip/archive.rb +91 -0
  364. data/lib/rex/zip/blocks.rb +182 -0
  365. data/lib/rex/zip/entry.rb +95 -0
  366. data/lib/rex/zip/samples/comment.rb +32 -0
  367. data/lib/rex/zip/samples/mkwar.rb +138 -0
  368. data/lib/rex/zip/samples/mkzip.rb +19 -0
  369. data/lib/rex/zip/samples/recursive.rb +58 -0
  370. metadata +435 -0
@@ -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
+ select(nil, nil, nil, 0.1)
63
+ end
64
+ else
65
+ begin
66
+ Timeout.timeout(interval) {
67
+ while(not self.done)
68
+ 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,135 @@
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
+ # Run queued commands
57
+ commands.delete_if { |ent|
58
+ run_single(ent)
59
+ true
60
+ }
61
+
62
+ # Run the interactive loop
63
+ run { |line|
64
+ # Run the command
65
+ run_single(line)
66
+
67
+ # If a block was supplied, call it, otherwise return false
68
+ if (block)
69
+ block.call
70
+ else
71
+ false
72
+ end
73
+ }
74
+ end
75
+
76
+ #
77
+ # Interacts with the supplied channel.
78
+ #
79
+ def interact_with_channel(channel)
80
+ channel.extend(InteractiveChannel) unless (channel.kind_of?(InteractiveChannel) == true)
81
+
82
+ channel.interact(input, output)
83
+ channel.reset_ui
84
+ end
85
+
86
+ #
87
+ # Queues a command to be run when the interactive loop is entered.
88
+ #
89
+ def queue_cmd(cmd)
90
+ self.commands << cmd
91
+ end
92
+
93
+ #
94
+ # Runs the specified command wrapper in something to catch meterpreter
95
+ # exceptions.
96
+ #
97
+ def run_command(dispatcher, method, arguments)
98
+ begin
99
+ super
100
+ rescue Timeout::Error
101
+ log_error("Operation timed out.")
102
+ rescue RequestError => info
103
+ log_error(info.to_s)
104
+ rescue ::Errno::EPIPE, ::OpenSSL::SSL::SSLError, ::IOError
105
+ self.client.kill
106
+ rescue ::Exception => e
107
+ log_error("Error running command #{method}: #{e.class} #{e}")
108
+ end
109
+ end
110
+
111
+ #
112
+ # Logs that an error occurred and persists the callstack.
113
+ #
114
+ def log_error(msg)
115
+ print_error(msg)
116
+
117
+ elog(msg, 'meterpreter')
118
+
119
+ dlog("Call stack:\n#{$@.join("\n")}", 'meterpreter')
120
+ end
121
+
122
+ attr_reader :client # :nodoc:
123
+
124
+ protected
125
+
126
+ attr_writer :client # :nodoc:
127
+ attr_accessor :commands # :nodoc:
128
+
129
+ end
130
+
131
+ end
132
+ end
133
+ end
134
+ end
135
+
@@ -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,595 @@
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
+ end
30
+
31
+ @@use_opts = Rex::Parser::Arguments.new(
32
+ "-l" => [ false, "List all available extensions" ],
33
+ "-h" => [ false, "Help menu." ])
34
+
35
+ #
36
+ # List of supported commands.
37
+ #
38
+ def commands
39
+ {
40
+ "?" => "Help menu",
41
+ "background" => "Backgrounds the current session",
42
+ "close" => "Closes a channel",
43
+ "channel" => "Displays information about active channels",
44
+ "exit" => "Terminate the meterpreter session",
45
+ "help" => "Help menu",
46
+ "interact" => "Interacts with a channel",
47
+ "irb" => "Drop into irb scripting mode",
48
+ "migrate" => "Migrate the server to another process",
49
+ "use" => "Load a one or more meterpreter extensions",
50
+ "quit" => "Terminate the meterpreter session",
51
+ "read" => "Reads data from a channel",
52
+ "run" => "Executes a meterpreter script",
53
+ "bgrun" => "Executes a meterpreter script as a background thread",
54
+ "bgkill" => "Kills a background meterpreter script",
55
+ "bglist" => "Lists running background scripts",
56
+ "write" => "Writes data to a channel",
57
+ }
58
+ end
59
+
60
+ #
61
+ # Core baby.
62
+ #
63
+ def name
64
+ "Core"
65
+ end
66
+
67
+ def cmd_background
68
+ client.interacting = false
69
+ end
70
+
71
+ #
72
+ # Displays information about active channels
73
+ #
74
+ @@channel_opts = Rex::Parser::Arguments.new(
75
+ "-l" => [ false, "List active channels." ],
76
+ "-h" => [ false, "Help menu." ])
77
+
78
+ #
79
+ # Performs operations on the supplied channel.
80
+ #
81
+ def cmd_channel(*args)
82
+ if (args.length == 0)
83
+ args.unshift("-h")
84
+ end
85
+
86
+ mode = nil
87
+
88
+ # Parse options
89
+ @@channel_opts.parse(args) { |opt, idx, val|
90
+ case opt
91
+ when "-h"
92
+ print(
93
+ "Usage: channel [options]\n\n" +
94
+ "Displays information about active channels.\n" +
95
+ @@channel_opts.usage)
96
+ return true
97
+ when "-l"
98
+ mode = 'list'
99
+ end
100
+ }
101
+
102
+ # No mode, no service.
103
+ if (mode == nil)
104
+ return true
105
+ elsif (mode == 'list')
106
+ tbl = Rex::Ui::Text::Table.new(
107
+ 'Indent' => 4,
108
+ 'Columns' =>
109
+ [
110
+ 'Id',
111
+ 'Class',
112
+ 'Type'
113
+ ])
114
+ items = 0
115
+
116
+ client.channels.each_pair { |cid, channel|
117
+ tbl << [ cid, channel.class.cls, channel.type ]
118
+ items += 1
119
+ }
120
+
121
+ if (items == 0)
122
+ print_line("No active channels.")
123
+ else
124
+ print("\n" + tbl.to_s + "\n")
125
+ end
126
+ end
127
+ end
128
+
129
+ #
130
+ # Closes a supplied channel.
131
+ #
132
+ def cmd_close(*args)
133
+ if (args.length == 0)
134
+ print_line(
135
+ "Usage: close channel_id\n\n" +
136
+ "Closes the supplied channel.")
137
+ return true
138
+ end
139
+
140
+ cid = args[0].to_i
141
+ channel = client.find_channel(cid)
142
+
143
+ if (!channel)
144
+ print_error("Invalid channel identifier specified.")
145
+ return true
146
+ else
147
+ channel._close # Issue #410
148
+
149
+ print_status("Closed channel #{cid}.")
150
+ end
151
+ end
152
+
153
+ #
154
+ # Terminates the meterpreter session.
155
+ #
156
+ def cmd_exit(*args)
157
+ shell.stop
158
+ end
159
+
160
+ alias cmd_quit cmd_exit
161
+
162
+ #
163
+ # Displays the help menu.
164
+ #
165
+ def cmd_help(*args)
166
+ print(shell.help_to_s)
167
+ end
168
+
169
+ alias cmd_? cmd_help
170
+
171
+ #
172
+ # Interacts with a channel.
173
+ #
174
+ def cmd_interact(*args)
175
+ if (args.length == 0)
176
+ print_line(
177
+ "Usage: interact channel_id\n\n" +
178
+ "Interacts with the supplied channel.")
179
+ return true
180
+ end
181
+
182
+ cid = args[0].to_i
183
+ channel = client.find_channel(cid)
184
+
185
+ if (channel)
186
+ print_line("Interacting with channel #{cid}...\n")
187
+
188
+ shell.interact_with_channel(channel)
189
+ else
190
+ print_error("Invalid channel identifier specified.")
191
+ end
192
+ end
193
+
194
+ #
195
+ # Runs the IRB scripting shell
196
+ #
197
+ def cmd_irb(*args)
198
+ print_status("Starting IRB shell")
199
+ print_status("The 'client' variable holds the meterpreter client\n")
200
+
201
+ Rex::Ui::Text::IrbShell.new(binding).run
202
+ end
203
+
204
+ #
205
+ # Migrates the server to the supplied process identifier.
206
+ #
207
+ def cmd_migrate(*args)
208
+ if (args.length == 0)
209
+ print_line(
210
+ "Usage: migrate pid\n\n" +
211
+ "Migrates the server instance to another process.\n" +
212
+ "Note: Any open channels or other dynamic state will be lost.")
213
+ return true
214
+ end
215
+
216
+ pid = args[0].to_i
217
+ if(pid == 0)
218
+ print_error("A process ID must be specified, not a process name")
219
+ return
220
+ end
221
+
222
+ print_status("Migrating to #{pid}...")
223
+
224
+ # Do this thang.
225
+ client.core.migrate(pid)
226
+
227
+ print_status("Migration completed successfully.")
228
+ end
229
+
230
+ #
231
+ # Loads one or more meterpreter extensions.
232
+ #
233
+ def cmd_use(*args)
234
+ if (args.length == 0)
235
+ args.unshift("-h")
236
+ end
237
+
238
+ modules = nil
239
+
240
+ @@use_opts.parse(args) { |opt, idx, val|
241
+ case opt
242
+ when "-l"
243
+ exts = []
244
+ path = ::File.join(Msf::Config.install_root, 'data', 'meterpreter')
245
+ ::Dir.entries(path).each { |f|
246
+ if (::File.file?(::File.join(path, f)) && f =~ /ext_server_(.*)\.#{client.binary_suffix}/ )
247
+ exts.push($1)
248
+ end
249
+ }
250
+ print(exts.sort.join("\n") + "\n")
251
+
252
+ return true
253
+ when "-h"
254
+ print(
255
+ "Usage: use ext1 ext2 ext3 ...\n\n" +
256
+ "Loads a meterpreter extension module or modules.\n" +
257
+ @@use_opts.usage)
258
+ return true
259
+ end
260
+ }
261
+
262
+ # Load each of the modules
263
+ args.each { |m|
264
+ md = m.downcase
265
+
266
+ if (extensions.include?(md))
267
+ print_error("The '#{md}' extension has already been loaded.")
268
+ next
269
+ end
270
+
271
+ print("Loading extension #{md}...")
272
+
273
+ begin
274
+ # Use the remote side, then load the client-side
275
+ if (client.core.use(md) == true)
276
+ add_extension_client(md)
277
+ end
278
+ rescue
279
+ print_line
280
+ log_error("Failed to load extension: #{$!}")
281
+ next
282
+ end
283
+
284
+ print_line("success.")
285
+ }
286
+
287
+ return true
288
+ end
289
+
290
+ def cmd_use_tabs(str, words)
291
+ tabs = []
292
+ path = ::File.join(Msf::Config.install_root, 'data', 'meterpreter')
293
+ ::Dir.entries(path).each { |f|
294
+ if (::File.file?(::File.join(path, f)) && f =~ /ext_server_(.*)\.#{client.binary_suffix}/ )
295
+ if (not extensions.include?($1))
296
+ tabs.push($1)
297
+ end
298
+ end
299
+ }
300
+ return tabs
301
+ end
302
+
303
+ #
304
+ # Reads data from a channel.
305
+ #
306
+ def cmd_read(*args)
307
+ if (args.length == 0)
308
+ print_line(
309
+ "Usage: read channel_id [length]\n\n" +
310
+ "Reads data from the supplied channel.")
311
+ return true
312
+ end
313
+
314
+ cid = args[0].to_i
315
+ length = (args.length >= 2) ? args[1].to_i : 16384
316
+ channel = client.find_channel(cid)
317
+
318
+ if (!channel)
319
+ print_error("Channel #{cid} is not valid.")
320
+ return true
321
+ end
322
+
323
+ data = channel.read(length)
324
+
325
+ if (data and data.length)
326
+ print("Read #{data.length} bytes from #{cid}:\n\n#{data}\n")
327
+ else
328
+ print_error("No data was returned.")
329
+ end
330
+
331
+ return true
332
+ end
333
+
334
+ #
335
+ # Executes a script in the context of the meterpreter session.
336
+ #
337
+ def cmd_run(*args)
338
+ if args.length == 0
339
+ print_line(
340
+ "Usage: run <script> [arguments]\n\n" +
341
+ "Executes a ruby script in the context of the meterpreter session.")
342
+ return true
343
+ end
344
+
345
+ # Get the script name
346
+ begin
347
+ # the rest of the arguments get passed in through the binding
348
+ client.execute_script(args.shift, args)
349
+ rescue
350
+ print_error("Error in script: #{$!.class} #{$!}")
351
+ elog("Error in script: #{$!.class} #{$!}")
352
+ dlog("Callstack: #{$@.join("\n")}")
353
+ end
354
+ end
355
+
356
+ def cmd_run_tabs(str, words)
357
+ if(not words[1] or not words[1].match(/^\//))
358
+ begin
359
+ my_directory = Msf::Config.script_directory + ::File::SEPARATOR + "meterpreter"
360
+ return ::Dir.new(my_directory).find_all { |e|
361
+ path = my_directory + ::File::SEPARATOR + e
362
+ ::File.file?(path) and ::File.readable?(path)
363
+ }.map { |e|
364
+ e.sub!(/\.rb$/, '')
365
+ }
366
+ rescue Exception
367
+ end
368
+ end
369
+ end
370
+
371
+
372
+ #
373
+ # Executes a script in the context of the meterpreter session in the background
374
+ #
375
+ def cmd_bgrun(*args)
376
+ if args.length == 0
377
+ print_line(
378
+ "Usage: bgrun <script> [arguments]\n\n" +
379
+ "Executes a ruby script in the context of the meterpreter session.")
380
+ return true
381
+ end
382
+
383
+ jid = self.bgjob_id
384
+ self.bgjob_id += 1
385
+
386
+ # Get the script name
387
+ self.bgjobs[jid] = ::Thread.new(jid,args) do |myjid,xargs|
388
+ ::Thread.current[:args] = xargs.dup
389
+ begin
390
+ # the rest of the arguments get passed in through the binding
391
+ client.execute_script(args.shift, args)
392
+ rescue ::Exception
393
+ print_error("Error in script: #{$!.class} #{$!}")
394
+ elog("Error in script: #{$!.class} #{$!}")
395
+ dlog("Callstack: #{$@.join("\n")}")
396
+ end
397
+ self.bgjobs[myjid] = nil
398
+ print_status("Background script with Job ID #{myjid} has completed (#{::Thread.current[:args].inspect})")
399
+ end
400
+
401
+ print_status("Executed Meterpreter with Job ID #{jid}")
402
+ end
403
+
404
+ #
405
+ # Map this to the normal run command tab completion
406
+ #
407
+ def cmd_bgrun_tabs(*args)
408
+ cmd_run_tabs(*args)
409
+ end
410
+
411
+ #
412
+ # Kill a background job
413
+ #
414
+ def cmd_bgkill(*args)
415
+ if args.length == 0
416
+ print_line("Usage: bgkill [id]")
417
+ return
418
+ end
419
+
420
+ args.each do |jid|
421
+ jid = jid.to_i
422
+ if self.bgjobs[jid]
423
+ print_status("Killing background job #{jid}...")
424
+ self.bgjobs[jid].kill
425
+ self.bgjobs[jid] = nil
426
+ else
427
+ print_error("Job #{jid} was not running")
428
+ end
429
+ end
430
+ end
431
+
432
+ #
433
+ # List background jobs
434
+ #
435
+ def cmd_bglist(*args)
436
+ self.bgjobs.each_index do |jid|
437
+ if self.bgjobs[jid]
438
+ print_status("Job #{jid}: #{self.bgjobs[jid][:args].inspect}")
439
+ end
440
+ end
441
+ end
442
+
443
+ #
444
+ # Writes data to a channel.
445
+ #
446
+ @@write_opts = Rex::Parser::Arguments.new(
447
+ "-f" => [ true, "Write the contents of a file on disk" ],
448
+ "-h" => [ false, "Help menu." ])
449
+
450
+ def cmd_write(*args)
451
+ if (args.length == 0)
452
+ args.unshift("-h")
453
+ end
454
+
455
+ src_file = nil
456
+ cid = nil
457
+
458
+ @@write_opts.parse(args) { |opt, idx, val|
459
+ case opt
460
+ when "-h"
461
+ print(
462
+ "Usage: write [options] channel_id\n\n" +
463
+ "Writes data to the supplied channel.\n" +
464
+ @@write_opts.usage)
465
+ return true
466
+ when "-f"
467
+ src_file = val
468
+ else
469
+ cid = val.to_i
470
+ end
471
+ }
472
+
473
+ # Find the channel associated with this cid, assuming the cid is valid.
474
+ if ((!cid) or
475
+ (!(channel = client.find_channel(cid))))
476
+ print_error("Invalid channel identifier specified.")
477
+ return true
478
+ end
479
+
480
+ # If they supplied a source file, read in its contents and write it to
481
+ # the channel
482
+ if (src_file)
483
+ begin
484
+ data = ''
485
+
486
+ ::File.open(src_file, 'rb') { |f|
487
+ data = f.read(f.stat.size)
488
+ }
489
+
490
+ rescue Errno::ENOENT
491
+ print_error("Invalid source file specified: #{src_file}")
492
+ return true
493
+ end
494
+
495
+ if (data and data.length > 0)
496
+ channel.write(data)
497
+ print_status("Wrote #{data.length} bytes to channel #{cid}.")
498
+ else
499
+ print_error("No data to send from file #{src_file}")
500
+ return true
501
+ end
502
+ # Otherwise, read from the input descriptor until we're good to go.
503
+ else
504
+ print("Enter data followed by a '.' on an empty line:\n\n")
505
+
506
+ data = ''
507
+
508
+ # Keep truckin'
509
+ while (s = shell.input.gets)
510
+ break if (s =~ /^\.\r?\n?$/)
511
+ data += s
512
+ end
513
+
514
+ if (!data or data.length == 0)
515
+ print_error("No data to send.")
516
+ else
517
+ channel.write(data)
518
+ print_status("Wrote #{data.length} bytes to channel #{cid}.")
519
+ end
520
+ end
521
+
522
+ return true
523
+ end
524
+
525
+ #
526
+ # Provide command-specific tab completion
527
+ # Stolen directly from msf/ui/console/command_dispatcher/core.rb
528
+ # perhaps this should be moved into rex/ui/text/dispatcher_shell.rb ?
529
+ #
530
+ def tab_complete_helper(str, words)
531
+ items = []
532
+
533
+ # Is the user trying to tab complete one of our commands?
534
+ if (commands.include?(words[0]))
535
+ if (self.respond_to?('cmd_'+words[0]+'_tabs'))
536
+ res = self.send('cmd_'+words[0]+'_tabs', str, words)
537
+ return nil if res.nil?
538
+ items.concat(res)
539
+ else
540
+ # Avoid the default completion list for known commands
541
+ return nil
542
+ end
543
+ end
544
+
545
+ return items
546
+ end
547
+
548
+ protected
549
+
550
+ attr_accessor :extensions # :nodoc:
551
+ attr_accessor :bgjobs, :bgjob_id # :nodoc:
552
+
553
+ CommDispatcher = Console::CommandDispatcher
554
+
555
+ #
556
+ # Loads the client extension specified in mod
557
+ #
558
+ def add_extension_client(mod)
559
+ path = "post/meterpreter/ui/console/command_dispatcher/#{mod}.rb"
560
+
561
+ if ((klass = CommDispatcher.check_hash(path)) == nil)
562
+ clirb = File.join(Rex::Root, path)
563
+ old = CommDispatcher.constants
564
+
565
+ if (require(clirb))
566
+ new = CommDispatcher.constants
567
+ diff = new - old
568
+
569
+ if (diff.empty? == true)
570
+ print_error("Failed to load client portion of #{mod}.")
571
+ return false
572
+ end
573
+
574
+ klass = CommDispatcher.const_get(diff[0])
575
+
576
+ CommDispatcher.set_hash(path, klass)
577
+ else
578
+ print_error("Failed to load client script file: #{clirb}")
579
+ return false
580
+ end
581
+ end
582
+
583
+ # Enstack the dispatcher
584
+ self.shell.enstack_dispatcher(klass)
585
+
586
+ # Insert the module into the list of extensions
587
+ self.extensions << mod
588
+ end
589
+ end
590
+
591
+ end
592
+ end
593
+ end
594
+ end
595
+