librex 0.0.68 → 0.0.70

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 (528) hide show
  1. checksums.yaml +15 -0
  2. data/README.markdown +1 -1
  3. data/Rakefile +18 -16
  4. data/lib/rex.rb +14 -10
  5. data/lib/rex/LICENSE +2 -2
  6. data/lib/rex/arch.rb +76 -76
  7. data/lib/rex/arch/sparc.rb +57 -58
  8. data/lib/rex/arch/x86.rb +506 -496
  9. data/lib/rex/assembly/nasm.rb +83 -84
  10. data/lib/rex/compat.rb +228 -173
  11. data/lib/rex/constants.rb +47 -37
  12. data/lib/rex/elfparsey.rb +0 -3
  13. data/lib/rex/elfparsey/elf.rb +107 -110
  14. data/lib/rex/elfparsey/elfbase.rb +244 -247
  15. data/lib/rex/elfparsey/exceptions.rb +0 -3
  16. data/lib/rex/elfscan.rb +0 -3
  17. data/lib/rex/elfscan/scanner.rb +184 -166
  18. data/lib/rex/elfscan/search.rb +35 -38
  19. data/lib/rex/encoder/alpha2.rb +1 -2
  20. data/lib/rex/encoder/alpha2/alpha_mixed.rb +52 -53
  21. data/lib/rex/encoder/alpha2/alpha_upper.rb +62 -63
  22. data/lib/rex/encoder/alpha2/generic.rb +77 -78
  23. data/lib/rex/encoder/alpha2/unicode_mixed.rb +101 -97
  24. data/lib/rex/encoder/alpha2/unicode_upper.rb +106 -107
  25. data/lib/rex/encoder/bloxor/bloxor.rb +326 -0
  26. data/lib/rex/encoder/ndr.rb +68 -68
  27. data/lib/rex/encoder/nonalpha.rb +50 -51
  28. data/lib/rex/encoder/nonupper.rb +50 -51
  29. data/lib/rex/encoder/xdr.rb +78 -78
  30. data/lib/rex/encoder/xor.rb +52 -53
  31. data/lib/rex/encoder/xor/dword.rb +1 -2
  32. data/lib/rex/encoder/xor/dword_additive.rb +1 -2
  33. data/lib/rex/encoders/xor_dword.rb +17 -18
  34. data/lib/rex/encoders/xor_dword_additive.rb +35 -36
  35. data/lib/rex/encoding/xor.rb +0 -1
  36. data/lib/rex/encoding/xor/byte.rb +3 -4
  37. data/lib/rex/encoding/xor/dword.rb +3 -4
  38. data/lib/rex/encoding/xor/dword_additive.rb +72 -73
  39. data/lib/rex/encoding/xor/exceptions.rb +2 -3
  40. data/lib/rex/encoding/xor/generic.rb +129 -130
  41. data/lib/rex/encoding/xor/qword.rb +3 -4
  42. data/lib/rex/encoding/xor/word.rb +3 -4
  43. data/lib/rex/exceptions.rb +100 -101
  44. data/lib/rex/exploitation/cmdstager.rb +3 -3
  45. data/lib/rex/exploitation/cmdstager/base.rb +170 -156
  46. data/lib/rex/exploitation/cmdstager/bourne.rb +105 -0
  47. data/lib/rex/exploitation/cmdstager/debug_asm.rb +110 -113
  48. data/lib/rex/exploitation/cmdstager/debug_write.rb +106 -109
  49. data/lib/rex/exploitation/cmdstager/echo.rb +164 -0
  50. data/lib/rex/exploitation/cmdstager/printf.rb +122 -0
  51. data/lib/rex/exploitation/cmdstager/tftp.rb +34 -27
  52. data/lib/rex/exploitation/cmdstager/vbs.rb +95 -98
  53. data/lib/rex/exploitation/egghunter.rb +359 -346
  54. data/lib/rex/exploitation/encryptjs.rb +60 -60
  55. data/lib/rex/exploitation/heaplib.rb +76 -76
  56. data/lib/rex/exploitation/js.rb +6 -0
  57. data/lib/rex/exploitation/js/detect.rb +69 -0
  58. data/lib/rex/exploitation/js/memory.rb +81 -0
  59. data/lib/rex/exploitation/js/network.rb +84 -0
  60. data/lib/rex/exploitation/js/utils.rb +33 -0
  61. data/lib/rex/exploitation/jsobfu.rb +448 -424
  62. data/lib/rex/exploitation/obfuscatejs.rb +301 -301
  63. data/lib/rex/exploitation/omelet.rb +257 -257
  64. data/lib/rex/exploitation/opcodedb.rb +699 -699
  65. data/lib/rex/exploitation/ropdb.rb +189 -0
  66. data/lib/rex/exploitation/seh.rb +68 -68
  67. data/lib/rex/file.rb +96 -49
  68. data/lib/rex/image_source.rb +0 -3
  69. data/lib/rex/image_source/disk.rb +45 -48
  70. data/lib/rex/image_source/image_source.rb +33 -36
  71. data/lib/rex/image_source/memory.rb +17 -20
  72. data/lib/rex/io/bidirectional_pipe.rb +118 -115
  73. data/lib/rex/io/datagram_abstraction.rb +13 -14
  74. data/lib/rex/io/ring_buffer.rb +273 -273
  75. data/lib/rex/io/stream.rb +284 -284
  76. data/lib/rex/io/stream_abstraction.rb +183 -181
  77. data/lib/rex/io/stream_server.rb +193 -193
  78. data/lib/rex/job_container.rb +167 -167
  79. data/lib/rex/logging.rb +0 -1
  80. data/lib/rex/logging/log_dispatcher.rb +113 -113
  81. data/lib/rex/logging/log_sink.rb +17 -17
  82. data/lib/rex/logging/sinks/flatfile.rb +36 -36
  83. data/lib/rex/logging/sinks/stderr.rb +27 -27
  84. data/lib/rex/mac_oui.rb +16572 -16571
  85. data/lib/rex/machparsey.rb +0 -1
  86. data/lib/rex/machparsey/exceptions.rb +0 -1
  87. data/lib/rex/machparsey/mach.rb +160 -161
  88. data/lib/rex/machparsey/machbase.rb +367 -368
  89. data/lib/rex/machscan.rb +0 -1
  90. data/lib/rex/machscan/scanner.rb +175 -176
  91. data/lib/rex/mime/encoding.rb +17 -0
  92. data/lib/rex/mime/header.rb +58 -58
  93. data/lib/rex/mime/message.rb +140 -137
  94. data/lib/rex/mime/part.rb +41 -12
  95. data/lib/rex/nop/opty2.rb +90 -90
  96. data/lib/rex/nop/opty2_tables.rb +273 -273
  97. data/lib/rex/ole.rb +0 -4
  98. data/lib/rex/ole/clsid.rb +26 -30
  99. data/lib/rex/ole/difat.rb +121 -125
  100. data/lib/rex/ole/directory.rb +205 -209
  101. data/lib/rex/ole/direntry.rb +217 -221
  102. data/lib/rex/ole/fat.rb +79 -83
  103. data/lib/rex/ole/header.rb +178 -182
  104. data/lib/rex/ole/minifat.rb +49 -53
  105. data/lib/rex/ole/propset.rb +113 -117
  106. data/lib/rex/ole/samples/create_ole.rb +8 -9
  107. data/lib/rex/ole/samples/dir.rb +10 -11
  108. data/lib/rex/ole/samples/dump_stream.rb +14 -15
  109. data/lib/rex/ole/samples/ole_info.rb +5 -6
  110. data/lib/rex/ole/storage.rb +372 -376
  111. data/lib/rex/ole/stream.rb +33 -37
  112. data/lib/rex/ole/substorage.rb +20 -24
  113. data/lib/rex/ole/util.rb +137 -141
  114. data/lib/rex/parser/acunetix_nokogiri.rb +398 -398
  115. data/lib/rex/parser/apple_backup_manifestdb.rb +116 -116
  116. data/lib/rex/parser/appscan_nokogiri.rb +359 -359
  117. data/lib/rex/parser/arguments.rb +88 -88
  118. data/lib/rex/parser/burp_session_nokogiri.rb +258 -258
  119. data/lib/rex/parser/ci_nokogiri.rb +184 -184
  120. data/lib/rex/parser/foundstone_nokogiri.rb +334 -333
  121. data/lib/rex/parser/fusionvm_nokogiri.rb +94 -94
  122. data/lib/rex/parser/ini.rb +167 -167
  123. data/lib/rex/parser/ip360_aspl_xml.rb +84 -84
  124. data/lib/rex/parser/ip360_xml.rb +77 -77
  125. data/lib/rex/parser/mbsa_nokogiri.rb +224 -224
  126. data/lib/rex/parser/nessus_xml.rb +100 -100
  127. data/lib/rex/parser/netsparker_xml.rb +89 -75
  128. data/lib/rex/parser/nexpose_raw_nokogiri.rb +677 -677
  129. data/lib/rex/parser/nexpose_simple_nokogiri.rb +322 -322
  130. data/lib/rex/parser/nexpose_xml.rb +105 -105
  131. data/lib/rex/parser/nmap_nokogiri.rb +386 -386
  132. data/lib/rex/parser/nmap_xml.rb +116 -116
  133. data/lib/rex/parser/nokogiri_doc_mixin.rb +223 -221
  134. data/lib/rex/parser/openvas_nokogiri.rb +162 -162
  135. data/lib/rex/parser/outpost24_nokogiri.rb +239 -0
  136. data/lib/rex/parser/retina_xml.rb +90 -90
  137. data/lib/rex/parser/unattend.rb +171 -0
  138. data/lib/rex/parser/wapiti_nokogiri.rb +89 -89
  139. data/lib/rex/payloads/win32/common.rb +14 -14
  140. data/lib/rex/payloads/win32/kernel.rb +36 -36
  141. data/lib/rex/payloads/win32/kernel/common.rb +32 -32
  142. data/lib/rex/payloads/win32/kernel/recovery.rb +27 -27
  143. data/lib/rex/payloads/win32/kernel/stager.rb +170 -170
  144. data/lib/rex/peparsey.rb +0 -3
  145. data/lib/rex/peparsey/exceptions.rb +0 -3
  146. data/lib/rex/peparsey/pe.rb +196 -199
  147. data/lib/rex/peparsey/pe_memdump.rb +35 -38
  148. data/lib/rex/peparsey/pebase.rb +1633 -1652
  149. data/lib/rex/peparsey/section.rb +115 -124
  150. data/lib/rex/pescan.rb +0 -3
  151. data/lib/rex/pescan/analyze.rb +351 -351
  152. data/lib/rex/pescan/scanner.rb +182 -182
  153. data/lib/rex/pescan/search.rb +59 -59
  154. data/lib/rex/platforms/windows.rb +37 -37
  155. data/lib/rex/poly.rb +111 -110
  156. data/lib/rex/poly/block.rb +419 -417
  157. data/lib/rex/poly/machine.rb +12 -0
  158. data/lib/rex/poly/machine/machine.rb +829 -0
  159. data/lib/rex/poly/machine/x86.rb +508 -0
  160. data/lib/rex/poly/register.rb +70 -70
  161. data/lib/rex/poly/register/x86.rb +22 -22
  162. data/lib/rex/post.rb +0 -1
  163. data/lib/rex/post/dir.rb +35 -36
  164. data/lib/rex/post/file.rb +140 -141
  165. data/lib/rex/post/file_stat.rb +198 -199
  166. data/lib/rex/post/io.rb +167 -168
  167. data/lib/rex/post/meterpreter.rb +1 -1
  168. data/lib/rex/post/meterpreter/channel.rb +389 -390
  169. data/lib/rex/post/meterpreter/channel_container.rb +33 -34
  170. data/lib/rex/post/meterpreter/channels/pool.rb +129 -130
  171. data/lib/rex/post/meterpreter/channels/pools/file.rb +35 -36
  172. data/lib/rex/post/meterpreter/channels/pools/stream_pool.rb +72 -73
  173. data/lib/rex/post/meterpreter/channels/stream.rb +62 -63
  174. data/lib/rex/post/meterpreter/client.rb +442 -436
  175. data/lib/rex/post/meterpreter/client_core.rb +326 -310
  176. data/lib/rex/post/meterpreter/dependencies.rb +0 -1
  177. data/lib/rex/post/meterpreter/extension.rb +12 -13
  178. data/lib/rex/post/meterpreter/extensions/espia/espia.rb +35 -36
  179. data/lib/rex/post/meterpreter/extensions/extapi/adsi/adsi.rb +71 -0
  180. data/lib/rex/post/meterpreter/extensions/extapi/clipboard/clipboard.rb +169 -0
  181. data/lib/rex/post/meterpreter/extensions/extapi/extapi.rb +45 -0
  182. data/lib/rex/post/meterpreter/extensions/extapi/service/service.rb +104 -0
  183. data/lib/rex/post/meterpreter/extensions/extapi/tlv.rb +77 -0
  184. data/lib/rex/post/meterpreter/extensions/extapi/window/window.rb +56 -0
  185. data/lib/rex/post/meterpreter/extensions/extapi/wmi/wmi.rb +75 -0
  186. data/lib/rex/post/meterpreter/extensions/incognito/incognito.rb +70 -71
  187. data/lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb +361 -0
  188. data/lib/rex/post/meterpreter/extensions/kiwi/tlv.rb +76 -0
  189. data/lib/rex/post/meterpreter/extensions/lanattacks/dhcp/dhcp.rb +78 -0
  190. data/lib/rex/post/meterpreter/extensions/lanattacks/lanattacks.rb +22 -78
  191. data/lib/rex/post/meterpreter/extensions/lanattacks/tftp/tftp.rb +49 -0
  192. data/lib/rex/post/meterpreter/extensions/lanattacks/tlv.rb +4 -4
  193. data/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb +128 -0
  194. data/lib/rex/post/meterpreter/extensions/mimikatz/tlv.rb +16 -0
  195. data/lib/rex/post/meterpreter/extensions/networkpug/networkpug.rb +38 -39
  196. data/lib/rex/post/meterpreter/extensions/networkpug/tlv.rb +1 -1
  197. data/lib/rex/post/meterpreter/extensions/priv/fs.rb +95 -96
  198. data/lib/rex/post/meterpreter/extensions/priv/passwd.rb +39 -40
  199. data/lib/rex/post/meterpreter/extensions/priv/priv.rb +80 -85
  200. data/lib/rex/post/meterpreter/extensions/sniffer/sniffer.rb +94 -95
  201. data/lib/rex/post/meterpreter/extensions/stdapi/constants.rb +207 -147
  202. data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +258 -259
  203. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +366 -301
  204. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file_stat.rb +72 -73
  205. data/lib/rex/post/meterpreter/extensions/stdapi/fs/io.rb +24 -25
  206. data/lib/rex/post/meterpreter/extensions/stdapi/net/arp.rb +59 -0
  207. data/lib/rex/post/meterpreter/extensions/stdapi/net/config.rb +227 -149
  208. data/lib/rex/post/meterpreter/extensions/stdapi/net/interface.rb +107 -108
  209. data/lib/rex/post/meterpreter/extensions/stdapi/net/netstat.rb +97 -0
  210. data/lib/rex/post/meterpreter/extensions/stdapi/net/resolve.rb +106 -0
  211. data/lib/rex/post/meterpreter/extensions/stdapi/net/route.rb +41 -42
  212. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +102 -101
  213. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +151 -152
  214. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb +142 -142
  215. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +185 -185
  216. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb +38118 -38117
  217. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb +7 -7
  218. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_advapi32.rb +2086 -2084
  219. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_crypt32.rb +15 -15
  220. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_iphlpapi.rb +80 -80
  221. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +3835 -3833
  222. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_netapi32.rb +84 -28
  223. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ntdll.rb +151 -137
  224. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_shell32.rb +15 -6
  225. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_user32.rb +3155 -3155
  226. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_version.rb +41 -0
  227. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wlanapi.rb +70 -70
  228. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb +128 -0
  229. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ws2_32.rb +596 -596
  230. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb +310 -301
  231. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb +71 -61
  232. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb +100 -100
  233. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_wrapper.rb +14 -14
  234. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/mock_magic.rb +488 -488
  235. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/multicall.rb +273 -264
  236. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/platform_util.rb +5 -5
  237. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb +240 -238
  238. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/tlv.rb +17 -15
  239. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/type/pointer_util.rb +61 -61
  240. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb +654 -635
  241. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb +49 -49
  242. data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +103 -102
  243. data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +98 -68
  244. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +165 -166
  245. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log_subsystem/event_record.rb +16 -17
  246. data/lib/rex/post/meterpreter/extensions/stdapi/sys/power.rb +34 -36
  247. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +363 -364
  248. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/image.rb +102 -103
  249. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/io.rb +28 -29
  250. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/memory.rb +303 -304
  251. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/thread.rb +113 -114
  252. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +260 -261
  253. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +165 -166
  254. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_value.rb +69 -70
  255. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/remote_registry_key.rb +160 -161
  256. data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +143 -144
  257. data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +29 -12
  258. data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +230 -231
  259. data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +181 -44
  260. data/lib/rex/post/meterpreter/inbound_packet_handler.rb +12 -13
  261. data/lib/rex/post/meterpreter/object_aliases.rb +56 -57
  262. data/lib/rex/post/meterpreter/packet.rb +591 -592
  263. data/lib/rex/post/meterpreter/packet_dispatcher.rb +506 -496
  264. data/lib/rex/post/meterpreter/packet_parser.rb +72 -73
  265. data/lib/rex/post/meterpreter/packet_response_waiter.rb +56 -57
  266. data/lib/rex/post/meterpreter/ui/console.rb +112 -112
  267. data/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb +53 -53
  268. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +911 -854
  269. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/espia.rb +86 -86
  270. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi.rb +65 -0
  271. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/adsi.rb +198 -0
  272. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/clipboard.rb +444 -0
  273. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/service.rb +199 -0
  274. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/window.rb +118 -0
  275. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/wmi.rb +108 -0
  276. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/incognito.rb +220 -220
  277. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb +509 -0
  278. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks.rb +60 -0
  279. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/dhcp.rb +254 -0
  280. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/tftp.rb +159 -0
  281. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +182 -0
  282. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/networkpug.rb +173 -173
  283. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv.rb +40 -40
  284. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +75 -77
  285. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/passwd.rb +30 -30
  286. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +105 -105
  287. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +182 -182
  288. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi.rb +37 -37
  289. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +504 -482
  290. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +401 -330
  291. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +883 -581
  292. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +296 -299
  293. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +320 -153
  294. data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +78 -78
  295. data/lib/rex/post/permission.rb +0 -1
  296. data/lib/rex/post/process.rb +39 -40
  297. data/lib/rex/post/thread.rb +41 -42
  298. data/lib/rex/post/ui.rb +35 -36
  299. data/lib/rex/proto/addp.rb +218 -0
  300. data/lib/rex/proto/dcerpc/client.rb +344 -344
  301. data/lib/rex/proto/dcerpc/exceptions.rb +128 -128
  302. data/lib/rex/proto/dcerpc/handle.rb +32 -32
  303. data/lib/rex/proto/dcerpc/ndr.rb +56 -56
  304. data/lib/rex/proto/dcerpc/packet.rb +249 -245
  305. data/lib/rex/proto/dcerpc/response.rb +170 -170
  306. data/lib/rex/proto/dcerpc/uuid.rb +65 -65
  307. data/lib/rex/proto/dcerpc/wdscp.rb +3 -0
  308. data/lib/rex/proto/dcerpc/wdscp/constants.rb +89 -0
  309. data/lib/rex/proto/dcerpc/wdscp/packet.rb +94 -0
  310. data/lib/rex/proto/dhcp.rb +0 -1
  311. data/lib/rex/proto/dhcp/constants.rb +0 -1
  312. data/lib/rex/proto/dhcp/server.rb +303 -304
  313. data/lib/rex/proto/drda/constants.rb +1 -1
  314. data/lib/rex/proto/drda/packet.rb +186 -186
  315. data/lib/rex/proto/drda/utils.rb +104 -104
  316. data/lib/rex/proto/http.rb +1 -0
  317. data/lib/rex/proto/http/client.rb +692 -820
  318. data/lib/rex/proto/http/client_request.rb +472 -0
  319. data/lib/rex/proto/http/handler.rb +25 -25
  320. data/lib/rex/proto/http/handler/erb.rb +104 -104
  321. data/lib/rex/proto/http/handler/proc.rb +37 -37
  322. data/lib/rex/proto/http/header.rb +149 -149
  323. data/lib/rex/proto/http/packet.rb +388 -382
  324. data/lib/rex/proto/http/request.rb +332 -335
  325. data/lib/rex/proto/http/response.rb +132 -72
  326. data/lib/rex/proto/http/server.rb +348 -338
  327. data/lib/rex/proto/iax2/call.rb +310 -310
  328. data/lib/rex/proto/iax2/client.rb +197 -197
  329. data/lib/rex/proto/iax2/codecs/alaw.rb +4 -4
  330. data/lib/rex/proto/iax2/codecs/mulaw.rb +4 -4
  331. data/lib/rex/proto/ipmi.rb +57 -0
  332. data/lib/rex/proto/ipmi/channel_auth_reply.rb +88 -0
  333. data/lib/rex/proto/ipmi/open_session_reply.rb +35 -0
  334. data/lib/rex/proto/ipmi/rakp2.rb +35 -0
  335. data/lib/rex/proto/ipmi/utils.rb +125 -0
  336. data/lib/rex/proto/natpmp.rb +1 -5
  337. data/lib/rex/proto/natpmp/constants.rb +4 -4
  338. data/lib/rex/proto/natpmp/packet.rb +25 -25
  339. data/lib/rex/proto/ntlm/base.rb +271 -271
  340. data/lib/rex/proto/ntlm/constants.rb +61 -61
  341. data/lib/rex/proto/ntlm/crypt.rb +348 -352
  342. data/lib/rex/proto/ntlm/exceptions.rb +3 -3
  343. data/lib/rex/proto/ntlm/message.rb +468 -471
  344. data/lib/rex/proto/ntlm/utils.rb +746 -746
  345. data/lib/rex/proto/pjl.rb +30 -0
  346. data/lib/rex/proto/pjl/client.rb +162 -0
  347. data/lib/rex/proto/proxy/socks4a.rb +440 -440
  348. data/lib/rex/proto/rfb.rb +1 -8
  349. data/lib/rex/proto/rfb/cipher.rb +46 -49
  350. data/lib/rex/proto/rfb/client.rb +179 -182
  351. data/lib/rex/proto/rfb/constants.rb +18 -21
  352. data/lib/rex/proto/smb/client.rb +1954 -1843
  353. data/lib/rex/proto/smb/constants.rb +533 -516
  354. data/lib/rex/proto/smb/crypt.rb +21 -21
  355. data/lib/rex/proto/smb/evasions.rb +43 -43
  356. data/lib/rex/proto/smb/exceptions.rb +791 -791
  357. data/lib/rex/proto/smb/simpleclient.rb +142 -286
  358. data/lib/rex/proto/smb/simpleclient/open_file.rb +106 -0
  359. data/lib/rex/proto/smb/simpleclient/open_pipe.rb +57 -0
  360. data/lib/rex/proto/smb/utils.rb +81 -81
  361. data/lib/rex/proto/sunrpc/client.rb +158 -158
  362. data/lib/rex/proto/tftp.rb +0 -1
  363. data/lib/rex/proto/tftp/client.rb +289 -289
  364. data/lib/rex/proto/tftp/constants.rb +9 -10
  365. data/lib/rex/proto/tftp/server.rb +466 -467
  366. data/lib/rex/random_identifier_generator.rb +176 -0
  367. data/lib/rex/registry.rb +1 -1
  368. data/lib/rex/registry/hive.rb +88 -88
  369. data/lib/rex/registry/lfkey.rb +25 -25
  370. data/lib/rex/registry/nodekey.rb +30 -30
  371. data/lib/rex/registry/regf.rb +10 -10
  372. data/lib/rex/registry/valuekey.rb +43 -43
  373. data/lib/rex/registry/valuelist.rb +13 -13
  374. data/lib/rex/ropbuilder/rop.rb +254 -253
  375. data/lib/rex/script.rb +21 -22
  376. data/lib/rex/script/base.rb +51 -50
  377. data/lib/rex/script/meterpreter.rb +2 -2
  378. data/lib/rex/service.rb +24 -24
  379. data/lib/rex/service_manager.rb +132 -132
  380. data/lib/rex/services/local_relay.rb +398 -398
  381. data/lib/rex/socket.rb +758 -763
  382. data/lib/rex/socket/comm.rb +95 -95
  383. data/lib/rex/socket/comm/local.rb +507 -440
  384. data/lib/rex/socket/ip.rb +118 -118
  385. data/lib/rex/socket/parameters.rb +351 -350
  386. data/lib/rex/socket/range_walker.rb +445 -368
  387. data/lib/rex/socket/ssl_tcp.rb +323 -317
  388. data/lib/rex/socket/ssl_tcp_server.rb +173 -158
  389. data/lib/rex/socket/subnet_walker.rb +48 -48
  390. data/lib/rex/socket/switch_board.rb +259 -259
  391. data/lib/rex/socket/tcp.rb +58 -56
  392. data/lib/rex/socket/tcp_server.rb +42 -42
  393. data/lib/rex/socket/udp.rb +152 -152
  394. data/lib/rex/sslscan/result.rb +200 -0
  395. data/lib/rex/sslscan/scanner.rb +205 -0
  396. data/lib/rex/struct2.rb +0 -1
  397. data/lib/rex/struct2/c_struct.rb +162 -163
  398. data/lib/rex/struct2/c_struct_template.rb +21 -22
  399. data/lib/rex/struct2/constant.rb +6 -7
  400. data/lib/rex/struct2/element.rb +30 -31
  401. data/lib/rex/struct2/generic.rb +60 -61
  402. data/lib/rex/struct2/restraint.rb +40 -41
  403. data/lib/rex/struct2/s_string.rb +60 -61
  404. data/lib/rex/struct2/s_struct.rb +97 -98
  405. data/lib/rex/sync.rb +0 -1
  406. data/lib/rex/sync/event.rb +62 -72
  407. data/lib/rex/sync/read_write_lock.rb +149 -149
  408. data/lib/rex/sync/ref.rb +42 -42
  409. data/lib/rex/sync/thread_safe.rb +59 -59
  410. data/lib/rex/text.rb +1803 -1315
  411. data/lib/rex/thread_factory.rb +25 -25
  412. data/lib/rex/time.rb +44 -44
  413. data/lib/rex/transformer.rb +91 -91
  414. data/lib/rex/ui/interactive.rb +265 -265
  415. data/lib/rex/ui/output.rb +66 -60
  416. data/lib/rex/ui/progress_tracker.rb +79 -79
  417. data/lib/rex/ui/subscriber.rb +144 -134
  418. data/lib/rex/ui/text/color.rb +76 -76
  419. data/lib/rex/ui/text/dispatcher_shell.rb +512 -505
  420. data/lib/rex/ui/text/input.rb +96 -96
  421. data/lib/rex/ui/text/input/buffer.rb +58 -58
  422. data/lib/rex/ui/text/input/readline.rb +114 -114
  423. data/lib/rex/ui/text/input/socket.rb +77 -77
  424. data/lib/rex/ui/text/input/stdio.rb +24 -24
  425. data/lib/rex/ui/text/irb_shell.rb +45 -41
  426. data/lib/rex/ui/text/output.rb +64 -60
  427. data/lib/rex/ui/text/output/buffer.rb +42 -42
  428. data/lib/rex/ui/text/output/buffer/stdout.rb +25 -0
  429. data/lib/rex/ui/text/output/file.rb +24 -24
  430. data/lib/rex/ui/text/output/socket.rb +24 -24
  431. data/lib/rex/ui/text/output/stdio.rb +29 -29
  432. data/lib/rex/ui/text/output/tee.rb +36 -36
  433. data/lib/rex/ui/text/progress_tracker.rb +37 -37
  434. data/lib/rex/ui/text/shell.rb +371 -361
  435. data/lib/rex/ui/text/table.rb +320 -284
  436. data/lib/rex/zip.rb +0 -1
  437. data/lib/rex/zip/archive.rb +115 -94
  438. data/lib/rex/zip/blocks.rb +101 -100
  439. data/lib/rex/zip/entry.rb +108 -99
  440. data/lib/rex/zip/jar.rb +261 -206
  441. data/lib/rex/zip/samples/comment.rb +1 -2
  442. data/lib/rex/zip/samples/mkwar.rb +12 -13
  443. data/lib/rex/zip/samples/mkzip.rb +1 -2
  444. data/lib/rex/zip/samples/recursive.rb +29 -30
  445. metadata +424 -446
  446. data/lib/rex/arch/sparc.rb.ut.rb +0 -19
  447. data/lib/rex/arch/x86.rb.ut.rb +0 -94
  448. data/lib/rex/assembly/nasm.rb.ut.rb +0 -23
  449. data/lib/rex/encoder/ndr.rb.ut.rb +0 -45
  450. data/lib/rex/encoder/xdr.rb.ut.rb +0 -30
  451. data/lib/rex/encoders/xor_dword_additive.rb.ut.rb +0 -13
  452. data/lib/rex/encoding/xor.rb.ts.rb +0 -15
  453. data/lib/rex/encoding/xor/byte.rb.ut.rb +0 -22
  454. data/lib/rex/encoding/xor/dword.rb.ut.rb +0 -16
  455. data/lib/rex/encoding/xor/dword_additive.rb.ut.rb +0 -16
  456. data/lib/rex/encoding/xor/generic.rb.ut.rb +0 -121
  457. data/lib/rex/encoding/xor/word.rb.ut.rb +0 -14
  458. data/lib/rex/exceptions.rb.ut.rb +0 -45
  459. data/lib/rex/exploitation/egghunter.rb.ut.rb +0 -28
  460. data/lib/rex/exploitation/javascriptosdetect.js +0 -1014
  461. data/lib/rex/exploitation/javascriptosdetect.rb +0 -43
  462. data/lib/rex/exploitation/omelet.rb.ut.rb +0 -27
  463. data/lib/rex/exploitation/opcodedb.rb.ut.rb +0 -280
  464. data/lib/rex/exploitation/seh.rb.ut.rb +0 -20
  465. data/lib/rex/file.rb.ut.rb +0 -17
  466. data/lib/rex/io/ring_buffer.rb.ut.rb +0 -135
  467. data/lib/rex/nop/opty2.rb.ut.rb +0 -24
  468. data/lib/rex/parser/arguments.rb.ut.rb +0 -68
  469. data/lib/rex/parser/ini.rb.ut.rb +0 -30
  470. data/lib/rex/post/meterpreter/extensions/stdapi/railgun.rb.ts.rb +0 -18
  471. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb.ut.rb +0 -39
  472. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb.ut.rb +0 -37
  473. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb.ut.rb +0 -52
  474. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb.ut.rb +0 -43
  475. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb.ut.rb +0 -128
  476. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_wrapper.rb.ut.rb +0 -64
  477. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/platform_util.rb.ut.rb +0 -29
  478. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb.ut.rb +0 -155
  479. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/type/pointer_util.rb.ut.rb +0 -128
  480. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb.ut.rb +0 -124
  481. data/lib/rex/proto.rb.ts.rb +0 -9
  482. data/lib/rex/proto/dcerpc.rb.ts.rb +0 -10
  483. data/lib/rex/proto/dcerpc/client.rb.ut.rb +0 -492
  484. data/lib/rex/proto/dcerpc/handle.rb.ut.rb +0 -86
  485. data/lib/rex/proto/dcerpc/ndr.rb.ut.rb +0 -42
  486. data/lib/rex/proto/dcerpc/packet.rb.ut.rb +0 -57
  487. data/lib/rex/proto/dcerpc/response.rb.ut.rb +0 -16
  488. data/lib/rex/proto/dcerpc/uuid.rb.ut.rb +0 -47
  489. data/lib/rex/proto/drda.rb.ts.rb +0 -18
  490. data/lib/rex/proto/drda/constants.rb.ut.rb +0 -24
  491. data/lib/rex/proto/drda/packet.rb.ut.rb +0 -110
  492. data/lib/rex/proto/drda/utils.rb.ut.rb +0 -85
  493. data/lib/rex/proto/http.rb.ts.rb +0 -13
  494. data/lib/rex/proto/http/client.rb.ut.rb +0 -96
  495. data/lib/rex/proto/http/handler/erb.rb.ut.rb +0 -22
  496. data/lib/rex/proto/http/handler/erb.rb.ut.rb.rhtml +0 -1
  497. data/lib/rex/proto/http/handler/proc.rb.ut.rb +0 -25
  498. data/lib/rex/proto/http/header.rb.ut.rb +0 -47
  499. data/lib/rex/proto/http/packet.rb.ut.rb +0 -166
  500. data/lib/rex/proto/http/request.rb.ut.rb +0 -215
  501. data/lib/rex/proto/http/response.rb.ut.rb +0 -150
  502. data/lib/rex/proto/http/server.rb.ut.rb +0 -80
  503. data/lib/rex/proto/ntlm.rb.ut.rb +0 -181
  504. data/lib/rex/proto/rfb.rb.ut.rb +0 -40
  505. data/lib/rex/proto/smb.rb.ts.rb +0 -9
  506. data/lib/rex/proto/smb/client.rb.ut.rb +0 -224
  507. data/lib/rex/proto/smb/constants.rb.ut.rb +0 -19
  508. data/lib/rex/proto/smb/simpleclient.rb.ut.rb +0 -129
  509. data/lib/rex/proto/smb/utils.rb.ut.rb +0 -21
  510. data/lib/rex/proto/tftp/server.rb.ut.rb +0 -29
  511. data/lib/rex/service_manager.rb.ut.rb +0 -33
  512. data/lib/rex/socket.rb.ut.rb +0 -108
  513. data/lib/rex/socket/comm/local.rb.ut.rb +0 -76
  514. data/lib/rex/socket/parameters.rb.ut.rb +0 -52
  515. data/lib/rex/socket/range_walker.rb.ut.rb +0 -56
  516. data/lib/rex/socket/ssl_tcp.rb.ut.rb +0 -40
  517. data/lib/rex/socket/ssl_tcp_server.rb.ut.rb +0 -62
  518. data/lib/rex/socket/subnet_walker.rb.ut.rb +0 -29
  519. data/lib/rex/socket/switch_board.rb.ut.rb +0 -53
  520. data/lib/rex/socket/tcp.rb.ut.rb +0 -65
  521. data/lib/rex/socket/tcp_server.rb.ut.rb +0 -45
  522. data/lib/rex/socket/udp.rb.ut.rb +0 -45
  523. data/lib/rex/test.rb +0 -36
  524. data/lib/rex/text.rb.ut.rb +0 -193
  525. data/lib/rex/transformer.rb.ut.rb +0 -39
  526. data/lib/rex/ui/text/color.rb.ut.rb +0 -19
  527. data/lib/rex/ui/text/progress_tracker.rb.ut.rb +0 -35
  528. data/lib/rex/ui/text/table.rb.ut.rb +0 -56
