dstruct 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (491) hide show
  1. checksums.yaml +15 -0
  2. data/README.markdown +23 -0
  3. data/examples/smb_example.rb +35 -0
  4. data/lib/rex.rb +108 -0
  5. data/lib/rex/LICENSE +29 -0
  6. data/lib/rex/arch.rb +104 -0
  7. data/lib/rex/arch/sparc.rb +75 -0
  8. data/lib/rex/arch/x86.rb +524 -0
  9. data/lib/rex/assembly/nasm.rb +104 -0
  10. data/lib/rex/codepage.map +104 -0
  11. data/lib/rex/compat.rb +389 -0
  12. data/lib/rex/constants.rb +124 -0
  13. data/lib/rex/elfparsey.rb +9 -0
  14. data/lib/rex/elfparsey/elf.rb +121 -0
  15. data/lib/rex/elfparsey/elfbase.rb +256 -0
  16. data/lib/rex/elfparsey/exceptions.rb +25 -0
  17. data/lib/rex/elfscan.rb +10 -0
  18. data/lib/rex/elfscan/scanner.rb +226 -0
  19. data/lib/rex/elfscan/search.rb +44 -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 +90 -0
  24. data/lib/rex/encoder/alpha2/unicode_mixed.rb +116 -0
  25. data/lib/rex/encoder/alpha2/unicode_upper.rb +123 -0
  26. data/lib/rex/encoder/bloxor/bloxor.rb +327 -0
  27. data/lib/rex/encoder/ndr.rb +90 -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 +107 -0
  31. data/lib/rex/encoder/xor.rb +69 -0
  32. data/lib/rex/encoder/xor/dword.rb +13 -0
  33. data/lib/rex/encoder/xor/dword_additive.rb +13 -0
  34. data/lib/rex/encoders/xor_dword.rb +35 -0
  35. data/lib/rex/encoders/xor_dword_additive.rb +53 -0
  36. data/lib/rex/encoding/xor.rb +20 -0
  37. data/lib/rex/encoding/xor/byte.rb +15 -0
  38. data/lib/rex/encoding/xor/dword.rb +21 -0
  39. data/lib/rex/encoding/xor/dword_additive.rb +92 -0
  40. data/lib/rex/encoding/xor/exceptions.rb +17 -0
  41. data/lib/rex/encoding/xor/generic.rb +146 -0
  42. data/lib/rex/encoding/xor/qword.rb +15 -0
  43. data/lib/rex/encoding/xor/word.rb +21 -0
  44. data/lib/rex/exceptions.rb +275 -0
  45. data/lib/rex/exploitation/cmdstager.rb +10 -0
  46. data/lib/rex/exploitation/cmdstager/base.rb +190 -0
  47. data/lib/rex/exploitation/cmdstager/bourne.rb +105 -0
  48. data/lib/rex/exploitation/cmdstager/debug_asm.rb +140 -0
  49. data/lib/rex/exploitation/cmdstager/debug_write.rb +134 -0
  50. data/lib/rex/exploitation/cmdstager/echo.rb +164 -0
  51. data/lib/rex/exploitation/cmdstager/printf.rb +122 -0
  52. data/lib/rex/exploitation/cmdstager/tftp.rb +71 -0
  53. data/lib/rex/exploitation/cmdstager/vbs.rb +126 -0
  54. data/lib/rex/exploitation/egghunter.rb +425 -0
  55. data/lib/rex/exploitation/encryptjs.rb +78 -0
  56. data/lib/rex/exploitation/heaplib.js.b64 +331 -0
  57. data/lib/rex/exploitation/heaplib.rb +107 -0
  58. data/lib/rex/exploitation/js.rb +6 -0
  59. data/lib/rex/exploitation/js/detect.rb +69 -0
  60. data/lib/rex/exploitation/js/memory.rb +81 -0
  61. data/lib/rex/exploitation/js/network.rb +84 -0
  62. data/lib/rex/exploitation/js/utils.rb +33 -0
  63. data/lib/rex/exploitation/jsobfu.rb +513 -0
  64. data/lib/rex/exploitation/obfuscatejs.rb +336 -0
  65. data/lib/rex/exploitation/omelet.rb +321 -0
  66. data/lib/rex/exploitation/opcodedb.rb +819 -0
  67. data/lib/rex/exploitation/powershell.rb +62 -0
  68. data/lib/rex/exploitation/powershell/function.rb +63 -0
  69. data/lib/rex/exploitation/powershell/obfu.rb +98 -0
  70. data/lib/rex/exploitation/powershell/output.rb +151 -0
  71. data/lib/rex/exploitation/powershell/param.rb +23 -0
  72. data/lib/rex/exploitation/powershell/parser.rb +183 -0
  73. data/lib/rex/exploitation/powershell/psh_methods.rb +70 -0
  74. data/lib/rex/exploitation/powershell/script.rb +99 -0
  75. data/lib/rex/exploitation/ropdb.rb +190 -0
  76. data/lib/rex/exploitation/seh.rb +93 -0
  77. data/lib/rex/file.rb +160 -0
  78. data/lib/rex/image_source.rb +10 -0
  79. data/lib/rex/image_source/disk.rb +58 -0
  80. data/lib/rex/image_source/image_source.rb +44 -0
  81. data/lib/rex/image_source/memory.rb +35 -0
  82. data/lib/rex/io/bidirectional_pipe.rb +161 -0
  83. data/lib/rex/io/datagram_abstraction.rb +35 -0
  84. data/lib/rex/io/ring_buffer.rb +369 -0
  85. data/lib/rex/io/stream.rb +312 -0
  86. data/lib/rex/io/stream_abstraction.rb +209 -0
  87. data/lib/rex/io/stream_server.rb +221 -0
  88. data/lib/rex/job_container.rb +200 -0
  89. data/lib/rex/logging.rb +4 -0
  90. data/lib/rex/logging/log_dispatcher.rb +180 -0
  91. data/lib/rex/logging/log_sink.rb +43 -0
  92. data/lib/rex/logging/sinks/flatfile.rb +56 -0
  93. data/lib/rex/logging/sinks/stderr.rb +44 -0
  94. data/lib/rex/mac_oui.rb +16581 -0
  95. data/lib/rex/machparsey.rb +9 -0
  96. data/lib/rex/machparsey/exceptions.rb +34 -0
  97. data/lib/rex/machparsey/mach.rb +209 -0
  98. data/lib/rex/machparsey/machbase.rb +408 -0
  99. data/lib/rex/machscan.rb +9 -0
  100. data/lib/rex/machscan/scanner.rb +217 -0
  101. data/lib/rex/mime.rb +10 -0
  102. data/lib/rex/mime/encoding.rb +17 -0
  103. data/lib/rex/mime/header.rb +78 -0
  104. data/lib/rex/mime/message.rb +150 -0
  105. data/lib/rex/mime/part.rb +50 -0
  106. data/lib/rex/nop/opty2.rb +109 -0
  107. data/lib/rex/nop/opty2_tables.rb +301 -0
  108. data/lib/rex/ole.rb +202 -0
  109. data/lib/rex/ole/clsid.rb +44 -0
  110. data/lib/rex/ole/difat.rb +138 -0
  111. data/lib/rex/ole/directory.rb +228 -0
  112. data/lib/rex/ole/direntry.rb +237 -0
  113. data/lib/rex/ole/docs/dependencies.txt +8 -0
  114. data/lib/rex/ole/docs/references.txt +1 -0
  115. data/lib/rex/ole/fat.rb +96 -0
  116. data/lib/rex/ole/header.rb +201 -0
  117. data/lib/rex/ole/minifat.rb +74 -0
  118. data/lib/rex/ole/propset.rb +141 -0
  119. data/lib/rex/ole/samples/create_ole.rb +27 -0
  120. data/lib/rex/ole/samples/dir.rb +35 -0
  121. data/lib/rex/ole/samples/dump_stream.rb +34 -0
  122. data/lib/rex/ole/samples/ole_info.rb +23 -0
  123. data/lib/rex/ole/storage.rb +392 -0
  124. data/lib/rex/ole/stream.rb +50 -0
  125. data/lib/rex/ole/substorage.rb +46 -0
  126. data/lib/rex/ole/util.rb +154 -0
  127. data/lib/rex/parser/acunetix_nokogiri.rb +406 -0
  128. data/lib/rex/parser/apple_backup_manifestdb.rb +132 -0
  129. data/lib/rex/parser/appscan_nokogiri.rb +367 -0
  130. data/lib/rex/parser/arguments.rb +108 -0
  131. data/lib/rex/parser/burp_session_nokogiri.rb +291 -0
  132. data/lib/rex/parser/ci_nokogiri.rb +193 -0
  133. data/lib/rex/parser/foundstone_nokogiri.rb +342 -0
  134. data/lib/rex/parser/fusionvm_nokogiri.rb +109 -0
  135. data/lib/rex/parser/group_policy_preferences.rb +185 -0
  136. data/lib/rex/parser/ini.rb +186 -0
  137. data/lib/rex/parser/ip360_aspl_xml.rb +103 -0
  138. data/lib/rex/parser/ip360_xml.rb +98 -0
  139. data/lib/rex/parser/mbsa_nokogiri.rb +256 -0
  140. data/lib/rex/parser/nessus_xml.rb +121 -0
  141. data/lib/rex/parser/netsparker_xml.rb +109 -0
  142. data/lib/rex/parser/nexpose_raw_nokogiri.rb +686 -0
  143. data/lib/rex/parser/nexpose_simple_nokogiri.rb +330 -0
  144. data/lib/rex/parser/nexpose_xml.rb +172 -0
  145. data/lib/rex/parser/nmap_nokogiri.rb +394 -0
  146. data/lib/rex/parser/nmap_xml.rb +166 -0
  147. data/lib/rex/parser/nokogiri_doc_mixin.rb +233 -0
  148. data/lib/rex/parser/openvas_nokogiri.rb +172 -0
  149. data/lib/rex/parser/outpost24_nokogiri.rb +240 -0
  150. data/lib/rex/parser/retina_xml.rb +110 -0
  151. data/lib/rex/parser/unattend.rb +171 -0
  152. data/lib/rex/parser/wapiti_nokogiri.rb +105 -0
  153. data/lib/rex/payloads.rb +2 -0
  154. data/lib/rex/payloads/win32.rb +3 -0
  155. data/lib/rex/payloads/win32/common.rb +27 -0
  156. data/lib/rex/payloads/win32/kernel.rb +54 -0
  157. data/lib/rex/payloads/win32/kernel/common.rb +55 -0
  158. data/lib/rex/payloads/win32/kernel/migration.rb +13 -0
  159. data/lib/rex/payloads/win32/kernel/recovery.rb +51 -0
  160. data/lib/rex/payloads/win32/kernel/stager.rb +195 -0
  161. data/lib/rex/peparsey.rb +10 -0
  162. data/lib/rex/peparsey/exceptions.rb +30 -0
  163. data/lib/rex/peparsey/pe.rb +210 -0
  164. data/lib/rex/peparsey/pe_memdump.rb +61 -0
  165. data/lib/rex/peparsey/pebase.rb +1662 -0
  166. data/lib/rex/peparsey/section.rb +128 -0
  167. data/lib/rex/pescan.rb +11 -0
  168. data/lib/rex/pescan/analyze.rb +366 -0
  169. data/lib/rex/pescan/scanner.rb +230 -0
  170. data/lib/rex/pescan/search.rb +68 -0
  171. data/lib/rex/platforms.rb +2 -0
  172. data/lib/rex/platforms/windows.rb +52 -0
  173. data/lib/rex/poly.rb +134 -0
  174. data/lib/rex/poly/block.rb +480 -0
  175. data/lib/rex/poly/machine.rb +13 -0
  176. data/lib/rex/poly/machine/machine.rb +830 -0
  177. data/lib/rex/poly/machine/x86.rb +509 -0
  178. data/lib/rex/poly/register.rb +101 -0
  179. data/lib/rex/poly/register/x86.rb +41 -0
  180. data/lib/rex/post.rb +7 -0
  181. data/lib/rex/post/dir.rb +51 -0
  182. data/lib/rex/post/file.rb +172 -0
  183. data/lib/rex/post/file_stat.rb +220 -0
  184. data/lib/rex/post/gen.pl +13 -0
  185. data/lib/rex/post/io.rb +182 -0
  186. data/lib/rex/post/meterpreter.rb +5 -0
  187. data/lib/rex/post/meterpreter/channel.rb +446 -0
  188. data/lib/rex/post/meterpreter/channel_container.rb +54 -0
  189. data/lib/rex/post/meterpreter/channels/pool.rb +160 -0
  190. data/lib/rex/post/meterpreter/channels/pools/file.rb +62 -0
  191. data/lib/rex/post/meterpreter/channels/pools/stream_pool.rb +103 -0
  192. data/lib/rex/post/meterpreter/channels/stream.rb +87 -0
  193. data/lib/rex/post/meterpreter/client.rb +483 -0
  194. data/lib/rex/post/meterpreter/client_core.rb +352 -0
  195. data/lib/rex/post/meterpreter/dependencies.rb +3 -0
  196. data/lib/rex/post/meterpreter/extension.rb +32 -0
  197. data/lib/rex/post/meterpreter/extensions/android/android.rb +128 -0
  198. data/lib/rex/post/meterpreter/extensions/android/tlv.rb +40 -0
  199. data/lib/rex/post/meterpreter/extensions/espia/espia.rb +58 -0
  200. data/lib/rex/post/meterpreter/extensions/espia/tlv.rb +17 -0
  201. data/lib/rex/post/meterpreter/extensions/extapi/adsi/adsi.rb +71 -0
  202. data/lib/rex/post/meterpreter/extensions/extapi/clipboard/clipboard.rb +169 -0
  203. data/lib/rex/post/meterpreter/extensions/extapi/extapi.rb +45 -0
  204. data/lib/rex/post/meterpreter/extensions/extapi/service/service.rb +104 -0
  205. data/lib/rex/post/meterpreter/extensions/extapi/tlv.rb +77 -0
  206. data/lib/rex/post/meterpreter/extensions/extapi/window/window.rb +56 -0
  207. data/lib/rex/post/meterpreter/extensions/extapi/wmi/wmi.rb +75 -0
  208. data/lib/rex/post/meterpreter/extensions/incognito/incognito.rb +94 -0
  209. data/lib/rex/post/meterpreter/extensions/incognito/tlv.rb +22 -0
  210. data/lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb +361 -0
  211. data/lib/rex/post/meterpreter/extensions/kiwi/tlv.rb +76 -0
  212. data/lib/rex/post/meterpreter/extensions/lanattacks/dhcp/dhcp.rb +78 -0
  213. data/lib/rex/post/meterpreter/extensions/lanattacks/lanattacks.rb +43 -0
  214. data/lib/rex/post/meterpreter/extensions/lanattacks/tftp/tftp.rb +49 -0
  215. data/lib/rex/post/meterpreter/extensions/lanattacks/tlv.rb +17 -0
  216. data/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb +128 -0
  217. data/lib/rex/post/meterpreter/extensions/mimikatz/tlv.rb +16 -0
  218. data/lib/rex/post/meterpreter/extensions/networkpug/networkpug.rb +57 -0
  219. data/lib/rex/post/meterpreter/extensions/networkpug/tlv.rb +16 -0
  220. data/lib/rex/post/meterpreter/extensions/priv/fs.rb +118 -0
  221. data/lib/rex/post/meterpreter/extensions/priv/passwd.rb +61 -0
  222. data/lib/rex/post/meterpreter/extensions/priv/priv.rb +109 -0
  223. data/lib/rex/post/meterpreter/extensions/priv/tlv.rb +29 -0
  224. data/lib/rex/post/meterpreter/extensions/sniffer/sniffer.rb +117 -0
  225. data/lib/rex/post/meterpreter/extensions/sniffer/tlv.rb +27 -0
  226. data/lib/rex/post/meterpreter/extensions/stdapi/constants.rb +396 -0
  227. data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +284 -0
  228. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +399 -0
  229. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file_stat.rb +104 -0
  230. data/lib/rex/post/meterpreter/extensions/stdapi/fs/io.rb +48 -0
  231. data/lib/rex/post/meterpreter/extensions/stdapi/net/arp.rb +59 -0
  232. data/lib/rex/post/meterpreter/extensions/stdapi/net/config.rb +256 -0
  233. data/lib/rex/post/meterpreter/extensions/stdapi/net/interface.rb +129 -0
  234. data/lib/rex/post/meterpreter/extensions/stdapi/net/netstat.rb +97 -0
  235. data/lib/rex/post/meterpreter/extensions/stdapi/net/resolve.rb +106 -0
  236. data/lib/rex/post/meterpreter/extensions/stdapi/net/route.rb +67 -0
  237. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +139 -0
  238. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +180 -0
  239. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb +168 -0
  240. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +209 -0
  241. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb +38146 -0
  242. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb +48 -0
  243. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_advapi32.rb +2102 -0
  244. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_crypt32.rb +32 -0
  245. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_iphlpapi.rb +97 -0
  246. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +3852 -0
  247. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_netapi32.rb +100 -0
  248. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ntdll.rb +168 -0
  249. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_psapi.rb +32 -0
  250. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_shell32.rb +32 -0
  251. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_user32.rb +3170 -0
  252. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_version.rb +41 -0
  253. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wlanapi.rb +87 -0
  254. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb +128 -0
  255. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ws2_32.rb +613 -0
  256. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb +388 -0
  257. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb +111 -0
  258. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb +149 -0
  259. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_wrapper.rb +27 -0
  260. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/mock_magic.rb +515 -0
  261. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/multicall.rb +319 -0
  262. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/platform_util.rb +23 -0
  263. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb +301 -0
  264. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/tlv.rb +56 -0
  265. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/type/pointer_util.rb +106 -0
  266. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb +676 -0
  267. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb +96 -0
  268. data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +151 -0
  269. data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +128 -0
  270. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +192 -0
  271. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log_subsystem/event_record.rb +41 -0
  272. data/lib/rex/post/meterpreter/extensions/stdapi/sys/power.rb +60 -0
  273. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +408 -0
  274. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/image.rb +129 -0
  275. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/io.rb +55 -0
  276. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/memory.rb +336 -0
  277. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/thread.rb +141 -0
  278. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +328 -0
  279. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +193 -0
  280. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_value.rb +102 -0
  281. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/remote_registry_key.rb +188 -0
  282. data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +180 -0
  283. data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +236 -0
  284. data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +259 -0
  285. data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +201 -0
  286. data/lib/rex/post/meterpreter/inbound_packet_handler.rb +30 -0
  287. data/lib/rex/post/meterpreter/object_aliases.rb +83 -0
  288. data/lib/rex/post/meterpreter/packet.rb +709 -0
  289. data/lib/rex/post/meterpreter/packet_dispatcher.rb +543 -0
  290. data/lib/rex/post/meterpreter/packet_parser.rb +94 -0
  291. data/lib/rex/post/meterpreter/packet_response_waiter.rb +83 -0
  292. data/lib/rex/post/meterpreter/ui/console.rb +142 -0
  293. data/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb +86 -0
  294. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb +383 -0
  295. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +939 -0
  296. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/espia.rb +109 -0
  297. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi.rb +65 -0
  298. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/adsi.rb +198 -0
  299. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/clipboard.rb +444 -0
  300. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/service.rb +199 -0
  301. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/window.rb +118 -0
  302. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/wmi.rb +108 -0
  303. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/incognito.rb +242 -0
  304. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb +509 -0
  305. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks.rb +60 -0
  306. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/dhcp.rb +254 -0
  307. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/tftp.rb +159 -0
  308. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +182 -0
  309. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/networkpug.rb +232 -0
  310. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv.rb +62 -0
  311. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +97 -0
  312. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/passwd.rb +52 -0
  313. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +133 -0
  314. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +204 -0
  315. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi.rb +66 -0
  316. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +527 -0
  317. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +448 -0
  318. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +906 -0
  319. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +318 -0
  320. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +343 -0
  321. data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +99 -0
  322. data/lib/rex/post/permission.rb +26 -0
  323. data/lib/rex/post/process.rb +57 -0
  324. data/lib/rex/post/thread.rb +57 -0
  325. data/lib/rex/post/ui.rb +52 -0
  326. data/lib/rex/proto.rb +15 -0
  327. data/lib/rex/proto/addp.rb +218 -0
  328. data/lib/rex/proto/dcerpc.rb +7 -0
  329. data/lib/rex/proto/dcerpc/client.rb +362 -0
  330. data/lib/rex/proto/dcerpc/exceptions.rb +151 -0
  331. data/lib/rex/proto/dcerpc/handle.rb +48 -0
  332. data/lib/rex/proto/dcerpc/ndr.rb +73 -0
  333. data/lib/rex/proto/dcerpc/packet.rb +264 -0
  334. data/lib/rex/proto/dcerpc/response.rb +188 -0
  335. data/lib/rex/proto/dcerpc/uuid.rb +85 -0
  336. data/lib/rex/proto/dcerpc/wdscp.rb +3 -0
  337. data/lib/rex/proto/dcerpc/wdscp/constants.rb +89 -0
  338. data/lib/rex/proto/dcerpc/wdscp/packet.rb +94 -0
  339. data/lib/rex/proto/dhcp.rb +7 -0
  340. data/lib/rex/proto/dhcp/constants.rb +34 -0
  341. data/lib/rex/proto/dhcp/server.rb +334 -0
  342. data/lib/rex/proto/drda.rb +6 -0
  343. data/lib/rex/proto/drda/constants.rb +50 -0
  344. data/lib/rex/proto/drda/packet.rb +253 -0
  345. data/lib/rex/proto/drda/utils.rb +124 -0
  346. data/lib/rex/proto/http.rb +7 -0
  347. data/lib/rex/proto/http/client.rb +722 -0
  348. data/lib/rex/proto/http/client_request.rb +472 -0
  349. data/lib/rex/proto/http/handler.rb +47 -0
  350. data/lib/rex/proto/http/handler/erb.rb +129 -0
  351. data/lib/rex/proto/http/handler/proc.rb +61 -0
  352. data/lib/rex/proto/http/header.rb +173 -0
  353. data/lib/rex/proto/http/packet.rb +414 -0
  354. data/lib/rex/proto/http/request.rb +354 -0
  355. data/lib/rex/proto/http/response.rb +151 -0
  356. data/lib/rex/proto/http/server.rb +385 -0
  357. data/lib/rex/proto/iax2.rb +2 -0
  358. data/lib/rex/proto/iax2/call.rb +326 -0
  359. data/lib/rex/proto/iax2/client.rb +218 -0
  360. data/lib/rex/proto/iax2/codecs.rb +5 -0
  361. data/lib/rex/proto/iax2/codecs/alaw.rb +16 -0
  362. data/lib/rex/proto/iax2/codecs/g711.rb +2176 -0
  363. data/lib/rex/proto/iax2/codecs/mulaw.rb +17 -0
  364. data/lib/rex/proto/iax2/constants.rb +262 -0
  365. data/lib/rex/proto/ipmi.rb +57 -0
  366. data/lib/rex/proto/ipmi/channel_auth_reply.rb +89 -0
  367. data/lib/rex/proto/ipmi/open_session_reply.rb +36 -0
  368. data/lib/rex/proto/ipmi/rakp2.rb +36 -0
  369. data/lib/rex/proto/ipmi/utils.rb +125 -0
  370. data/lib/rex/proto/natpmp.rb +7 -0
  371. data/lib/rex/proto/natpmp/constants.rb +19 -0
  372. data/lib/rex/proto/natpmp/packet.rb +45 -0
  373. data/lib/rex/proto/ntlm.rb +8 -0
  374. data/lib/rex/proto/ntlm/base.rb +327 -0
  375. data/lib/rex/proto/ntlm/constants.rb +75 -0
  376. data/lib/rex/proto/ntlm/crypt.rb +412 -0
  377. data/lib/rex/proto/ntlm/exceptions.rb +17 -0
  378. data/lib/rex/proto/ntlm/message.rb +534 -0
  379. data/lib/rex/proto/ntlm/utils.rb +765 -0
  380. data/lib/rex/proto/ntp.rb +3 -0
  381. data/lib/rex/proto/ntp/constants.rb +12 -0
  382. data/lib/rex/proto/ntp/modes.rb +130 -0
  383. data/lib/rex/proto/pjl.rb +31 -0
  384. data/lib/rex/proto/pjl/client.rb +163 -0
  385. data/lib/rex/proto/proxy/socks4a.rb +441 -0
  386. data/lib/rex/proto/rfb.rb +13 -0
  387. data/lib/rex/proto/rfb/cipher.rb +82 -0
  388. data/lib/rex/proto/rfb/client.rb +205 -0
  389. data/lib/rex/proto/rfb/constants.rb +50 -0
  390. data/lib/rex/proto/sip.rb +4 -0
  391. data/lib/rex/proto/sip/response.rb +61 -0
  392. data/lib/rex/proto/smb.rb +8 -0
  393. data/lib/rex/proto/smb/client.rb +2064 -0
  394. data/lib/rex/proto/smb/constants.rb +1064 -0
  395. data/lib/rex/proto/smb/crypt.rb +37 -0
  396. data/lib/rex/proto/smb/evasions.rb +67 -0
  397. data/lib/rex/proto/smb/exceptions.rb +867 -0
  398. data/lib/rex/proto/smb/simpleclient.rb +173 -0
  399. data/lib/rex/proto/smb/simpleclient/open_file.rb +106 -0
  400. data/lib/rex/proto/smb/simpleclient/open_pipe.rb +57 -0
  401. data/lib/rex/proto/smb/utils.rb +104 -0
  402. data/lib/rex/proto/sunrpc.rb +2 -0
  403. data/lib/rex/proto/sunrpc/client.rb +196 -0
  404. data/lib/rex/proto/tftp.rb +13 -0
  405. data/lib/rex/proto/tftp/client.rb +344 -0
  406. data/lib/rex/proto/tftp/constants.rb +39 -0
  407. data/lib/rex/proto/tftp/server.rb +497 -0
  408. data/lib/rex/random_identifier_generator.rb +177 -0
  409. data/lib/rex/registry.rb +14 -0
  410. data/lib/rex/registry/hive.rb +132 -0
  411. data/lib/rex/registry/lfkey.rb +51 -0
  412. data/lib/rex/registry/nodekey.rb +54 -0
  413. data/lib/rex/registry/regf.rb +25 -0
  414. data/lib/rex/registry/valuekey.rb +67 -0
  415. data/lib/rex/registry/valuelist.rb +29 -0
  416. data/lib/rex/ropbuilder.rb +8 -0
  417. data/lib/rex/ropbuilder/rop.rb +271 -0
  418. data/lib/rex/script.rb +42 -0
  419. data/lib/rex/script/base.rb +61 -0
  420. data/lib/rex/script/meterpreter.rb +16 -0
  421. data/lib/rex/script/shell.rb +10 -0
  422. data/lib/rex/service.rb +49 -0
  423. data/lib/rex/service_manager.rb +154 -0
  424. data/lib/rex/services/local_relay.rb +424 -0
  425. data/lib/rex/socket.rb +788 -0
  426. data/lib/rex/socket/comm.rb +120 -0
  427. data/lib/rex/socket/comm/local.rb +526 -0
  428. data/lib/rex/socket/ip.rb +132 -0
  429. data/lib/rex/socket/parameters.rb +363 -0
  430. data/lib/rex/socket/range_walker.rb +470 -0
  431. data/lib/rex/socket/ssl_tcp.rb +345 -0
  432. data/lib/rex/socket/ssl_tcp_server.rb +188 -0
  433. data/lib/rex/socket/subnet_walker.rb +76 -0
  434. data/lib/rex/socket/switch_board.rb +289 -0
  435. data/lib/rex/socket/tcp.rb +79 -0
  436. data/lib/rex/socket/tcp_server.rb +67 -0
  437. data/lib/rex/socket/udp.rb +165 -0
  438. data/lib/rex/sslscan/result.rb +201 -0
  439. data/lib/rex/sslscan/scanner.rb +206 -0
  440. data/lib/rex/struct2.rb +5 -0
  441. data/lib/rex/struct2/c_struct.rb +181 -0
  442. data/lib/rex/struct2/c_struct_template.rb +39 -0
  443. data/lib/rex/struct2/constant.rb +26 -0
  444. data/lib/rex/struct2/element.rb +44 -0
  445. data/lib/rex/struct2/generic.rb +73 -0
  446. data/lib/rex/struct2/restraint.rb +54 -0
  447. data/lib/rex/struct2/s_string.rb +72 -0
  448. data/lib/rex/struct2/s_struct.rb +111 -0
  449. data/lib/rex/sync.rb +6 -0
  450. data/lib/rex/sync/event.rb +85 -0
  451. data/lib/rex/sync/read_write_lock.rb +177 -0
  452. data/lib/rex/sync/ref.rb +58 -0
  453. data/lib/rex/sync/thread_safe.rb +83 -0
  454. data/lib/rex/text.rb +1813 -0
  455. data/lib/rex/thread_factory.rb +43 -0
  456. data/lib/rex/time.rb +66 -0
  457. data/lib/rex/transformer.rb +116 -0
  458. data/lib/rex/ui.rb +22 -0
  459. data/lib/rex/ui/interactive.rb +304 -0
  460. data/lib/rex/ui/output.rb +85 -0
  461. data/lib/rex/ui/output/none.rb +19 -0
  462. data/lib/rex/ui/progress_tracker.rb +97 -0
  463. data/lib/rex/ui/subscriber.rb +160 -0
  464. data/lib/rex/ui/text/color.rb +98 -0
  465. data/lib/rex/ui/text/dispatcher_shell.rb +538 -0
  466. data/lib/rex/ui/text/input.rb +119 -0
  467. data/lib/rex/ui/text/input/buffer.rb +79 -0
  468. data/lib/rex/ui/text/input/readline.rb +129 -0
  469. data/lib/rex/ui/text/input/socket.rb +96 -0
  470. data/lib/rex/ui/text/input/stdio.rb +46 -0
  471. data/lib/rex/ui/text/irb_shell.rb +62 -0
  472. data/lib/rex/ui/text/output.rb +86 -0
  473. data/lib/rex/ui/text/output/buffer.rb +62 -0
  474. data/lib/rex/ui/text/output/buffer/stdout.rb +26 -0
  475. data/lib/rex/ui/text/output/file.rb +44 -0
  476. data/lib/rex/ui/text/output/socket.rb +44 -0
  477. data/lib/rex/ui/text/output/stdio.rb +53 -0
  478. data/lib/rex/ui/text/output/tee.rb +56 -0
  479. data/lib/rex/ui/text/progress_tracker.rb +57 -0
  480. data/lib/rex/ui/text/shell.rb +403 -0
  481. data/lib/rex/ui/text/table.rb +346 -0
  482. data/lib/rex/zip.rb +96 -0
  483. data/lib/rex/zip/archive.rb +130 -0
  484. data/lib/rex/zip/blocks.rb +184 -0
  485. data/lib/rex/zip/entry.rb +122 -0
  486. data/lib/rex/zip/jar.rb +283 -0
  487. data/lib/rex/zip/samples/comment.rb +32 -0
  488. data/lib/rex/zip/samples/mkwar.rb +138 -0
  489. data/lib/rex/zip/samples/mkzip.rb +19 -0
  490. data/lib/rex/zip/samples/recursive.rb +58 -0
  491. metadata +536 -0
