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,168 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.join(File.dirname(__FILE__), '..'))
4
+
5
+ require 'test/unit'
6
+ require 'rex/text'
7
+ require 'rex/exceptions'
8
+ class Rex::Text::UnitTest < Test::Unit::TestCase
9
+
10
+ def test_uri_encode
11
+ srand(0)
12
+ assert_equal('A1%21', Rex::Text.uri_encode('A1!'), 'uri encode')
13
+ assert_equal('A1!', Rex::Text.uri_encode('A1!', 'none'), 'uri encode: none')
14
+ assert_equal('A1%21', Rex::Text.uri_encode('A1!', 'hex-normal'), 'uri encode: hex-normal')
15
+ assert_equal('%41%31%21', Rex::Text.uri_encode('A1!', 'hex-all'), 'uri encode: hex-all')
16
+ assert_equal('A1%u01c3', Rex::Text.uri_encode('A1!', 'u-normal'), 'uri encode: u-normal')
17
+ assert_equal('%uff21%u2081%uff01', Rex::Text.uri_encode('A1!', 'u-all'), 'uri encode: u-all')
18
+ srand(0)
19
+ assert_equal("%uff2d%uff49%uff43%uff52%uff4f%uff53%uff4f%uff46%uff54%u2004%uff45%uff4e%uff43%uff4f%uff44%uff49%uff4e%uff47%u3000%uff44%uff52%uff49%uff56%uff45%uff53%u2005%uff4d%uff45%u2000%uff43%uff52%uff41%uff5a%uff59%uff01", Rex::Text.uri_encode('Microsoft encoding drives me crazy!', 'u-half'))
20
+
21
+ assert_raises(TypeError) {
22
+ Rex::Text.uri_encode('a', 'umpa lumpa')
23
+ }
24
+ end
25
+
26
+ def test_html_encode
27
+ assert_equal('&#x41', Rex::Text.html_encode('A'), 'html_encode default')
28
+ assert_equal('&#x41', Rex::Text.html_encode('A','hex'), 'html_encode hex')
29
+ assert_equal('&#65', Rex::Text.html_encode('A','int'), 'html_encode int')
30
+ assert_equal('&#0000065', Rex::Text.html_encode('A','int-wide'), 'html_encode int-wide')
31
+
32
+ assert_raises(TypeError) {
33
+ Rex::Text.html_encode('a', 'umpa lumpa')
34
+ }
35
+ end
36
+
37
+ def test_rand_text
38
+ srand(0)
39
+ assert_equal("\254/u\300C\373\303g\t\323", Rex::Text.rand_text(10), 'rand text 1')
40
+ assert_equal("\025\362$WF\330X\214:\301", Rex::Text.rand_text(10), 'rand text 2')
41
+ assert_equal("\346'W\256XQ\245\031MH", Rex::Text.rand_text(10), 'rand text 3')
42
+ assert_equal('bababbabba', Rex::Text.rand_text(10, nil, 'ab'), 'rand text with specified "good"')
43
+ assert_equal('MA', Rex::Text.rand_state(), 'rand state')
44
+ assert_equal('xzdttongb.5gfk0xjly3.aak.fmo0rp.com', Rex::Text.rand_hostname(), 'rand hostname')
45
+ assert_equal('9aaf811799', Rex::Text.rand_text_hex(10), 'rand hex')
46
+ end
47
+
48
+
49
+ def test_unicode
50
+ assert_equal("a\x00b\x00c\x00", Rex::Text.to_unicode('abc'), 'unicode, default = little endian')
51
+ assert_equal("a\x00b\x00c\x00", Rex::Text.to_unicode('abc', 'utf-16le'), 'utf-16le')
52
+ assert_equal("\x00a\x00b\x00c", Rex::Text.to_unicode('abc', 'utf-16be'), 'utf-16be')
53
+ assert_equal("a\x00\x00\x00b\x00\x00\x00c\x00\x00\x00", Rex::Text.to_unicode('abc', 'utf-32le'), 'utf-32le')
54
+ assert_equal("\x00\x00\x00a\x00\x00\x00b\x00\x00\x00c", Rex::Text.to_unicode('abc', 'utf-32be'), 'utf-32be')
55
+ assert_equal("abc+-abc-+AAA-", Rex::Text.to_unicode("abc+abc-\x00", 'utf-7'), 'utf-7')
56
+ assert_equal("+AGE-+AGI-+AGM-+ACs-+AGE-+AGI-+AGM-+AC0-+AAA-", Rex::Text.to_unicode("abc+abc-\x00", 'utf-7', 'all'), 'utf-7-all')
57
+
58
+ assert_equal("a\303\272", Rex::Text.to_unicode("a\xFA", 'utf-8'))
59
+ assert_equal("\xC1\xA1", Rex::Text.to_unicode('a', 'utf-8', 'overlong', 2), 'utf-8 overlong')
60
+ assert_equal("\xE0\x81\xA1", Rex::Text.to_unicode('a', 'utf-8', 'overlong', 3), 'utf-8 overlong')
61
+ assert_equal("\xF0\x80\x81\xA1", Rex::Text.to_unicode('a', 'utf-8', 'overlong', 4), 'utf-8 overlong')
62
+ assert_equal("\xF8\x80\x80\x81\xA1", Rex::Text.to_unicode('a', 'utf-8', 'overlong', 5), 'utf-8 overlong')
63
+ assert_equal("\xFC\x80\x80\x80\x81\xA1", Rex::Text.to_unicode('a', 'utf-8', 'overlong', 6), 'utf-8 overlong')
64
+ assert_equal("\xFE\x80\x80\x80\x80\x81\xA1", Rex::Text.to_unicode('a', 'utf-8', 'overlong', 7), 'utf-8 overlong')
65
+ 100.times {
66
+ assert(["\xC1\x21","\xC1\x61","\xC1\xE1"].include?(Rex::Text.to_unicode('a', 'utf-8', 'invalid')), 'utf-8 invalid')
67
+ assert(["\xE0\x01\x21","\xE0\x01\x61","\xE0\x01\xA1","\xE0\x01\xE1","\xE0\x41\x21","\xE0\x41\x61","\xE0\x41\xA1","\xE0\x41\xE1","\xE0\x81\x21","\xE0\x81\x61","\xE0\x81\xA1","\xE0\x81\xE1","\xE0\xC1\x21","\xE0\xC1\x61","\xE0\xC1\xA1","\xE0\xC1\xE1"].include?(Rex::Text.to_unicode('a', 'utf-8', 'invalid', 3)), 'utf-8 invalid 3 byte')
68
+ }
69
+
70
+ a = ["\xC1\x21","\xC1\x61","\xC1\xE1"]
71
+ 10.times {
72
+ encoded = Rex::Text.to_unicode('a', 'utf-8', 'invalid')
73
+ if a.include?(encoded)
74
+ a.delete(encoded)
75
+ end
76
+ }
77
+ assert_equal([], a, 'all possible values')
78
+
79
+ assert_raises(TypeError) {
80
+ Rex::Text.to_unicode('a', 'utf-8', '', 8)
81
+ }
82
+ assert_raises(TypeError) {
83
+ Rex::Text.to_unicode('a', 'utf-8', 'foo', 6)
84
+ }
85
+
86
+ assert_raises(TypeError) {
87
+ Rex::Text.to_unicode('a', 'uhwtfms', -1)
88
+ }
89
+
90
+ 100.times {
91
+ assert(["\x01\x00","\x01\x02","\x01\x04","\x01\xcd","\x01\xde","\xff\x21"].include?(Rex::Text.to_unicode('A', 'uhwtfms')), 'uhwtfms')
92
+ assert(["\x00\xc0","\x00\xc1","\x00\xc2","\x00\xc3","\x00\xc4","\x00\xc5"].include?(Rex::Text.to_unicode('A', 'uhwtfms', 949)), 'uhwtfms codepage 949')
93
+ }
94
+
95
+ a = ["\x01\x00","\x01\x02","\x01\x04","\x01\xcd","\x01\xde","\xff\x21"]
96
+ 20.times {
97
+ encoded = Rex::Text.to_unicode('A', 'uhwtfms')
98
+ if a.include?(encoded)
99
+ a.delete(encoded)
100
+ end
101
+ }
102
+ assert_equal([], a, 'all possible values uhwtfms')
103
+
104
+ assert_raises(TypeError) {
105
+ Rex::Text.to_unicode('a', 'uhwtfms-half', 1)
106
+ }
107
+
108
+ assert_equal("\xFF\x01", Rex::Text.to_unicode('!', 'uhwtfms-half'))
109
+ srand(0)
110
+ assert_equal("\xff\x2d\xff\x49\xff\x43\xff\x52\xff\x4f\xff\x53\xff\x4f\xff\x46\xff\x54\x20\x04\xff\x45\xff\x4e\xff\x43\xff\x4f\xff\x44\xff\x49\xff\x4e\xff\x47\x30\x00\xff\x44\xff\x52\xff\x49\xff\x56\xff\x45\xff\x53\x20\x05\xff\x4d\xff\x45\x20\x00\xff\x43\xff\x52\xff\x41\xff\x5a\xff\x59\xff\x01", Rex::Text.to_unicode('Microsoft encoding drives me crazy!', 'uhwtfms-half'))
111
+ end
112
+
113
+ def test_zlib
114
+ assert_equal("x\332\313\310T\310\315\317\005\000\a\225\002;", Rex::Text.zlib_deflate('hi mom'), 'compress')
115
+ assert_equal('hi mom', Rex::Text.zlib_inflate("x\234\313\310T\310\315\317\005\000\a\225\002;"), 'decompress')
116
+ end
117
+
118
+ def test_gzip
119
+ string = Rex::Text.gzip('hi mom')
120
+ assert_equal("\x1f\x8b\x08\x00", string.slice!(0,4), 'gzip headers')
121
+
122
+ # skip the next 6 bytes as it is host & time specific (zlib's example gun does, so why not us too?)
123
+ string.slice!(0,6)
124
+
125
+ assert_equal("\xcb\xc8\x54\xc8\xcd\xcf\x05\x00\x68\xa4\x1c\xf0\x06\x00\x00\x00", string, 'gzip data')
126
+
127
+ assert_equal('hi mom', Rex::Text.ungzip("\037\213\010\000|\261\275C\002\003\313\310T\310\315\317\005\000h\244\034\360\006\000\000\000"), 'ungzip')
128
+ end
129
+
130
+ def test_badchar_index
131
+ assert_equal(nil, Rex::Text.badchar_index('abcdef', 'gzk'))
132
+ assert_equal(2, Rex::Text.badchar_index('123avd', 'ly3'))
133
+ end
134
+
135
+ def test_hexify
136
+ str = "\x01\x02\xff\x00"
137
+
138
+ assert_equal("\\x01\\x02\\xff\\x00", Rex::Text.to_hex(str), 'to_hex')
139
+ assert_equal("ABC01ABC02ABCffABC00", Rex::Text.to_hex(str, 'ABC'), 'to_hex with prefix')
140
+ assert_equal('%u0102%uff00', Rex::Text.to_hex(str, '%u', 2), 'to_hex with chunk size of 2')
141
+
142
+ # to_hex, without providing enouigh data to chunk on a given size
143
+ assert_raises(RuntimeError){ Rex::Text.to_hex('a', '', 2) }
144
+
145
+ assert_equal("buf = \n\"\\x01\\x02\\xff\\x00\"\n", Rex::Text.to_ruby(str), 'to_ruby')
146
+ assert_equal("my $buf = \n\"\\x01\\x02\\xff\\x00\";\n", Rex::Text.to_perl(str), 'to_perl')
147
+ assert_equal("unsigned char buf[] = \n\"\\x01\\x02\\xff\\x00\";\n", Rex::Text.to_c(str), 'to_c')
148
+
149
+ # 0 -> 20
150
+ str = "\000\001\002\003\004\005\006\a\010\t\n\v\f\r\016\017\020\021\022\023"
151
+
152
+ assert_equal("buf = \n\"\\x00\\x01\\x02\\x03\" +\n\"\\x04\\x05\\x06\\x07\" +\n\"\\x08\\x09\\x0a\\x0b\" +\n\"\\x0c\\x0d\\x0e\\x0f\" +\n\"\\x10\\x11\\x12\\x13\"\n", Rex::Text.to_ruby(str, 20), 'to_ruby with wrap')
153
+ assert_equal("my $buf = \n\"\\x00\\x01\\x02\\x03\" .\n\"\\x04\\x05\\x06\\x07\" .\n\"\\x08\\x09\\x0a\\x0b\" .\n\"\\x0c\\x0d\\x0e\\x0f\" .\n\"\\x10\\x11\\x12\\x13\";\n", Rex::Text.to_perl(str, 20), 'to_perl with wrap')
154
+ assert_equal("unsigned char buf[] = \n\"\\x00\\x01\\x02\\x03\\x04\"\n\"\\x05\\x06\\x07\\x08\\x09\"\n\"\\x0a\\x0b\\x0c\\x0d\\x0e\"\n\"\\x0f\\x10\\x11\\x12\\x13\";\n", Rex::Text.to_c(str, 20, "buf"), 'to_c with wrap')
155
+ assert_equal("\\x0a", Rex::Text.to_hex("\n"), 'to_hex newline')
156
+ end
157
+
158
+ def test_wordwrap
159
+ txt = "this is a test of the word wrap features"
160
+
161
+ assert_equal("this is a \ntest of \nthe word \nwrap \nfeatures\n", Rex::Text.wordwrap(txt, 0, 10))
162
+ end
163
+
164
+ def test_transforms
165
+ assert_equal("acbd18db4cc2f85cedef654fccc4a4d8", Rex::Text.md5('foo'))
166
+ end
167
+
168
+ end
@@ -0,0 +1,65 @@
1
+ module Rex
2
+
3
+ ###
4
+ #
5
+ # Extended time related functions.
6
+ #
7
+ ###
8
+ module ExtTime
9
+
10
+ #
11
+ # Convert seconds to a string that is broken down into years, days, hours,
12
+ # minutes, and second.
13
+ #
14
+ def self.sec_to_s(seconds)
15
+ parts = [ 31536000, 86400, 3600, 60, 1 ].map { |d|
16
+ if ((c = seconds / d) > 0)
17
+ seconds -= c.truncate * d
18
+ c.truncate
19
+ else
20
+ 0
21
+ end
22
+ }.reverse
23
+
24
+ str = ''
25
+
26
+ [ "sec", "min", "hour", "day", "year" ].each_with_index { |name, idx|
27
+ next if (!parts[idx] or parts[idx] == 0)
28
+
29
+ str = "#{parts[idx]} #{name + ((parts[idx] != 1) ? 's' :'')} " + str
30
+ }
31
+
32
+ str.empty? ? "0 secs" : str.strip
33
+ end
34
+
35
+ #
36
+ # Converts a string in the form n years g days x hours y mins z secs.
37
+ #
38
+ def self.str_to_sec(str)
39
+ fields = str.split(/ /)
40
+ secs = 0
41
+
42
+ fields.each_with_index { |f, idx|
43
+ val = 0
44
+ case f
45
+ when /^year/
46
+ val = 31536000
47
+ when /^day/
48
+ val = 86400
49
+ when /^hour/
50
+ val = 3600
51
+ when /^min/
52
+ val = 60
53
+ when /^sec/
54
+ val = 1
55
+ end
56
+
57
+ secs += val * fields[idx-1].to_i
58
+ }
59
+
60
+ secs
61
+ end
62
+
63
+ end
64
+
65
+ end
@@ -0,0 +1,115 @@
1
+ module Rex
2
+
3
+ ###
4
+ #
5
+ # Transformer - more than meets the eye!
6
+ #
7
+ # This class, aside from having a kickass name, is responsible for translating
8
+ # object instances of one or more types into a single list instance of one or
9
+ # more types. This is useful for translating object instances that be can
10
+ # either strings or an array of strings into an array of strings, for
11
+ # instance. It lets you make things take a uniform structure in an abstract
12
+ # manner.
13
+ #
14
+ ###
15
+ class Transformer
16
+
17
+ #
18
+ # Translates the object instance supplied in src_instance to an instance of
19
+ # dst_class. The dst_class parameter's instance must support the <<
20
+ # operator. An example call to this method looks something like:
21
+ #
22
+ # Transformer.transform(string, Array, [ String ], target)
23
+ #
24
+ def Transformer.transform(src_instance, dst_class, supported_classes,
25
+ target = nil)
26
+ dst_instance = dst_class.new
27
+
28
+ if (src_instance.kind_of?(Array))
29
+ src_instance.each { |src_inst|
30
+ Transformer.transform_single(src_inst, dst_instance,
31
+ supported_classes, target)
32
+ }
33
+ elsif (!src_instance.kind_of?(NilClass))
34
+ Transformer.transform_single(src_instance, dst_instance,
35
+ supported_classes, target)
36
+ end
37
+
38
+ return dst_instance
39
+ end
40
+
41
+ protected
42
+
43
+ #
44
+ # Transform a single source instance.
45
+ #
46
+ def Transformer.transform_single(src_instance, dst_instance,
47
+ supported_classes, target)
48
+ # If the src instance's class is supported, just add it to the dst
49
+ # instance
50
+ if (supported_classes.include?(src_instance.class))
51
+ dst_instance << src_instance
52
+ # If the src instance's class is an array, then we should check to see
53
+ # if any of the supporting classes support from_a.
54
+ elsif (src_instance.kind_of?(Array))
55
+ new_src_instance = nil
56
+
57
+ # Walk each supported class calling from_a if exported
58
+ supported_classes.each { |sup_class|
59
+ next if (sup_class.respond_to?('from_a') == false)
60
+
61
+ new_src_instance = sup_class.from_a(src_instance)
62
+
63
+ if (new_src_instance != nil)
64
+ dst_instance << new_src_instance
65
+ break
66
+ end
67
+ }
68
+
69
+ # If we don't have a valid new src instance, then we suck
70
+ if (new_src_instance == nil)
71
+ bomb_translation(src_instance, target)
72
+ end
73
+
74
+ # If the source instance is a string, query each of the supported
75
+ # classes to see if they can serialize it to their particular data
76
+ # type.
77
+ elsif (src_instance.kind_of?(String))
78
+ new_src_instance = nil
79
+
80
+ # Walk each supported class calling from_s if exported
81
+ supported_classes.each { |sup_class|
82
+ next if (sup_class.respond_to?('from_s') == false)
83
+
84
+ new_src_instance = sup_class.from_s(src_instance)
85
+
86
+ if (new_src_instance != nil)
87
+ dst_instance << new_src_instance
88
+ break
89
+ end
90
+ }
91
+
92
+ # If we don't have a valid new src instance, then we suck
93
+ if (new_src_instance == nil)
94
+ bomb_translation(src_instance, target)
95
+ end
96
+ # Otherwise, bomb translation
97
+ else
98
+ bomb_translation(src_instance, target)
99
+ end
100
+ end
101
+
102
+ def Transformer.bomb_translation(src_instance, target) # :nodoc:
103
+ error = "Invalid source class (#{src_instance.class})"
104
+
105
+ if (target != nil)
106
+ error += " for #{target}"
107
+ end
108
+
109
+ raise ArgumentError, error, caller
110
+ end
111
+
112
+ end
113
+
114
+ end
115
+
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.join(File.dirname(__FILE__), '..'))
4
+
5
+ require 'test/unit'
6
+ require 'rex/exceptions'
7
+ require 'rex/transformer'
8
+
9
+ class Rex::Transformer::UnitTest < Test::Unit::TestCase
10
+ class Pizza
11
+ def Pizza.from_s(str)
12
+ end
13
+ end
14
+
15
+ class ArrayTester
16
+ def self.from_a(a)
17
+ a[0] + a[1]
18
+ end
19
+ end
20
+
21
+ def test_transformer
22
+ a = Rex::Transformer.transform([ 'yo', 'ho' ], Array, [ String ], 'Jones')
23
+
24
+ assert_equal(2, a.length, "invalid array length")
25
+ assert_equal('yo', a[0], "invalid first element")
26
+ assert_equal('ho', a[1], "invalid second element")
27
+
28
+ assert_raise(Rex::ArgumentError, "invalid transform") {
29
+ Rex::Transformer.transform('dog', Array, [ Pizza ], 'bob')
30
+ }
31
+ end
32
+
33
+ def test_from_a
34
+ a = Rex::Transformer.transform([ [ 'one', 'two' ] ], Array, [ ArrayTester ], 'Jimmy')
35
+
36
+ assert_equal('onetwo', a[0], "invalid from_a conversion")
37
+ end
38
+ end
@@ -0,0 +1,21 @@
1
+ #
2
+ # This file includes everything needed to interact with the user interface
3
+ # wrappers of the rex library.
4
+ #
5
+
6
+ # General classes
7
+ require 'rex/ui/output'
8
+ require 'rex/ui/progress_tracker'
9
+
10
+ # Text-based user interfaces
11
+ require 'rex/ui/text/input'
12
+ require 'rex/ui/text/shell'
13
+ require 'rex/ui/text/dispatcher_shell'
14
+ require 'rex/ui/text/irb_shell'
15
+
16
+ require 'rex/ui/text/color'
17
+ require 'rex/ui/text/table'
18
+
19
+ # Ui subscriber
20
+ require 'rex/ui/subscriber'
21
+ require 'rex/ui/interactive'
@@ -0,0 +1,252 @@
1
+ module Rex
2
+ module Ui
3
+
4
+ ###
5
+ #
6
+ # This class implements the stubs that are needed to provide an interactive
7
+ # user interface that is backed against something arbitrary.
8
+ #
9
+ ###
10
+ module Interactive
11
+
12
+ #
13
+ # Interactive sessions by default may interact with the local user input
14
+ # and output.
15
+ #
16
+ include Rex::Ui::Subscriber
17
+
18
+ #
19
+ # Starts interacting with the session at the most raw level, simply
20
+ # forwarding input from user_input to rstream and forwarding input from
21
+ # rstream to user_output.
22
+ #
23
+ def interact(user_input, user_output)
24
+
25
+ # Detach from any existing console
26
+ if(self.interacting)
27
+ detach()
28
+ end
29
+
30
+ init_ui(user_input, user_output)
31
+
32
+ self.interacting = true
33
+ self.completed = false
34
+
35
+ eof = false
36
+
37
+ # Start the readline stdin monitor
38
+ # XXX disabled
39
+ # user_input.readline_start() if user_input.supports_readline
40
+
41
+ # Handle suspend notifications
42
+ handle_suspend
43
+
44
+ # As long as we're interacting...
45
+ while (self.interacting == true)
46
+
47
+ begin
48
+ _interact
49
+
50
+ rescue Interrupt
51
+ # If we get an interrupt exception, ask the user if they want to
52
+ # abort the interaction. If they do, then we return out of
53
+ # the interact function and call it a day.
54
+ eof = true if (_interrupt)
55
+
56
+ rescue EOFError, Errno::ECONNRESET, IOError
57
+ # If we reach EOF or the connection is reset...
58
+ eof = true
59
+
60
+ end
61
+
62
+ break if eof
63
+ end
64
+
65
+ begin
66
+
67
+ # Restore the suspend handler
68
+ restore_suspend
69
+
70
+ # If we've hit eof, call the interact complete handler
71
+ _interact_complete if (eof == true)
72
+
73
+ # Shutdown the readline thread
74
+ # XXX disabled
75
+ # user_input.readline_stop() if user_input.supports_readline
76
+
77
+ # Detach from the input/output handles
78
+ reset_ui()
79
+
80
+ ensure
81
+ # Mark this as completed
82
+ self.completed = true
83
+ end
84
+
85
+ # Return whether or not EOF was reached
86
+ return eof
87
+ end
88
+
89
+ #
90
+ # Stops the current interaction
91
+ #
92
+ def detach
93
+ if (self.interacting)
94
+ self.interacting = false
95
+ while(not self.completed)
96
+ select(nil, nil, nil, 0.25)
97
+ end
98
+ end
99
+ end
100
+
101
+ #
102
+ # Whether or not the session is currently being interacted with
103
+ #
104
+ attr_accessor :interacting
105
+
106
+ #
107
+ # Whether or not the session has completed interaction
108
+ #
109
+ attr_accessor :completed
110
+
111
+ protected
112
+
113
+ #
114
+ # The original suspend proc.
115
+ #
116
+ attr_accessor :orig_suspend
117
+
118
+ #
119
+ # Stub method that is meant to handler interaction
120
+ #
121
+ def _interact
122
+ end
123
+
124
+ #
125
+ # Called when an interrupt is sent.
126
+ #
127
+ def _interrupt
128
+ true
129
+ end
130
+
131
+ #
132
+ # Called when a suspend is sent.
133
+ #
134
+ def _suspend
135
+ false
136
+ end
137
+
138
+ #
139
+ # Called when interaction has completed and one of the sides has closed.
140
+ #
141
+ def _interact_complete
142
+ true
143
+ end
144
+
145
+ #
146
+ # Read from remote and write to local.
147
+ #
148
+ def _stream_read_remote_write_local(stream)
149
+ data = stream.get
150
+
151
+ user_output.print(data)
152
+ end
153
+
154
+ #
155
+ # Read from local and write to remote.
156
+ #
157
+ def _stream_read_local_write_remote(stream)
158
+ data = user_input.gets
159
+
160
+ stream.put(data)
161
+ end
162
+
163
+ #
164
+ # The local file descriptor handle.
165
+ #
166
+ def _local_fd
167
+ user_input.fd
168
+ end
169
+
170
+ #
171
+ # The remote file descriptor handle.
172
+ #
173
+ def _remote_fd(stream)
174
+ stream.fd
175
+ end
176
+
177
+ #
178
+ # Interacts with two streaming connections, reading data from one and
179
+ # writing it to the other. Both are expected to implement Rex::IO::Stream.
180
+ #
181
+ def interact_stream(stream)
182
+ while self.interacting
183
+
184
+ # Select input and rstream
185
+ sd = Rex::ThreadSafe.select([ _local_fd, _remote_fd(stream) ], nil, nil, 0.25)
186
+
187
+ # Cycle through the items that have data
188
+ # From the stream? Write to user_output.
189
+ sd[0].each { |s|
190
+ if (s == _remote_fd(stream))
191
+ _stream_read_remote_write_local(stream)
192
+ # From user_input? Write to stream.
193
+ elsif (s == _local_fd)
194
+ _stream_read_local_write_remote(stream)
195
+ end
196
+ } if (sd)
197
+
198
+ Thread.pass
199
+ end
200
+ end
201
+
202
+ #
203
+ # Installs a signal handler to monitor suspend signal notifications.
204
+ #
205
+ def handle_suspend
206
+ if (orig_suspend == nil)
207
+ begin
208
+ self.orig_suspend = Signal.trap("TSTP") {
209
+ _suspend
210
+ }
211
+ rescue
212
+ end
213
+ end
214
+ end
215
+
216
+ #
217
+ # Restores the previously installed signal handler for suspend
218
+ # notifications.
219
+ #
220
+ def restore_suspend
221
+ if (orig_suspend)
222
+ begin
223
+ Signal.trap("TSTP", orig_suspend)
224
+ rescue
225
+ end
226
+
227
+ self.orig_suspend = nil
228
+ end
229
+ end
230
+
231
+ #
232
+ # Prompt the user for input if possible.
233
+ # XXX: This is not thread-safe on Windows
234
+ #
235
+ def prompt(query)
236
+ if (user_output and user_input)
237
+ user_output.print("\n" + query)
238
+ user_input.sysread(2)
239
+ end
240
+ end
241
+
242
+ #
243
+ # Check the return value of a yes/no prompt
244
+ #
245
+ def prompt_yesno(query)
246
+ (prompt(query + " [y/N] ") =~ /^y/i) ? true : false
247
+ end
248
+
249
+ end
250
+
251
+ end
252
+ end