@@ -12,87 +12,87 @@ module Text
12
12
  ###
13
13
  module Color
14
14
 
15
- AnsiAttributes =
16
- {
17
- 'clear' => 0,
18
- 'reset' => 0,
19
- 'bold' => 1,
20
- 'dark' => 2,
21
- 'underline' => 4,
22
- 'underscore' => 4,
23
- 'blink' => 5,
24
- 'reverse' => 7,
25
- 'concealed' => 8,
26
- 'black' => 30, 'on_black' => 40,
27
- 'red' => 31, 'on_red' => 41,
28
- 'green' => 32, 'on_green' => 42,
29
- 'yellow' => 33, 'on_yellow' => 43,
30
- 'blue' => 34, 'on_blue' => 44,
31
- 'magenta' => 35, 'on_magenta' => 45,
32
- 'cyan' => 36, 'on_cyan' => 46,
33
- 'white' => 37, 'on_white' => 47
34
- }
15
+ AnsiAttributes =
16
+ {
17
+ 'clear' => 0,
18
+ 'reset' => 0,
19
+ 'bold' => 1,
20
+ 'dark' => 2,
21
+ 'underline' => 4,
22
+ 'underscore' => 4,
23
+ 'blink' => 5,
24
+ 'reverse' => 7,
25
+ 'concealed' => 8,
26
+ 'black' => 30, 'on_black' => 40,
27
+ 'red' => 31, 'on_red' => 41,
28
+ 'green' => 32, 'on_green' => 42,
29
+ 'yellow' => 33, 'on_yellow' => 43,
30
+ 'blue' => 34, 'on_blue' => 44,
31
+ 'magenta' => 35, 'on_magenta' => 45,
32
+ 'cyan' => 36, 'on_cyan' => 46,
33
+ 'white' => 37, 'on_white' => 47
34
+ }
35
35
 