@@ -0,0 +1,6 @@
1
+ # -*- coding: binary -*-
2
+ require 'rex/proto/drda/constants'
3
+ require 'rex/proto/drda/packet'
4
+ require 'rex/proto/drda/utils'
5
+
6
+
@@ -0,0 +1,50 @@
1
+ # -*- coding: binary -*-
2
+ require 'rex/proto/drda'
3
+
4
+ module Rex
5
+ module Proto
6
+ module DRDA
7
+ class Constants
8
+
9
+ require 'rex/text'
10
+
11
+ # DRDA Code Points
12
+
13
+ EXCSAT = 0x1041 # Exchange Server Attributes
14
+ EXTNAM = 0x115e # External Name
15
+ MGRLVLLS = 0x1404 # Manager-Level List
16
+ SRVCLSNM = 0x1147 # Server Class Name
17
+ SRVNAM = 0x116d # Server Name
18
+ SRVRLSLV = 0x115a # Server Product Release Level
19
+ ACCSEC = 0x106d # Access Security
20
+ SECMEC = 0x11a2 # Security Mechanism
21
+ RDBNAM = 0x2110 # Relational Database Name
22
+ SECTKN = 0x11dc # Security Token
23
+ EXCSATRD = 0x1443 # Server Attributes Reply Data
24
+ ACCSECRD = 0x14ac # Access Security Reply Data
25
+ SRVDGN = 0x1153 # Server Diagnostic Information
26
+ RDBNFNRM = 0x2211 # Relational Database Not Found
27
+ SECCHK = 0x106e # Security Check
28
+ USERID = 0x11a0 # Remote User ID
29
+ PASSWORD = 0x11a1 # Remote Password
30
+ RDBACCCL = 0x210f # RDB Access Manager Class
31
+ PRDID = 0x112e # Product-Specific Identifier
32
+ PRDDTA = 0x2104 # Product-Specific Data
33
+ TYPEDEFNAM = 0x002f # Data Type Definition Name
34
+ TTPEDEFOVR = 0x0035 # TYPEDEF Overrides
35
+ CRRTKN = 0x2135 # Correlation Token
36
+ TRGDFTRT = 0x213b # Target Default Value Return
37
+ SQLCARD = 0x2408 # SQL Communications Area Reply Data
38
+ SECCHKRM = 0x1219 # Security Check Response Message
39
+ SRVCOD = 0x1149 # Severity Code
40
+ SECCHKCD = 0x11a4 # Security Check Code
41
+ ACCRDBRM = 0x2201 # Access to RDB Completed
42
+
43
+ def self.const_values
44
+ self.constants.map {|x| self.const_get x}
45
+ end
46
+
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,253 @@
1
+ # -*- coding: binary -*-
2
+ require 'rex/proto/drda'
3
+
4
+ module Rex
5
+ module Proto
6
+ module DRDA
7
+
8
+ class Error < StandardError; end
9
+ class RespError < Error; end
10
+
11
+ # See:
12
+ # http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=/com.ibm.db29.doc.drda/db2z_excsat.htm
13
+ class MGRLVLLS_PARAM < Struct.new(:length, :codepoint, :payload)
14
+ def initialize(args={})
15
+ self[:codepoint] = Constants::MGRLVLLS
16
+ self[:payload] = "\x14\x03\x00\x0a\x24\x07\x00\x0a" +
17
+ "\x14\x74\x00\x05\x24\x0f\x00\x08" +
18
+ "\x14\x40\x00\x09\x1c\x08\x04\xb8"
19
+ self[:length] = self[:payload].to_s.size+4
20
+ end
21
+ def to_s
22
+ self.to_a.pack("nna*")
23
+ end
24
+ end
25
+
26
+ # Currently, only takes a MGRLVLLS param. Extend the struct
27
+ # when more parameters are defined.
28
+ class EXCSAT_DDM < Struct.new(:length, :magic, :format, :correlid, :length2,
29
+ :codepoint, :mgrlvlls)
30
+
31
+ def initialize(args={})
32
+ self[:magic] = 0xd0
33
+ self[:format] = 0x41
34
+ self[:correlid] = 1
35
+ self[:codepoint] = Constants::EXCSAT
36
+ self[:mgrlvlls] = args[:mgrlvlls] || MGRLVLLS_PARAM.new.to_s
37
+ self[:length] = (10 + self[:mgrlvlls].to_s.size)
38
+ self[:length2] = self[:length]-6
39
+ end
40
+
41
+ def to_s
42
+ packstr = "nCCnnn"
43
+ packstr += "a*" # Pack smarter as more params are added.
44
+ self.to_a.pack(packstr)
45
+ end
46
+ end
47
+
48
+ # See http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=/com.ibm.db29.doc.drda/db2z_accsec.htm
49
+ # for all sorts of info about SECMEC.
50
+ class SECMEC_PARAM < Struct.new(:length, :codepoint, :payload)
51
+ def initialize(args={})
52
+ self[:length] = 6
53
+ self[:codepoint] = Constants::SECMEC
54
+ self[:payload] = 3 # Plaintext username and password.
55
+ end
56
+ def to_s
57
+ self.to_a.pack("nnn")
58
+ end
59
+ end
60
+
61
+ # Relational Database name parameter.
62
+ class RDBNAM_PARAM < Struct.new(:length, :codepoint, :payload)
63
+ def initialize(args={})
64
+ self[:length] = 22 # Since the database name is padded out.
65
+ self[:codepoint] = Constants::RDBNAM
66
+ self[:payload] = encode(args[:payload].to_s)
67
+ end
68
+
69
+ def encode(str)
70
+ Rex::Text.to_ebcdic([str].pack("A18"))
71
+ end
72
+
73
+ def payload=(str)
74
+ self[:payload] = encode(str.to_s)
75
+ end
76
+
77
+ def to_s
78
+ self.to_a.pack("nna18")
79
+ end
80
+
81
+ end
82
+
83
+ # The ACCSEC DDM is responsible for picking the security mechanism (SECMEC)
84
+ # which, in our case, will always be plain text username and password. It
85
+ # also sets the relational database name (RDBNAM), if specified. You need
86
+ # one to login, but not to probe.
87
+ class ACCSEC_DDM < Struct.new(:length, :magic, :format, :correlid, :length2,
88
+ :codepoint, :secmec, :rdbnam)
89
+ def initialize(args={})
90
+ self[:magic] = 0xd0
91
+ self[:format] = args[:format] || 0x01
92
+ self[:correlid] = 2
93
+ self[:codepoint] = Constants::ACCSEC
94
+ self[:secmec] = SECMEC_PARAM.new.to_s
95
+ if args[:dbname] # Include a database name if we're given one.
96
+ self[:rdbnam] = RDBNAM_PARAM.new(:payload => args[:dbname]).to_s
97
+ end
98
+ self[:length] = 10 + self[:secmec].to_s.size + self[:rdbnam].to_s.size
99
+ self[:length2] = self[:length]-6
100
+ end
101
+ def dbname=(str)
102
+ self[:rdbnam] = RDBNAM_PARAM.new(:payload => args[:dbname]).to_s
103
+ end
104
+ def to_s
105
+ packstr = "nCCnnna6"
106
+ packstr += "a22" if self[:rdbnam]
107
+ self.to_a.pack(packstr)
108
+ end
109
+ end
110
+
111
+ class DDM_PARAM < Struct.new(:length, :codepoint, :payload)
112
+
113
+ def read(str="")
114
+ raise DRDA::Error, "Input isn't a String." if !str.kind_of? String
115
+ raise DRDA::RespError, "DDM_PARAM is too short" if str.size < 4
116
+ (self[:length], self[:codepoint]) =
117
+ str.unpack("nn")
118
+ raise DRDA::RespError, "DDM_PARAM Length is too short" if self[:length] < 4
119
+ rest = str[4,self[:length]-4] # If it's negative or whatever, it'll end up as "".
120
+ self[:payload] = rest.to_s[0,self[:length]-4]
121
+ return self
122
+ end
123
+
124
+ def to_s
125
+ self.to_a.pack("nna*")
126
+ end
127
+
128
+ end
129
+
130
+ class BASIC_DDM < Struct.new(:length, :magic, :format, :correlid,
131
+ :length2, :codepoint, :payload)
132
+ def initialize
133
+ self[:payload] = []
134
+ end
135
+
136
+ def read(str="")
137
+ self[:payload].clear
138
+ raise DRDA::Error, "Input isn't a String." if !str.kind_of? String
139
+ raise DRDA::RespError, "Response is too short." if str.size < 10
140
+ (self[:length],self[:magic],self[:format],
141
+ self[:correlid],self[:length2],self[:codepoint]) =
142
+ str.unpack("nCCnnn")
143
+ sanity_check
144
+ rest = str[10,self[:length2]-4]
145
+ i = 0
146
+ while (i < rest.size)
147
+ if self[:codepoint] == Constants::SQLCARD # These aren't DDM's.
148
+ this_param = rest[i,self[:length]-10]
149
+ else
150
+ this_param = DDM_PARAM.new.read(rest[i,rest.size])
151
+ end
152
+ self[:payload] << this_param
153
+ i += this_param.to_s.size
154
+ end
155
+ return self
156
+ end
157
+
158
+ # Just a quick test.
159
+ def sanity_check
160
+ if self[:length] < 10
161
+ raise DRDA::RespError, "DDM Length is too short."
162
+ elsif self[:length2] < 4
163
+ raise DRDA::RespError, "DDM Length2 is too short."
164
+ elsif self[:length]-6 != self[:length2]
165
+ raise DRDA::RespError, "Codepoint: 0x#{self[:codepoint].to_s(16)} DDM Length2 (0x#{self[:length2].to_s(16)}) isn't six less than Length (0x#{self[:length].to_s(16)})"
166
+ end
167
+ end
168
+
169
+ def to_s
170
+ self.to_a.pack("nCCnnn") + self[:payload].map {|x| x.to_s}.join
171
+ end
172
+
173
+ end
174
+
175
+ class SERVER_PACKET < Array
176
+
177
+ def read(str="")
178
+ raise DRDA::Error, "Input isn't a String." if !str.kind_of? String
179
+ self.clear
180
+ i = 0
181
+ while(i < str.size)
182
+ this_ddm = BASIC_DDM.new.read(str[i,str.size])
183
+ self << this_ddm
184
+ i += this_ddm.to_s.size
185
+ end
186
+ return self
187
+ end
188
+
189
+ def to_s; self.join; end
190
+ def sz; self.to_s.size; end
191
+
192
+ end
193
+
194
+ class PASSWORD_PARAM < Struct.new(:length, :codepoint, :payload)
195
+ def initialize(args={})
196
+ self[:codepoint] = Constants::PASSWORD
197
+ self[:payload] = Rex::Text.to_ebcdic(args[:payload].to_s)
198
+ self[:length] = self[:payload].size + 4
199
+ end
200
+ def encode(str)
201
+ Rex::Text.to_ebcdic(str)
202
+ end
203
+ def to_s
204
+ self.to_a.pack("nna*")
205
+ end
206
+ end
207
+
208
+ class USERID_PARAM < Struct.new(:length, :codepoint, :payload)
209
+ def initialize(args={})
210
+ self[:codepoint] = Constants::USERID
211
+ self[:payload] = Rex::Text.to_ebcdic(args[:payload].to_s)
212
+ self[:length] = self[:payload].size + 4
213
+ end
214
+ def encode(str)
215
+ Rex::Text.to_ebcdic(str)
216
+ end
217
+ def to_s
218
+ self.to_a.pack("nna*")
219
+ end
220
+ end
221
+
222
+ class SECCHK_DDM < Struct.new(:length, :magic, :format, :correlid, :length2,
223
+ :codepoint, :secmec, :rdbnam, :password, :userid)
224
+ def initialize(args={}) # Takes :dbname, :dbpass, :dbuser
225
+ self[:magic] = 0xd0
226
+ self[:format] = 0x01
227
+ self[:correlid] = 2
228
+ self[:codepoint] = Constants::SECCHK
229
+ self[:secmec] = SECMEC_PARAM.new.to_s
230
+ if args[:dbname] # Include a database name if we're given one.
231
+ self[:rdbnam] = RDBNAM_PARAM.new(:payload => args[:dbname]).to_s
232
+ end
233
+ self[:password] = PASSWORD_PARAM.new(:payload => args[:dbpass]).to_s
234
+ self[:userid] = USERID_PARAM.new(:payload => args[:dbuser]).to_s
235
+ self[:length] = ( 10 + self[:secmec].to_s.size + self[:rdbnam].to_s.size +
236
+ self[:password].to_s.size + self[:userid].to_s.size )
237
+ self[:length2] = self[:length]-6
238
+ end
239
+ def dbname=(str)
240
+ self[:rdbnam] = RDBNAM_PARAM.new(:payload => args[:dbname]).to_s
241
+ end
242
+ def to_s
243
+ packstr = "nCCnnna6"
244
+ packstr += "a22" if self[:rdbnam]
245
+ packstr += "a*a*" # username and password
246
+ self.to_a.pack(packstr)
247
+ end
248
+ end
249
+
250
+ end
251
+ end
252
+ end
253
+
@@ -0,0 +1,124 @@
1
+ # -*- coding: binary -*-
2
+ require 'rex/proto/drda'
3
+
4
+ module Rex
5
+ module Proto
6
+ module DRDA
7
+ class Utils
8
+
9
+ # Creates a packet with EXCSAT_DDM and an ACCSEC_DDM. This will elicit
10
+ # a reponse from the target server.
11
+ def self.client_probe(dbname=nil)
12
+ pkt = [
13
+ EXCSAT_DDM.new,
14
+ ACCSEC_DDM.new(:dbname => dbname)
15
+ ]
16
+ pkt.map {|x| x.to_s}.join
17
+ end
18
+
19
+ # Creates a packet with EXCSAT_DDM and an SECCHK_DDM.
20
+ # In order to ever succeed, you do need a successful probe first.
21
+ def self.client_auth(args={})
22
+ dbname = args[:dbname]
23
+ dbuser = args[:dbuser]
24
+ dbpass = args[:dbpass]
25
+ pkt = [
26
+ ACCSEC_DDM.new(:format => 0x41),
27
+ SECCHK_DDM.new(:dbname => dbname, :dbuser => dbuser, :dbpass => dbpass)
28
+ ]
29
+ pkt.map {|x| x.to_s}.join
30
+ end
31
+
32
+ def self.server_packet_info(obj)
33
+ info_hash = {}
34
+ return info_hash unless obj.kind_of? Rex::Proto::DRDA::SERVER_PACKET
35
+ obj.each do |ddm|
36
+ case ddm.codepoint
37
+ when Constants::EXCSATRD
38
+ info_hash.merge!(_info_excsatrd(ddm))
39
+ when Constants::ACCSECRD
40
+ info_hash.merge!(_info_accsecrd(ddm))
41
+ when Constants::RDBNFNRM
42
+ info_hash.merge!(_info_rdbnfnrm(ddm))
43
+ when Constants::SECCHKRM
44
+ info_hash.merge!(_info_secchkrm(ddm))
45
+ else
46
+ next
47
+ end
48
+ end
49
+ return info_hash
50
+ end
51
+
52
+ def self._info_excsatrd(ddm)
53
+ info_hash = {:excsatrd => true}
54
+ ddm.payload.each do |param|
55
+ case param.codepoint
56
+ when Constants::SRVNAM
57
+ info_hash[:instance_name] = Rex::Text.from_ebcdic(param.payload)
58
+ when Constants::SRVCLSNM
59
+ info_hash[:platform] = Rex::Text.from_ebcdic(param.payload)
60
+ when Constants::SRVRLSLV
61
+ info_hash[:version] = Rex::Text.from_ebcdic(param.payload)
62
+ else
63
+ next
64
+ end
65
+ end
66
+ return info_hash
67
+ end
68
+
69
+ def self._info_accsecrd(ddm)
70
+ info_hash = {:accsecrd => true}
71
+ ddm.payload.each do |param|
72
+ case param.codepoint
73
+ when Constants::SECMEC
74
+ info_hash[:plaintext_auth] = true if param.payload =~ /\x00\x03/n
75
+ when Constants::SECCHKCD
76
+ info_hash[:security_check_code] = param.payload.unpack("C").first
77
+ # A little spurious? This is always nonzero when there's no SECCHKRM DDM.
78
+ info_hash[:db_login_success] = false unless info_hash[:security_check_code].zero?
79
+ else
80
+ next
81
+ end
82
+ end
83
+ return info_hash
84
+ end
85
+
86
+ def self._info_rdbnfnrm(ddm)
87
+ info_hash = {:rdbnfnrm => true}
88
+ info_hash[:database_found] = false
89
+ ddm.payload.each do |param|
90
+ case param.codepoint
91
+ when Constants::RDBNAM
92
+ info_hash[:db_name] = Rex::Text.from_ebcdic(param.payload).unpack("A*").first
93
+ when Constants::SRVDGN
94
+ info_hash[:error_message] = Rex::Text.from_ebcdic(param.payload)
95
+ else
96
+ next
97
+ end
98
+ end
99
+ return info_hash
100
+ end
101
+
102
+ def self._info_secchkrm(ddm)
103
+ info_hash = {:secchkrm => true}
104
+ ddm.payload.each do |param|
105
+ case param.codepoint
106
+ when Constants::SRVCOD
107
+ info_hash[:severity_code] = param.payload.unpack("n").first
108
+ when Constants::SECCHKCD
109
+ info_hash[:security_check_code] = param.payload.unpack("C").first
110
+ else
111
+ next
112
+ end
113
+ end
114
+ if info_hash[:serverity].to_i.zero? and info_hash[:security_check_code].to_i.zero?
115
+ info_hash[:db_login_success] = true
116
+ end
117
+ return info_hash
118
+ end
119
+
120
+ end
121
+
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,7 @@
1
+ # -*- coding: binary -*-
2
+ require 'rex/proto/http/packet'
3
+ require 'rex/proto/http/request'
4
+ require 'rex/proto/http/response'
5
+ require 'rex/proto/http/client'
6
+ require 'rex/proto/http/server'
7
+ require 'rex/proto/http/client_request'
@@ -0,0 +1,722 @@
1
+ # -*- coding: binary -*-
2
+ require 'rex/socket'
3
+ require 'rex/proto/http'
4
+ require 'rex/text'
5
+ require 'digest'
6
+ require 'rex/proto/ntlm/crypt'
7
+ require 'rex/proto/ntlm/constants'
8
+ require 'rex/proto/ntlm/utils'
9
+ require 'rex/proto/ntlm/exceptions'
10
+
11
+ require 'rex/proto/http/client_request'
12
+
13
+ module Rex
14
+ module Proto
15
+ module Http
16
+
17
+ ###
18
+ #
19
+ # Acts as a client to an HTTP server, sending requests and receiving responses.
20
+ #
21
+ # See the RFC: http://www.w3.org/Protocols/rfc2616/rfc2616.html
22
+ #
23
+ ###
24
+ class Client
25
+
26
+ DefaultUserAgent = ClientRequest::DefaultUserAgent
27
+
28
+ #
29
+ # Creates a new client instance
30
+ #
31
+ def initialize(host, port = 80, context = {}, ssl = nil, ssl_version = nil, proxies = nil, username = '', password = '')
32
+ self.hostname = host
33
+ self.port = port.to_i
34
+ self.context = context
35
+ self.ssl = ssl
36
+ self.ssl_version = ssl_version
37
+ self.proxies = proxies
38
+ self.username = username
39
+ self.password = password
40
+
41
+ # Take ClientRequest's defaults, but override with our own
42
+ self.config = Http::ClientRequest::DefaultConfig.merge({
43
+ 'read_max_data' => (1024*1024*1),
44
+ 'vhost' => self.hostname,
45
+ })
46
+
47
+ # XXX: This info should all be controlled by ClientRequest
48
+ self.config_types = {
49
+ 'uri_encode_mode' => ['hex-normal', 'hex-all', 'hex-random', 'u-normal', 'u-random', 'u-all'],
50
+ 'uri_encode_count' => 'integer',
51
+ 'uri_full_url' => 'bool',
52
+ 'pad_method_uri_count' => 'integer',
53
+ 'pad_uri_version_count' => 'integer',
54
+ 'pad_method_uri_type' => ['space', 'tab', 'apache'],
55
+ 'pad_uri_version_type' => ['space', 'tab', 'apache'],
56
+ 'method_random_valid' => 'bool',
57
+ 'method_random_invalid' => 'bool',
58
+ 'method_random_case' => 'bool',
59
+ 'version_random_valid' => 'bool',
60
+ 'version_random_invalid' => 'bool',
61
+ 'version_random_case' => 'bool',
62
+ 'uri_dir_self_reference' => 'bool',
63
+ 'uri_dir_fake_relative' => 'bool',
64
+ 'uri_use_backslashes' => 'bool',
65
+ 'pad_fake_headers' => 'bool',
66
+ 'pad_fake_headers_count' => 'integer',
67
+ 'pad_get_params' => 'bool',
68
+ 'pad_get_params_count' => 'integer',
69
+ 'pad_post_params' => 'bool',
70
+ 'pad_post_params_count' => 'integer',
71
+ 'uri_fake_end' => 'bool',
72
+ 'uri_fake_params_start' => 'bool',
73
+ 'header_folding' => 'bool',
74
+ 'chunked_size' => 'integer'
75
+ }
76
+
77
+
78
+ end
79
+
80
+ #
81
+ # Set configuration options
82
+ #
83
+ def set_config(opts = {})
84
+ opts.each_pair do |var,val|
85
+ # Default type is string
86
+ typ = self.config_types[var] || 'string'
87
+
88
+ # These are enum types
89
+ if(typ.class.to_s == 'Array')
90
+ if not typ.include?(val)
91
+ raise RuntimeError, "The specified value for #{var} is not one of the valid choices"
92
+ end
93
+ end
94
+
95
+ # The caller should have converted these to proper ruby types, but
96
+ # take care of the case where they didn't before setting the
97
+ # config.
98
+
99
+ if(typ == 'bool')
100
+ val = (val =~ /^(t|y|1)$/i ? true : false || val === true)
101
+ end
102
+
103
+ if(typ == 'integer')
104
+ val = val.to_i
105
+ end
106
+
107
+ self.config[var]=val
108
+ end
109
+ end
110
+
111
+ #
112
+ # Create an arbitrary HTTP request
113
+ #
114
+ # @param opts [Hash]
115
+ # @option opts 'agent' [String] User-Agent header value
116
+ # @option opts 'connection' [String] Connection header value
117
+ # @option opts 'cookie' [String] Cookie header value
118
+ # @option opts 'data' [String] HTTP data (only useful with some methods, see rfc2616)
119
+ # @option opts 'encode' [Bool] URI encode the supplied URI, default: false
120
+ # @option opts 'headers' [Hash] HTTP headers, e.g. <code>{ "X-MyHeader" => "value" }</code>
121
+ # @option opts 'method' [String] HTTP method to use in the request, not limited to standard methods defined by rfc2616, default: GET
122
+ # @option opts 'proto' [String] protocol, default: HTTP
123
+ # @option opts 'query' [String] raw query string
124
+ # @option opts 'raw_headers' [Hash] HTTP headers
125
+ # @option opts 'uri' [String] the URI to request
126
+ # @option opts 'version' [String] version of the protocol, default: 1.1
127
+ # @option opts 'vhost' [String] Host header value
128
+ #
129
+ # @return [ClientRequest]
130
+ def request_raw(opts={})
131
+ opts = self.config.merge(opts)
132
+
133
+ opts['ssl'] = self.ssl
134
+ opts['cgi'] = false
135
+ opts['port'] = self.port
136
+
137
+ req = ClientRequest.new(opts)
138
+ end
139
+
140
+
141
+ #
142
+ # Create a CGI compatible request
143
+ #
144
+ # @param (see #request_raw)
145
+ # @option opts (see #request_raw)
146
+ # @option opts 'ctype' [String] Content-Type header value, default: +application/x-www-form-urlencoded+
147
+ # @option opts 'encode_params' [Bool] URI encode the GET or POST variables (names and values), default: true
148
+ # @option opts 'vars_get' [Hash] GET variables as a hash to be translated into a query string
149
+ # @option opts 'vars_post' [Hash] POST variables as a hash to be translated into POST data
150
+ #
151
+ # @return [ClientRequest]
152
+ def request_cgi(opts={})
153
+ opts = self.config.merge(opts)
154
+
155
+ opts['ctype'] ||= 'application/x-www-form-urlencoded'
156
+ opts['ssl'] = self.ssl
157
+ opts['cgi'] = true
158
+ opts['port'] = self.port
159
+
160
+ req = ClientRequest.new(opts)
161
+ req
162
+ end
163
+
164
+ #
165
+ # Connects to the remote server if possible.
166
+ #
167
+ # @param t [Fixnum] Timeout
168
+ # @see Rex::Socket::Tcp.create
169
+ # @return [Rex::Socket::Tcp]
170
+ def connect(t = -1)
171
+ # If we already have a connection and we aren't pipelining, close it.
172
+ if (self.conn)
173
+ if !pipelining?
174
+ close
175
+ else
176
+ return self.conn
177
+ end
178
+ end
179
+
180
+ timeout = (t.nil? or t == -1) ? 0 : t
181
+
182
+ self.conn = Rex::Socket::Tcp.create(
183
+ 'PeerHost' => self.hostname,
184
+ 'PeerPort' => self.port.to_i,
185
+ 'LocalHost' => self.local_host,
186
+ 'LocalPort' => self.local_port,
187
+ 'Context' => self.context,
188
+ 'SSL' => self.ssl,
189
+ 'SSLVersion' => self.ssl_version,
190
+ 'Proxies' => self.proxies,
191
+ 'Timeout' => timeout
192
+ )
193
+ end
194
+
195
+ #
196
+ # Closes the connection to the remote server.
197
+ #
198
+ def close
199
+ if (self.conn)
200
+ self.conn.shutdown
201
+ self.conn.close unless self.conn.closed?
202
+ end
203
+
204
+ self.conn = nil
205
+ end
206
+
207
+ #
208
+ # Sends a request and gets a response back
209
+ #
210
+ # If the request is a 401, and we have creds, it will attempt to complete
211
+ # authentication and return the final response
212
+ #
213
+ # @return (see #_send_recv)
214
+ def send_recv(req, t = -1, persist=false)
215
+ res = _send_recv(req,t,persist)
216
+ if res and res.code == 401 and res.headers['WWW-Authenticate']
217
+ res = send_auth(res, req.opts, t, persist)
218
+ end
219
+ res
220
+ end
221
+
222
+ #
223
+ # Transmit an HTTP request and receive the response
224
+ #
225
+ # If persist is set, then the request will attempt to reuse an existing
226
+ # connection.
227
+ #
228
+ # Call this directly instead of {#send_recv} if you don't want automatic
229
+ # authentication handling.
230
+ #
231
+ # @return (see #read_response)
232
+ def _send_recv(req, t = -1, persist=false)
233
+ @pipeline = persist
234
+ send_request(req, t)
235
+ res = read_response(t)
236
+ res.request = req.to_s if res
237
+ res
238
+ end
239
+
240
+ #
241
+ # Send an HTTP request to the server
242
+ #
243
+ # @param req [Request,ClientRequest,#to_s] The request to send
244
+ # @param t (see #connect)
245
+ #
246
+ # @return [void]
247
+ def send_request(req, t = -1)
248
+ connect(t)
249
+ conn.put(req.to_s)
250
+ end
251
+
252
+ # Resends an HTTP Request with the propper authentcation headers
253
+ # set. If we do not support the authentication type the server requires
254
+ # we return the original response object
255
+ #
256
+ # @param res [Response] the HTTP Response object
257
+ # @param opts [Hash] the options used to generate the original HTTP request
258
+ # @param t [Fixnum] the timeout for the request in seconds
259
+ # @param persist [Boolean] whether or not to persist the TCP connection (pipelining)
260
+ #
261
+ # @return [Response] the last valid HTTP response object we received
262
+ def send_auth(res, opts, t, persist)
263
+ if opts['username'].nil? or opts['username'] == ''
264
+ if self.username and not (self.username == '')
265
+ opts['username'] = self.username
266
+ opts['password'] = self.password
267
+ else
268
+ opts['username'] = nil
269
+ opts['password'] = nil
270
+ end
271
+ end
272
+
273
+ return res if opts['username'].nil? or opts['username'] == ''
274
+ supported_auths = res.headers['WWW-Authenticate']
275
+ if supported_auths.include? 'Basic'
276
+ opts['headers'] ||= {}
277
+ opts['headers']['Authorization'] = basic_auth_header(opts['username'],opts['password'] )
278
+ req = request_cgi(opts)
279
+ res = _send_recv(req,t,persist)
280
+ return res
281
+ elsif supported_auths.include? "Digest"
282
+ temp_response = digest_auth(opts)
283
+ if temp_response.kind_of? Rex::Proto::Http::Response
284
+ res = temp_response
285
+ end
286
+ return res
287
+ elsif supported_auths.include? "NTLM"
288
+ opts['provider'] = 'NTLM'
289
+ temp_response = negotiate_auth(opts)
290
+ if temp_response.kind_of? Rex::Proto::Http::Response
291
+ res = temp_response
292
+ end
293
+ return res
294
+ elsif supported_auths.include? "Negotiate"
295
+ opts['provider'] = 'Negotiate'
296
+ temp_response = negotiate_auth(opts)
297
+ if temp_response.kind_of? Rex::Proto::Http::Response
298
+ res = temp_response
299
+ end
300
+ return res
301
+ end
302
+ return res
303
+ end
304
+
305
+ # Converts username and password into the HTTP Basic authorization
306
+ # string.
307
+ #
308
+ # @return [String] A value suitable for use as an Authorization header
309
+ def basic_auth_header(username,password)
310
+ auth_str = username.to_s + ":" + password.to_s
311
+ auth_str = "Basic " + Rex::Text.encode_base64(auth_str)
312
+ end
313
+
314
+ # Send a series of requests to complete Digest Authentication
315
+ #
316
+ # @param opts [Hash] the options used to build an HTTP request
317
+ #
318
+ # @return [Response] the last valid HTTP response we received
319
+ def digest_auth(opts={})
320
+ @nonce_count = 0
321
+
322
+ to = opts['timeout'] || 20
323
+
324
+ digest_user = opts['username'] || ""
325
+ digest_password = opts['password'] || ""
326
+
327
+ method = opts['method']
328
+ path = opts['uri']
329
+ iis = true
330
+ if (opts['DigestAuthIIS'] == false or self.config['DigestAuthIIS'] == false)
331
+ iis = false
332
+ end
333
+
334
+ begin
335
+ @nonce_count += 1
336
+
337
+ resp = opts['response']
338
+
339
+ if not resp
340
+ # Get authentication-challenge from server, and read out parameters required
341
+ r = request_cgi(opts.merge({
342
+ 'uri' => path,
343
+ 'method' => method }))
344
+ resp = _send_recv(r, to)
345
+ unless resp.kind_of? Rex::Proto::Http::Response
346
+ return nil
347
+ end
348
+
349
+ if resp.code != 401
350
+ return resp
351
+ end
352
+ return resp unless resp.headers['WWW-Authenticate']
353
+ end
354
+
355
+ # Don't anchor this regex to the beginning of string because header
356
+ # folding makes it appear later when the server presents multiple
357
+ # WWW-Authentication options (such as is the case with IIS configured
358
+ # for Digest or NTLM).
359
+ resp['www-authenticate'] =~ /Digest (.*)/
360
+
361
+ parameters = {}
362
+ $1.split(/,[[:space:]]*/).each do |p|
363
+ k, v = p.split("=", 2)
364
+ parameters[k] = v.gsub('"', '')
365
+ end
366
+
367
+ qop = parameters['qop']
368
+
369
+ if parameters['algorithm'] =~ /(.*?)(-sess)?$/
370
+ algorithm = case $1
371
+ when 'MD5' then Digest::MD5
372
+ when 'SHA1' then Digest::SHA1
373
+ when 'SHA2' then Digest::SHA2
374
+ when 'SHA256' then Digest::SHA256
375
+ when 'SHA384' then Digest::SHA384
376
+ when 'SHA512' then Digest::SHA512
377
+ when 'RMD160' then Digest::RMD160
378
+ else raise Error, "unknown algorithm \"#{$1}\""
379
+ end
380
+ algstr = parameters["algorithm"]
381
+ sess = $2
382
+ else
383
+ algorithm = Digest::MD5
384
+ algstr = "MD5"
385
+ sess = false
386
+ end
387
+
388
+ a1 = if sess then
389
+ [
390
+ algorithm.hexdigest("#{digest_user}:#{parameters['realm']}:#{digest_password}"),
391
+ parameters['nonce'],
392
+ @cnonce
393
+ ].join ':'
394
+ else
395
+ "#{digest_user}:#{parameters['realm']}:#{digest_password}"
396
+ end
397
+
398
+ ha1 = algorithm.hexdigest(a1)
399
+ ha2 = algorithm.hexdigest("#{method}:#{path}")
400
+
401
+ request_digest = [ha1, parameters['nonce']]
402
+ request_digest.push(('%08x' % @nonce_count), @cnonce, qop) if qop
403
+ request_digest << ha2
404
+ request_digest = request_digest.join ':'
405
+
406
+ # Same order as IE7
407
+ auth = [
408
+ "Digest username=\"#{digest_user}\"",
409
+ "realm=\"#{parameters['realm']}\"",
410
+ "nonce=\"#{parameters['nonce']}\"",
411
+ "uri=\"#{path}\"",
412
+ "cnonce=\"#{@cnonce}\"",
413
+ "nc=#{'%08x' % @nonce_count}",
414
+ "algorithm=#{algstr}",
415
+ "response=\"#{algorithm.hexdigest(request_digest)[0, 32]}\"",
416
+ # The spec says the qop value shouldn't be enclosed in quotes, but
417
+ # some versions of IIS require it and Apache accepts it. Chrome
418
+ # and Firefox both send it without quotes but IE does it this way.
419
+ # Use the non-compliant-but-everybody-does-it to be as compatible
420
+ # as possible by default. The user can override if they don't like
421
+ # it.
422
+ if qop.nil? then
423
+ elsif iis then
424
+ "qop=\"#{qop}\""
425
+ else
426
+ "qop=#{qop}"
427
+ end,
428
+ if parameters.key? 'opaque' then
429
+ "opaque=\"#{parameters['opaque']}\""
430
+ end
431
+ ].compact
432
+
433
+ headers ={ 'Authorization' => auth.join(', ') }
434
+ headers.merge!(opts['headers']) if opts['headers']
435
+
436
+ # Send main request with authentication
437
+ r = request_cgi(opts.merge({
438
+ 'uri' => path,
439
+ 'method' => method,
440
+ 'headers' => headers }))
441
+ resp = _send_recv(r, to, true)
442
+ unless resp.kind_of? Rex::Proto::Http::Response
443
+ return nil
444
+ end
445
+
446
+ return resp
447
+
448
+ rescue ::Errno::EPIPE, ::Timeout::Error
449
+ end
450
+ end
451
+
452
+ #
453
+ # Builds a series of requests to complete Negotiate Auth. Works essentially
454
+ # the same way as Digest auth. Same pipelining concerns exist.
455
+ #
456
+ # @option opts (see #send_request_cgi)
457
+ # @option opts provider ["Negotiate","NTLM"] What Negotiate provider to use
458
+ #
459
+ # @return [Response] the last valid HTTP response we received
460
+ def negotiate_auth(opts={})
461
+ ntlm_options = {
462
+ :signing => false,
463
+ :usentlm2_session => self.config['usentlm2_session'],
464
+ :use_ntlmv2 => self.config['use_ntlmv2'],
465
+ :send_lm => self.config['send_lm'],
466
+ :send_ntlm => self.config['send_ntlm']
467
+ }
468
+
469
+ to = opts['timeout'] || 20
470
+ opts['username'] ||= ''
471
+ opts['password'] ||= ''
472
+
473
+ if opts['provider'] and opts['provider'].include? 'Negotiate'
474
+ provider = "Negotiate "
475
+ else
476
+ provider = 'NTLM '
477
+ end
478
+
479
+ opts['method']||= 'GET'
480
+ opts['headers']||= {}
481
+
482
+ ntlmssp_flags = ::Rex::Proto::NTLM::Utils.make_ntlm_flags(ntlm_options)
483
+ workstation_name = Rex::Text.rand_text_alpha(rand(8)+6)
484
+ domain_name = self.config['domain']
485
+
486
+ b64_blob = Rex::Text::encode_base64(
487
+ ::Rex::Proto::NTLM::Utils::make_ntlmssp_blob_init(
488
+ domain_name,
489
+ workstation_name,
490
+ ntlmssp_flags
491
+ ))
492
+
493
+ ntlm_message_1 = provider + b64_blob
494
+
495
+ begin
496
+ # First request to get the challenge
497
+ opts['headers']['Authorization'] = ntlm_message_1
498
+ r = request_cgi(opts)
499
+ resp = _send_recv(r, to)
500
+ unless resp.kind_of? Rex::Proto::Http::Response
501
+ return nil
502
+ end
503
+
504
+ return resp unless resp.code == 401 && resp.headers['WWW-Authenticate']
505
+
506
+ # Get the challenge and craft the response
507
+ ntlm_challenge = resp.headers['WWW-Authenticate'].scan(/#{provider}([A-Z0-9\x2b\x2f=]+)/ni).flatten[0]
508
+ return resp unless ntlm_challenge
509
+
510
+ ntlm_message_2 = Rex::Text::decode_base64(ntlm_challenge)
511
+ blob_data = ::Rex::Proto::NTLM::Utils.parse_ntlm_type_2_blob(ntlm_message_2)
512
+
513
+ challenge_key = blob_data[:challenge_key]
514
+ server_ntlmssp_flags = blob_data[:server_ntlmssp_flags] #else should raise an error
515
+ default_name = blob_data[:default_name] || '' #netbios name
516
+ default_domain = blob_data[:default_domain] || '' #netbios domain
517
+ dns_host_name = blob_data[:dns_host_name] || '' #dns name
518
+ dns_domain_name = blob_data[:dns_domain_name] || '' #dns domain
519
+ chall_MsvAvTimestamp = blob_data[:chall_MsvAvTimestamp] || '' #Client time
520
+
521
+ spnopt = {:use_spn => self.config['SendSPN'], :name => self.hostname}
522
+
523
+ resp_lm, resp_ntlm, client_challenge, ntlm_cli_challenge = ::Rex::Proto::NTLM::Utils.create_lm_ntlm_responses(
524
+ opts['username'],
525
+ opts['password'],
526
+ challenge_key,
527
+ domain_name,
528
+ default_name,
529
+ default_domain,
530
+ dns_host_name,
531
+ dns_domain_name,
532
+ chall_MsvAvTimestamp,
533
+ spnopt,
534
+ ntlm_options
535
+ )
536
+
537
+ ntlm_message_3 = ::Rex::Proto::NTLM::Utils.make_ntlmssp_blob_auth(
538
+ domain_name,
539
+ workstation_name,
540
+ opts['username'],
541
+ resp_lm,
542
+ resp_ntlm,
543
+ '',
544
+ ntlmssp_flags
545
+ )
546
+
547
+ ntlm_message_3 = Rex::Text::encode_base64(ntlm_message_3)
548
+
549
+ # Send the response
550
+ opts['headers']['Authorization'] = "#{provider}#{ntlm_message_3}"
551
+ r = request_cgi(opts)
552
+ resp = _send_recv(r, to, true)
553
+ unless resp.kind_of? Rex::Proto::Http::Response
554
+ return nil
555
+ end
556
+ return resp
557
+
558
+ rescue ::Errno::EPIPE, ::Timeout::Error
559
+ return nil
560
+ end
561
+ end
562
+ #
563
+ # Read a response from the server
564
+ #
565
+ # @return [Response]
566
+ def read_response(t = -1, opts = {})
567
+
568
+ resp = Response.new
569
+ resp.max_data = config['read_max_data']
570
+
571
+ # Wait at most t seconds for the full response to be read in. We only
572
+ # do this if t was specified as a negative value indicating an infinite
573
+ # wait cycle. If t were specified as nil it would indicate that no
574
+ # response parsing is required.
575
+
576
+ return resp if not t
577
+
578
+ Timeout.timeout((t < 0) ? nil : t) do
579
+
580
+ rv = nil
581
+ while (
582
+ rv != Packet::ParseCode::Completed and
583
+ rv != Packet::ParseCode::Error
584
+ )
585
+
586
+ begin
587
+
588
+ buff = conn.get_once(-1, 1)
589
+ rv = resp.parse( buff || '' )
590
+
591
+ # Handle unexpected disconnects
592
+ rescue ::Errno::EPIPE, ::EOFError, ::IOError
593
+ case resp.state
594
+ when Packet::ParseState::ProcessingHeader
595
+ resp = nil
596
+ when Packet::ParseState::ProcessingBody
597
+ # truncated request, good enough
598
+ resp.error = :truncated
599
+ end
600
+ break
601
+ end
602
+
603
+ # This is a dirty hack for broken HTTP servers
604
+ if rv == Packet::ParseCode::Completed
605
+ rbody = resp.body
606
+ rbufq = resp.bufq
607
+
608
+ rblob = rbody.to_s + rbufq.to_s
609
+ tries = 0
610
+ begin
611
+ # XXX: This doesn't deal with chunked encoding or "Content-type: text/html; charset=..."
612
+ while tries < 1000 and resp.headers["Content-Type"]== "text/html" and rblob !~ /<\/html>/i
613
+ buff = conn.get_once(-1, 0.05)
614
+ break if not buff
615
+ rblob += buff
616
+ tries += 1
617
+ end
618
+ rescue ::Errno::EPIPE, ::EOFError, ::IOError
619
+ end
620
+
621
+ resp.bufq = ""
622
+ resp.body = rblob
623
+ end
624
+ end
625
+ end
626
+
627
+ return resp if not resp
628
+
629
+ # As a last minute hack, we check to see if we're dealing with a 100 Continue here.
630
+ # Most of the time this is handled by the parser via check_100()
631
+ if resp.proto == '1.1' and resp.code == 100 and not opts[:skip_100]
632
+ # Read the real response from the body if we found one
633
+ # If so, our real response became the body, so we re-parse it.
634
+ if resp.body.to_s =~ /^HTTP/
635
+ body = resp.body
636
+ resp = Response.new
637
+ resp.max_data = config['read_max_data']
638
+ rv = resp.parse(body)
639
+ # We found a 100 Continue but didn't read the real reply yet
640
+ # Otherwise reread the reply, but don't try this hack again
641
+ else
642
+ resp = read_response(t, :skip_100 => true)
643
+ end
644
+ end
645
+
646
+ resp
647
+ end
648
+
649
+ #
650
+ # Cleans up any outstanding connections and other resources.
651
+ #
652
+ def stop
653
+ close
654
+ end
655
+
656
+ #
657
+ # Returns whether or not the conn is valid.
658
+ #
659
+ def conn?
660
+ conn != nil
661
+ end
662
+
663
+ #
664
+ # Whether or not connections should be pipelined.
665
+ #
666
+ def pipelining?
667
+ pipeline
668
+ end
669
+
670
+ #
671
+ # The client request configuration
672
+ #
673
+ attr_accessor :config
674
+ #
675
+ # The client request configuration classes
676
+ #
677
+ attr_accessor :config_types
678
+ #
679
+ # Whether or not pipelining is in use.
680
+ #
681
+ attr_accessor :pipeline
682
+ #
683
+ # The local host of the client.
684
+ #
685
+ attr_accessor :local_host
686
+ #
687
+ # The local port of the client.
688
+ #
689
+ attr_accessor :local_port
690
+ #
691
+ # The underlying connection.
692
+ #
693
+ attr_accessor :conn
694
+ #
695
+ # The calling context to pass to the socket
696
+ #
697
+ attr_accessor :context
698
+ #
699
+ # The proxy list
700
+ #
701
+ attr_accessor :proxies
702
+
703
+ # Auth
704
+ attr_accessor :username, :password
705
+
706
+ # When parsing the request, thunk off the first response from the server, since junk
707
+ attr_accessor :junk_pipeline
708
+
709
+ protected
710
+
711
+ # https
712
+ attr_accessor :ssl, :ssl_version # :nodoc:
713
+
714
+ attr_accessor :hostname, :port # :nodoc:
715
+
716
+
717
+ end
718
+
719
+ end
720
+ end
721
+ end
722
+