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,123 @@
1
+ require 'rex/proto/drda'
2
+
3
+ module Rex
4
+ module Proto
5
+ module DRDA
6
+ class Utils
7
+
8
+ # Creates a packet with EXCSAT_DDM and an ACCSEC_DDM. This will elicit
9
+ # a reponse from the target server.
10
+ def self.client_probe(dbname=nil)
11
+ pkt = [
12
+ EXCSAT_DDM.new,
13
+ ACCSEC_DDM.new(:dbname => dbname)
14
+ ]
15
+ pkt.map {|x| x.to_s}.join
16
+ end
17
+
18
+ # Creates a packet with EXCSAT_DDM and an SECCHK_DDM.
19
+ # In order to ever succeed, you do need a successful probe first.
20
+ def self.client_auth(args={})
21
+ dbname = args[:dbname]
22
+ dbuser = args[:dbuser]
23
+ dbpass = args[:dbpass]
24
+ pkt = [
25
+ ACCSEC_DDM.new(:format => 0x41),
26
+ SECCHK_DDM.new(:dbname => dbname, :dbuser => dbuser, :dbpass => dbpass)
27
+ ]
28
+ pkt.map {|x| x.to_s}.join
29
+ end
30
+
31
+ def self.server_packet_info(obj)
32
+ info_hash = {}
33
+ return info_hash unless obj.kind_of? Rex::Proto::DRDA::SERVER_PACKET
34
+ obj.each do |ddm|
35
+ case ddm.codepoint
36
+ when Constants::EXCSATRD
37
+ info_hash.merge!(_info_excsatrd(ddm))
38
+ when Constants::ACCSECRD
39
+ info_hash.merge!(_info_accsecrd(ddm))
40
+ when Constants::RDBNFNRM
41
+ info_hash.merge!(_info_rdbnfnrm(ddm))
42
+ when Constants::SECCHKRM
43
+ info_hash.merge!(_info_secchkrm(ddm))
44
+ else
45
+ next
46
+ end
47
+ end
48
+ return info_hash
49
+ end
50
+
51
+ def self._info_excsatrd(ddm)
52
+ info_hash = {:excsatrd => true}
53
+ ddm.payload.each do |param|
54
+ case param.codepoint
55
+ when Constants::SRVNAM
56
+ info_hash[:instance_name] = Rex::Text.from_ebcdic(param.payload)
57
+ when Constants::SRVCLSNM
58
+ info_hash[:platform] = Rex::Text.from_ebcdic(param.payload)
59
+ when Constants::SRVRLSLV
60
+ info_hash[:version] = Rex::Text.from_ebcdic(param.payload)
61
+ else
62
+ next
63
+ end
64
+ end
65
+ return info_hash
66
+ end
67
+
68
+ def self._info_accsecrd(ddm)
69
+ info_hash = {:accsecrd => true}
70
+ ddm.payload.each do |param|
71
+ case param.codepoint
72
+ when Constants::SECMEC
73
+ info_hash[:plaintext_auth] = true if param.payload =~ /\x00\x03/
74
+ when Constants::SECCHKCD
75
+ info_hash[:security_check_code] = param.payload.unpack("C").first
76
+ # A little spurious? This is always nonzero when there's no SECCHKRM DDM.
77
+ info_hash[:db_login_success] = false unless info_hash[:security_check_code].zero?
78
+ else
79
+ next
80
+ end
81
+ end
82
+ return info_hash
83
+ end
84
+
85
+ def self._info_rdbnfnrm(ddm)
86
+ info_hash = {:rdbnfnrm => true}
87
+ info_hash[:database_found] = false
88
+ ddm.payload.each do |param|
89
+ case param.codepoint
90
+ when Constants::RDBNAM
91
+ info_hash[:db_name] = Rex::Text.from_ebcdic(param.payload).unpack("A*").first
92
+ when Constants::SRVDGN
93
+ info_hash[:error_message] = Rex::Text.from_ebcdic(param.payload)
94
+ else
95
+ next
96
+ end
97
+ end
98
+ return info_hash
99
+ end
100
+
101
+ def self._info_secchkrm(ddm)
102
+ info_hash = {:secchkrm => true}
103
+ ddm.payload.each do |param|
104
+ case param.codepoint
105
+ when Constants::SRVCOD
106
+ info_hash[:severity_code] = param.payload.unpack("n").first
107
+ when Constants::SECCHKCD
108
+ info_hash[:security_check_code] = param.payload.unpack("C").first
109
+ else
110
+ next
111
+ end
112
+ end
113
+ if info_hash[:serverity].to_i.zero? and info_hash[:security_check_code].to_i.zero?
114
+ info_hash[:db_login_success] = true
115
+ end
116
+ return info_hash
117
+ end
118
+
119
+ end
120
+
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.join(File.dirname(__FILE__), '..', '..', '..'))
4
+
5
+ require 'rex/test'
6
+ require 'rex/proto/drda/utils'
7
+ require 'rex/socket'
8
+
9
+ class Rex::Proto::DRDA::Utils::UnitTest < Test::Unit::TestCase
10
+
11
+ Klass = Rex::Proto::DRDA
12
+
13
+ def test_socket_connectivity
14
+ assert_nothing_raised do
15
+ socket = Rex::Socket.create_tcp(
16
+ 'PeerHost' => $_REX_TEST_DRDA_HOST.to_s, # PeerHost can be nil!
17
+ 'PeerPort' => 50000
18
+ )
19
+ assert_kind_of Socket, socket
20
+ assert !socket.closed?
21
+ socket.close
22
+ assert socket.closed?
23
+ end
24
+ end
25
+
26
+ def test_client_probe_create
27
+ probe_pkt = Klass::Utils.client_probe
28
+ assert_equal 54, probe_pkt.size
29
+ end
30
+
31
+ def test_client_probe
32
+ probe_pkt = Klass::Utils.client_probe('toolsdb')
33
+ begin
34
+ Timeout.timeout($_REX_TEST_TIMEOUT) do
35
+ socket = Rex::Socket.create_tcp(
36
+ 'PeerHost' => $_REX_TEST_DRDA_HOST.to_s,
37
+ 'PeerPort' => 50000
38
+ )
39
+ sent = socket.put probe_pkt
40
+ assert_equal 76, sent
41
+ probe_reply = socket.get_once
42
+ assert_operator probe_reply.size, :>=, 10
43
+ parsed_reply = Klass::SERVER_PACKET.new.read probe_reply
44
+ assert_kind_of Array, parsed_reply
45
+ assert_equal parsed_reply[0].codepoint, Klass::Constants::EXCSATRD
46
+ socket.close
47
+ end
48
+ rescue Timeout::Error
49
+ flunk("Timed out")
50
+ end
51
+ end
52
+
53
+ # Client auth requires a successful probe. This is a complete authentication
54
+ # sequence, culminating in info[:db_login_sucess] returning either true or
55
+ # false.
56
+ def test_client_auth
57
+ probe_pkt = Klass::Utils.client_probe('toolsdb')
58
+ auth_pkt = Klass::Utils.client_auth(:dbname => 'toolsdb',
59
+ :dbuser => $_REX_TEST_DRDA_USER.to_s,
60
+ :dbpass => $_REX_TEST_DRDA_PASS.to_s
61
+ )
62
+ begin
63
+ Timeout.timeout($_REX_TEST_TIMEOUT) do
64
+ socket = Rex::Socket.create_tcp(
65
+ 'PeerHost' => $_REX_TEST_DRDA_HOST.to_s,
66
+ 'PeerPort' => 50000
67
+ )
68
+ sent = socket.put probe_pkt
69
+ probe_reply = socket.get_once
70
+ sent = socket.put auth_pkt
71
+ assert_equal(75, sent)
72
+ auth_reply = socket.get_once
73
+ parsed_auth_reply = Klass::SERVER_PACKET.new.read auth_reply
74
+ info = Klass::Utils.server_packet_info(parsed_auth_reply)
75
+ assert info[:db_login_success]
76
+ socket.close
77
+ end
78
+ rescue Timeout::Error
79
+ flunk("Timed out")
80
+ end
81
+ end
82
+
83
+ end
84
+
@@ -0,0 +1,5 @@
1
+ require 'rex/proto/http/packet'
2
+ require 'rex/proto/http/request'
3
+ require 'rex/proto/http/response'
4
+ require 'rex/proto/http/client'
5
+ require 'rex/proto/http/server'
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+
5
+ require 'rex/proto/http/client.rb.ut'
6
+ require 'rex/proto/http/server.rb.ut'
7
+ require 'rex/proto/http/packet.rb.ut'
8
+ require 'rex/proto/http/header.rb.ut'
9
+ require 'rex/proto/http/request.rb.ut'
10
+ require 'rex/proto/http/response.rb.ut'
11
+ require 'rex/proto/http/handler/erb.rb.ut'
12
+ require 'rex/proto/http/handler/proc.rb.ut'
@@ -0,0 +1,821 @@
1
+ require 'rex/socket'
2
+ require 'rex/proto/http'
3
+ require 'rex/text'
4
+
5
+ module Rex
6
+ module Proto
7
+ module Http
8
+
9
+ ###
10
+ #
11
+ # Acts as a client to an HTTP server, sending requests and receiving responses.
12
+ #
13
+ # See the RFC: http://www.w3.org/Protocols/rfc2616/rfc2616.html
14
+ #
15
+ ###
16
+ class Client
17
+
18
+ #
19
+ # Creates a new client instance
20
+ #
21
+ def initialize(host, port = 80, context = {}, ssl = nil, ssl_version = nil, proxies = nil)
22
+ self.hostname = host
23
+ self.port = port.to_i
24
+ self.context = context
25
+ self.ssl = ssl
26
+ self.ssl_version = ssl_version
27
+ self.proxies = proxies
28
+ self.config = {
29
+ 'read_max_data' => (1024*1024*1),
30
+ 'vhost' => self.hostname,
31
+ 'version' => '1.1',
32
+ 'agent' => "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
33
+ #
34
+ # Evasion options
35
+ #
36
+ 'uri_encode_mode' => 'hex-normal', # hex-all, hex-random, u-normal, u-random, u-all
37
+ 'uri_encode_count' => 1, # integer
38
+ 'uri_full_url' => false, # bool
39
+ 'pad_method_uri_count' => 1, # integer
40
+ 'pad_uri_version_count' => 1, # integer
41
+ 'pad_method_uri_type' => 'space', # space, tab, apache
42
+ 'pad_uri_version_type' => 'space', # space, tab, apache
43
+ 'method_random_valid' => false, # bool
44
+ 'method_random_invalid' => false, # bool
45
+ 'method_random_case' => false, # bool
46
+ 'version_random_valid' => false, # bool
47
+ 'version_random_invalid' => false, # bool
48
+ 'version_random_case' => false, # bool
49
+ 'uri_dir_self_reference' => false, # bool
50
+ 'uri_dir_fake_relative' => false, # bool
51
+ 'uri_use_backslashes' => false, # bool
52
+ 'pad_fake_headers' => false, # bool
53
+ 'pad_fake_headers_count' => 16, # integer
54
+ 'pad_get_params' => false, # bool
55
+ 'pad_get_params_count' => 8, # integer
56
+ 'pad_post_params' => false, # bool
57
+ 'pad_post_params_count' => 8, # integer
58
+ 'uri_fake_end' => false, # bool
59
+ 'uri_fake_params_start' => false, # bool
60
+ 'header_folding' => false, # bool
61
+ 'chunked_size' => 0 # integer
62
+ }
63
+
64
+ # This is not used right now...
65
+ self.config_types = {
66
+ 'uri_encode_mode' => ['hex-normal', 'hex-all', 'hex-random', 'u-normal', 'u-random', 'u-all'],
67
+ 'uri_encode_count' => 'integer',
68
+ 'uri_full_url' => 'bool',
69
+ 'pad_method_uri_count' => 'integer',
70
+ 'pad_uri_version_count' => 'integer',
71
+ 'pad_method_uri_type' => ['space', 'tab', 'apache'],
72
+ 'pad_uri_version_type' => ['space', 'tab', 'apache'],
73
+ 'method_random_valid' => 'bool',
74
+ 'method_random_invalid' => 'bool',
75
+ 'method_random_case' => 'bool',
76
+ 'version_random_valid' => 'bool',
77
+ 'version_random_invalid' => 'bool',
78
+ 'version_random_case' => 'bool',
79
+ 'uri_dir_self_reference' => 'bool',
80
+ 'uri_dir_fake_relative' => 'bool',
81
+ 'uri_use_backslashes' => 'bool',
82
+ 'pad_fake_headers' => 'bool',
83
+ 'pad_fake_headers_count' => 'integer',
84
+ 'pad_get_params' => 'bool',
85
+ 'pad_get_params_count' => 'integer',
86
+ 'pad_post_params' => 'bool',
87
+ 'pad_post_params_count' => 'integer',
88
+ 'uri_fake_end' => 'bool',
89
+ 'uri_fake_params_start' => 'bool',
90
+ 'header_folding' => 'bool',
91
+ 'chunked_size' => 'integer'
92
+ }
93
+ end
94
+
95
+ #
96
+ # Set configuration options
97
+ #
98
+ def set_config(opts = {})
99
+ opts.each_pair do |var,val|
100
+ typ = self.config_types[var] || 'string'
101
+
102
+ if(typ.class.to_s == 'Array')
103
+ if not typ.include?(val)
104
+ raise RuntimeError, "The specified value for #{var} is not one of the valid choices"
105
+ end
106
+ end
107
+
108
+ if(typ == 'bool')
109
+ val = (val =~ /^(t|y|1)$/i ? true : false)
110
+ end
111
+
112
+ if(typ == 'integer')
113
+ val = val.to_i
114
+ end
115
+
116
+ self.config[var]=val
117
+ end
118
+
119
+ end
120
+
121
+ #
122
+ # Create an arbitrary HTTP request
123
+ #
124
+ def request_raw(opts={})
125
+ c_enc = opts['encode'] || false
126
+ c_uri = opts['uri'] || '/'
127
+ c_body = opts['data'] || ''
128
+ c_meth = opts['method'] || 'GET'
129
+ c_prot = opts['proto'] || 'HTTP'
130
+ c_vers = opts['version'] || config['version'] || '1.1'
131
+ c_qs = opts['query']
132
+ c_ag = opts['agent'] || config['agent']
133
+ c_cook = opts['cookie'] || config['cookie']
134
+ c_host = opts['vhost'] || config['vhost'] || self.hostname
135
+ c_head = opts['headers'] || config['headers'] || {}
136
+ c_rawh = opts['raw_headers']|| config['raw_headers'] || ''
137
+ c_conn = opts['connection']
138
+ c_auth = opts['basic_auth'] || config['basic_auth'] || ''
139
+
140
+ uri = set_uri(c_uri)
141
+
142
+ req = ''
143
+ req << set_method(c_meth)
144
+ req << set_method_uri_spacer()
145
+ req << set_uri_prepend()
146
+ req << (c_enc ? set_encode_uri(uri) : uri)
147
+
148
+ if (c_qs)
149
+ req << '?'
150
+ req << (c_enc ? set_encode_qs(c_qs) : c_qs)
151
+ end
152
+
153
+ req << set_uri_append()
154
+ req << set_uri_version_spacer()
155
+ req << set_version(c_prot, c_vers)
156
+ req << set_host_header(c_host)
157
+ req << set_agent_header(c_ag)
158
+
159
+ if (c_auth.length > 0)
160
+ req << set_basic_auth_header(c_auth)
161
+ end
162
+
163
+ req << set_cookie_header(c_cook)
164
+ req << set_connection_header(c_conn)
165
+ req << set_extra_headers(c_head)
166
+ req << set_raw_headers(c_rawh)
167
+ req << set_body(c_body)
168
+
169
+ req
170
+ end
171
+
172
+
173
+ #
174
+ # Create a CGI compatible request
175
+ #
176
+ # Options:
177
+ # - agent: User-Agent header value
178
+ # - basic_auth: Basic-Auth header value
179
+ # - connection: Connection header value
180
+ # - cookie: Cookie header value
181
+ # - ctype: Content-Type header value, default: +application/x-www-form-urlencoded+
182
+ # - data: HTTP data (only useful with some methods, see rfc2616)
183
+ # - encode: URI encode the supplied URI
184
+ # - headers: HTTP headers as a hash, e.g. <code>{ "X-MyHeader" => "value" }</code>
185
+ # - method: HTTP method to use in the request, not limited to standard methods defined by rfc2616, default: GET
186
+ # - proto: protocol, default: HTTP
187
+ # - query: raw query string
188
+ # - raw_headers: HTTP headers as a hash
189
+ # - uri: the URI to request
190
+ # - vars_get: GET variables as a hash to be translated into a query string
191
+ # - vars_post: POST variables as a hash to be translated into POST data
192
+ # - version: version of the protocol, default: 1.1
193
+ # - vhost: Host header value
194
+ #
195
+ def request_cgi(opts={})
196
+ c_enc = opts['encode'] || false
197
+ c_cgi = opts['uri'] || '/'
198
+ c_body = opts['data'] || ''
199
+ c_meth = opts['method'] || 'GET'
200
+ c_prot = opts['proto'] || 'HTTP'
201
+ c_vers = opts['version'] || config['version'] || '1.1'
202
+ c_qs = opts['query'] || ''
203
+ c_varg = opts['vars_get'] || {}
204
+ c_varp = opts['vars_post'] || {}
205
+ c_head = opts['headers'] || config['headers'] || {}
206
+ c_rawh = opts['raw_headers']|| config['raw_headers'] || ''
207
+ c_type = opts['ctype'] || 'application/x-www-form-urlencoded'
208
+ c_ag = opts['agent'] || config['agent']
209
+ c_cook = opts['cookie'] || config['cookie']
210
+ c_host = opts['vhost'] || config['vhost']
211
+ c_conn = opts['connection']
212
+ c_path = opts['path_info']
213
+ c_auth = opts['basic_auth'] || config['basic_auth'] || ''
214
+
215
+ uri = set_cgi(c_cgi)
216
+ qstr = c_qs
217
+ pstr = c_body
218
+
219
+ if (config['pad_get_params'])
220
+ 1.upto(config['pad_get_params_count'].to_i) do |i|
221
+ qstr << '&' if qstr.length > 0
222
+ qstr << set_encode_uri(Rex::Text.rand_text_alphanumeric(rand(32)+1))
223
+ qstr << '='
224
+ qstr << set_encode_uri(Rex::Text.rand_text_alphanumeric(rand(32)+1))
225
+ end
226
+ end
227
+
228
+ c_varg.each_pair do |var,val|
229
+ qstr << '&' if qstr.length > 0
230
+ qstr << set_encode_uri(var)
231
+ qstr << '='
232
+ qstr << set_encode_uri(val)
233
+ end
234
+
235
+ if (config['pad_post_params'])
236
+ 1.upto(config['pad_post_params_count'].to_i) do |i|
237
+ pstr << '&' if qstr.length > 0
238
+ pstr << set_encode_uri(Rex::Text.rand_text_alphanumeric(rand(32)+1))
239
+ pstr << '='
240
+ pstr << set_encode_uri(Rex::Text.rand_text_alphanumeric(rand(32)+1))
241
+ end
242
+ end
243
+
244
+ c_varp.each_pair do |var,val|
245
+ pstr << '&' if pstr.length > 0
246
+ pstr << set_encode_uri(var)
247
+ pstr << '='
248
+ pstr << set_encode_uri(val)
249
+ end
250
+
251
+ req = ''
252
+ req << set_method(c_meth)
253
+ req << set_method_uri_spacer()
254
+ req << set_uri_prepend()
255
+ req << (c_enc ? set_encode_uri(uri):uri)
256
+
257
+ if (qstr.length > 0)
258
+ req << '?'
259
+ req << qstr
260
+ end
261
+
262
+ req << set_path_info(c_path)
263
+ req << set_uri_append()
264
+ req << set_uri_version_spacer()
265
+ req << set_version(c_prot, c_vers)
266
+ req << set_host_header(c_host)
267
+ req << set_agent_header(c_ag)
268
+
269
+ if (c_auth.length > 0)
270
+ req << set_basic_auth_header(c_auth)
271
+ end
272
+
273
+ req << set_cookie_header(c_cook)
274
+ req << set_connection_header(c_conn)
275
+ req << set_extra_headers(c_head)
276
+
277
+ req << set_content_type_header(c_type)
278
+ req << set_content_len_header(pstr.length)
279
+ req << set_chunked_header()
280
+ req << set_raw_headers(c_rawh)
281
+ req << set_body(pstr)
282
+
283
+ req
284
+ end
285
+
286
+ #
287
+ # Connects to the remote server if possible.
288
+ #
289
+ def connect
290
+ # If we already have a connection and we aren't pipelining, close it.
291
+ if (self.conn)
292
+ if !pipelining?
293
+ close
294
+ else
295
+ return self.conn
296
+ end
297
+ end
298
+
299
+ self.conn = Rex::Socket::Tcp.create(
300
+ 'PeerHost' => self.hostname,
301
+ 'PeerPort' => self.port.to_i,
302
+ 'LocalHost' => self.local_host,
303
+ 'LocalPort' => self.local_port,
304
+ 'Context' => self.context,
305
+ 'SSL' => self.ssl,
306
+ 'SSLVersion'=> self.ssl_version,
307
+ 'Proxies' => self.proxies
308
+ )
309
+ end
310
+
311
+ #
312
+ # Closes the connection to the remote server.
313
+ #
314
+ def close
315
+ if (self.conn)
316
+ self.conn.shutdown
317
+ self.conn.close
318
+ end
319
+
320
+ self.conn = nil
321
+ end
322
+
323
+ #
324
+ # Transmit an HTTP request and receive the response
325
+ # If persist is set, then the request will attempt
326
+ # to reuse an existing connection.
327
+ #
328
+ def send_recv(req, t = -1, persist=false)
329
+ @pipeline = persist
330
+ send_request(req)
331
+ res = read_response(t)
332
+ res.request = req.to_s if res
333
+ res
334
+ end
335
+
336
+ #
337
+ # Send an HTTP request to the server
338
+ #
339
+ def send_request(req)
340
+ connect
341
+ conn.put(req.to_s)
342
+ end
343
+
344
+ #
345
+ # Read a response from the server
346
+ #
347
+ def read_response(t = -1)
348
+
349
+ resp = Response.new
350
+ resp.max_data = config['read_max_data']
351
+
352
+ # Wait at most t seconds for the full response to be read in. We only
353
+ # do this if t was specified as a negative value indicating an infinite
354
+ # wait cycle. If t were specified as nil it would indicate that no
355
+ # response parsing is required.
356
+
357
+ return resp if not t
358
+
359
+ Timeout.timeout((t < 0) ? nil : t) do
360
+
361
+ rv = nil
362
+ while (
363
+ rv != Packet::ParseCode::Completed and
364
+ rv != Packet::ParseCode::Error
365
+ )
366
+
367
+ begin
368
+
369
+ buff = conn.get_once(-1, 1)
370
+ rv = resp.parse( buff || '' )
371
+
372
+ ##########################################################################
373
+ # XXX: NOTE: BUG: get_once currently (as of r10042) rescues "Exception"
374
+ # As such, the following rescue block will ever be reached. -jjd
375
+ ##########################################################################
376
+
377
+ # Handle unexpected disconnects
378
+ rescue ::Errno::EPIPE, ::EOFError, ::IOError
379
+ case resp.state
380
+ when Packet::ParseState::ProcessingHeader
381
+ resp = nil
382
+ when Packet::ParseState::ProcessingBody
383
+ # truncated request, good enough
384
+ resp.error = :truncated
385
+ end
386
+ break
387
+ end
388
+
389
+ # This is a dirty hack for broken HTTP servers
390
+ if rv == Packet::ParseCode::Completed
391
+ rbody = resp.body
392
+ rbufq = resp.bufq
393
+
394
+ rblob = rbody.to_s + rbufq.to_s
395
+ tries = 0
396
+ begin
397
+ # XXX: This doesn't deal with chunked encoding or "Content-type: text/html; charset=..."
398
+ while tries < 1000 and resp.headers["Content-Type"]== "text/html" and rblob !~ /<\/html>/i
399
+ buff = conn.get_once(-1, 0.05)
400
+ break if not buff
401
+ rblob += buff
402
+ tries += 1
403
+ end
404
+ rescue ::Errno::EPIPE, ::EOFError, ::IOError
405
+ end
406
+
407
+ resp.bufq = ""
408
+ resp.body = rblob
409
+ end
410
+ end
411
+ end
412
+
413
+ return resp if not resp
414
+
415
+ # As a last minute hack, we check to see if we're dealing with a 100 Continue here.
416
+ if resp.proto == '1.1' and resp.code == 100
417
+ # If so, our real response becaome the body, so we re-parse it.
418
+ body = resp.body
419
+ resp = Response.new
420
+ resp.max_data = config['read_max_data']
421
+ rv = resp.parse(body)
422
+ # XXX: At some point, this may benefit from processing post-completion code
423
+ # as seen above.
424
+ end
425
+
426
+ resp
427
+ end
428
+
429
+ #
430
+ # Cleans up any outstanding connections and other resources.
431
+ #
432
+ def stop
433
+ close
434
+ end
435
+
436
+ #
437
+ # Returns whether or not the conn is valid.
438
+ #
439
+ def conn?
440
+ conn != nil
441
+ end
442
+
443
+ #
444
+ # Whether or not connections should be pipelined.
445
+ #
446
+ def pipelining?
447
+ pipeline
448
+ end
449
+
450
+ #
451
+ # Return the encoded URI
452
+ # ['none','hex-normal', 'hex-all', 'u-normal', 'u-all']
453
+ def set_encode_uri(uri)
454
+ a = uri
455
+ self.config['uri_encode_count'].times {
456
+ a = Rex::Text.uri_encode(a, self.config['uri_encode_mode'])
457
+ }
458
+ return a
459
+ end
460
+
461
+ #
462
+ # Return the encoded query string
463
+ #
464
+ def set_encode_qs(qs)
465
+ a = qs
466
+ self.config['uri_encode_count'].times {
467
+ a = Rex::Text.uri_encode(a, self.config['uri_encode_mode'])
468
+ }
469
+ return a
470
+ end
471
+
472
+ #
473
+ # Return the uri
474
+ #
475
+ def set_uri(uri)
476
+
477
+ if (self.config['uri_dir_self_reference'])
478
+ uri.gsub!('/', '/./')
479
+ end
480
+
481
+ if (self.config['uri_dir_fake_relative'])
482
+ buf = ""
483
+ uri.split('/').each do |part|
484
+ cnt = rand(8)+2
485
+ 1.upto(cnt) { |idx|
486
+ buf << "/" + Rex::Text.rand_text_alphanumeric(rand(32)+1)
487
+ }
488
+ buf << ("/.." * cnt)
489
+ buf << "/" + part
490
+ end
491
+ uri = buf
492
+ end
493
+
494
+ if (self.config['uri_full_url'])
495
+ url = self.ssl ? "https" : "http"
496
+ url << self.config['vhost']
497
+ url << ((self.port == 80) ? "" : ":#{self.port}")
498
+ url << uri
499
+ url
500
+ else
501
+ uri
502
+ end
503
+ end
504
+
505
+ #
506
+ # Return the cgi
507
+ #
508
+ def set_cgi(uri)
509
+
510
+ if (self.config['uri_dir_self_reference'])
511
+ uri.gsub!('/', '/./')
512
+ end
513
+
514
+ if (self.config['uri_dir_fake_relative'])
515
+ buf = ""
516
+ uri.split('/').each do |part|
517
+ cnt = rand(8)+2
518
+ 1.upto(cnt) { |idx|
519
+ buf << "/" + Rex::Text.rand_text_alphanumeric(rand(32)+1)
520
+ }
521
+ buf << ("/.." * cnt)
522
+ buf << "/" + part
523
+ end
524
+ uri = buf
525
+ end
526
+
527
+ url = uri
528
+
529
+ if (self.config['uri_full_url'])
530
+ url = self.ssl ? "https" : "http"
531
+ url << self.config['vhost']
532
+ url << (self.port == 80) ? "" : ":#{self.port}"
533
+ url << uri
534
+ end
535
+
536
+ url
537
+ end
538
+
539
+ #
540
+ # Return the HTTP method string
541
+ #
542
+ def set_method(method)
543
+ ret = method
544
+
545
+ if (self.config['method_random_valid'])
546
+ ret = ['GET', 'POST', 'HEAD'][rand(3)]
547
+ end
548
+
549
+ if (self.config['method_random_invalid'])
550
+ ret = Rex::Text.rand_text_alpha(rand(20)+1)
551
+ end
552
+
553
+ if (self.config['method_random_case'])
554
+ ret = Rex::Text.to_rand_case(ret)
555
+ end
556
+
557
+ ret
558
+ end
559
+
560
+ #
561
+ # Return the HTTP version string
562
+ #
563
+ def set_version(protocol, version)
564
+ ret = protocol + "/" + version
565
+
566
+ if (self.config['version_random_valid'])
567
+ ret = protocol + "/" + ['1.0', '1.1'][rand(2)]
568
+ end
569
+
570
+ if (self.config['version_random_invalid'])
571
+ ret = Rex::Text.rand_text_alphanumeric(rand(20)+1)
572
+ end
573
+
574
+ if (self.config['version_random_case'])
575
+ ret = Rex::Text.to_rand_case(ret)
576
+ end
577
+
578
+ ret << "\r\n"
579
+ end
580
+
581
+ #
582
+ # Return the HTTP seperator and body string
583
+ #
584
+ def set_body(data)
585
+ return "\r\n" + data if self.config['chunked_size'] == 0
586
+ str = data.dup
587
+ chunked = ''
588
+ while str.size > 0
589
+ chunk = str.slice!(0,rand(self.config['chunked_size']) + 1)
590
+ chunked << sprintf("%x", chunk.size) + "\r\n" + chunk + "\r\n"
591
+ end
592
+ "\r\n" + chunked + "0\r\n\r\n"
593
+ end
594
+
595
+ #
596
+ # Return the HTTP path info
597
+ # TODO:
598
+ # * Encode path information
599
+ def set_path_info(path)
600
+ path ? path : ''
601
+ end
602
+
603
+ #
604
+ # Return the spacing between the method and uri
605
+ #
606
+ def set_method_uri_spacer
607
+ len = self.config['pad_method_uri_count'].to_i
608
+ set = " "
609
+ buf = ""
610
+
611
+ case self.config['pad_method_uri_type']
612
+ when 'tab'
613
+ set = "\t"
614
+ when 'apache'
615
+ set = "\t \x0b\x0c\x0d"
616
+ end
617
+
618
+ while(buf.length < len)
619
+ buf << set[ rand(set.length) ]
620
+ end
621
+
622
+ return buf
623
+ end
624
+
625
+ #
626
+ # Return the spacing between the uri and the version
627
+ #
628
+ def set_uri_version_spacer
629
+ len = self.config['pad_uri_version_count'].to_i
630
+ set = " "
631
+ buf = ""
632
+
633
+ case self.config['pad_uri_version_type']
634
+ when 'tab'
635
+ set = "\t"
636
+ when 'apache'
637
+ set = "\t \x0b\x0c\x0d"
638
+ end
639
+
640
+ while(buf.length < len)
641
+ buf << set[ rand(set.length) ]
642
+ end
643
+
644
+ return buf
645
+ end
646
+
647
+ #
648
+ # Return the padding to place before the uri
649
+ #
650
+ def set_uri_prepend
651
+ prefix = ""
652
+
653
+ if (self.config['uri_fake_params_start'])
654
+ prefix << '/%3fa=b/../'
655
+ end
656
+
657
+ if (self.config['uri_fake_end'])
658
+ prefix << '/%20HTTP/1.0/../../'
659
+ end
660
+
661
+ prefix
662
+ end
663
+
664
+ #
665
+ # Return the padding to place before the uri
666
+ #
667
+ def set_uri_append
668
+ # TODO:
669
+ # * Support different padding types
670
+ ""
671
+ end
672
+
673
+ #
674
+ # Return the HTTP Host header
675
+ #
676
+ def set_host_header(host)
677
+ return "" if self.config['uri_full_url']
678
+ host ||= self.config['vhost']
679
+ set_formatted_header("Host", host)
680
+ end
681
+
682
+ #
683
+ # Return the HTTP agent header
684
+ #
685
+ def set_agent_header(agent)
686
+ agent ? set_formatted_header("User-Agent", agent) : ""
687
+ end
688
+
689
+ #
690
+ # Return the HTTP cookie header
691
+ #
692
+ def set_cookie_header(cookie)
693
+ cookie ? set_formatted_header("Cookie", cookie) : ""
694
+ end
695
+
696
+ #
697
+ # Return the HTTP connection header
698
+ #
699
+ def set_connection_header(conn)
700
+ conn ? set_formatted_header("Connection", conn) : ""
701
+ end
702
+
703
+ #
704
+ # Return the content type header
705
+ #
706
+ def set_content_type_header(ctype)
707
+ set_formatted_header("Content-Type", ctype)
708
+ end
709
+
710
+ #
711
+ # Return the content length header
712
+ def set_content_len_header(clen)
713
+ return "" if self.config['chunked_size'] > 0
714
+ set_formatted_header("Content-Length", clen)
715
+ end
716
+
717
+ #
718
+ # Return the Authorization basic-auth header
719
+ #
720
+ def set_basic_auth_header(auth)
721
+ auth ? set_formatted_header("Authorization", "Basic " + Rex::Text.encode_base64(auth)) : ""
722
+ end
723
+
724
+ #
725
+ # Return a string of formatted extra headers
726
+ #
727
+ def set_extra_headers(headers)
728
+ buf = ''
729
+
730
+ if (self.config['pad_fake_headers'])
731
+ 1.upto(self.config['pad_fake_headers_count'].to_i) do |i|
732
+ buf << set_formatted_header(
733
+ Rex::Text.rand_text_alphanumeric(rand(32)+1),
734
+ Rex::Text.rand_text_alphanumeric(rand(32)+1)
735
+ )
736
+ end
737
+ end
738
+
739
+ headers.each_pair do |var,val|
740
+ buf << set_formatted_header(var, val)
741
+ end
742
+
743
+ buf
744
+ end
745
+
746
+ def set_chunked_header()
747
+ return "" if self.config['chunked_size'] == 0
748
+ set_formatted_header('Transfer-Encoding', 'chunked')
749
+ end
750
+
751
+ #
752
+ # Return a string of raw header data
753
+ #
754
+ def set_raw_headers(data)
755
+ data
756
+ end
757
+
758
+ #
759
+ # Return a formatted header string
760
+ #
761
+ def set_formatted_header(var, val)
762
+ if (self.config['header_folding'])
763
+ "#{var}:\r\n\t#{val}\r\n"
764
+ else
765
+ "#{var}: #{val}\r\n"
766
+ end
767
+ end
768
+
769
+
770
+
771
+ #
772
+ # The client request configuration
773
+ #
774
+ attr_accessor :config
775
+ #
776
+ # The client request configuration classes
777
+ #
778
+ attr_accessor :config_types
779
+ #
780
+ # Whether or not pipelining is in use.
781
+ #
782
+ attr_accessor :pipeline
783
+ #
784
+ # The local host of the client.
785
+ #
786
+ attr_accessor :local_host
787
+ #
788
+ # The local port of the client.
789
+ #
790
+ attr_accessor :local_port
791
+ #
792
+ # The underlying connection.
793
+ #
794
+ attr_accessor :conn
795
+ #
796
+ # The calling context to pass to the socket
797
+ #
798
+ attr_accessor :context
799
+ #
800
+ # The proxy list
801
+ #
802
+ attr_accessor :proxies
803
+
804
+
805
+ # When parsing the request, thunk off the first response from the server, since junk
806
+ attr_accessor :junk_pipeline
807
+
808
+ protected
809
+
810
+ # https
811
+ attr_accessor :ssl, :ssl_version # :nodoc:
812
+
813
+ attr_accessor :hostname, :port # :nodoc:
814
+
815
+
816
+ end
817
+
818
+ end
819
+ end
820
+ end
821
+