librex 0.0.20 → 0.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (435) hide show
  1. data/Rakefile +1 -0
  2. data/lib/rex/LICENSE +29 -0
  3. data/lib/rex/arch.rb +103 -0
  4. data/lib/rex/arch/sparc.rb +75 -0
  5. data/lib/rex/arch/sparc.rb.ut.rb +18 -0
  6. data/lib/rex/arch/x86.rb +513 -0
  7. data/lib/rex/arch/x86.rb.ut.rb +93 -0
  8. data/lib/rex/assembly/nasm.rb +104 -0
  9. data/lib/rex/assembly/nasm.rb.ut.rb +22 -0
  10. data/lib/rex/codepage.map +104 -0
  11. data/lib/rex/compat.rb +311 -0
  12. data/lib/rex/constants.rb +113 -0
  13. data/lib/rex/elfparsey.rb +11 -0
  14. data/lib/rex/elfparsey/elf.rb +123 -0
  15. data/lib/rex/elfparsey/elfbase.rb +258 -0
  16. data/lib/rex/elfparsey/exceptions.rb +27 -0
  17. data/lib/rex/elfscan.rb +12 -0
  18. data/lib/rex/elfscan/scanner.rb +207 -0
  19. data/lib/rex/elfscan/search.rb +46 -0
  20. data/lib/rex/encoder/alpha2.rb +31 -0
  21. data/lib/rex/encoder/alpha2/alpha_mixed.rb +68 -0
  22. data/lib/rex/encoder/alpha2/alpha_upper.rb +79 -0
  23. data/lib/rex/encoder/alpha2/generic.rb +114 -0
  24. data/lib/rex/encoder/alpha2/unicode_mixed.rb +117 -0
  25. data/lib/rex/encoder/alpha2/unicode_upper.rb +129 -0
  26. data/lib/rex/encoder/ndr.rb +89 -0
  27. data/lib/rex/encoder/ndr.rb.ut.rb +44 -0
  28. data/lib/rex/encoder/nonalpha.rb +61 -0
  29. data/lib/rex/encoder/nonupper.rb +64 -0
  30. data/lib/rex/encoder/xdr.rb +106 -0
  31. data/lib/rex/encoder/xdr.rb.ut.rb +29 -0
  32. data/lib/rex/encoder/xor.rb +69 -0
  33. data/lib/rex/encoder/xor/dword.rb +13 -0
  34. data/lib/rex/encoder/xor/dword_additive.rb +13 -0
  35. data/lib/rex/encoders/xor_dword.rb +35 -0
  36. data/lib/rex/encoders/xor_dword_additive.rb +53 -0
  37. data/lib/rex/encoders/xor_dword_additive.rb.ut.rb +12 -0
  38. data/lib/rex/encoding/xor.rb +20 -0
  39. data/lib/rex/encoding/xor.rb.ts.rb +14 -0
  40. data/lib/rex/encoding/xor/byte.rb +15 -0
  41. data/lib/rex/encoding/xor/byte.rb.ut.rb +21 -0
  42. data/lib/rex/encoding/xor/dword.rb +21 -0
  43. data/lib/rex/encoding/xor/dword.rb.ut.rb +15 -0
  44. data/lib/rex/encoding/xor/dword_additive.rb +92 -0
  45. data/lib/rex/encoding/xor/dword_additive.rb.ut.rb +15 -0
  46. data/lib/rex/encoding/xor/exceptions.rb +17 -0
  47. data/lib/rex/encoding/xor/generic.rb +146 -0
  48. data/lib/rex/encoding/xor/generic.rb.ut.rb +120 -0
  49. data/lib/rex/encoding/xor/qword.rb +15 -0
  50. data/lib/rex/encoding/xor/word.rb +21 -0
  51. data/lib/rex/encoding/xor/word.rb.ut.rb +13 -0
  52. data/lib/rex/exceptions.rb +275 -0
  53. data/lib/rex/exceptions.rb.ut.rb +44 -0
  54. data/lib/rex/exploitation/cmdstager.rb +9 -0
  55. data/lib/rex/exploitation/cmdstager/base.rb +175 -0
  56. data/lib/rex/exploitation/cmdstager/debug_asm.rb +142 -0
  57. data/lib/rex/exploitation/cmdstager/debug_write.rb +136 -0
  58. data/lib/rex/exploitation/cmdstager/tftp.rb +63 -0
  59. data/lib/rex/exploitation/cmdstager/vbs.rb +128 -0
  60. data/lib/rex/exploitation/egghunter.rb +277 -0
  61. data/lib/rex/exploitation/egghunter.rb.ut.rb +25 -0
  62. data/lib/rex/exploitation/encryptjs.rb +77 -0
  63. data/lib/rex/exploitation/heaplib.js.b64 +331 -0
  64. data/lib/rex/exploitation/heaplib.rb +94 -0
  65. data/lib/rex/exploitation/javascriptosdetect.rb +897 -0
  66. data/lib/rex/exploitation/obfuscatejs.rb +335 -0
  67. data/lib/rex/exploitation/omelet.rb +320 -0
  68. data/lib/rex/exploitation/omelet.rb.ut.rb +13 -0
  69. data/lib/rex/exploitation/opcodedb.rb +818 -0
  70. data/lib/rex/exploitation/opcodedb.rb.ut.rb +279 -0
  71. data/lib/rex/exploitation/seh.rb +92 -0
  72. data/lib/rex/exploitation/seh.rb.ut.rb +19 -0
  73. data/lib/rex/file.rb +112 -0
  74. data/lib/rex/file.rb.ut.rb +16 -0
  75. data/lib/rex/image_source.rb +12 -0
  76. data/lib/rex/image_source/disk.rb +60 -0
  77. data/lib/rex/image_source/image_source.rb +46 -0
  78. data/lib/rex/image_source/memory.rb +37 -0
  79. data/lib/rex/io/bidirectional_pipe.rb +157 -0
  80. data/lib/rex/io/datagram_abstraction.rb +35 -0
  81. data/lib/rex/io/ring_buffer.rb +364 -0
  82. data/lib/rex/io/stream.rb +319 -0
  83. data/lib/rex/io/stream_abstraction.rb +197 -0
  84. data/lib/rex/io/stream_server.rb +211 -0
  85. data/lib/rex/job_container.rb +187 -0
  86. data/lib/rex/logging.rb +4 -0
  87. data/lib/rex/logging/log_dispatcher.rb +179 -0
  88. data/lib/rex/logging/log_sink.rb +42 -0
  89. data/lib/rex/logging/sinks/flatfile.rb +55 -0
  90. data/lib/rex/logging/sinks/stderr.rb +43 -0
  91. data/lib/rex/machparsey.rb +9 -0
  92. data/lib/rex/machparsey/exceptions.rb +34 -0
  93. data/lib/rex/machparsey/mach.rb +209 -0
  94. data/lib/rex/machparsey/machbase.rb +408 -0
  95. data/lib/rex/machscan.rb +9 -0
  96. data/lib/rex/machscan/scanner.rb +217 -0
  97. data/lib/rex/mime.rb +9 -0
  98. data/lib/rex/mime/header.rb +77 -0
  99. data/lib/rex/mime/message.rb +144 -0
  100. data/lib/rex/mime/part.rb +20 -0
  101. data/lib/rex/nop/opty2.rb +108 -0
  102. data/lib/rex/nop/opty2.rb.ut.rb +23 -0
  103. data/lib/rex/nop/opty2_tables.rb +300 -0
  104. data/lib/rex/ole.rb +205 -0
  105. data/lib/rex/ole/clsid.rb +47 -0
  106. data/lib/rex/ole/difat.rb +141 -0
  107. data/lib/rex/ole/directory.rb +231 -0
  108. data/lib/rex/ole/direntry.rb +240 -0
  109. data/lib/rex/ole/docs/dependencies.txt +8 -0
  110. data/lib/rex/ole/docs/references.txt +1 -0
  111. data/lib/rex/ole/fat.rb +99 -0
  112. data/lib/rex/ole/header.rb +204 -0
  113. data/lib/rex/ole/minifat.rb +77 -0
  114. data/lib/rex/ole/propset.rb +144 -0
  115. data/lib/rex/ole/samples/create_ole.rb +27 -0
  116. data/lib/rex/ole/samples/dir.rb +35 -0
  117. data/lib/rex/ole/samples/dump_stream.rb +34 -0
  118. data/lib/rex/ole/samples/ole_info.rb +23 -0
  119. data/lib/rex/ole/storage.rb +395 -0
  120. data/lib/rex/ole/stream.rb +53 -0
  121. data/lib/rex/ole/substorage.rb +49 -0
  122. data/lib/rex/ole/util.rb +157 -0
  123. data/lib/rex/parser/arguments.rb +97 -0
  124. data/lib/rex/parser/arguments.rb.ut.rb +67 -0
  125. data/lib/rex/parser/ini.rb +185 -0
  126. data/lib/rex/parser/ini.rb.ut.rb +29 -0
  127. data/lib/rex/parser/ip360_aspl_xml.rb +102 -0
  128. data/lib/rex/parser/ip360_xml.rb +97 -0
  129. data/lib/rex/parser/nessus_xml.rb +118 -0
  130. data/lib/rex/parser/netsparker_xml.rb +94 -0
  131. data/lib/rex/parser/nexpose_xml.rb +136 -0
  132. data/lib/rex/parser/nmap_xml.rb +137 -0
  133. data/lib/rex/parser/retina_xml.rb +109 -0
  134. data/lib/rex/payloads.rb +1 -0
  135. data/lib/rex/payloads/win32.rb +2 -0
  136. data/lib/rex/payloads/win32/common.rb +26 -0
  137. data/lib/rex/payloads/win32/kernel.rb +53 -0
  138. data/lib/rex/payloads/win32/kernel/common.rb +54 -0
  139. data/lib/rex/payloads/win32/kernel/migration.rb +12 -0
  140. data/lib/rex/payloads/win32/kernel/recovery.rb +50 -0
  141. data/lib/rex/payloads/win32/kernel/stager.rb +194 -0
  142. data/lib/rex/peparsey.rb +12 -0
  143. data/lib/rex/peparsey/exceptions.rb +32 -0
  144. data/lib/rex/peparsey/pe.rb +212 -0
  145. data/lib/rex/peparsey/pe_memdump.rb +63 -0
  146. data/lib/rex/peparsey/pebase.rb +1680 -0
  147. data/lib/rex/peparsey/section.rb +136 -0
  148. data/lib/rex/pescan.rb +13 -0
  149. data/lib/rex/pescan/analyze.rb +309 -0
  150. data/lib/rex/pescan/scanner.rb +206 -0
  151. data/lib/rex/pescan/search.rb +56 -0
  152. data/lib/rex/platforms.rb +1 -0
  153. data/lib/rex/platforms/windows.rb +51 -0
  154. data/lib/rex/poly.rb +132 -0
  155. data/lib/rex/poly/block.rb +477 -0
  156. data/lib/rex/poly/register.rb +100 -0
  157. data/lib/rex/poly/register/x86.rb +40 -0
  158. data/lib/rex/post.rb +8 -0
  159. data/lib/rex/post/dir.rb +51 -0
  160. data/lib/rex/post/file.rb +172 -0
  161. data/lib/rex/post/file_stat.rb +220 -0
  162. data/lib/rex/post/gen.pl +13 -0
  163. data/lib/rex/post/io.rb +182 -0
  164. data/lib/rex/post/meterpreter.rb +4 -0
  165. data/lib/rex/post/meterpreter/channel.rb +445 -0
  166. data/lib/rex/post/meterpreter/channel_container.rb +54 -0
  167. data/lib/rex/post/meterpreter/channels/pool.rb +160 -0
  168. data/lib/rex/post/meterpreter/channels/pools/file.rb +62 -0
  169. data/lib/rex/post/meterpreter/channels/pools/stream_pool.rb +103 -0
  170. data/lib/rex/post/meterpreter/channels/stream.rb +87 -0
  171. data/lib/rex/post/meterpreter/client.rb +364 -0
  172. data/lib/rex/post/meterpreter/client_core.rb +274 -0
  173. data/lib/rex/post/meterpreter/dependencies.rb +3 -0
  174. data/lib/rex/post/meterpreter/extension.rb +32 -0
  175. data/lib/rex/post/meterpreter/extensions/espia/espia.rb +58 -0
  176. data/lib/rex/post/meterpreter/extensions/espia/tlv.rb +16 -0
  177. data/lib/rex/post/meterpreter/extensions/incognito/incognito.rb +94 -0
  178. data/lib/rex/post/meterpreter/extensions/incognito/tlv.rb +21 -0
  179. data/lib/rex/post/meterpreter/extensions/networkpug/networkpug.rb +57 -0
  180. data/lib/rex/post/meterpreter/extensions/networkpug/tlv.rb +15 -0
  181. data/lib/rex/post/meterpreter/extensions/priv/fs.rb +118 -0
  182. data/lib/rex/post/meterpreter/extensions/priv/passwd.rb +61 -0
  183. data/lib/rex/post/meterpreter/extensions/priv/priv.rb +111 -0
  184. data/lib/rex/post/meterpreter/extensions/priv/tlv.rb +28 -0
  185. data/lib/rex/post/meterpreter/extensions/sniffer/sniffer.rb +101 -0
  186. data/lib/rex/post/meterpreter/extensions/sniffer/tlv.rb +26 -0
  187. data/lib/rex/post/meterpreter/extensions/stdapi/constants.rb +333 -0
  188. data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +282 -0
  189. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +266 -0
  190. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file_stat.rb +103 -0
  191. data/lib/rex/post/meterpreter/extensions/stdapi/fs/io.rb +48 -0
  192. data/lib/rex/post/meterpreter/extensions/stdapi/net/config.rb +144 -0
  193. data/lib/rex/post/meterpreter/extensions/stdapi/net/interface.rb +73 -0
  194. data/lib/rex/post/meterpreter/extensions/stdapi/net/route.rb +56 -0
  195. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +137 -0
  196. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +180 -0
  197. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb +167 -0
  198. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +208 -0
  199. data/lib/rex/post/meterpreter/extensions/stdapi/railgun.rb.ts.rb +6 -0
  200. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb +38106 -0
  201. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb.ut.rb +31 -0
  202. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb +47 -0
  203. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb.ut.rb +36 -0
  204. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_advapi32.rb +1818 -0
  205. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_iphlpapi.rb +96 -0
  206. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +3848 -0
  207. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_netapi32.rb +26 -0
  208. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ntdll.rb +153 -0
  209. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_shell32.rb +21 -0
  210. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_user32.rb +3169 -0
  211. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ws2_32.rb +599 -0
  212. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb +318 -0
  213. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb +100 -0
  214. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb.ut.rb +42 -0
  215. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb +148 -0
  216. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb.ut.rb +127 -0
  217. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/multicall.rb +309 -0
  218. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb +204 -0
  219. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/tlv.rb +51 -0
  220. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb +630 -0
  221. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb +75 -0
  222. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb.ut.rb +103 -0
  223. data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +149 -0
  224. data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +97 -0
  225. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +192 -0
  226. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log_subsystem/event_record.rb +41 -0
  227. data/lib/rex/post/meterpreter/extensions/stdapi/sys/power.rb +61 -0
  228. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +370 -0
  229. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/image.rb +129 -0
  230. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/io.rb +55 -0
  231. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/memory.rb +336 -0
  232. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/thread.rb +141 -0
  233. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +279 -0
  234. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +193 -0
  235. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_value.rb +102 -0
  236. data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +180 -0
  237. data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +211 -0
  238. data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +227 -0
  239. data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +63 -0
  240. data/lib/rex/post/meterpreter/inbound_packet_handler.rb +30 -0
  241. data/lib/rex/post/meterpreter/object_aliases.rb +83 -0
  242. data/lib/rex/post/meterpreter/packet.rb +688 -0
  243. data/lib/rex/post/meterpreter/packet_dispatcher.rb +431 -0
  244. data/lib/rex/post/meterpreter/packet_parser.rb +94 -0
  245. data/lib/rex/post/meterpreter/packet_response_waiter.rb +83 -0
  246. data/lib/rex/post/meterpreter/ui/console.rb +137 -0
  247. data/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb +62 -0
  248. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +730 -0
  249. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/espia.rb +108 -0
  250. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/incognito.rb +241 -0
  251. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/networkpug.rb +231 -0
  252. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv.rb +61 -0
  253. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +98 -0
  254. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/passwd.rb +51 -0
  255. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +132 -0
  256. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +187 -0
  257. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi.rb +65 -0
  258. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +442 -0
  259. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +298 -0
  260. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +486 -0
  261. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +315 -0
  262. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +157 -0
  263. data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +95 -0
  264. data/lib/rex/post/permission.rb +26 -0
  265. data/lib/rex/post/process.rb +57 -0
  266. data/lib/rex/post/thread.rb +57 -0
  267. data/lib/rex/post/ui.rb +52 -0
  268. data/lib/rex/proto.rb +13 -0
  269. data/lib/rex/proto.rb.ts.rb +8 -0
  270. data/lib/rex/proto/dcerpc.rb +6 -0
  271. data/lib/rex/proto/dcerpc.rb.ts.rb +9 -0
  272. data/lib/rex/proto/dcerpc/client.rb +361 -0
  273. data/lib/rex/proto/dcerpc/client.rb.ut.rb +491 -0
  274. data/lib/rex/proto/dcerpc/exceptions.rb +150 -0
  275. data/lib/rex/proto/dcerpc/handle.rb +47 -0
  276. data/lib/rex/proto/dcerpc/handle.rb.ut.rb +85 -0
  277. data/lib/rex/proto/dcerpc/ndr.rb +72 -0
  278. data/lib/rex/proto/dcerpc/ndr.rb.ut.rb +41 -0
  279. data/lib/rex/proto/dcerpc/packet.rb +253 -0
  280. data/lib/rex/proto/dcerpc/packet.rb.ut.rb +56 -0
  281. data/lib/rex/proto/dcerpc/response.rb +187 -0
  282. data/lib/rex/proto/dcerpc/response.rb.ut.rb +15 -0
  283. data/lib/rex/proto/dcerpc/uuid.rb +84 -0
  284. data/lib/rex/proto/dcerpc/uuid.rb.ut.rb +46 -0
  285. data/lib/rex/proto/dhcp.rb +7 -0
  286. data/lib/rex/proto/dhcp/constants.rb +33 -0
  287. data/lib/rex/proto/dhcp/server.rb +292 -0
  288. data/lib/rex/proto/drda.rb +5 -0
  289. data/lib/rex/proto/drda.rb.ts.rb +17 -0
  290. data/lib/rex/proto/drda/constants.rb +49 -0
  291. data/lib/rex/proto/drda/constants.rb.ut.rb +23 -0
  292. data/lib/rex/proto/drda/packet.rb +252 -0
  293. data/lib/rex/proto/drda/packet.rb.ut.rb +109 -0
  294. data/lib/rex/proto/drda/utils.rb +123 -0
  295. data/lib/rex/proto/drda/utils.rb.ut.rb +84 -0
  296. data/lib/rex/proto/http.rb +5 -0
  297. data/lib/rex/proto/http.rb.ts.rb +12 -0
  298. data/lib/rex/proto/http/client.rb +821 -0
  299. data/lib/rex/proto/http/client.rb.ut.rb +95 -0
  300. data/lib/rex/proto/http/handler.rb +46 -0
  301. data/lib/rex/proto/http/handler/erb.rb +128 -0
  302. data/lib/rex/proto/http/handler/erb.rb.ut.rb +21 -0
  303. data/lib/rex/proto/http/handler/erb.rb.ut.rb.rhtml +1 -0
  304. data/lib/rex/proto/http/handler/proc.rb +60 -0
  305. data/lib/rex/proto/http/handler/proc.rb.ut.rb +24 -0
  306. data/lib/rex/proto/http/header.rb +161 -0
  307. data/lib/rex/proto/http/header.rb.ut.rb +46 -0
  308. data/lib/rex/proto/http/packet.rb +407 -0
  309. data/lib/rex/proto/http/packet.rb.ut.rb +165 -0
  310. data/lib/rex/proto/http/request.rb +356 -0
  311. data/lib/rex/proto/http/request.rb.ut.rb +214 -0
  312. data/lib/rex/proto/http/response.rb +90 -0
  313. data/lib/rex/proto/http/response.rb.ut.rb +149 -0
  314. data/lib/rex/proto/http/server.rb +369 -0
  315. data/lib/rex/proto/http/server.rb.ut.rb +79 -0
  316. data/lib/rex/proto/ntlm.rb +7 -0
  317. data/lib/rex/proto/ntlm.rb.ut.rb +177 -0
  318. data/lib/rex/proto/ntlm/base.rb +326 -0
  319. data/lib/rex/proto/ntlm/constants.rb +74 -0
  320. data/lib/rex/proto/ntlm/crypt.rb +415 -0
  321. data/lib/rex/proto/ntlm/exceptions.rb +16 -0
  322. data/lib/rex/proto/ntlm/message.rb +536 -0
  323. data/lib/rex/proto/ntlm/utils.rb +764 -0
  324. data/lib/rex/proto/proxy/socks4a.rb +440 -0
  325. data/lib/rex/proto/rfb.rb +19 -0
  326. data/lib/rex/proto/rfb.rb.ut.rb +37 -0
  327. data/lib/rex/proto/rfb/cipher.rb +84 -0
  328. data/lib/rex/proto/rfb/client.rb +207 -0
  329. data/lib/rex/proto/rfb/constants.rb +52 -0
  330. data/lib/rex/proto/smb.rb +7 -0
  331. data/lib/rex/proto/smb.rb.ts.rb +8 -0
  332. data/lib/rex/proto/smb/client.rb +1952 -0
  333. data/lib/rex/proto/smb/client.rb.ut.rb +223 -0
  334. data/lib/rex/proto/smb/constants.rb +1047 -0
  335. data/lib/rex/proto/smb/constants.rb.ut.rb +18 -0
  336. data/lib/rex/proto/smb/crypt.rb +36 -0
  337. data/lib/rex/proto/smb/evasions.rb +66 -0
  338. data/lib/rex/proto/smb/exceptions.rb +858 -0
  339. data/lib/rex/proto/smb/simpleclient.rb +306 -0
  340. data/lib/rex/proto/smb/simpleclient.rb.ut.rb +128 -0
  341. data/lib/rex/proto/smb/utils.rb +103 -0
  342. data/lib/rex/proto/smb/utils.rb.ut.rb +20 -0
  343. data/lib/rex/proto/sunrpc.rb +1 -0
  344. data/lib/rex/proto/sunrpc/client.rb +195 -0
  345. data/lib/rex/proto/tftp.rb +12 -0
  346. data/lib/rex/proto/tftp/constants.rb +39 -0
  347. data/lib/rex/proto/tftp/server.rb +497 -0
  348. data/lib/rex/proto/tftp/server.rb.ut.rb +28 -0
  349. data/lib/rex/script.rb +42 -0
  350. data/lib/rex/script/base.rb +59 -0
  351. data/lib/rex/script/meterpreter.rb +15 -0
  352. data/lib/rex/script/shell.rb +9 -0
  353. data/lib/rex/service.rb +48 -0
  354. data/lib/rex/service_manager.rb +141 -0
  355. data/lib/rex/service_manager.rb.ut.rb +32 -0
  356. data/lib/rex/services/local_relay.rb +423 -0
  357. data/lib/rex/socket.rb +684 -0
  358. data/lib/rex/socket.rb.ut.rb +107 -0
  359. data/lib/rex/socket/comm.rb +119 -0
  360. data/lib/rex/socket/comm/local.rb +412 -0
  361. data/lib/rex/socket/comm/local.rb.ut.rb +75 -0
  362. data/lib/rex/socket/ip.rb +130 -0
  363. data/lib/rex/socket/parameters.rb +345 -0
  364. data/lib/rex/socket/parameters.rb.ut.rb +51 -0
  365. data/lib/rex/socket/range_walker.rb +346 -0
  366. data/lib/rex/socket/range_walker.rb.ut.rb +55 -0
  367. data/lib/rex/socket/ssl_tcp.rb +184 -0
  368. data/lib/rex/socket/ssl_tcp.rb.ut.rb +39 -0
  369. data/lib/rex/socket/ssl_tcp_server.rb +122 -0
  370. data/lib/rex/socket/ssl_tcp_server.rb.ut.rb +61 -0
  371. data/lib/rex/socket/subnet_walker.rb +75 -0
  372. data/lib/rex/socket/subnet_walker.rb.ut.rb +28 -0
  373. data/lib/rex/socket/switch_board.rb +278 -0
  374. data/lib/rex/socket/switch_board.rb.ut.rb +52 -0
  375. data/lib/rex/socket/tcp.rb +76 -0
  376. data/lib/rex/socket/tcp.rb.ut.rb +64 -0
  377. data/lib/rex/socket/tcp_server.rb +66 -0
  378. data/lib/rex/socket/tcp_server.rb.ut.rb +44 -0
  379. data/lib/rex/socket/udp.rb +164 -0
  380. data/lib/rex/socket/udp.rb.ut.rb +44 -0
  381. data/lib/rex/struct2.rb +5 -0
  382. data/lib/rex/struct2/c_struct.rb +181 -0
  383. data/lib/rex/struct2/c_struct_template.rb +39 -0
  384. data/lib/rex/struct2/constant.rb +26 -0
  385. data/lib/rex/struct2/element.rb +44 -0
  386. data/lib/rex/struct2/generic.rb +73 -0
  387. data/lib/rex/struct2/restraint.rb +54 -0
  388. data/lib/rex/struct2/s_string.rb +72 -0
  389. data/lib/rex/struct2/s_struct.rb +111 -0
  390. data/lib/rex/sync.rb +6 -0
  391. data/lib/rex/sync/event.rb +94 -0
  392. data/lib/rex/sync/read_write_lock.rb +176 -0
  393. data/lib/rex/sync/ref.rb +57 -0
  394. data/lib/rex/sync/thread_safe.rb +82 -0
  395. data/lib/rex/test.rb +35 -0
  396. data/lib/rex/text.rb +1163 -0
  397. data/lib/rex/text.rb.ut.rb +190 -0
  398. data/lib/rex/thread_factory.rb +42 -0
  399. data/lib/rex/time.rb +65 -0
  400. data/lib/rex/transformer.rb +115 -0
  401. data/lib/rex/transformer.rb.ut.rb +38 -0
  402. data/lib/rex/ui.rb +21 -0
  403. data/lib/rex/ui/interactive.rb +298 -0
  404. data/lib/rex/ui/output.rb +78 -0
  405. data/lib/rex/ui/output/none.rb +18 -0
  406. data/lib/rex/ui/progress_tracker.rb +96 -0
  407. data/lib/rex/ui/subscriber.rb +149 -0
  408. data/lib/rex/ui/text/color.rb +97 -0
  409. data/lib/rex/ui/text/color.rb.ut.rb +18 -0
  410. data/lib/rex/ui/text/dispatcher_shell.rb +467 -0
  411. data/lib/rex/ui/text/input.rb +117 -0
  412. data/lib/rex/ui/text/input/buffer.rb +75 -0
  413. data/lib/rex/ui/text/input/readline.rb +129 -0
  414. data/lib/rex/ui/text/input/socket.rb +95 -0
  415. data/lib/rex/ui/text/input/stdio.rb +45 -0
  416. data/lib/rex/ui/text/irb_shell.rb +57 -0
  417. data/lib/rex/ui/text/output.rb +80 -0
  418. data/lib/rex/ui/text/output/buffer.rb +61 -0
  419. data/lib/rex/ui/text/output/file.rb +43 -0
  420. data/lib/rex/ui/text/output/socket.rb +43 -0
  421. data/lib/rex/ui/text/output/stdio.rb +40 -0
  422. data/lib/rex/ui/text/progress_tracker.rb +56 -0
  423. data/lib/rex/ui/text/progress_tracker.rb.ut.rb +34 -0
  424. data/lib/rex/ui/text/shell.rb +328 -0
  425. data/lib/rex/ui/text/table.rb +279 -0
  426. data/lib/rex/ui/text/table.rb.ut.rb +55 -0
  427. data/lib/rex/zip.rb +93 -0
  428. data/lib/rex/zip/archive.rb +184 -0
  429. data/lib/rex/zip/blocks.rb +182 -0
  430. data/lib/rex/zip/entry.rb +104 -0
  431. data/lib/rex/zip/samples/comment.rb +32 -0
  432. data/lib/rex/zip/samples/mkwar.rb +138 -0
  433. data/lib/rex/zip/samples/mkzip.rb +19 -0
  434. data/lib/rex/zip/samples/recursive.rb +58 -0
  435. metadata +434 -1