36
- #
37
- # Return a string with ANSI codes substituted. Derived from code
38
- # written by The FaerieMUD Consortium.
39
- #
40
- def ansi(*attrs)
41
- attr = attrs.collect {|a| AnsiAttributes[a] ? AnsiAttributes[a] : nil}.compact.join(';')
42
- attr = "\e[%sm" % attr if (attr.empty? == false)
43
- return attr
44
- end
36
+ #
37
+ # Return a string with ANSI codes substituted. Derived from code
38
+ # written by The FaerieMUD Consortium.
39
+ #
40
+ def ansi(*attrs)
41
+ attr = attrs.collect {|a| AnsiAttributes[a] ? AnsiAttributes[a] : nil}.compact.join(';')
42
+ attr = "\e[%sm" % attr if (attr.empty? == false)
43
+ return attr
44
+ end
45
45
 
46
- #
47
- # Colorize if this shell supports it
48
- #
49
- def colorize(*color)
50
- supports_color?() ? ansi(*color) : ''
51
- end
46
+ #
47
+ # Colorize if this shell supports it
48
+ #
49
+ def colorize(*color)
50
+ supports_color?() ? ansi(*color) : ''
51
+ end
52
52
 
53
- def substitute_colors(msg, in_prompt = nil)
54
- str = msg.dup
55
- pre_color = post_color = ''
56
- if (in_prompt)
57
- pre_color = "\x01" # RL_PROMPT_START_IGNORE
58
- post_color = "\x02" # RL_PROMPT_END_IGNORE
59
- end
60
- str.gsub!(/%cya/, pre_color+colorize('cyan')+post_color)
61
- str.gsub!(/%red/, pre_color+colorize('red')+post_color)
62
- str.gsub!(/%grn/, pre_color+colorize('green')+post_color)
63
- str.gsub!(/%blu/, pre_color+colorize('blue')+post_color)
64
- str.gsub!(/%yel/, pre_color+colorize('yellow')+post_color)
65
- str.gsub!(/%whi/, pre_color+colorize('white')+post_color)
66
- str.gsub!(/%mag/, pre_color+colorize('magenta')+post_color)
67
- str.gsub!(/%blk/, pre_color+colorize('black')+post_color)
68
- str.gsub!(/%dred/, pre_color+colorize('dark', 'red')+post_color)
69
- str.gsub!(/%dgrn/, pre_color+colorize('dark', 'green')+post_color)
70
- str.gsub!(/%dblu/, pre_color+colorize('dark', 'blue')+post_color)
71
- str.gsub!(/%dyel/, pre_color+colorize('dark', 'yellow')+post_color)
72
- str.gsub!(/%dcya/, pre_color+colorize('dark', 'cyan')+post_color)
73
- str.gsub!(/%dwhi/, pre_color+colorize('dark', 'white')+post_color)
74
- str.gsub!(/%dmag/, pre_color+colorize('dark', 'magenta')+post_color)
75
- str.gsub!(/%und/, pre_color+colorize('underline')+post_color)
76
- str.gsub!(/%bld/, pre_color+colorize('bold')+post_color)
77
- str.gsub!(/%clr/, pre_color+colorize('clear')+post_color)
53
+ def substitute_colors(msg, in_prompt = nil)
54
+ str = msg.dup
55
+ pre_color = post_color = ''
56
+ if (in_prompt)
57
+ pre_color = "\x01" # RL_PROMPT_START_IGNORE
58
+ post_color = "\x02" # RL_PROMPT_END_IGNORE
59
+ end
60
+ str.gsub!(/%cya/, pre_color+colorize('cyan')+post_color)
61
+ str.gsub!(/%red/, pre_color+colorize('red')+post_color)
62
+ str.gsub!(/%grn/, pre_color+colorize('green')+post_color)
63
+ str.gsub!(/%blu/, pre_color+colorize('blue')+post_color)
64
+ str.gsub!(/%yel/, pre_color+colorize('yellow')+post_color)
65
+ str.gsub!(/%whi/, pre_color+colorize('white')+post_color)
66
+ str.gsub!(/%mag/, pre_color+colorize('magenta')+post_color)
67
+ str.gsub!(/%blk/, pre_color+colorize('black')+post_color)
68
+ str.gsub!(/%dred/, pre_color+colorize('dark', 'red')+post_color)
69
+ str.gsub!(/%dgrn/, pre_color+colorize('dark', 'green')+post_color)
70
+ str.gsub!(/%dblu/, pre_color+colorize('dark', 'blue')+post_color)
71
+ str.gsub!(/%dyel/, pre_color+colorize('dark', 'yellow')+post_color)
72
+ str.gsub!(/%dcya/, pre_color+colorize('dark', 'cyan')+post_color)
73
+ str.gsub!(/%dwhi/, pre_color+colorize('dark', 'white')+post_color)
74
+ str.gsub!(/%dmag/, pre_color+colorize('dark', 'magenta')+post_color)
75
+ str.gsub!(/%und/, pre_color+colorize('underline')+post_color)
76
+ str.gsub!(/%bld/, pre_color+colorize('bold')+post_color)
77
+ str.gsub!(/%clr/, pre_color+colorize('clear')+post_color)
78
78
 
