librex 0.0.18 → 0.0.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (435) hide show
  1. data/Rakefile +2 -2
  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
data/lib/rex/test.rb ADDED
@@ -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
data/lib/rex/text.rb ADDED
@@ -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
+