@@ -0,0 +1,176 @@
1
+ require 'thread'
2
+
3
+ module Rex
4
+
5
+ ###
6
+ #
7
+ # This class implements a read/write lock synchronization
8
+ # primitive. It is meant to allow for more efficient access to
9
+ # resources that are more often read from than written to and many
10
+ # times can have concurrent reader threads. By allowing the reader
11
+ # threads to lock the resource concurrently rather than serially,
12
+ # a large performance boost can be seen. Acquiring a write lock
13
+ # results in exclusive access to the resource and thereby prevents
14
+ # any read operations during the time that a write lock is acquired.
15
+ # Only one write lock may be acquired at a time.
16
+ #
17
+ ###
18
+ class ReadWriteLock
19
+
20
+ #
21
+ # Initializes a reader/writer lock instance.
22
+ #
23
+ def initialize
24
+ @read_sync_mutex = Mutex.new
25
+ @write_sync_mutex = Mutex.new
26
+ @exclusive_mutex = Mutex.new
27
+ @readers = 0
28
+ @writer = false
29
+ end
30
+
31
+ #
32
+ # Acquires the read lock for the calling thread.
33
+ #
34
+ def lock_read
35
+ read_sync_mutex.lock
36
+
37
+ begin
38
+ # If there are a non-zero number of readers and a
39
+ # writer is waiting to acquire the exclusive lock,
40
+ # free up the sync mutex temporarily and lock/unlock
41
+ # the exclusive lock. This is to give the writer
42
+ # thread a chance to acquire the lock and prevents
43
+ # it from being constantly starved.
44
+ if ((@readers > 0) and
45
+ (@writer))
46
+ read_sync_mutex.unlock
47
+ exclusive_mutex.lock
48
+ exclusive_mutex.unlock
49
+ read_sync_mutex.lock
50
+ end
51
+
52
+ # Increment the active reader count
53
+ @readers += 1
54
+
55
+ # If we now have just one reader, acquire the exclusive
56
+ # lock. Track the thread owner so that we release the
57
+ # lock from within the same thread context later on.
58
+ if (@readers == 1)
59
+ exclusive_mutex.lock
60
+
61
+ @owner = Thread.current
62
+ end
63
+ ensure
64
+ read_sync_mutex.unlock
65
+ end
66
+ end
67
+
68
+ #
69
+ # Releases the read lock for the calling thread.
70
+ #
71
+ def unlock_read
72
+ read_sync_mutex.lock
73
+
74
+ begin
75
+ unlocked = false
76
+
77
+ # Keep looping until we've lost this thread's reader
78
+ # lock
79
+ while (!unlocked)
80
+ # If there are no more readers left after this one
81
+ if (@readers - 1 == 0)
82
+ # If the calling thread is the owner of the exclusive
83
+ # reader lock, then let's release it
84
+ if (Thread.current == @owner)
85
+ @owner = nil
86
+
87
+ exclusive_mutex.unlock
88
+ end
89
+ # If there is more than one reader left and this thread is
90
+ # the owner of the exclusive lock, then keep looping so that
91
+ # we can eventually unlock the exclusive mutex in this thread's
92
+ # context
93
+ elsif (Thread.current == @owner)
94
+ read_sync_mutex.unlock
95
+
96
+ next
97
+ end
98
+
99
+ # Unlocked!
100
+ unlocked = true
101
+
102
+ # Decrement the active reader count
103
+ @readers -= 1
104
+ end
105
+ ensure
106
+ read_sync_mutex.unlock
107
+ end
108
+ end
109
+
110
+ #
111
+ # Acquire the exclusive write lock.
112
+ #
113
+ def lock_write
114
+ write_sync_mutex.lock
115
+
116
+ begin
117
+ @writer = true
118
+
119
+ exclusive_mutex.lock
120
+
121
+ @owner = Thread.current
122
+ ensure
123
+ write_sync_mutex.unlock
124
+ end
125
+ end
126
+
127
+ #
128
+ # Release the exclusive write lock.
129
+ #
130
+ def unlock_write
131
+ # If the caller is not the owner of the write lock, then someone is
132
+ # doing something broken, let's let them know.
133
+ if (Thread.current != @owner)
134
+ raise RuntimeError, "Non-owner calling thread attempted to release write lock", caller
135
+ end
136
+
137
+ # Otherwise, release the exclusive write lock
138
+ @writer = false
139
+
140
+ exclusive_mutex.unlock
141
+ end
142
+
143
+ #
144
+ # Synchronize a block for read access.
145
+ #
146
+ def synchronize_read
147
+ lock_read
148
+ begin
149
+ yield
150
+ ensure
151
+ unlock_read
152
+ end
153
+ end
154
+
155
+ #
156
+ # Synchronize a block for write access.
157
+ #
158
+ def synchronize_write
159
+ lock_write
160
+ begin
161
+ yield
162
+ ensure
163
+ unlock_write
164
+ end
165
+ end
166
+
167
+ protected
168
+
169
+ attr_accessor :read_sync_mutex # :nodoc:
170
+ attr_accessor :write_sync_mutex # :nodoc:
171
+ attr_accessor :exclusive_mutex # :nodoc:
172
+
173
+ end
174
+
175
+ end
176
+
@@ -0,0 +1,57 @@
1
+ require 'thread'
2
+
3
+ module Rex
4
+
5
+ ###
6
+ #
7
+ # This module provides a uniform reference counted interface for classes to
8
+ # use.
9
+ #
10
+ ###
11
+ module Ref
12
+
13
+ #
14
+ # Initializes the reference count to one.
15
+ #
16
+ def refinit
17
+ @_references = 1
18
+ @_references_mutex = Mutex.new
19
+
20
+ self
21
+ end
22
+
23
+ #
24
+ # Increments the total number of references.
25
+ #
26
+ def ref
27
+ @_references_mutex.synchronize {
28
+ @_references += 1
29
+ }
30
+
31
+ self
32
+ end
33
+
34
+ #
35
+ # Decrements the total number of references. If the reference count
36
+ # reaches zero, true is returned. Otherwise, false is returned.
37
+ #
38
+ def deref
39
+ @_references_mutex.synchronize {
40
+ if ((@_references -= 1) == 0)
41
+ cleanup
42
+
43
+ true
44
+ else
45
+ false
46
+ end
47
+ }
48
+ end
49
+
50
+ #
51
+ # Called to clean up resources once the ref count drops to zero.
52
+ #
53
+ def cleanup
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,82 @@
1
+ require 'timeout'
2
+
3
+ module Rex
4
+
5
+ ###
6
+ #
7
+ # This module provides a set of methods for performing various blocking
8
+ # operations in a manner that is compatible with ruby style threads.
9
+ #
10
+ ###
11
+ module ThreadSafe
12
+
13
+ DefaultCycle = 0.2
14
+
15
+ #
16
+ # Wraps calls to select with a lower timeout period and does the
17
+ # calculations to walk down to zero timeout. This has a little room for
18
+ # improvement in that it should probably check how much time actually
19
+ # elapsed during the select call considering ruby threading wont be exactly
20
+ # accurate perhaps.
21
+ #
22
+ def self.select(rfd = nil, wfd = nil, efd = nil, t = nil)
23
+ left = t
24
+
25
+ # Immediately raise a StreamClosedError if the socket was closed. This
26
+ # prevents a bad fd from being passed downstream and solves an issue
27
+ # with Ruby on Windows.
28
+ rfd.each { |fd| raise StreamClosedError.new(fd) if (fd.closed?) } if rfd
29
+
30
+ begin
31
+ orig_size = rfd.length if (rfd)
32
+
33
+ # Poll the set supplied to us at least once.
34
+ begin
35
+ rv = ::IO.select(rfd, wfd, efd, DefaultCycle)
36
+ rescue ::IOError, ::Errno::EBADF, ::Errno::ENOTSOCK
37
+ # If a stream was detected as being closed, re-raise the error as
38
+ # a StreamClosedError with the specific file descriptor that was
39
+ # detected as being closed. This is to better handle the case of
40
+ # a closed socket being detected so that it can be cleaned up and
41
+ # removed.
42
+ rfd.each { |fd| raise StreamClosedError.new(fd) if (fd.closed?) } if rfd
43
+
44
+ # If the original rfd length is not the same as the current
45
+ # length, then the list may have been altered and as such may not
46
+ # contain the socket that caused the IOError. This is a bad way
47
+ # to do this since it's possible that the array length could be
48
+ # back to the size that it was originally and yet have had the
49
+ # socket that caused the IOError to be removed.
50
+ return nil if (rfd and rfd.length != orig_size)
51
+
52
+ # Re-raise the exception since we didn't handle it here.
53
+ raise $!
54
+ # rescue ::Exception => e
55
+ # $stderr.puts "SELECT(#{t}) #{[rfd,wfd,efd].inspect} #{e.class} #{e} #{e.backtrace}"
56
+ end
57
+
58
+ return rv if (rv)
59
+
60
+ # Decrement the amount of time left by the polling cycle
61
+ left -= DefaultCycle if (left)
62
+
63
+ # Keep chugging until we run out of time, if time was supplied.
64
+ end while ((left == nil) or (left > 0))
65
+
66
+ # Nothin.
67
+ nil
68
+ end
69
+
70
+ #
71
+ # Simulates a sleep operation by selecting on nil until a timeout period
72
+ # expires.
73
+ #
74
+ def self.sleep(seconds)
75
+ self.select(nil, nil, nil, seconds)
76
+
77
+ seconds
78
+ end
79
+
80
+ end
81
+
82
+ end
@@ -0,0 +1,35 @@
1
+ require 'test/unit'
2
+
3
+ # DEFAULTS
4
+ module Rex
5
+ class Test
6
+
7
+ $_REX_TEST_NO_MOCK = nil
8
+ $_REX_TEST_TIMEOUT = 30
9
+ $_REX_TEST_SMB_HOST = '10.4.10.58'
10
+ $_REX_TEXT_SMB_USER = 'SMBTest'
11
+ $_REX_TEXT_SMB_PASS = 'SMBTest'
12
+
13
+ # overwrite test defaults with rex/test-config.rb
14
+ def self.load()
15
+ file = File.join( ENV.fetch('HOME'), '.msf3', 'test')
16
+ begin
17
+ if File.stat(file + '.rb')
18
+ require file
19
+ end
20
+ rescue
21
+ # just ignore the errors
22
+ end
23
+
24
+ end
25
+
26
+ def self.cantmock()
27
+ if (!$_REX_TEST_NO_MOCK)
28
+ raise RuntimeError, "*** $_REX_TEST_NO_MOCK must not be set for this test ***", caller
29
+ end
30
+ end
31
+
32
+ Rex::Test.load()
33
+
34
+ end
35
+ end
@@ -0,0 +1,1163 @@
1
+ require 'digest/md5'
2
+ require 'stringio'
3
+
4
+ begin
5
+ require 'iconv'
6
+ require 'zlib'
7
+ rescue LoadError
8
+ end
9
+
10
+ module Rex
11
+
12
+ ###
13
+ #
14
+ # This class formats text in various fashions and also provides
15
+ # a mechanism for wrapping text at a given column.
16
+ #
17
+ ###
18
+ module Text
19
+ @@codepage_map_cache = nil
20
+
21
+ ##
22
+ #
23
+ # Constants
24
+ #
25
+ ##
26
+
27
+ States = ["AK", "AL", "AR", "AZ", "CA", "CO", "CT", "DE", "FL", "GA", "HI",
28
+ "IA", "ID", "IL", "IN", "KS", "KY", "LA", "MA", "MD", "ME", "MI", "MN",
29
+ "MO", "MS", "MT", "NC", "ND", "NE", "NH", "NJ", "NM", "NV", "NY", "OH",
30
+ "OK", "OR", "PA", "RI", "SC", "SD", "TN", "TX", "UT", "VA", "VT", "WA",
31
+ "WI", "WV", "WY"]
32
+ UpperAlpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
33
+ LowerAlpha = "abcdefghijklmnopqrstuvwxyz"
34
+ Numerals = "0123456789"
35
+ Alpha = UpperAlpha + LowerAlpha
36
+ AlphaNumeric = Alpha + Numerals
37
+ HighAscii = [*(0x80 .. 0xff)].pack("C*")
38
+ DefaultWrap = 60
39
+ AllChars = [*(0x00 .. 0xff)].pack("C*")
40
+
41
+ DefaultPatternSets = [ Rex::Text::UpperAlpha, Rex::Text::LowerAlpha, Rex::Text::Numerals ]
42
+
43
+ # In case Iconv isn't loaded
44
+ Iconv_EBCDIC = ["\x00", "\x01", "\x02", "\x03", "7", "-", ".", "/", "\x16", "\x05", "%", "\v", "\f", "\r", "\x0E", "\x0F", "\x10", "\x11", "\x12", "\x13", "<", "=", "2", "&", "\x18", "\x19", "?", "'", "\x1C", "\x1D", "\x1E", "\x1F", "@", "Z", "\x7F", "{", "[", "l", "P", "}", "M", "]", "\\", "N", "k", "`", "K", "a", "\xF0", "\xF1", "\xF2", "\xF3", "\xF4", "\xF5", "\xF6", "\xF7", "\xF8", "\xF9", "z", "^", "L", "~", "n", "o", "|", "\xC1", "\xC2", "\xC3", "\xC4", "\xC5", "\xC6", "\xC7", "\xC8", "\xC9", "\xD1", "\xD2", "\xD3", "\xD4", "\xD5", "\xD6", "\xD7", "\xD8", "\xD9", "\xE2", "\xE3", "\xE4", "\xE5", "\xE6", "\xE7", "\xE8", "\xE9", nil, "\xE0", nil, nil, "m", "y", "\x81", "\x82", "\x83", "\x84", "\x85", "\x86", "\x87", "\x88", "\x89", "\x91", "\x92", "\x93", "\x94", "\x95", "\x96", "\x97", "\x98", "\x99", "\xA2", "\xA3", "\xA4", "\xA5", "\xA6", "\xA7", "\xA8", "\xA9", "\xC0", "O", "\xD0", "\xA1", "\a", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
45
+ Iconv_ASCII = ["\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\a", "\b", "\t", "\n", "\v", "\f", "\r", "\x0E", "\x0F", "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", "\x18", "\x19", "\x1A", "\e", "\x1C", "\x1D", "\x1E", "\x1F", " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", nil, "\\", nil, nil, "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "\x7F", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
46
+
47
+ ##
48
+ #
49
+ # Serialization
50
+ #
51
+ ##
52
+
53
+ #
54
+ # Converts a raw string into a ruby buffer
55
+ #
56
+ def self.to_ruby(str, wrap = DefaultWrap, name = "buf")
57
+ return hexify(str, wrap, '"', '" +', "#{name} = \n", '"')
58
+ end
59
+
60
+ #
61
+ # Creates a ruby-style comment
62
+ #
63
+ def self.to_ruby_comment(str, wrap = DefaultWrap)
64
+ return wordwrap(str, 0, wrap, '', '# ')
65
+ end
66
+
67
+ #
68
+ # Converts a raw string into a C buffer
69
+ #
70
+ def self.to_c(str, wrap = DefaultWrap, name = "buf")
71
+ return hexify(str, wrap, '"', '"', "unsigned char #{name}[] = \n", '";')
72
+ end
73
+
74
+ #
75
+ # Creates a c-style comment
76
+ #
77
+ def self.to_c_comment(str, wrap = DefaultWrap)
78
+ return "/*\n" + wordwrap(str, 0, wrap, '', ' * ') + " */\n"
79
+ end
80
+
81
+ #
82
+ # Creates a javascript-style comment
83
+ #
84
+ def self.to_js_comment(str, wrap = DefaultWrap)
85
+ return wordwrap(str, 0, wrap, '', '// ')
86
+ end
87
+
88
+ #
89
+ # Converts a raw string into a perl buffer
90
+ #
91
+ def self.to_perl(str, wrap = DefaultWrap, name = "buf")
92
+ return hexify(str, wrap, '"', '" .', "my $#{name} = \n", '";')
93
+ end
94
+
95
+ #
96
+ # Converts a raw string into a java byte array
97
+ #
98
+ def self.to_java(str, name = "shell")
99
+ buff = "byte #{name}[] = new byte[]\n{\n"
100
+ cnt = 0
101
+ max = 0
102
+ str.unpack('C*').each do |c|
103
+ buff << ", " if max > 0
104
+ buff << "\t" if max == 0
105
+ buff << sprintf('(byte) 0x%.2x', c)
106
+ max +=1
107
+ cnt +=1
108
+
109
+ if (max > 7)
110
+ buff << ",\n" if cnt != str.length
111
+ max = 0
112
+ end
113
+ end
114
+ buff << "\n};\n"
115
+ return buff
116
+ end
117
+
118
+ #
119
+ # Creates a perl-style comment
120
+ #
121
+ def self.to_perl_comment(str, wrap = DefaultWrap)
122
+ return wordwrap(str, 0, wrap, '', '# ')
123
+ end
124
+
125
+ #
126
+ # Returns the raw string
127
+ #
128
+ def self.to_raw(str)
129
+ return str
130
+ end
131
+
132
+ #
133
+ # Converts ISO-8859-1 to UTF-8
134
+ #
135
+ def self.to_utf8(str)
136
+ begin
137
+ Iconv.iconv("utf-8","iso-8859-1", str).join(" ")
138
+ rescue
139
+ raise ::RuntimeError, "Your installation does not support iconv (needed for utf8 conversion)"
140
+ end
141
+ end
142
+
143
+ #
144
+ # Converts ASCII to EBCDIC
145
+ #
146
+ class IllegalSequence < ArgumentError; end
147
+
148
+ # A native implementation of the ASCII->EBCDIC table, used to fall back from using
149
+ # Iconv
150
+ def self.to_ebcdic_rex(str)
151
+ new_str = []
152
+ str.each_byte do |x|
153
+ if Iconv_ASCII.index(x.chr)
154
+ new_str << Iconv_EBCDIC[Iconv_ASCII.index(x.chr)]
155
+ else
156
+ raise Rex::Text::IllegalSequence, ("\\x%x" % x)
157
+ end
158
+ end
159
+ new_str.join
160
+ end
161
+
162
+ # A native implementation of the EBCDIC->ASCII table, used to fall back from using
163
+ # Iconv
164
+ def self.from_ebcdic_rex(str)
165
+ new_str = []
166
+ str.each_byte do |x|
167
+ if Iconv_EBCDIC.index(x.chr)
168
+ new_str << Iconv_ASCII[Iconv_EBCDIC.index(x.chr)]
169
+ else
170
+ raise Rex::Text::IllegalSequence, ("\\x%x" % x)
171
+ end
172
+ end
173
+ new_str.join
174
+ end
175
+
176
+ def self.to_ebcdic(str)
177
+ begin
178
+ Iconv.iconv("EBCDIC-US", "ASCII", str).first
179
+ rescue ::Iconv::IllegalSequence => e
180
+ raise e
181
+ rescue
182
+ self.to_ebcdic_rex(str)
183
+ end
184
+ end
185
+
186
+ #
187
+ # Converts EBCIDC to ASCII
188
+ #
189
+ def self.from_ebcdic(str)
190
+ begin
191
+ Iconv.iconv("ASCII", "EBCDIC-US", str).first
192
+ rescue ::Iconv::IllegalSequence => e
193
+ raise e
194
+ rescue
195
+ self.from_ebcdic_rex(str)
196
+ end
197
+ end
198
+
199
+ #
200
+ # Returns a unicode escaped string for Javascript
201
+ #
202
+ def self.to_unescape(data, endian=ENDIAN_LITTLE)
203
+ data << "\x41" if (data.length % 2 != 0)
204
+ dptr = 0
205
+ buff = ''
206
+ while (dptr < data.length)
207
+ c1 = data[dptr,1].unpack("C*")[0]
208
+ dptr += 1
209
+ c2 = data[dptr,1].unpack("C*")[0]
210
+ dptr += 1
211
+
212
+ if (endian == ENDIAN_LITTLE)
213
+ buff << sprintf('%%u%.2x%.2x', c2, c1)
214
+ else
215
+ buff << sprintf('%%u%.2x%.2x', c1, c2)
216
+ end
217
+ end
218
+ return buff
219
+ end
220
+
221
+ #
222
+ # Returns the hex version of the supplied string
223
+ #
224
+ def self.to_hex(str, prefix = "\\x", count = 1)
225
+ raise ::RuntimeError, "unable to chunk into #{count} byte chunks" if ((str.length % count) > 0)
226
+
227
+ # XXX: Regexp.new is used here since using /.{#{count}}/o would compile
228
+ # the regex the first time it is used and never check again. Since we
229
+ # want to know how many to capture on every instance, we do it this
230
+ # way.
231
+ return str.unpack('H*')[0].gsub(Regexp.new(".{#{count * 2}}", nil, 'n')) { |s| prefix + s }
232
+ end
233
+
234
+ #
235
+ # Returns the string with nonprintable hex characters sanitized to ascii. Similiar to to_hex,
236
+ # but regular ASCII is not translated if count is 1.
237
+ #
238
+ def self.to_hex_ascii(str, prefix = "\\x", count = 1, suffix=nil)
239
+ raise ::RuntimeError, "unable to chunk into #{count} byte chunks" if ((str.length % count) > 0)
240
+ return str.unpack('H*')[0].gsub(Regexp.new(".{#{count * 2}}", nil, 'n')) { |s|
241
+ (0x20..0x7e) === s.to_i(16) ? s.to_i(16).chr : prefix + s + suffix.to_s
242
+ }
243
+ end
244
+
245
+ #
246
+ # Converts standard ASCII text to a unicode string.
247
+ #
248
+ # Supported unicode types include: utf-16le, utf16-be, utf32-le, utf32-be, utf-7, and utf-8
249
+ #
250
+ # Providing 'mode' provides hints to the actual encoder as to how it should encode the string. Only UTF-7 and UTF-8 use "mode".
251
+ #
252
+ # utf-7 by default does not encode alphanumeric and a few other characters. By specifying the mode of "all", then all of the characters are encoded, not just the non-alphanumeric set.
253
+ # to_unicode(str, 'utf-7', 'all')
254
+ #
255
+ # utf-8 specifies that alphanumeric characters are used directly, eg "a" is just "a". However, there exist 6 different overlong encodings of "a" that are technically not valid, but parse just fine in most utf-8 parsers. (0xC1A1, 0xE081A1, 0xF08081A1, 0xF8808081A1, 0xFC80808081A1, 0xFE8080808081A1). How many bytes to use for the overlong enocding is specified providing 'size'.
256
+ # to_unicode(str, 'utf-8', 'overlong', 2)
257
+ #
258
+ # Many utf-8 parsers also allow invalid overlong encodings, where bits that are unused when encoding a single byte are modified. Many parsers will ignore these bits, rendering simple string matching to be ineffective for dealing with UTF-8 strings. There are many more invalid overlong encodings possible for "a". For example, three encodings are available for an invalid 2 byte encoding of "a". (0xC1E1 0xC161 0xC121). By specifying "invalid", a random invalid encoding is chosen for the given byte size.
259
+ # to_unicode(str, 'utf-8', 'invalid', 2)
260
+ #
261
+ # utf-7 defaults to 'normal' utf-7 encoding
262
+ # utf-8 defaults to 2 byte 'normal' encoding
263
+ #
264
+ def self.to_unicode(str='', type = 'utf-16le', mode = '', size = '')
265
+ return '' if not str
266
+ case type
267
+ when 'utf-16le'
268
+ return str.unpack('C*').pack('v*')
269
+ when 'utf-16be'
270
+ return str.unpack('C*').pack('n*')
271
+ when 'utf-32le'
272
+ return str.unpack('C*').pack('V*')
273
+ when 'utf-32be'
274
+ return str.unpack('C*').pack('N*')
275
+ when 'utf-7'
276
+ case mode
277
+ when 'all'
278
+ return str.gsub(/./){ |a|
279
+ out = ''
280
+ if 'a' != '+'
281
+ out = encode_base64(to_unicode(a, 'utf-16be')).gsub(/[=\r\n]/, '')
282
+ end
283
+ '+' + out + '-'
284
+ }
285
+ else
286
+ return str.gsub(/[^\n\r\t\ A-Za-z0-9\'\(\),-.\/\:\?]/){ |a|
287
+ out = ''
288
+ if a != '+'
289
+ out = encode_base64(to_unicode(a, 'utf-16be')).gsub(/[=\r\n]/, '')
290
+ end
291
+ '+' + out + '-'
292
+ }
293
+ end
294
+ when 'utf-8'
295
+ if size == ''
296
+ size = 2
297
+ end
298
+
299
+ if size >= 2 and size <= 7
300
+ string = ''
301
+ str.each_byte { |a|
302
+ if (a < 21 || a > 0x7f) || mode != ''
303
+ # ugh. turn a single byte into the binary representation of it, in array form
304
+ bin = [a].pack('C').unpack('B8')[0].split(//)
305
+
306
+ # even more ugh.
307
+ bin.collect!{|a_| a_.to_i}
308
+
309
+ out = Array.new(8 * size, 0)
310
+
311
+ 0.upto(size - 1) { |i|
312
+ out[i] = 1
313
+ out[i * 8] = 1
314
+ }
315
+
316
+ i = 0
317
+ byte = 0
318
+ bin.reverse.each { |bit|
319
+ if i < 6
320
+ mod = (((size * 8) - 1) - byte * 8) - i
321
+ out[mod] = bit
322
+ else
323
+ byte = byte + 1
324
+ i = 0
325
+ redo
326
+ end
327
+ i = i + 1
328
+ }
329
+
330
+ if mode != ''
331
+ case mode
332
+ when 'overlong'
333
+ # do nothing, since we already handle this as above...
334
+ when 'invalid'
335
+ done = 0
336
+ while done == 0
337
+ # the ghetto...
338
+ bits = [7, 8, 15, 16, 23, 24, 31, 32, 41]
339
+ bits.each { |bit|
340
+ bit = (size * 8) - bit
341
+ if bit > 1
342
+ set = rand(2)
343
+ if out[bit] != set
344
+ out[bit] = set
345
+ done = 1
346
+ end
347
+ end
348
+ }
349
+ end
350
+ else
351
+ raise TypeError, 'Invalid mode. Only "overlong" and "invalid" are acceptable modes for utf-8'
352
+ end
353
+ end
354
+ string << [out.join('')].pack('B*')
355
+ else
356
+ string << [a].pack('C')
357
+ end
358
+ }
359
+ return string
360
+ else
361
+ raise TypeError, 'invalid utf-8 size'
362
+ end
363
+ when 'uhwtfms' # suggested name from HD :P
364
+ load_codepage()
365
+
366
+ string = ''
367
+ # overloading mode as codepage
368
+ if mode == ''
369
+ mode = 1252 # ANSI - Latan 1, default for US installs of MS products
370
+ else
371
+ mode = mode.to_i
372
+ end
373
+ if @@codepage_map_cache[mode].nil?
374
+ raise TypeError, "Invalid codepage #{mode}"
375
+ end
376
+ str.each_byte {|byte|
377
+ char = [byte].pack('C*')
378
+ possible = @@codepage_map_cache[mode]['data'][char]
379
+ if possible.nil?
380
+ raise TypeError, "codepage #{mode} does not provide an encoding for 0x#{char.unpack('H*')[0]}"
381
+ end
382
+ string << possible[ rand(possible.length) ]
383
+ }
384
+ return string
385
+ when 'uhwtfms-half' # suggested name from HD :P
386
+ load_codepage()
387
+ string = ''
388
+ # overloading mode as codepage
389
+ if mode == ''
390
+ mode = 1252 # ANSI - Latan 1, default for US installs of MS products
391
+ else
392
+ mode = mode.to_i
393
+ end
394
+ if mode != 1252
395
+ raise TypeError, "Invalid codepage #{mode}, only 1252 supported for uhwtfms_half"
396
+ end
397
+ str.each_byte {|byte|
398
+ if ((byte >= 33 && byte <= 63) || (byte >= 96 && byte <= 126))
399
+ string << "\xFF" + [byte ^ 32].pack('C')
400
+ elsif (byte >= 64 && byte <= 95)
401
+ string << "\xFF" + [byte ^ 96].pack('C')
402
+ else
403
+ char = [byte].pack('C')
404
+ possible = @@codepage_map_cache[mode]['data'][char]
405
+ if possible.nil?
406
+ raise TypeError, "codepage #{mode} does not provide an encoding for 0x#{char.unpack('H*')[0]}"
407
+ end
408
+ string << possible[ rand(possible.length) ]
409
+ end
410
+ }
411
+ return string
412
+ else
413
+ raise TypeError, 'invalid utf type'
414
+ end
415
+ end
416
+
417
+ #
418
+ # Converts a unicode string to standard ASCII text.
419
+ #
420
+ def self.to_ascii(str='', type = 'utf-16le', mode = '', size = '')
421
+ return '' if not str
422
+ case type
423
+ when 'utf-16le'
424
+ return str.unpack('v*').pack('C*')
425
+ when 'utf-16be'
426
+ return str.unpack('n*').pack('C*')
427
+ when 'utf-32le'
428
+ return str.unpack('V*').pack('C*')
429
+ when 'utf-32be'
430
+ return str.unpack('N*').pack('C*')
431
+ when 'utf-7'
432
+ raise TypeError, 'invalid utf type, not yet implemented'
433
+ when 'utf-8'
434
+ raise TypeError, 'invalid utf type, not yet implemented'
435
+ when 'uhwtfms' # suggested name from HD :P
436
+ raise TypeError, 'invalid utf type, not yet implemented'
437
+ when 'uhwtfms-half' # suggested name from HD :P
438
+ raise TypeError, 'invalid utf type, not yet implemented'
439
+ else
440
+ raise TypeError, 'invalid utf type'
441
+ end
442
+ end
443
+
444
+ #
445
+ # Encode a string in a manor useful for HTTP URIs and URI Parameters.
446
+ #
447
+ def self.uri_encode(str, mode = 'hex-normal')
448
+ return "" if str == nil
449
+
450
+ return str if mode == 'none' # fast track no encoding
451
+
452
+ all = /[^\/\\]+/
453
+ normal = /[^a-zA-Z0-9\/\\\.\-]+/
454
+ normal_na = /[a-zA-Z0-9\/\\\.\-]/
455
+
456
+ case mode
457
+ when 'hex-normal'
458
+ return str.gsub(normal) { |s| Rex::Text.to_hex(s, '%') }
459
+ when 'hex-all'
460
+ return str.gsub(all) { |s| Rex::Text.to_hex(s, '%') }
461
+ when 'hex-random'
462
+ res = ''
463
+ str.each_byte do |c|
464
+ b = c.chr
465
+ res << ((rand(2) == 0) ?
466
+ b.gsub(all) { |s| Rex::Text.to_hex(s, '%') } :
467
+ b.gsub(normal){ |s| Rex::Text.to_hex(s, '%') } )
468
+ end
469
+ return res
470
+ when 'u-normal'
471
+ return str.gsub(normal) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) }
472
+ when 'u-all'
473
+ return str.gsub(all) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) }
474
+ when 'u-random'
475
+ res = ''
476
+ str.each_byte do |c|
477
+ b = c.chr
478
+ res << ((rand(2) == 0) ?
479
+ b.gsub(all) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) } :
480
+ b.gsub(normal){ |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms'), '%u', 2) } )
481
+ end
482
+ return res
483
+ when 'u-half'
484
+ return str.gsub(all) { |s| Rex::Text.to_hex(Rex::Text.to_unicode(s, 'uhwtfms-half'), '%u', 2) }
485
+ else
486
+ raise TypeError, 'invalid mode'
487
+ end
488
+ end
489
+
490
+ #
491
+ # Encode a string in a manner useful for HTTP URIs and URI Parameters.
492
+ #
493
+ def self.html_encode(str, mode = 'hex')
494
+ case mode
495
+ when 'hex'
496
+ return str.unpack('C*').collect{ |i| "&#x" + ("%.2x" % i) + ";"}.join
497
+ when 'int'
498
+ return str.unpack('C*').collect{ |i| "&#" + i.to_s + ";"}.join
499
+ when 'int-wide'
500
+ return str.unpack('C*').collect{ |i| "&#" + ("0" * (7 - i.to_s.length)) + i.to_s + ";" }.join
501
+ else
502
+ raise TypeError, 'invalid mode'
503
+ end
504
+ end
505
+
506
+ #
507
+ # Encode an ASCII string so it's safe for XML. It's a wrapper for to_hex_ascii.
508
+ #
509
+ def self.xml_char_encode(str)
510
+ self.to_hex_ascii(str, "&#x", 1, ";")
511
+ end
512
+
513
+ #
514
+ # Decode a URI encoded string
515
+ #
516
+ def self.uri_decode(str)
517
+ str.gsub(/(%[a-z0-9]{2})/i){ |c| [c[1,2]].pack("H*") }
518
+ end
519
+
520
+ #
521
+ # Converts a string to random case
522
+ #
523
+ def self.to_rand_case(str)
524
+ buf = str.dup
525
+ 0.upto(str.length) do |i|
526
+ buf[i,1] = rand(2) == 0 ? str[i,1].upcase : str[i,1].downcase
527
+ end
528
+ return buf
529
+ end
530
+
531
+ #
532
+ # Takes a string, and returns an array of all mixed case versions.
533
+ #
534
+ # Example:
535
+ #
536
+ # >> Rex::Text.to_mixed_case_array "abc1"
537
+ # => ["abc1", "abC1", "aBc1", "aBC1", "Abc1", "AbC1", "ABc1", "ABC1"]
538
+ #
539
+ def self.to_mixed_case_array(str)
540
+ letters = []
541
+ str.scan(/./).each { |l| letters << [l.downcase, l.upcase] }
542
+ coords = []
543
+ (1 << str.size).times { |i| coords << ("%0#{str.size}b" % i) }
544
+ mixed = []
545
+ coords.each do |coord|
546
+ c = coord.scan(/./).map {|x| x.to_i}
547
+ this_str = ""
548
+ c.each_with_index { |d,i| this_str << letters[i][d] }
549
+ mixed << this_str
550
+ end
551
+ return mixed.uniq
552
+ end
553
+
554
+ #
555
+ # Converts a string a nicely formatted hex dump
556
+ #
557
+ def self.to_hex_dump(str, width=16)
558
+ buf = ''
559
+ idx = 0
560
+ cnt = 0
561
+ snl = false
562
+ lst = 0
563
+
564
+ while (idx < str.length)
565
+
566
+ chunk = str[idx, width]
567
+ line = chunk.unpack("H*")[0].scan(/../).join(" ")
568
+ buf << line
569
+
570
+ if (lst == 0)
571
+ lst = line.length
572
+ buf << " " * 4
573
+ else
574
+ buf << " " * ((lst - line.length) + 4).abs
575
+ end
576
+
577
+ chunk.unpack("C*").each do |c|
578
+ if (c > 0x1f and c < 0x7f)
579
+ buf << c.chr
580
+ else
581
+ buf << "."
582
+ end
583
+ end
584
+
585
+ buf << "\n"
586
+
587
+ idx += width
588
+ end
589
+
590
+ buf << "\n"
591
+ end
592
+
593
+ #
594
+ # Converts a hex string to a raw string
595
+ #
596
+ def self.hex_to_raw(str)
597
+ [ str.downcase.gsub(/'/,'').gsub(/\\?x([a-f0-9][a-f0-9])/, '\1') ].pack("H*")
598
+ end
599
+
600
+ #
601
+ # Turn non-printable chars into hex representations, leaving others alone
602
+ #
603
+ # If +whitespace+ is true, converts whitespace (0x20, 0x09, etc) to hex as
604
+ # well.
605
+ #
606
+ def self.ascii_safe_hex(str, whitespace=false)
607
+ if whitespace
608
+ str.gsub(/([\x00-\x20\x80-\xFF])/){ |x| "\\x%.2x" % x.unpack("C*")[0] }
609
+ else
610
+ str.gsub(/([\x00-\x08\x0b\x0c\x0e-\x1f\x80-\xFF])/n){ |x| "\\x%.2x" % x.unpack("C*")[0]}
611
+ end
612
+ end
613
+
614
+ #
615
+ # Wraps text at a given column using a supplied indention
616
+ #
617
+ def self.wordwrap(str, indent = 0, col = DefaultWrap, append = '', prepend = '')
618
+ return str.gsub(/.{1,#{col - indent}}(?:\s|\Z)/){
619
+ ( (" " * indent) + prepend + $& + append + 5.chr).gsub(/\n\005/,"\n").gsub(/\005/,"\n")}
620
+ end
621
+
622
+ #
623
+ # Converts a string to a hex version with wrapping support
624
+ #
625
+ def self.hexify(str, col = DefaultWrap, line_start = '', line_end = '', buf_start = '', buf_end = '')
626
+ output = buf_start
627
+ cur = 0
628
+ count = 0
629
+ new_line = true
630
+
631
+ # Go through each byte in the string
632
+ str.each_byte { |byte|
633
+ count += 1
634
+ append = ''
635
+
636
+ # If this is a new line, prepend with the
637
+ # line start text
638
+ if (new_line == true)
639
+ append << line_start
640
+ new_line = false
641
+ end
642
+
643
+ # Append the hexified version of the byte
644
+ append << sprintf("\\x%.2x", byte)
645
+ cur += append.length
646
+
647
+ # If we're about to hit the column or have gone past it,
648
+ # time to finish up this line
649
+ if ((cur + line_end.length >= col) or (cur + buf_end.length >= col))
650
+ new_line = true
651
+ cur = 0
652
+
653
+ # If this is the last byte, use the buf_end instead of
654
+ # line_end
655
+ if (count == str.length)
656
+ append << buf_end + "\n"
657
+ else
658
+ append << line_end + "\n"
659
+ end
660
+ end
661
+
662
+ output << append
663
+ }
664
+
665
+ # If we were in the middle of a line, finish the buffer at this point
666
+ if (new_line == false)
667
+ output << buf_end + "\n"
668
+ end
669
+
670
+ return output
671
+ end
672
+
673
+ ##
674
+ #
675
+ # Transforms
676
+ #
677
+ ##
678
+
679
+ #
680
+ # Base64 encoder
681
+ #
682
+ def self.encode_base64(str, delim='')
683
+ [str].pack("m").gsub(/\s+/, delim)
684
+ end
685
+
686
+ #
687
+ # Base64 decoder
688
+ #
689
+ def self.decode_base64(str)
690
+ str.unpack("m")[0]
691
+ end
692
+
693
+ #
694
+ # Raw MD5 digest of the supplied string
695
+ #
696
+ def self.md5_raw(str)
697
+ Digest::MD5.digest(str)
698
+ end
699
+
700
+ #
701
+ # Hexidecimal MD5 digest of the supplied string
702
+ #
703
+ def self.md5(str)
704
+ Digest::MD5.hexdigest(str)
705
+ end
706
+
707
+
708
+ ##
709
+ #
710
+ # Generators
711
+ #
712
+ ##
713
+
714
+
715
+ # Generates a random character.
716
+ def self.rand_char(bad, chars = AllChars)
717
+ rand_text(1, bad, chars)
718
+ end
719
+
720
+ # Base text generator method
721
+ def self.rand_base(len, bad, *foo)
722
+ cset = (foo.join.unpack("C*") - bad.to_s.unpack("C*")).uniq
723
+ return "" if cset.length == 0
724
+ outp = []
725
+ len.times { outp << cset[rand(cset.length)] }
726
+ outp.pack("C*")
727
+ end
728
+
729
+ # Generate random bytes of data
730
+ def self.rand_text(len, bad='', chars = AllChars)
731
+ foo = chars.split('')
732
+ rand_base(len, bad, *foo)
733
+ end
734
+
735
+ # Generate random bytes of alpha data
736
+ def self.rand_text_alpha(len, bad='')
737
+ foo = []
738
+ foo += ('A' .. 'Z').to_a
739
+ foo += ('a' .. 'z').to_a
740
+ rand_base(len, bad, *foo )
741
+ end
742
+
743
+ # Generate random bytes of lowercase alpha data
744
+ def self.rand_text_alpha_lower(len, bad='')
745
+ rand_base(len, bad, *('a' .. 'z').to_a)
746
+ end
747
+
748
+ # Generate random bytes of uppercase alpha data
749
+ def self.rand_text_alpha_upper(len, bad='')
750
+ rand_base(len, bad, *('A' .. 'Z').to_a)
751
+ end
752
+
753
+ # Generate random bytes of alphanumeric data
754
+ def self.rand_text_alphanumeric(len, bad='')
755
+ foo = []
756
+ foo += ('A' .. 'Z').to_a
757
+ foo += ('a' .. 'z').to_a
758
+ foo += ('0' .. '9').to_a
759
+ rand_base(len, bad, *foo )
760
+ end
761
+
762
+ # Generate random bytes of alphanumeric hex.
763
+ def self.rand_text_hex(len, bad='')
764
+ foo = []
765
+ foo += ('0' .. '9').to_a
766
+ foo += ('a' .. 'f').to_a
767
+ rand_base(len, bad, *foo)
768
+ end
769
+
770
+ # Generate random bytes of numeric data
771
+ def self.rand_text_numeric(len, bad='')
772
+ foo = ('0' .. '9').to_a
773
+ rand_base(len, bad, *foo )
774
+ end
775
+
776
+ # Generate random bytes of english-like data
777
+ def self.rand_text_english(len, bad='')
778
+ foo = []
779
+ foo += (0x21 .. 0x7e).map{ |c| c.chr }
780
+ rand_base(len, bad, *foo )
781
+ end
782
+
783
+ # Generate random bytes of high ascii data
784
+ def self.rand_text_highascii(len, bad='')
785
+ foo = []
786
+ foo += (0x80 .. 0xff).map{ |c| c.chr }
787
+ rand_base(len, bad, *foo )
788
+ end
789
+
790
+ #
791
+ # Creates a pattern that can be used for offset calculation purposes. This
792
+ # routine is capable of generating patterns using a supplied set and a
793
+ # supplied number of identifiable characters (slots). The supplied sets
794
+ # should not contain any duplicate characters or the logic will fail.
795
+ #
796
+ def self.pattern_create(length, sets = nil)
797
+ buf = ''
798
+ idx = 0
799
+ offsets = []
800
+
801
+ # Make sure there's something in sets even if we were given an explicit nil
802
+ sets ||= [ UpperAlpha, LowerAlpha, Numerals ]
803
+
804
+ # Return stupid uses
805
+ return "" if length.to_i < 1
806
+ return sets[0][0] * length if sets.size == 1 and sets[0].size == 1
807
+
808
+ sets.length.times { offsets << 0 }
809
+
810
+ until buf.length >= length
811
+ begin
812
+ buf << converge_sets(sets, 0, offsets, length)
813
+ end
814
+ end
815
+
816
+ # Maximum permutations reached, but we need more data
817
+ if (buf.length < length)
818
+ buf = buf * (length / buf.length.to_f).ceil
819
+ end
820
+
821
+ buf[0,length]
822
+ end
823
+
824
+ # Step through an arbitrary number of sets of bytes to build up a findable pattern.
825
+ # This is mostly useful for experimentially determining offset lengths into memory
826
+ # structures. Note that the supplied sets should never contain duplicate bytes, or
827
+ # else it can become impossible to measure the offset accurately.
828
+ def self.patt2(len, sets = nil)
829
+ buf = ""
830
+ counter = []
831
+ sets ||= [ UpperAlpha, LowerAlpha, Numerals ]
832
+ len ||= len.to_i
833
+ return "" if len.zero?
834
+
835
+ sets = sets.map {|a| a.split(//)}
836
+ sets.size.times { counter << 0}
837
+ 0.upto(len-1) do |i|
838
+ setnum = i % sets.size
839
+
840
+ puts counter.inspect
841
+ end
842
+
843
+ return buf
844
+ end
845
+
846
+ #
847
+ # Calculate the offset to a pattern
848
+ #
849
+ def self.pattern_offset(pattern, value, start=0)
850
+ if (value.kind_of?(String))
851
+ pattern.index(value, start)
852
+ elsif (value.kind_of?(Fixnum) or value.kind_of?(Bignum))
853
+ pattern.index([ value ].pack('V'), start)
854
+ else
855
+ raise ::ArgumentError, "Invalid class for value: #{value.class}"
856
+ end
857
+ end
858
+
859
+ #
860
+ # Compresses a string, eliminating all superfluous whitespace before and
861
+ # after lines and eliminating all lines.
862
+ #
863
+ def self.compress(str)
864
+ str.gsub(/\n/m, ' ').gsub(/\s+/, ' ').gsub(/^\s+/, '').gsub(/\s+$/, '')
865
+ end
866
+
867
+ #
868
+ # Randomize the whitespace in a string
869
+ #
870
+ def self.randomize_space(str)
871
+ str.gsub(/\s+/) { |s|
872
+ len = rand(50)+2
873
+ set = "\x09\x20\x0d\x0a"
874
+ buf = ''
875
+ while (buf.length < len)
876
+ buf << set[rand(set.length),1]
877
+ end
878
+
879
+ buf
880
+ }
881
+ end
882
+
883
+ # Returns true if zlib can be used.
884
+ def self.zlib_present?
885
+ begin
886
+ temp = Zlib
887
+ return true
888
+ rescue
889
+ return false
890
+ end
891
+ end
892
+
893
+ # backwards compat for just a bit...
894
+ def self.gzip_present?
895
+ self.zlib_present?
896
+ end
897
+
898
+ #
899
+ # Compresses a string using zlib
900
+ #
901
+ def self.zlib_deflate(str, level = Zlib::BEST_COMPRESSION)
902
+ if self.zlib_present?
903
+ z = Zlib::Deflate.new(level)
904
+ dst = z.deflate(str, Zlib::FINISH)
905
+ z.close
906
+ return dst
907
+ else
908
+ raise RuntimeError, "Gzip support is not present."
909
+ end
910
+ end
911
+
912
+ #
913
+ # Uncompresses a string using zlib
914
+ #
915
+ def self.zlib_inflate(str)
916
+ if(self.zlib_present?)
917
+ zstream = Zlib::Inflate.new
918
+ buf = zstream.inflate(str)
919
+ zstream.finish
920
+ zstream.close
921
+ return buf
922
+ else
923
+ raise RuntimeError, "Gzip support is not present."
924
+ end
925
+ end
926
+
927
+ #
928
+ # Compresses a string using gzip
929
+ #
930
+ def self.gzip(str, level = 9)
931
+ raise RuntimeError, "Gzip support is not present." if (!zlib_present?)
932
+ raise RuntimeError, "Invalid gzip compression level" if (level < 1 or level > 9)
933
+
934
+ s = ""
935
+ s.force_encoding('ASCII-8BIT') if s.respond_to?(:encoding)
936
+ gz = Zlib::GzipWriter.new(StringIO.new(s, 'wb'), level)
937
+ gz << str
938
+ gz.close
939
+ return s
940
+ end
941
+
942
+ #
943
+ # Uncompresses a string using gzip
944
+ #
945
+ def self.ungzip(str)
946
+ raise RuntimeError, "Gzip support is not present." if (!zlib_present?)
947
+
948
+ s = ""
949
+ s.force_encoding('ASCII-8BIT') if s.respond_to?(:encoding)
950
+ gz = Zlib::GzipReader.new(StringIO.new(str, 'rb'))
951
+ s << gz.read
952
+ gz.close
953
+ return s
954
+ end
955
+
956
+ #
957
+ # Return the index of the first badchar in data, otherwise return
958
+ # nil if there wasn't any badchar occurences.
959
+ #
960
+ def self.badchar_index(data, badchars = '')
961
+ badchars.unpack("C*").each { |badchar|
962
+ pos = data.index(badchar.chr)
963
+ return pos if pos
964
+ }
965
+ return nil
966
+ end
967
+
968
+ #
969
+ # This method removes bad characters from a string.
970
+ #
971
+ def self.remove_badchars(data, badchars = '')
972
+ data.delete(badchars)
973
+ end
974
+
975
+ #
976
+ # This method returns all chars but the supplied set
977
+ #
978
+ def self.charset_exclude(keepers)
979
+ [*(0..255)].pack('C*').delete(keepers)
980
+ end
981
+
982
+ #
983
+ # Shuffles a byte stream
984
+ #
985
+ def self.shuffle_s(str)
986
+ shuffle_a(str.unpack("C*")).pack("C*")
987
+ end
988
+
989
+ #
990
+ # Performs a Fisher-Yates shuffle on an array
991
+ #
992
+ def self.shuffle_a(arr)
993
+ len = arr.length
994
+ max = len - 1
995
+ cyc = [* (0..max) ]
996
+ for d in cyc
997
+ e = rand(d+1)
998
+ next if e == d
999
+ f = arr[d];
1000
+ g = arr[e];
1001
+ arr[d] = g;
1002
+ arr[e] = f;
1003
+ end
1004
+ return arr
1005
+ end
1006
+
1007
+ # Permute the case of a word
1008
+ def self.permute_case(word, idx=0)
1009
+ res = []
1010
+
1011
+ if( (UpperAlpha+LowerAlpha).index(word[idx,1]))
1012
+
1013
+ word_ucase = word.dup
1014
+ word_ucase[idx, 1] = word[idx, 1].upcase
1015
+
1016
+ word_lcase = word.dup
1017
+ word_lcase[idx, 1] = word[idx, 1].downcase
1018
+
1019
+ if (idx == word.length)
1020
+ return [word]
1021
+ else
1022
+ res << permute_case(word_ucase, idx+1)
1023
+ res << permute_case(word_lcase, idx+1)
1024
+ end
1025
+ else
1026
+ res << permute_case(word, idx+1)
1027
+ end
1028
+
1029
+ res.flatten
1030
+ end
1031
+
1032
+ # Generate a random hostname
1033
+ def self.rand_hostname
1034
+ host = []
1035
+ (rand(5) + 1).times {
1036
+ host.push(Rex::Text.rand_text_alphanumeric(rand(10) + 1))
1037
+ }
1038
+ d = ['com', 'net', 'org', 'gov']
1039
+ host.push(d[rand(d.size)])
1040
+ host.join('.').downcase
1041
+ end
1042
+
1043
+ # Generate a state
1044
+ def self.rand_state()
1045
+ States[rand(States.size)]
1046
+ end
1047
+
1048
+
1049
+ #
1050
+ # Calculate the ROR13 hash of a given string
1051
+ #
1052
+ def self.ror13_hash(name)
1053
+ hash = 0
1054
+ name.unpack("C*").each {|c| hash = ror(hash, 13); hash += c }
1055
+ hash
1056
+ end
1057
+
1058
+ #
1059
+ # Rotate a 32-bit value to the right by cnt bits
1060
+ #
1061
+ def self.ror(val, cnt)
1062
+ bits = [val].pack("N").unpack("B32")[0].split(//)
1063
+ 1.upto(cnt) do |c|
1064
+ bits.unshift( bits.pop )
1065
+ end
1066
+ [bits.join].pack("B32").unpack("N")[0]
1067
+ end
1068
+
1069
+ #
1070
+ # Rotate a 32-bit value to the left by cnt bits
1071
+ #
1072
+ def self.rol(val, cnt)
1073
+ bits = [val].pack("N").unpack("B32")[0].split(//)
1074
+ 1.upto(cnt) do |c|
1075
+ bits.push( bits.shift )
1076
+ end
1077
+ [bits.join].pack("B32").unpack("N")[0]
1078
+ end
1079
+
1080
+ #
1081
+ # Split a string by n charachter into an array
1082
+ #
1083
+ def self.split_to_a(str, n)
1084
+ if n > 0
1085
+ s = str.dup
1086
+ until s.empty?
1087
+ (ret ||= []).push s.slice!(0, n)
1088
+ end
1089
+ else
1090
+ ret = str
1091
+ end
1092
+ ret
1093
+ end
1094
+
1095
+ #
1096
+ #Pack a value as 64 bit litle endian; does not exist for Array.pack
1097
+ #
1098
+ def self.pack_int64le(val)
1099
+ [val & 0x00000000ffffffff, val >> 32].pack("V2")
1100
+ end
1101
+
1102
+
1103
+ protected
1104
+
1105
+ def self.converge_sets(sets, idx, offsets, length) # :nodoc:
1106
+ buf = sets[idx][offsets[idx]].chr
1107
+
1108
+ # If there are more sets after use, converage with them.
1109
+ if (sets[idx + 1])
1110
+ buf << converge_sets(sets, idx + 1, offsets, length)
1111
+ else
1112
+ # Increment the current set offset as well as previous ones if we
1113
+ # wrap back to zero.
1114
+ while (idx >= 0 and ((offsets[idx] = (offsets[idx] + 1) % sets[idx].length)) == 0)
1115
+ idx -= 1
1116
+ end
1117
+
1118
+ # If we reached the point where the idx fell below zero, then that
1119
+ # means we've reached the maximum threshold for permutations.
1120
+ if (idx < 0)
1121
+ return buf
1122
+ end
1123
+
1124
+ end
1125
+
1126
+ buf
1127
+ end
1128
+
1129
+ def self.load_codepage()
1130
+ return if (!@@codepage_map_cache.nil?)
1131
+ file = File.join(File.dirname(__FILE__),'codepage.map')
1132
+ page = ''
1133
+ name = ''
1134
+ map = {}
1135
+ File.open(file).each { |line|
1136
+ next if line =~ /^#/
1137
+ next if line =~ /^\s*$/
1138
+ data = line.split
1139
+ if data[1] =~ /^\(/
1140
+ page = data.shift.to_i
1141
+ name = data.join(' ').sub(/^\(/,'').sub(/\)$/,'')
1142
+ map[page] = {}
1143
+ map[page]['name'] = name
1144
+ map[page]['data'] = {}
1145
+ else
1146
+ data.each { |entry|
1147
+ wide, char = entry.split(':')
1148
+ char = [char].pack('H*')
1149
+ wide = [wide].pack('H*')
1150
+ if map[page]['data'][char].nil?
1151
+ map[page]['data'][char] = [wide]
1152
+ else
1153
+ map[page]['data'][char].push(wide)
1154
+ end
1155
+ }
1156
+ end
1157
+ }
1158
+ @@codepage_map_cache = map
1159
+ end
1160
+
1161
+ end
1162
+ end
1163
+