79
- str
80
- end
79
+ str
80
+ end
81
81
 
82
- #
83
- # Resets coloring so that it's back to normal.
84
- #
85
- def reset_color
86
- return if not supports_color?
87
- print(colorize('clear'))
88
- end
82
+ #
83
+ # Resets coloring so that it's back to normal.
84
+ #
85
+ def reset_color
86
+ return if not supports_color?
87
+ print(colorize('clear'))
88
+ end
89
89
 
90
- #
91
- # Colorize if this shell supports it
92
- #
93
- def do_colorize(*color)
94
- supports_color?() ? ansi(*color) : ''
95
- end
96
- end
90
+ #
91
+ # Colorize if this shell supports it
92
+ #
93
+ def do_colorize(*color)
94
+ supports_color?() ? ansi(*color) : ''
95
+ end
96
+ end
97
97
 
98
98
  end end end
@@ -18,511 +18,518 @@ module Text
18
18
  ###
19
19
  module DispatcherShell
20
20
 
21
- ###
22
- #
23
- # Empty template base class for command dispatchers.
24
- #
25
- ###
26
- module CommandDispatcher
27
-
28
- #
29
- # Initializes the command dispatcher mixin.
30
- #
31
- def initialize(shell)
32
- self.shell = shell
33
- self.tab_complete_items = []
34
- end
35
-
36
- #
37
- # Returns nil for an empty set of commands.
38
- #
39
- # This method should be overridden to return a Hash with command
40
- # names for keys and brief help text for values.
41
- #
42
- def commands
43
- end
44
-
45
- #
46
- # Returns an empty set of commands.
47
- #
48
- # This method should be overridden if the dispatcher has commands that
49
- # should be treated as deprecated. Deprecated commands will not show up in
50
- # help and will not tab-complete, but will still be callable.
51
- #
52
- def deprecated_commands
53
- []
54
- end
55
-
56
- #
57
- # Wraps shell.print_error
58
- #
59
- def print_error(msg = '')
60
- shell.print_error(msg)
61
- end
62
-
63
- #
64
- # Wraps shell.print_status
65
- #
66
- def print_status(msg = '')
67
- shell.print_status(msg)
68
- end
69
-
70
- #
71
- # Wraps shell.print_line
72
- #
73
- def print_line(msg = '')
74
- shell.print_line(msg)
75
- end
76
-
77
- #
78
- # Wraps shell.print_good
79
- #
80
- def print_good(msg = '')
81
- shell.print_good(msg)
82
- end
83
-
84
- #
85
- # Wraps shell.print
86
- #
87
- def print(msg = '')
88
- shell.print(msg)
89
- end
90
-
91
- #
92
- # Print a warning that the called command is deprecated and optionally
93
- # forward to the replacement +method+ (useful for when commands are
94
- # renamed).
95
- #
96
- def deprecated_cmd(method=nil, *args)
97
- cmd = caller[0].match(/`cmd_(.*)'/)[1]
98
- print_error "The #{cmd} command is DEPRECATED"
99
- if cmd == "db_autopwn"
100
- print_error "See http://r-7.co/xY65Zr instead"
101
- elsif method and self.respond_to?("cmd_#{method}")
102
- print_error "Use #{method} instead"
103
- self.send("cmd_#{method}", *args)
104
- end
105
- end
106
-
107
- def deprecated_help(method=nil)
108
- cmd = caller[0].match(/`cmd_(.*)_help'/)[1]
109
- print_error "The #{cmd} command is DEPRECATED"
110
- if cmd == "db_autopwn"
111
- print_error "See http://r-7.co/xY65Zr instead"
112
- elsif method and self.respond_to?("cmd_#{method}_help")
113
- print_error "Use 'help #{method}' instead"
114
- self.send("cmd_#{method}_help")
115
- end
116
- end
117
-
118
- #
119
- # Wraps shell.update_prompt
120
- #
121
- def update_prompt(prompt=nil, prompt_char = nil, mode = false)
122
- shell.update_prompt(prompt, prompt_char, mode)
123
- end
124
-
125
- def cmd_help_help
126
- print_line "There's only so much I can do"
127
- end
128
-
129
- #
130
- # Displays the help banner. With no arguments, this is just a list of
131
- # all commands grouped by dispatcher. Otherwise, tries to use a method
132
- # named cmd_#{+cmd+}_help for the first dispatcher that has a command
133
- # named +cmd+. If no such method exists, uses +cmd+ as a regex to
134
- # compare against each enstacked dispatcher's name and dumps commands
135
- # of any that match.
136
- #
137
- def cmd_help(cmd=nil, *ignored)
138
- if cmd
139
- help_found = false
140
- cmd_found = false
141
- shell.dispatcher_stack.each do |dispatcher|
142
- next unless dispatcher.respond_to?(:commands)
143
- next if (dispatcher.commands.nil?)
144
- next if (dispatcher.commands.length == 0)
145
-
146
- if dispatcher.respond_to?("cmd_#{cmd}")
147
- cmd_found = true
148
- break unless dispatcher.respond_to? "cmd_#{cmd}_help"
149
- dispatcher.send("cmd_#{cmd}_help")
150
- help_found = true
151
- break
152
- end
153
- end
154
-
155
- unless cmd_found
156
- # We didn't find a cmd, try it as a dispatcher name
157
- shell.dispatcher_stack.each do |dispatcher|
158
- if dispatcher.name =~ /#{cmd}/i
159
- print_line(dispatcher.help_to_s)
160
- cmd_found = help_found = true
161
- end
162
- end
163
- end
164
- print_error("No help for #{cmd}, try -h") if cmd_found and not help_found
165
- print_error("No such command") if not cmd_found
166
- else
167
- print(shell.help_to_s)
168
- end
169
- end
170
-
171
- #
172
- # Tab completion for the help command
173
- #
174
- # By default just returns a list of all commands in all dispatchers.
175
- #
176
- def cmd_help_tabs(str, words)
177
- return [] if words.length > 1
178
-
179
- tabs = []
180
- shell.dispatcher_stack.each { |dispatcher|
181
- tabs += dispatcher.commands.keys
182
- }
183
- return tabs
184
- end
185
-
186
- alias cmd_? cmd_help
187
-
188
- #
189
- # Return a pretty, user-readable table of commands provided by this
190
- # dispatcher.
191
- #
192
- def help_to_s(opts={})
193
- # If this dispatcher has no commands, we can't do anything useful.
194
- return "" if commands.nil? or commands.length == 0
195
-
196
- # Display the commands
197
- tbl = Table.new(
198
- 'Header' => "#{self.name} Commands",
199
- 'Indent' => opts['Indent'] || 4,
200
- 'Columns' =>
201
- [
202
- 'Command',
203
- 'Description'
204
- ],
205
- 'ColProps' =>
206
- {
207
- 'Command' =>
208
- {
209
- 'MaxWidth' => 12
210
- }
211
- })
212
-
213
- commands.sort.each { |c|
214
- tbl << c
215
- }
216
-
217
- return "\n" + tbl.to_s + "\n"
218
- end
219
-
220
- #
221
- # No tab completion items by default
222
- #
223
- attr_accessor :shell, :tab_complete_items
224
-
225
- #
226
- # Provide a generic tab completion for file names.
227
- #
228
- # If the only completion is a directory, this descends into that directory
229
- # and continues completions with filenames contained within.
230
- #
231
- def tab_complete_filenames(str, words)
232
- matches = ::Readline::FILENAME_COMPLETION_PROC.call(str)
233
- if matches and matches.length == 1 and File.directory?(matches[0])
234
- dir = matches[0]
235
- dir += File::SEPARATOR if dir[-1,1] != File::SEPARATOR
236
- matches = ::Readline::FILENAME_COMPLETION_PROC.call(dir)
237
- end
238
- matches
239
- end
240
-
241
- end
242
-
243
- #
244
- # DispatcherShell derives from shell.
245
- #
246
- include Shell
247
-
248
- #
249
- # Initialize the dispatcher shell.
250
- #
251
- def initialize(prompt, prompt_char = '>', histfile = nil, framework = nil)
252
- super
253
-
254
- # Initialze the dispatcher array
255
- self.dispatcher_stack = []
256
-
257
- # Initialize the tab completion array
258
- self.tab_words = []
259
- self.on_command_proc = nil
260
- end
261
-
262
- #
263
- # This method accepts the entire line of text from the Readline
264
- # routine, stores all completed words, and passes the partial
265
- # word to the real tab completion function. This works around
266
- # a design problem in the Readline module and depends on the
267
- # Readline.basic_word_break_characters variable being set to \x00
268
- #
269
- def tab_complete(str)
270
- # Check trailing whitespace so we can tell 'x' from 'x '
271
- str_match = str.match(/\s+$/)
272
- str_trail = (str_match.nil?) ? '' : str_match[0]
273
-
274
- # Split the line up by whitespace into words
275
- str_words = str.split(/[\s\t\n]+/)
276
-
277
- # Append an empty word if we had trailing whitespace
278
- str_words << '' if str_trail.length > 0
279
-
280
- # Place the word list into an instance variable
281
- self.tab_words = str_words
282
-
283
- # Pop the last word and pass it to the real method
284
- tab_complete_stub(self.tab_words.pop)
285
- end
286
-
287
- # Performs tab completion of a command, if supported
288
- # Current words can be found in self.tab_words
289
- #
290
- def tab_complete_stub(str)
291
- items = []
292
-
293
- return nil if not str
294
-
295
- # puts "Words(#{tab_words.join(", ")}) Partial='#{str}'"
296
-
297
- # Next, try to match internal command or value completion
298
- # Enumerate each entry in the dispatcher stack
299
- dispatcher_stack.each { |dispatcher|
300
-
301
- # If no command is set and it supports commands, add them all
302
- if (tab_words.empty? and dispatcher.respond_to?('commands'))
303
- items.concat(dispatcher.commands.keys)
304
- end
305
-
306
- # If the dispatcher exports a tab completion function, use it
307
- if(dispatcher.respond_to?('tab_complete_helper'))
308
- res = dispatcher.tab_complete_helper(str, tab_words)
309
- else
310
- res = tab_complete_helper(dispatcher, str, tab_words)
311
- end
312
-
313
- if (res.nil?)
314
- # A nil response indicates no optional arguments
315
- return [''] if items.empty?
316
- else
317
- # Otherwise we add the completion items to the list
318
- items.concat(res)
319
- end
320
- }
321
-
322
- # Verify that our search string is a valid regex
323
- begin
324
- Regexp.compile(str)
325
- rescue RegexpError
326
- str = Regexp.escape(str)
327
- end
328
-
329
- # XXX - This still doesn't fix some Regexp warnings:
330
- # ./lib/rex/ui/text/dispatcher_shell.rb:171: warning: regexp has `]' without escape
331
-
332
- # Match based on the partial word
333
- items.find_all { |e|
334
- e =~ /^#{str}/
335
- # Prepend the rest of the command (or it gets replaced!)
336
- }.map { |e|
337
- tab_words.dup.push(e).join(' ')
338
- }
339
- end
340
-
341
- #
342
- # Provide command-specific tab completion
343
- #
344
- def tab_complete_helper(dispatcher, str, words)
345
- items = []
346
-
347
- tabs_meth = "cmd_#{words[0]}_tabs"
348
- # Is the user trying to tab complete one of our commands?
349
- if (dispatcher.commands.include?(words[0]) and dispatcher.respond_to?(tabs_meth))
350
- res = dispatcher.send(tabs_meth, str, words)
351
- return [] if res.nil?
352
- items.concat(res)
353
- else
354
- # Avoid the default completion list for known commands
355
- return []
356
- end
357
-
358
- return items
359
- end
360
-
361
- #
362
- # Run a single command line.
363
- #
364
- def run_single(line)
365
- arguments = parse_line(line)
366
- method = arguments.shift
367
- found = false
368
- error = false
369
-
370
- # If output is disabled output will be nil
371
- output.reset_color if (output)
372
-
373
- if (method)
374
- entries = dispatcher_stack.length
375
-
376
- dispatcher_stack.each { |dispatcher|
377
- next if not dispatcher.respond_to?('commands')
378
-
379
- begin
380
- if (dispatcher.commands.has_key?(method) or dispatcher.deprecated_commands.include?(method))
381
- self.on_command_proc.call(line.strip) if self.on_command_proc
382
- run_command(dispatcher, method, arguments)
383
- found = true
384
- end
385
- rescue
386
- error = $!
387
-
388
- print_error(
389
- "Error while running command #{method}: #{$!}" +
390
- "\n\nCall stack:\n#{$@.join("\n")}")
391
- rescue ::Exception
392
- error = $!
393
-
394
- print_error(
395
- "Error while running command #{method}: #{$!}")
396
- end
397
-
398
- # If the dispatcher stack changed as a result of this command,
399
- # break out
400
- break if (dispatcher_stack.length != entries)
401
- }
402
-
403
- if (found == false and error == false)
404
- unknown_command(method, line)
405
- end
406
- end
407
-
408
- return found
409
- end
410
-
411
- #
412
- # Runs the supplied command on the given dispatcher.
413
- #
414
- def run_command(dispatcher, method, arguments)
415
- self.busy = true
416
-
417
- if(blocked_command?(method))
418
- print_error("The #{method} command has been disabled.")
419
- else
420
- dispatcher.send('cmd_' + method, *arguments)
421
- end
422
- self.busy = false
423
- end
424
-
425
- #
426
- # If the command is unknown...
427
- #
428
- def unknown_command(method, line)
429
- print_error("Unknown command: #{method}.")
430
- end
431
-
432
- #
433
- # Push a dispatcher to the front of the stack.
434
- #
435
- def enstack_dispatcher(dispatcher)
436
- self.dispatcher_stack.unshift(inst = dispatcher.new(self))
437
-
438
- inst
439
- end
440
-
441
- #
442
- # Pop a dispatcher from the front of the stacker.
443
- #
444
- def destack_dispatcher
445
- self.dispatcher_stack.shift
446
- end
447
-
448
- #
449
- # Adds the supplied dispatcher to the end of the dispatcher stack so that
450
- # it doesn't affect any enstack'd dispatchers.
451
- #
452
- def append_dispatcher(dispatcher)
453
- inst = dispatcher.new(self)
454
- self.dispatcher_stack.each { |disp|
455
- if (disp.name == inst.name)
456
- raise RuntimeError.new("Attempting to load already loaded dispatcher #{disp.name}")
457
- end
458
- }
459
- self.dispatcher_stack.push(inst)
460
-
461
- inst
462
- end
463
-
464
- #
465
- # Removes the supplied dispatcher instance.
466
- #
467
- def remove_dispatcher(name)
468
- self.dispatcher_stack.delete_if { |inst|
469
- (inst.name == name)
470
- }
471
- end
472
-
473
- #
474
- # Returns the current active dispatcher
475
- #
476
- def current_dispatcher
477
- self.dispatcher_stack[0]
478
- end
479
-
480
- #
481
- # Return a readable version of a help banner for all of the enstacked
482
- # dispatchers.
483
- #
484
- # See +CommandDispatcher#help_to_s+
485
- #
486
- def help_to_s(opts = {})
487
- str = ''
488
-
489
- dispatcher_stack.reverse.each { |dispatcher|
490
- str << dispatcher.help_to_s
491
- }
492
-
493
- return str
494
- end
495
-
496
-
497
- #
498
- # Returns nil for an empty set of blocked commands.
499
- #
500
- def blocked_command?(cmd)
501
- return false if not self.blocked
502
- self.blocked.has_key?(cmd)
503
- end
504
-
505
- #
506
- # Block a specific command
507
- #
508
- def block_command(cmd)
509
- self.blocked ||= {}
510
- self.blocked[cmd] = true
511
- end
512
-
513
- #
514
- # Unblock a specific command
515
- #
516
- def unblock_command(cmd)
517
- self.blocked || return
518
- self.blocked.delete(cmd)
519
- end
520
-
521
-
522
- attr_accessor :dispatcher_stack # :nodoc:
523
- attr_accessor :tab_words # :nodoc:
524
- attr_accessor :busy # :nodoc:
525
- attr_accessor :blocked # :nodoc:
21
+ ###
22
+ #
23
+ # Empty template base class for command dispatchers.
24
+ #
25
+ ###
26
+ module CommandDispatcher
27
+
28
+ #
29
+ # Initializes the command dispatcher mixin.
30
+ #
31
+ def initialize(shell)
32
+ self.shell = shell
33
+ self.tab_complete_items = []
34
+ end
35
+
36
+ #
37
+ # Returns nil for an empty set of commands.
38
+ #
39
+ # This method should be overridden to return a Hash with command
40
+ # names for keys and brief help text for values.
41
+ #
42
+ def commands
43
+ end
44
+
45
+ #
46
+ # Returns an empty set of commands.
47
+ #
48
+ # This method should be overridden if the dispatcher has commands that
49
+ # should be treated as deprecated. Deprecated commands will not show up in
50
+ # help and will not tab-complete, but will still be callable.
51
+ #
52
+ def deprecated_commands
53
+ []
54
+ end
55
+
56
+ #
57
+ # Wraps shell.print_error
58
+ #
59
+ def print_error(msg = '')
60
+ shell.print_error(msg)
61
+ end
62
+
63
+ #
64
+ # Wraps shell.print_status
65
+ #
66
+ def print_status(msg = '')
67
+ shell.print_status(msg)
68
+ end
69
+
70
+ #
71
+ # Wraps shell.print_line
72
+ #
73
+ def print_line(msg = '')
74
+ shell.print_line(msg)
75
+ end
76
+
77
+ #
78
+ # Wraps shell.print_good
79
+ #
80
+ def print_good(msg = '')
81
+ shell.print_good(msg)
82
+ end
83
+
84
+ #
85
+ # Wraps shell.print_warning
86
+ #
87
+ def print_warning(msg = '')
88
+ shell.print_warning(msg)
89
+ end
90
+
91
+ #
92
+ # Wraps shell.print
93
+ #
94
+ def print(msg = '')
95
+ shell.print(msg)
96
+ end
97
+
98
+ #
99
+ # Print a warning that the called command is deprecated and optionally
100
+ # forward to the replacement +method+ (useful for when commands are
101
+ # renamed).
102
+ #
103
+ def deprecated_cmd(method=nil, *args)
104
+ cmd = caller[0].match(/`cmd_(.*)'/)[1]
105
+ print_error "The #{cmd} command is DEPRECATED"
106
+ if cmd == "db_autopwn"
107
+ print_error "See http://r-7.co/xY65Zr instead"
108
+ elsif method and self.respond_to?("cmd_#{method}")
109
+ print_error "Use #{method} instead"
110
+ self.send("cmd_#{method}", *args)
111
+ end
112
+ end
113
+
114
+ def deprecated_help(method=nil)
115
+ cmd = caller[0].match(/`cmd_(.*)_help'/)[1]
116
+ print_error "The #{cmd} command is DEPRECATED"
117
+ if cmd == "db_autopwn"
118
+ print_error "See http://r-7.co/xY65Zr instead"
119
+ elsif method and self.respond_to?("cmd_#{method}_help")
120
+ print_error "Use 'help #{method}' instead"
121
+ self.send("cmd_#{method}_help")
122
+ end
123
+ end
124
+
125
+ #
126
+ # Wraps shell.update_prompt
127
+ #
128
+ def update_prompt(prompt=nil, prompt_char = nil, mode = false)
129
+ shell.update_prompt(prompt, prompt_char, mode)
130
+ end
131
+
132
+ def cmd_help_help
133
+ print_line "There's only so much I can do"
134
+ end
135
+
136
+ #
137
+ # Displays the help banner. With no arguments, this is just a list of
138
+ # all commands grouped by dispatcher. Otherwise, tries to use a method
139
+ # named cmd_#{+cmd+}_help for the first dispatcher that has a command
140
+ # named +cmd+. If no such method exists, uses +cmd+ as a regex to
141
+ # compare against each enstacked dispatcher's name and dumps commands
142
+ # of any that match.
143
+ #
144
+ def cmd_help(cmd=nil, *ignored)
145
+ if cmd
146
+ help_found = false
147
+ cmd_found = false
148
+ shell.dispatcher_stack.each do |dispatcher|
149
+ next unless dispatcher.respond_to?(:commands)
150
+ next if (dispatcher.commands.nil?)
151
+ next if (dispatcher.commands.length == 0)
152
+
153
+ if dispatcher.respond_to?("cmd_#{cmd}")
154
+ cmd_found = true
155
+ break unless dispatcher.respond_to? "cmd_#{cmd}_help"
156
+ dispatcher.send("cmd_#{cmd}_help")
157
+ help_found = true
158
+ break
159
+ end
160
+ end
161
+
162
+ unless cmd_found
163
+ # We didn't find a cmd, try it as a dispatcher name
164
+ shell.dispatcher_stack.each do |dispatcher|
165
+ if dispatcher.name =~ /#{cmd}/i
166
+ print_line(dispatcher.help_to_s)
167
+ cmd_found = help_found = true
168
+ end
169
+ end
170
+ end
171
+ print_error("No help for #{cmd}, try -h") if cmd_found and not help_found
172
+ print_error("No such command") if not cmd_found
173
+ else
174
+ print(shell.help_to_s)
175
+ end
176
+ end
177
+
178
+ #
179
+ # Tab completion for the help command
180
+ #
181
+ # By default just returns a list of all commands in all dispatchers.
182
+ #
183
+ def cmd_help_tabs(str, words)
184
+ return [] if words.length > 1
185
+
186
+ tabs = []
187
+ shell.dispatcher_stack.each { |dispatcher|
188
+ tabs += dispatcher.commands.keys
189
+ }
190
+ return tabs
191
+ end
192
+
193
+ alias cmd_? cmd_help
194
+
195
+ #
196
+ # Return a pretty, user-readable table of commands provided by this
197
+ # dispatcher.
198
+ #
199
+ def help_to_s(opts={})
200
+ # If this dispatcher has no commands, we can't do anything useful.
201
+ return "" if commands.nil? or commands.length == 0
202
+
203
+ # Display the commands
204
+ tbl = Table.new(
205
+ 'Header' => "#{self.name} Commands",
206
+ 'Indent' => opts['Indent'] || 4,
207
+ 'Columns' =>
208
+ [
209
+ 'Command',
210
+ 'Description'
211
+ ],
212
+ 'ColProps' =>
213
+ {
214
+ 'Command' =>
215
+ {
216
+ 'MaxWidth' => 12
217
+ }
218
+ })
219
+
220
+ commands.sort.each { |c|
221
+ tbl << c
222
+ }
223
+
224
+ return "\n" + tbl.to_s + "\n"
225
+ end
226
+
227
+ #
228
+ # No tab completion items by default
229
+ #
230
+ attr_accessor :shell, :tab_complete_items
231
+
232
+ #
233
+ # Provide a generic tab completion for file names.
234
+ #
235
+ # If the only completion is a directory, this descends into that directory
236
+ # and continues completions with filenames contained within.
237
+ #
238
+ def tab_complete_filenames(str, words)
239
+ matches = ::Readline::FILENAME_COMPLETION_PROC.call(str)
240
+ if matches and matches.length == 1 and File.directory?(matches[0])
241
+ dir = matches[0]
242
+ dir += File::SEPARATOR if dir[-1,1] != File::SEPARATOR
243
+ matches = ::Readline::FILENAME_COMPLETION_PROC.call(dir)
244
+ end
245
+ matches
246
+ end
247
+
248
+ end
249
+
250
+ #
251
+ # DispatcherShell derives from shell.
252
+ #
253
+ include Shell
254
+
255
+ #
256
+ # Initialize the dispatcher shell.
257
+ #
258
+ def initialize(prompt, prompt_char = '>', histfile = nil, framework = nil)
259
+ super
260
+
261
+ # Initialze the dispatcher array
262
+ self.dispatcher_stack = []
263
+
264
+ # Initialize the tab completion array
265
+ self.tab_words = []
266
+ self.on_command_proc = nil
267
+ end
268
+
269
+ #
270
+ # This method accepts the entire line of text from the Readline
271
+ # routine, stores all completed words, and passes the partial
272
+ # word to the real tab completion function. This works around
273
+ # a design problem in the Readline module and depends on the
274
+ # Readline.basic_word_break_characters variable being set to \x00
275
+ #
276
+ def tab_complete(str)
277
+ # Check trailing whitespace so we can tell 'x' from 'x '
278
+ str_match = str.match(/\s+$/)
279
+ str_trail = (str_match.nil?) ? '' : str_match[0]
280
+
281
+ # Split the line up by whitespace into words
282
+ str_words = str.split(/[\s\t\n]+/)
283
+
284
+ # Append an empty word if we had trailing whitespace
285
+ str_words << '' if str_trail.length > 0
286
+
287
+ # Place the word list into an instance variable
288
+ self.tab_words = str_words
289
+
290
+ # Pop the last word and pass it to the real method
291
+ tab_complete_stub(self.tab_words.pop)
292
+ end
293
+
294
+ # Performs tab completion of a command, if supported
295
+ # Current words can be found in self.tab_words
296
+ #
297
+ def tab_complete_stub(str)
298
+ items = []
299
+
300
+ return nil if not str
301
+
302
+ # puts "Words(#{tab_words.join(", ")}) Partial='#{str}'"
303
+
304
+ # Next, try to match internal command or value completion
305
+ # Enumerate each entry in the dispatcher stack
306
+ dispatcher_stack.each { |dispatcher|
307
+
308
+ # If no command is set and it supports commands, add them all
309
+ if (tab_words.empty? and dispatcher.respond_to?('commands'))
310
+ items.concat(dispatcher.commands.keys)
311
+ end
312
+
313
+ # If the dispatcher exports a tab completion function, use it
314
+ if(dispatcher.respond_to?('tab_complete_helper'))
315
+ res = dispatcher.tab_complete_helper(str, tab_words)
316
+ else
317
+ res = tab_complete_helper(dispatcher, str, tab_words)
318
+ end
319
+
320
+ if (res.nil?)
321
+ # A nil response indicates no optional arguments
322
+ return [''] if items.empty?
323
+ else
324
+ # Otherwise we add the completion items to the list
325
+ items.concat(res)
326
+ end
327
+ }
328
+
329
+ # Verify that our search string is a valid regex
330
+ begin
331
+ Regexp.compile(str)
332
+ rescue RegexpError
333
+ str = Regexp.escape(str)
334
+ end
335
+
336
+ # @todo - This still doesn't fix some Regexp warnings:
337
+ # ./lib/rex/ui/text/dispatcher_shell.rb:171: warning: regexp has `]' without escape
338
+
339
+ # Match based on the partial word
340
+ items.find_all { |e|
341
+ e =~ /^#{str}/
342
+ # Prepend the rest of the command (or it all gets replaced!)
343
+ }.map { |e|
344
+ tab_words.dup.push(e).join(' ')
345
+ }
346
+ end
347
+
348
+ #
349
+ # Provide command-specific tab completion
350
+ #
351
+ def tab_complete_helper(dispatcher, str, words)
352
+ items = []
353
+
354
+ tabs_meth = "cmd_#{words[0]}_tabs"
355
+ # Is the user trying to tab complete one of our commands?
356
+ if (dispatcher.commands.include?(words[0]) and dispatcher.respond_to?(tabs_meth))
357
+ res = dispatcher.send(tabs_meth, str, words)
358
+ return [] if res.nil?
359
+ items.concat(res)
360
+ else
361
+ # Avoid the default completion list for known commands
362
+ return []
363
+ end
364
+
365
+ return items
366
+ end
367
+
368
+ #
369
+ # Run a single command line.
370
+ #
371
+ def run_single(line)
372
+ arguments = parse_line(line)
373
+ method = arguments.shift
374
+ found = false
375
+ error = false
376
+
377
+ # If output is disabled output will be nil
378
+ output.reset_color if (output)
379
+
380
+ if (method)
381
+ entries = dispatcher_stack.length
382
+
383
+ dispatcher_stack.each { |dispatcher|
384
+ next if not dispatcher.respond_to?('commands')
385
+
386
+ begin
387
+ if (dispatcher.commands.has_key?(method) or dispatcher.deprecated_commands.include?(method))
388
+ self.on_command_proc.call(line.strip) if self.on_command_proc
389
+ run_command(dispatcher, method, arguments)
390
+ found = true
391
+ end
392
+ rescue
393
+ error = $!
394
+
395
+ print_error(
396
+ "Error while running command #{method}: #{$!}" +
397
+ "\n\nCall stack:\n#{$@.join("\n")}")
398
+ rescue ::Exception
399
+ error = $!
400
+
401
+ print_error(
402
+ "Error while running command #{method}: #{$!}")
403
+ end
404
+
405
+ # If the dispatcher stack changed as a result of this command,
406
+ # break out
407
+ break if (dispatcher_stack.length != entries)
408
+ }
409
+
410
+ if (found == false and error == false)
411
+ unknown_command(method, line)
412
+ end
413
+ end
414
+
415
+ return found
416
+ end
417
+
418
+ #
419
+ # Runs the supplied command on the given dispatcher.
420
+ #
421
+ def run_command(dispatcher, method, arguments)
422
+ self.busy = true
423
+
424
+ if(blocked_command?(method))
425
+ print_error("The #{method} command has been disabled.")
426
+ else
427
+ dispatcher.send('cmd_' + method, *arguments)
428
+ end
429
+ self.busy = false
430
+ end
431
+
432
+ #
433
+ # If the command is unknown...
434
+ #
435
+ def unknown_command(method, line)
436
+ print_error("Unknown command: #{method}.")
437
+ end
438
+
439
+ #
440
+ # Push a dispatcher to the front of the stack.
441
+ #
442
+ def enstack_dispatcher(dispatcher)
443
+ self.dispatcher_stack.unshift(inst = dispatcher.new(self))
444
+
445
+ inst
446
+ end
447
+
448
+ #
449
+ # Pop a dispatcher from the front of the stacker.
450
+ #
451
+ def destack_dispatcher
452
+ self.dispatcher_stack.shift
453
+ end
454
+
455
+ #
456
+ # Adds the supplied dispatcher to the end of the dispatcher stack so that
457
+ # it doesn't affect any enstack'd dispatchers.
458
+ #
459
+ def append_dispatcher(dispatcher)
460
+ inst = dispatcher.new(self)
461
+ self.dispatcher_stack.each { |disp|
462
+ if (disp.name == inst.name)
463
+ raise RuntimeError.new("Attempting to load already loaded dispatcher #{disp.name}")
464
+ end
465
+ }
466
+ self.dispatcher_stack.push(inst)
467
+
468
+ inst
469
+ end
470
+
471
+ #
472
+ # Removes the supplied dispatcher instance.
473
+ #
474
+ def remove_dispatcher(name)
475
+ self.dispatcher_stack.delete_if { |inst|
476
+ (inst.name == name)
477
+ }
478
+ end
479
+
480
+ #
481
+ # Returns the current active dispatcher
482
+ #
483
+ def current_dispatcher
484
+ self.dispatcher_stack[0]
485
+ end
486
+
487
+ #
488
+ # Return a readable version of a help banner for all of the enstacked
489
+ # dispatchers.
490
+ #
491
+ # See +CommandDispatcher#help_to_s+
492
+ #
493
+ def help_to_s(opts = {})
494
+ str = ''
495
+
496
+ dispatcher_stack.reverse.each { |dispatcher|
497
+ str << dispatcher.help_to_s
498
+ }
499
+
500
+ return str
501
+ end
502
+
503
+
504
+ #
505
+ # Returns nil for an empty set of blocked commands.
506
+ #
507
+ def blocked_command?(cmd)
508
+ return false if not self.blocked
509
+ self.blocked.has_key?(cmd)
510
+ end
511
+
512
+ #
513
+ # Block a specific command
514
+ #
515
+ def block_command(cmd)
516
+ self.blocked ||= {}
517
+ self.blocked[cmd] = true
518
+ end
519
+
520
+ #
521
+ # Unblock a specific command
522
+ #
523
+ def unblock_command(cmd)
524
+ self.blocked || return
525
+ self.blocked.delete(cmd)
526
+ end
527
+
528
+
529
+ attr_accessor :dispatcher_stack # :nodoc:
530
+ attr_accessor :tab_words # :nodoc:
531
+ attr_accessor :busy # :nodoc:
532
+ attr_accessor :blocked # :nodoc:
526
533
 
527
534
  end
528
535