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,51 @@
1
+ require 'rex/post/meterpreter'
2
+
3
+ module Rex
4
+ module Post
5
+ module Meterpreter
6
+ module Ui
7
+
8
+ ###
9
+ #
10
+ # The password database portion of the privilege escalation extension.
11
+ #
12
+ ###
13
+ class Console::CommandDispatcher::Priv::Passwd
14
+
15
+ Klass = Console::CommandDispatcher::Priv::Passwd
16
+
17
+ include Console::CommandDispatcher
18
+
19
+ #
20
+ # List of supported commands.
21
+ #
22
+ def commands
23
+ {
24
+ "hashdump" => "Dumps the contents of the SAM database"
25
+ }
26
+ end
27
+
28
+ #
29
+ # Name for this dispatcher.
30
+ #
31
+ def name
32
+ "Priv: Password database"
33
+ end
34
+
35
+ #
36
+ # Displays the contents of the SAM database
37
+ #
38
+ def cmd_hashdump(*args)
39
+ client.priv.sam_hashes.each { |user|
40
+ print_line("#{user}")
41
+ }
42
+
43
+ return true
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,132 @@
1
+ require 'rex/post/meterpreter'
2
+
3
+ module Rex
4
+ module Post
5
+ module Meterpreter
6
+ module Ui
7
+
8
+ ###
9
+ #
10
+ # This class provides commands that interact with the timestomp feature set of
11
+ # the privilege escalation extension.
12
+ #
13
+ ###
14
+ class Console::CommandDispatcher::Priv::Timestomp
15
+
16
+ Klass = Console::CommandDispatcher::Priv::Timestomp
17
+
18
+ include Console::CommandDispatcher
19
+
20
+ @@timestomp_opts = Rex::Parser::Arguments.new(
21
+ "-m" => [ true, "Set the \"last written\" time of the file" ],
22
+ "-a" => [ true, "Set the \"last accessed\" time of the file" ],
23
+ "-c" => [ true, "Set the \"creation\" time of the file" ],
24
+ "-e" => [ true, "Set the \"mft entry modified\" time of the file" ],
25
+ "-z" => [ true, "Set all four attributes (MACE) of the file" ],
26
+ "-f" => [ true, "Set the MACE of attributes equal to the supplied file" ],
27
+ "-b" => [ false, "Set the MACE timestamps so that EnCase shows blanks" ],
28
+ "-r" => [ false, "Set the MACE timestamps recursively on a directory" ],
29
+ "-v" => [ false, "Display the UTC MACE values of the file" ],
30
+ "-h" => [ false, "Help banner" ])
31
+
32
+ #
33
+ # List of supported commands.
34
+ #
35
+ def commands
36
+ {
37
+ "timestomp" => "Manipulate file MACE attributes"
38
+ }
39
+ end
40
+
41
+ #
42
+ # Name for this dispatcher.
43
+ #
44
+ def name
45
+ "Priv: Timestomp"
46
+ end
47
+
48
+ #
49
+ # This command provides the same level of features that vinnie's command
50
+ # line timestomp interface provides with a similar argument set.
51
+ #
52
+ def cmd_timestomp(*args)
53
+ if (args.length < 2)
54
+ print_line("\nUsage: timestomp file_path OPTIONS\n" +
55
+ @@timestomp_opts.usage)
56
+ return
57
+ end
58
+
59
+ file_path = args.shift
60
+ modified = nil
61
+ accessed = nil
62
+ creation = nil
63
+ emodified = nil
64
+
65
+ @@timestomp_opts.parse(args) { |opt, idx, val|
66
+ case opt
67
+ when "-m"
68
+ modified = str_to_time(val)
69
+ when "-a"
70
+ accessed = str_to_time(val)
71
+ when "-c"
72
+ creation = str_to_time(val)
73
+ when "-e"
74
+ emodified = str_to_time(val)
75
+ when "-z"
76
+ puts "#{val}"
77
+ modified = str_to_time(val)
78
+ accessed = str_to_time(val)
79
+ creation = str_to_time(val)
80
+ emodified = str_to_time(val)
81
+ when "-f"
82
+ print_status("Setting MACE attributes on #{file_path} from #{val}")
83
+ client.priv.fs.set_file_mace_from_file(file_path, val)
84
+ when "-b"
85
+ print_status("Blanking file MACE attributes on #{file_path}")
86
+ client.priv.fs.blank_file_mace(file_path)
87
+ when "-r"
88
+ print_status("Blanking directory MACE attributes on #{file_path}")
89
+ client.priv.fs.blank_directory_mace(file_path)
90
+ when "-v"
91
+ hash = client.priv.fs.get_file_mace(file_path)
92
+
93
+ print_line("Modified : #{hash['Modified']}")
94
+ print_line("Accessed : #{hash['Accessed']}")
95
+ print_line("Created : #{hash['Created']}")
96
+ print_line("Entry Modified: #{hash['Entry Modified']}")
97
+ when "-h"
98
+ print_line("\nUsage: timestomp file_path OPTIONS\n" +
99
+ @@timestomp_opts.usage)
100
+ return
101
+ end
102
+ }
103
+
104
+ # If any one of the four times were specified, change them.
105
+ if (modified or accessed or creation or emodified)
106
+ print_status("Setting specific MACE attributes on #{file_path}")
107
+ client.priv.fs.set_file_mace(file_path, modified, accessed,
108
+ creation, emodified)
109
+ end
110
+ end
111
+
112
+ protected
113
+
114
+ #
115
+ # Converts a date/time in the form of MM/DD/YYYY HH24:MI:SS
116
+ #
117
+ def str_to_time(str) # :nodoc:
118
+ r, mon, day, year, hour, min, sec = str.match("^(\\d+?)/(\\d+?)/(\\d+?) (\\d+?):(\\d+?):(\\d+?)$").to_a
119
+
120
+ if (mon == nil)
121
+ raise ArgumentError, "Invalid date format, expected MM/DD/YYYY HH24:MI:SS (got #{str})"
122
+ end
123
+
124
+ Time.mktime(year, mon, day, hour, min, sec, 0)
125
+ end
126
+
127
+ end
128
+
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,187 @@
1
+ require 'rex/post/meterpreter'
2
+
3
+ module Rex
4
+ module Post
5
+ module Meterpreter
6
+ module Ui
7
+
8
+ ###
9
+ #
10
+ # Packet sniffer extension user interface.
11
+ #
12
+ ###
13
+ class Console::CommandDispatcher::Sniffer
14
+
15
+ Klass = Console::CommandDispatcher::Sniffer
16
+
17
+ include Console::CommandDispatcher
18
+
19
+ #
20
+ # Initializes an instance of the sniffer command interaction.
21
+ #
22
+ def initialize(shell)
23
+ super
24
+ end
25
+
26
+ #
27
+ # List of supported commands.
28
+ #
29
+ def commands
30
+ {
31
+ "sniffer_interfaces" => "Enumerate all sniffable network interfaces",
32
+ "sniffer_start" => "Start packet capture on a specific interface",
33
+ "sniffer_stop" => "Stop packet capture on a specific interface",
34
+ "sniffer_stats" => "View statistics of an active capture",
35
+ "sniffer_dump" => "Retrieve captured packet data to PCAP file",
36
+ }
37
+ end
38
+
39
+
40
+ def cmd_sniffer_interfaces(*args)
41
+
42
+ ifaces = client.sniffer.interfaces()
43
+
44
+ print_line()
45
+
46
+ ifaces.each do |i|
47
+ print_line(sprintf("%d - '%s' ( type:%d mtu:%d usable:%s dhcp:%s wifi:%s )",
48
+ i['idx'], i['description'],
49
+ i['type'], i['mtu'], i['usable'], i['dhcp'], i['wireless'])
50
+ )
51
+ end
52
+
53
+ print_line()
54
+
55
+ return true
56
+ end
57
+
58
+ def cmd_sniffer_start(*args)
59
+ intf = args[0].to_i
60
+ if (intf == 0)
61
+ print_error("Usage: sniffer_start [interface-id] [packet-buffer (1-200000)]")
62
+ return
63
+ end
64
+ maxp = args[1].to_i
65
+ maxp = 50000 if maxp == 0
66
+
67
+ client.sniffer.capture_start(intf, maxp)
68
+ print_status("Capture started on interface #{intf} (#{maxp} packet buffer)")
69
+ return true
70
+ end
71
+
72
+ def cmd_sniffer_stop(*args)
73
+ intf = args[0].to_i
74
+ if (intf == 0)
75
+ print_error("Usage: sniffer_stop [interface-id]")
76
+ return
77
+ end
78
+
79
+ client.sniffer.capture_stop(intf)
80
+ print_status("Capture stopped on interface #{intf}")
81
+ return true
82
+ end
83
+
84
+ def cmd_sniffer_stats(*args)
85
+ intf = args[0].to_i
86
+ if (intf == 0)
87
+ print_error("Usage: sniffer_stats [interface-id]")
88
+ return
89
+ end
90
+
91
+ stats = client.sniffer.capture_stats(intf)
92
+ print_status("Capture statistics for interface #{intf}")
93
+ stats.each_key do |k|
94
+ puts "\t#{k}: #{stats[k]}"
95
+ end
96
+
97
+ return true
98
+ end
99
+
100
+ def cmd_sniffer_dump(*args)
101
+ intf = args[0].to_i
102
+ if (intf == 0 or not args[1])
103
+ print_error("Usage: sniffer_dump [interface-id] [pcap-file]")
104
+ return
105
+ end
106
+
107
+ path_cap = args[1]
108
+ path_raw = args[1] + '.raw'
109
+
110
+ fd = ::File.new(path_raw, 'wb+')
111
+
112
+ print_status("Flushing packet capture buffer for interface #{intf}...")
113
+ res = client.sniffer.capture_dump(intf)
114
+ print_status("Flushed #{res[:packets]} packets (#{res[:bytes]} bytes)")
115
+
116
+ bytes_all = res[:bytes] || 0
117
+ bytes_got = 0
118
+ bytes_pct = 0
119
+
120
+ while (bytes_all > 0)
121
+ res = client.sniffer.capture_dump_read(intf,1024*512)
122
+
123
+ bytes_got += res[:bytes]
124
+
125
+ pct = ((bytes_got.to_f / bytes_all.to_f) * 100).to_i
126
+ if(pct > bytes_pct)
127
+ print_status("Downloaded #{"%.3d" % pct}% (#{bytes_got}/#{bytes_all})...")
128
+ bytes_pct = pct
129
+ end
130
+ break if res[:bytes] == 0
131
+ fd.write(res[:data])
132
+ end
133
+
134
+ fd.close
135
+
136
+ print_status("Download completed, converting to PCAP...")
137
+
138
+ fd = nil
139
+ if(::File.exist?(path_cap))
140
+ fd = ::File.new(path_cap, 'ab+')
141
+ else
142
+ fd = ::File.new(path_cap, 'wb+')
143
+ fd.write([0xa1b2c3d4, 2, 4, 0, 0, 65536, 1].pack('NnnNNNN'))
144
+ end
145
+
146
+ pkts = {}
147
+ od = ::File.new(path_raw, 'rb')
148
+
149
+
150
+ # TODO: reorder packets based on the ID (only an issue if the buffer wraps)
151
+ while(true)
152
+ buf = od.read(20)
153
+ break if not buf
154
+
155
+ idh,idl,thi,tlo,len = buf.unpack('N5')
156
+ break if not len
157
+ if(len > 10000)
158
+ print_error("Corrupted packet data (length:#{len})")
159
+ break
160
+ end
161
+
162
+ pkt_id = (idh << 32) +idl
163
+ pkt_ts = Rex::Proto::SMB::Utils.time_smb_to_unix(thi,tlo)
164
+ pkt = od.read(len)
165
+
166
+ fd.write([pkt_ts,0,len,len].pack('NNNN')+pkt)
167
+ end
168
+ od.close
169
+ fd.close
170
+
171
+ ::File.unlink(path_raw)
172
+ print_status("PCAP file written to #{path_cap}")
173
+ end
174
+
175
+ #
176
+ # Name for this dispatcher
177
+ # sni
178
+ def name
179
+ "Sniffer"
180
+ end
181
+
182
+ end
183
+
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,63 @@
1
+ require 'rex/post/meterpreter'
2
+
3
+ module Rex
4
+ module Post
5
+ module Meterpreter
6
+ module Ui
7
+
8
+ ###
9
+ #
10
+ # Standard API extension.
11
+ #
12
+ ###
13
+ class Console::CommandDispatcher::Stdapi
14
+
15
+ require 'rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs'
16
+ require 'rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net'
17
+ require 'rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys'
18
+ require 'rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui'
19
+
20
+ Klass = Console::CommandDispatcher::Stdapi
21
+
22
+ Dispatchers =
23
+ [
24
+ Klass::Fs,
25
+ Klass::Net,
26
+ Klass::Sys,
27
+ Klass::Ui,
28
+ ]
29
+
30
+ include Console::CommandDispatcher
31
+
32
+ #
33
+ # Initializes an instance of the stdapi command interaction.
34
+ #
35
+ def initialize(shell)
36
+ super
37
+
38
+ Dispatchers.each { |d|
39
+ shell.enstack_dispatcher(d)
40
+ }
41
+ end
42
+
43
+ #
44
+ # List of supported commands.
45
+ #
46
+ def commands
47
+ {
48
+ }
49
+ end
50
+
51
+ #
52
+ # Name for this dispatcher
53
+ #
54
+ def name
55
+ "Standard extension"
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,376 @@
1
+ require 'tempfile'
2
+ require 'rex/post/meterpreter'
3
+
4
+ module Rex
5
+ module Post
6
+ module Meterpreter
7
+ module Ui
8
+
9
+ ###
10
+ #
11
+ # The file system portion of the standard API extension.
12
+ #
13
+ ###
14
+ class Console::CommandDispatcher::Stdapi::Fs
15
+
16
+ Klass = Console::CommandDispatcher::Stdapi::Fs
17
+
18
+ include Console::CommandDispatcher
19
+
20
+ #
21
+ # Options for the download command.
22
+ #
23
+ @@download_opts = Rex::Parser::Arguments.new(
24
+ "-r" => [ false, "Download recursively." ])
25
+ #
26
+ # Options for the upload command.
27
+ #
28
+ @@upload_opts = Rex::Parser::Arguments.new(
29
+ "-r" => [ false, "Upload recursively." ])
30
+
31
+ #
32
+ # List of supported commands.
33
+ #
34
+ def commands
35
+ {
36
+ "cat" => "Read the contents of a file to the screen",
37
+ "cd" => "Change directory",
38
+ "download" => "Download a file or directory",
39
+ "edit" => "Edit a file",
40
+ "getwd" => "Print working directory",
41
+ "ls" => "List files",
42
+ "mkdir" => "Make directory",
43
+ "pwd" => "Print working directory",
44
+ "rmdir" => "Remove directory",
45
+ "upload" => "Upload a file or directory",
46
+ "lcd" => "Change local working directory",
47
+ "getlwd" => "Print local working directory",
48
+ "lpwd" => "Print local working directory",
49
+ "rm" => "Delete the specified file",
50
+ "del" => "Delete the specified file"
51
+ }
52
+ end
53
+
54
+ #
55
+ # Name for this dispatcher.
56
+ #
57
+ def name
58
+ "Stdapi: File system"
59
+ end
60
+
61
+ #
62
+ # Reads the contents of a file and prints them to the screen.
63
+ #
64
+ def cmd_cat(*args)
65
+ if (args.length == 0)
66
+ print_line("Usage: cat file")
67
+ return true
68
+ end
69
+
70
+ fd = client.fs.file.new(args[0], "rb")
71
+
72
+ until fd.eof?
73
+ print(fd.read)
74
+ end
75
+
76
+ fd.close
77
+
78
+ true
79
+ end
80
+
81
+ #
82
+ # Change the working directory.
83
+ #
84
+ def cmd_cd(*args)
85
+ if (args.length == 0)
86
+ print_line("Usage: cd directory")
87
+ return true
88
+ end
89
+
90
+ client.fs.dir.chdir(args[0])
91
+
92
+ return true
93
+ end
94
+
95
+ #
96
+ # Change the local working directory.
97
+ #
98
+ def cmd_lcd(*args)
99
+ if (args.length == 0)
100
+ print_line("Usage: lcd directory")
101
+ return true
102
+ end
103
+
104
+ ::Dir.chdir(args[0])
105
+
106
+ return true
107
+ end
108
+
109
+ #
110
+ # Delete the specified file.
111
+ #
112
+ def cmd_rm(*args)
113
+ if (args.length == 0)
114
+ print_line("Usage: rm file")
115
+ return true
116
+ end
117
+
118
+ client.fs.file.rm(args[0])
119
+
120
+ return true
121
+ end
122
+
123
+ alias :cmd_del :cmd_rm
124
+
125
+ #
126
+ # Downloads a file or directory from the remote machine to the local
127
+ # machine.
128
+ #
129
+ def cmd_download(*args)
130
+ if (args.empty?)
131
+ print(
132
+ "Usage: download [options] src1 src2 src3 ... destination\n\n" +
133
+ "Downloads remote files and directories to the local machine.\n" +
134
+ @@download_opts.usage)
135
+ return true
136
+ end
137
+
138
+ recursive = false
139
+ src_items = []
140
+ last = nil
141
+ dest = nil
142
+
143
+ @@download_opts.parse(args) { |opt, idx, val|
144
+ case opt
145
+ when "-r"
146
+ recursive = true
147
+ when nil
148
+ if (last)
149
+ src_items << last
150
+ end
151
+
152
+ last = val
153
+ end
154
+ }
155
+
156
+ return true if not last
157
+
158
+ # Source and destination will be the same
159
+ src_items << last if src_items.empty?
160
+
161
+ dest = last
162
+
163
+ # Go through each source item and download them
164
+ src_items.each { |src|
165
+ stat = client.fs.file.stat(src)
166
+
167
+ if (stat.directory?)
168
+ client.fs.dir.download(dest, src, recursive) { |step, src, dst|
169
+ print_status("#{step.ljust(11)}: #{src} -> #{dst}")
170
+ }
171
+ elsif (stat.file?)
172
+ client.fs.file.download(dest, src) { |step, src, dst|
173
+ print_status("#{step.ljust(11)}: #{src} -> #{dst}")
174
+ }
175
+ end
176
+ }
177
+
178
+ return true
179
+ end
180
+
181
+ #
182
+ # Downloads a file to a temporary file, spawns and editor, and then uploads
183
+ # the contents to the remote machine after completion.
184
+ #
185
+ def cmd_edit(*args)
186
+ if (args.length == 0)
187
+ print_line("Usage: edit file")
188
+ return true
189
+ end
190
+
191
+ # Get a temporary file path
192
+ temp_path = Tempfile.new('meterp').path
193
+
194
+ begin
195
+ # Download the remote file to the temporary file
196
+ client.fs.file.download_file(temp_path, args[0])
197
+ rescue RequestError => re
198
+ # If the file doesn't exist, then it's okay. Otherwise, throw the
199
+ # error.
200
+ if re.result != 2
201
+ raise $!
202
+ end
203
+ end
204
+
205
+ # Spawn the editor (default to vi)
206
+ editor = Rex::Compat.getenv('EDITOR') || 'vi'
207
+
208
+ # If it succeeds, upload it to the remote side.
209
+ if (system("#{editor} #{temp_path}") == true)
210
+ client.fs.file.upload_file(args[0], temp_path)
211
+ end
212
+
213
+ # Get rid of that pesky temporary file
214
+ temp_path.close(true)
215
+ end
216
+
217
+ #
218
+ # Display the local working directory.
219
+ #
220
+ def cmd_lpwd(*args)
221
+ print_line(::Dir.pwd)
222
+ return true
223
+ end
224
+
225
+ alias cmd_getlwd cmd_lpwd
226
+
227
+ #
228
+ # Lists files
229
+ #
230
+ # TODO: make this more useful
231
+ #
232
+ def cmd_ls(*args)
233
+ path = args[0] || client.fs.dir.getwd
234
+ tbl = Rex::Ui::Text::Table.new(
235
+ 'Header' => "Listing: #{path}",
236
+ 'Columns' =>
237
+ [
238
+ 'Mode',
239
+ 'Size',
240
+ 'Type',
241
+ 'Last modified',
242
+ 'Name',
243
+ ])
244
+
245
+ items = 0
246
+
247
+ # Enumerate each item...
248
+ client.fs.dir.entries_with_info(path).sort { |a,b| a['FileName'] <=> b['FileName'] }.each { |p|
249
+
250
+ tbl <<
251
+ [
252
+ p['StatBuf'] ? p['StatBuf'].prettymode : '',
253
+ p['StatBuf'] ? p['StatBuf'].size : '',
254
+ p['StatBuf'] ? p['StatBuf'].ftype[0,3] : '',
255
+ p['StatBuf'] ? p['StatBuf'].mtime : '',
256
+ p['FileName'] || 'unknown'
257
+ ]
258
+
259
+ items += 1
260
+ }
261
+
262
+ if (items > 0)
263
+ print("\n" + tbl.to_s + "\n")
264
+ else
265
+ print_line("No entries exist in #{path}")
266
+ end
267
+
268
+ return true
269
+ end
270
+
271
+ #
272
+ # Make one or more directory.
273
+ #
274
+ def cmd_mkdir(*args)
275
+ if (args.length == 0)
276
+ print_line("Usage: mkdir dir1 dir2 dir3 ...")
277
+ return true
278
+ end
279
+
280
+ args.each { |dir|
281
+ print_line("Creating directory: #{dir}")
282
+
283
+ client.fs.dir.mkdir(dir)
284
+ }
285
+
286
+ return true
287
+ end
288
+
289
+ #
290
+ # Display the working directory.
291
+ #
292
+ def cmd_pwd(*args)
293
+ print_line(client.fs.dir.getwd)
294
+ end
295
+
296
+ alias cmd_getwd cmd_pwd
297
+
298
+ #
299
+ # Removes one or more directory if it's empty.
300
+ #
301
+ def cmd_rmdir(*args)
302
+ if (args.length == 0)
303
+ print_line("Usage: rmdir dir1 dir2 dir3 ...")
304
+ return true
305
+ end
306
+
307
+ args.each { |dir|
308
+ print_line("Removing directory: #{dir}")
309
+ client.fs.dir.rmdir(dir)
310
+ }
311
+
312
+ return true
313
+ end
314
+
315
+ #
316
+ # Uploads a file or directory to the remote machine from the local
317
+ # machine.
318
+ #
319
+ def cmd_upload(*args)
320
+ if (args.empty?)
321
+ print(
322
+ "Usage: upload [options] src1 src2 src3 ... destination\n\n" +
323
+ "Uploads local files and directories to the remote machine.\n" +
324
+ @@upload_opts.usage)
325
+ return true
326
+ end
327
+
328
+ recursive = false
329
+ src_items = []
330
+ last = nil
331
+ dest = nil
332
+
333
+ @@upload_opts.parse(args) { |opt, idx, val|
334
+ case opt
335
+ when "-r"
336
+ recursive = true
337
+ when nil
338
+ if (last)
339
+ src_items << last
340
+ end
341
+
342
+ last = val
343
+ end
344
+ }
345
+
346
+ return true if not last
347
+
348
+ # Source and destination will be the same
349
+ src_items << last if src_items.empty?
350
+
351
+ dest = last
352
+
353
+ # Go through each source item and upload them
354
+ src_items.each { |src|
355
+ stat = ::File.stat(src)
356
+
357
+ if (stat.directory?)
358
+ client.fs.dir.upload(dest, src, recursive) { |step, src, dst|
359
+ print_status("#{step.ljust(11)}: #{src} -> #{dst}")
360
+ }
361
+ elsif (stat.file?)
362
+ client.fs.file.upload(dest, src) { |step, src, dst|
363
+ print_status("#{step.ljust(11)}: #{src} -> #{dst}")
364
+ }
365
+ end
366
+ }
367
+
368
+ return true
369
+ end
370
+
371
+ end
372
+
373
+ end
374
+ end
375
+ end
376
+ end