dstruct 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,13 @@
1
+ # -*- coding: binary -*-
2
+ #
3
+ # TFTP Server implementation according to:
4
+ #
5
+ # RFC1350, RFC2347, RFC2348, RFC2349
6
+ #
7
+ # written by jduck <jduck [at] metasploit.com>
8
+ # thx to scriptjunkie for pointing out option extensions
9
+ #
10
+
11
+ require 'rex/proto/tftp/constants'
12
+ require 'rex/proto/tftp/server'
13
+ require 'rex/proto/tftp/client'
@@ -0,0 +1,344 @@
1
+ # -*- coding: binary -*-
2
+ require 'rex/socket'
3
+ require 'rex/proto/tftp'
4
+ require 'tempfile'
5
+
6
+ module Rex
7
+ module Proto
8
+ module TFTP
9
+
10
+ #
11
+ # TFTP Client class
12
+ #
13
+ # Note that TFTP has blocks, and so does Ruby. Watch out with the variable names!
14
+ #
15
+ # The big gotcha right now is that setting the mode between octet, netascii, or
16
+ # anything else doesn't actually do anything other than declare it to the
17
+ # server.
18
+ #
19
+ # Also, since TFTP clients act as both clients and servers, we use two
20
+ # threads to handle transfers, regardless of the direction. For this reason,
21
+ # the transfer actions are nonblocking; if you need to see the
22
+ # results of a transfer before doing something else, check the boolean complete
23
+ # attribute and any return data in the :status attribute. It's a little
24
+ # weird like that.
25
+ #
26
+ # Finally, most (all?) clients will alter the data in netascii mode in order
27
+ # to try to conform to the RFC standard for what "netascii" means, but there are
28
+ # ambiguities in implementations on things like if nulls are allowed, what
29
+ # to do with Unicode, and all that. For this reason, "octet" is default, and
30
+ # if you want to send "netascii" data, it's on you to fix up your source data
31
+ # prior to sending it.
32
+ #
33
+ class Client
34
+
35
+ attr_accessor :local_host, :local_port, :peer_host, :peer_port
36
+ attr_accessor :threads, :context, :server_sock, :client_sock
37
+ attr_accessor :local_file, :remote_file, :mode, :action
38
+ attr_accessor :complete, :recv_tempfile, :status
39
+ attr_accessor :block_size # This definitely breaks spec, should only use for fuzz/sploit.
40
+
41
+ # Returns an array of [code, type, msg]. Data packets
42
+ # specifically will /not/ unpack, since that would drop any trailing spaces or nulls.
43
+ def parse_tftp_response(str)
44
+ return nil unless str.length >= 4
45
+ ret = str.unpack("nnA*")
46
+ ret[2] = str[4,str.size] if ret[0] == OpData
47
+ return ret
48
+ end
49
+
50
+ def initialize(params)
51
+ self.threads = []
52
+ self.local_host = params["LocalHost"] || "0.0.0.0"
53
+ self.local_port = params["LocalPort"] || (1025 + rand(0xffff-1025))
54
+ self.peer_host = params["PeerHost"] || (raise ArgumentError, "Need a peer host.")
55
+ self.peer_port = params["PeerPort"] || 69
56
+ self.context = params["Context"]
57
+ self.local_file = params["LocalFile"]
58
+ self.remote_file = params["RemoteFile"] || (::File.split(self.local_file).last if self.local_file)
59
+ self.mode = params["Mode"] || "octet"
60
+ self.action = params["Action"] || (raise ArgumentError, "Need an action.")
61
+ self.block_size = params["BlockSize"] || 512
62
+ end
63
+
64
+ #
65
+ # Methods for both upload and download
66
+ #
67
+
68
+ def start_server_socket
69
+ self.server_sock = Rex::Socket::Udp.create(
70
+ 'LocalHost' => local_host,
71
+ 'LocalPort' => local_port,
72
+ 'Context' => context
73
+ )
74
+ if self.server_sock and block_given?
75
+ yield "Started TFTP client listener on #{local_host}:#{local_port}"
76
+ end
77
+ self.threads << Rex::ThreadFactory.spawn("TFTPServerMonitor", false) {
78
+ if block_given?
79
+ monitor_server_sock {|msg| yield msg}
80
+ else
81
+ monitor_server_sock
82
+ end
83
+ }
84
+ end
85
+
86
+ def monitor_server_sock
87
+ yield "Listening for incoming ACKs" if block_given?
88
+ res = self.server_sock.recvfrom(65535)
89
+ if res and res[0]
90
+ code, type, data = parse_tftp_response(res[0])
91
+ if code == OpAck and self.action == :upload
92
+ if block_given?
93
+ yield "WRQ accepted, sending the file." if type == 0
94
+ send_data(res[1], res[2]) {|msg| yield msg}
95
+ else
96
+ send_data(res[1], res[2])
97
+ end
98
+ elsif code == OpData and self.action == :download
99
+ if block_given?
100
+ recv_data(res[1], res[2], data) {|msg| yield msg}
101
+ else
102
+ recv_data(res[1], res[2], data)
103
+ end
104
+ elsif code == OpError
105
+ yield("Aborting, got error type:%d, message:'%s'" % [type, data]) if block_given?
106
+ self.status = {:error => [code, type, data]}
107
+ else
108
+ yield("Aborting, got code:%d, type:%d, message:'%s'" % [code, type, data]) if block_given?
109
+ self.status = {:error => [code, type, data]}
110
+ end
111
+ end
112
+ stop
113
+ end
114
+
115
+ def monitor_client_sock
116
+ res = self.client_sock.recvfrom(65535)
117
+ if res[1] # Got a response back, so that's never good; Acks come back on server_sock.
118
+ code, type, data = parse_tftp_response(res[0])
119
+ yield("Aborting, got code:%d, type:%d, message:'%s'" % [code, type, data]) if block_given?
120
+ self.status = {:error => [code, type, data]}
121
+ stop
122
+ end
123
+ end
124
+
125
+ def stop
126
+ self.complete = true
127
+ begin
128
+ self.server_sock.close
129
+ self.client_sock.close
130
+ self.server_sock = nil
131
+ self.client_sock = nil
132
+ self.threads.each {|t| t.kill}
133
+ rescue
134
+ nil
135
+ end
136
+ end
137
+
138
+ #
139
+ # Methods for download
140
+ #
141
+
142
+ def rrq_packet
143
+ req = [OpRead, self.remote_file, self.mode]
144
+ packstr = "na#{self.remote_file.length+1}a#{self.mode.length+1}"
145
+ req.pack(packstr)
146
+ end
147
+
148
+ def ack_packet(blocknum=0)
149
+ req = [OpAck, blocknum].pack("nn")
150
+ end
151
+
152
+ def send_read_request(&block)
153
+ self.status = nil
154
+ self.complete = false
155
+ if block_given?
156
+ start_server_socket {|msg| yield msg}
157
+ else
158
+ start_server_socket
159
+ end
160
+ self.client_sock = Rex::Socket::Udp.create(
161
+ 'PeerHost' => peer_host,
162
+ 'PeerPort' => peer_port,
163
+ 'LocalHost' => local_host,
164
+ 'LocalPort' => local_port,
165
+ 'Context' => context
166
+ )
167
+ self.client_sock.sendto(rrq_packet, peer_host, peer_port)
168
+ self.threads << Rex::ThreadFactory.spawn("TFTPClientMonitor", false) {
169
+ if block_given?
170
+ monitor_client_sock {|msg| yield msg}
171
+ else
172
+ monitor_client_sock
173
+ end
174
+ }
175
+ until self.complete
176
+ return self.status
177
+ end
178
+ end
179
+
180
+ def recv_data(host, port, first_block)
181
+ self.recv_tempfile = Rex::Quickfile.new('msf-tftp')
182
+ recvd_blocks = 1
183
+ if block_given?
184
+ yield "Source file: #{self.remote_file}, destination file: #{self.local_file}"
185
+ yield "Received and acknowledged #{first_block.size} in block #{recvd_blocks}"
186
+ end
187
+ if block_given?
188
+ write_and_ack_data(first_block,1,host,port) {|msg| yield msg}
189
+ else
190
+ write_and_ack_data(first_block,1,host,port)
191
+ end
192
+ current_block = first_block
193
+ while current_block.size == 512
194
+ res = self.server_sock.recvfrom(65535)
195
+ if res and res[0]
196
+ code, block_num, current_block = parse_tftp_response(res[0])
197
+ if code == 3
198
+ if block_given?
199
+ write_and_ack_data(current_block,block_num,host,port) {|msg| yield msg}
200
+ else
201
+ write_and_ack_data(current_block,block_num,host,port)
202
+ end
203
+ recvd_blocks += 1
204
+ else
205
+ yield("Aborting, got code:%d, type:%d, message:'%s'" % [code, type, msg]) if block_given?
206
+ stop
207
+ end
208
+ end
209
+ end
210
+ if block_given?
211
+ yield("Transferred #{self.recv_tempfile.size} bytes in #{recvd_blocks} blocks, download complete!")
212
+ end
213
+ self.status = {:success => [
214
+ self.local_file,
215
+ self.remote_file,
216
+ self.recv_tempfile.size,
217
+ recvd_blocks.size]
218
+ }
219
+ self.recv_tempfile.close
220
+ stop
221
+ end
222
+
223
+ def write_and_ack_data(data,blocknum,host,port)
224
+ self.recv_tempfile.write(data)
225
+ self.recv_tempfile.flush
226
+ req = ack_packet(blocknum)
227
+ self.server_sock.sendto(req, host, port)
228
+ yield "Received and acknowledged #{data.size} in block #{blocknum}" if block_given?
229
+ end
230
+
231
+ #
232
+ # Methods for upload
233
+ #
234
+
235
+ def wrq_packet
236
+ req = [OpWrite, self.remote_file, self.mode]
237
+ packstr = "na#{self.remote_file.length+1}a#{self.mode.length+1}"
238
+ req.pack(packstr)
239
+ end
240
+
241
+ # Note that the local filename for uploading need not be a real filename --
242
+ # if it begins with DATA: it can be any old string of bytes. If it's missing
243
+ # completely, then just quit.
244
+ def blockify_file_or_data
245
+ if self.local_file =~ /^DATA:(.*)/m
246
+ data = $1
247
+ elsif ::File.file?(self.local_file) and ::File.readable?(self.local_file)
248
+ data = ::File.open(self.local_file, "rb") {|f| f.read f.stat.size} rescue []
249
+ else
250
+ return []
251
+ end
252
+ data_blocks = data.scan(/.{1,#{block_size}}/m)
253
+ # Drop any trailing empty blocks
254
+ if data_blocks.size > 1 and data_blocks.last.empty?
255
+ data_blocks.pop
256
+ end
257
+ return data_blocks
258
+ end
259
+
260
+ def send_write_request(&block)
261
+ self.status = nil
262
+ self.complete = false
263
+ if block_given?
264
+ start_server_socket {|msg| yield msg}
265
+ else
266
+ start_server_socket
267
+ end
268
+ self.client_sock = Rex::Socket::Udp.create(
269
+ 'PeerHost' => peer_host,
270
+ 'PeerPort' => peer_port,
271
+ 'LocalHost' => local_host,
272
+ 'LocalPort' => local_port,
273
+ 'Context' => context
274
+ )
275
+ self.client_sock.sendto(wrq_packet, peer_host, peer_port)
276
+ self.threads << Rex::ThreadFactory.spawn("TFTPClientMonitor", false) {
277
+ if block_given?
278
+ monitor_client_sock {|msg| yield msg}
279
+ else
280
+ monitor_client_sock
281
+ end
282
+ }
283
+ until self.complete
284
+ return self.status
285
+ end
286
+ end
287
+
288
+ def send_data(host,port)
289
+ self.status = {:write_allowed => true}
290
+ data_blocks = blockify_file_or_data()
291
+ if data_blocks.empty?
292
+ yield "Closing down since there is no data to send." if block_given?
293
+ self.status = {:success => [self.local_file, self.local_file, 0, 0]}
294
+ return nil
295
+ end
296
+ sent_data = 0
297
+ sent_blocks = 0
298
+ expected_blocks = data_blocks.size
299
+ expected_size = data_blocks.join.size
300
+ if block_given?
301
+ yield "Source file: #{self.local_file =~ /^DATA:/ ? "(Data)" : self.remote_file}, destination file: #{self.remote_file}"
302
+ yield "Sending #{expected_size} bytes (#{expected_blocks} blocks)"
303
+ end
304
+ data_blocks.each_with_index do |data_block,idx|
305
+ req = [OpData, (idx + 1), data_block].pack("nnA*")
306
+ if self.server_sock.sendto(req, host, port) > 0
307
+ sent_data += data_block.size
308
+ end
309
+ res = self.server_sock.recvfrom(65535)
310
+ if res
311
+ code, type, msg = parse_tftp_response(res[0])
312
+ if code == 4
313
+ sent_blocks += 1
314
+ yield "Sent #{data_block.size} bytes in block #{sent_blocks}" if block_given?
315
+ else
316
+ if block_given?
317
+ yield "Got an unexpected response: Code:%d, Type:%d, Message:'%s'. Aborting." % [code, type, msg]
318
+ end
319
+ break
320
+ end
321
+ end
322
+ end
323
+ if block_given?
324
+ if(sent_data == expected_size)
325
+ yield("Transferred #{sent_data} bytes in #{sent_blocks} blocks, upload complete!")
326
+ else
327
+ yield "Upload complete, but with errors."
328
+ end
329
+ end
330
+ if sent_data == expected_size
331
+ self.status = {:success => [
332
+ self.local_file,
333
+ self.remote_file,
334
+ sent_data,
335
+ sent_blocks
336
+ ] }
337
+ end
338
+ end
339
+
340
+ end
341
+
342
+ end
343
+ end
344
+ end
@@ -0,0 +1,39 @@
1
+ # -*- coding: binary -*-
2
+ require 'rex/proto/tftp'
3
+
4
+ module Rex
5
+ module Proto
6
+ module TFTP
7
+
8
+ OPCODES = %w{ Unknown RRQ WRQ DATA ACK ERROR }
9
+ OpRead = 1
10
+ OpWrite = 2
11
+ OpData = 3
12
+ OpAck = 4
13
+ OpError = 5
14
+ OpOptAck = 6
15
+
16
+ ERRCODES = [
17
+ "Undefined",
18
+ "File not found",
19
+ "Access violation",
20
+ "Disk full or allocation exceeded",
21
+ "Illegal TFTP operation",
22
+ "Unknown transfer ID",
23
+ "File already exists",
24
+ "No such user",
25
+ "Failed option negotiation"
26
+ ]
27
+
28
+ ErrFileNotFound = 1
29
+ ErrAccessViolation = 2
30
+ ErrDiskFull = 3
31
+ ErrIllegalOperation = 4
32
+ ErrUnknownTransferId = 5
33
+ ErrFileExists = 6
34
+ ErrNoSuchUser = 7
35
+ ErrFailedOptNegotiation = 8
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,497 @@
1
+ # -*- coding: binary -*-
2
+ require 'rex/socket'
3
+ require 'rex/proto/tftp'
4
+
5
+ module Rex
6
+ module Proto
7
+ module TFTP
8
+
9
+ #
10
+ # Little util function
11
+ #
12
+ def self.get_string(data)
13
+ idx = data.index("\x00")
14
+ return nil if not idx
15
+ ret = data.slice!(0, idx)
16
+ # Slice off the nul byte.
17
+ data.slice!(0,1)
18
+ ret
19
+ end
20
+
21
+
22
+ ##
23
+ #
24
+ # TFTP Server class
25
+ #
26
+ ##
27
+ class Server
28
+
29
+ def initialize(port = 69, listen_host = '0.0.0.0', context = {})
30
+ self.listen_host = listen_host
31
+ self.listen_port = port
32
+ self.context = context
33
+ self.sock = nil
34
+ @shutting_down = false
35
+ @output_dir = nil
36
+ @tftproot = nil
37
+
38
+ self.files = []
39
+ self.uploaded = []
40
+ self.transfers = []
41
+ end
42
+
43
+
44
+ #
45
+ # Start the TFTP server
46
+ #
47
+ def start
48
+ self.sock = Rex::Socket::Udp.create(
49
+ 'LocalHost' => listen_host,
50
+ 'LocalPort' => listen_port,
51
+ 'Context' => context
52
+ )
53
+
54
+ self.thread = Rex::ThreadFactory.spawn("TFTPServerMonitor", false) {
55
+ monitor_socket
56
+ }
57
+ end
58
+
59
+
60
+ #
61
+ # Stop the TFTP server
62
+ #
63
+ def stop
64
+ @shutting_down = true
65
+
66
+ # Wait a maximum of 30 seconds for all transfers to finish.
67
+ start = ::Time.now
68
+ while (self.transfers.length > 0)
69
+ ::IO.select(nil, nil, nil, 0.5)
70
+ dur = ::Time.now - start
71
+ break if (dur > 30)
72
+ end
73
+
74
+ self.files.clear
75
+ self.thread.kill
76
+ self.sock.close rescue nil # might be closed already
77
+ end
78
+
79
+
80
+ #
81
+ # Register a filename and content for a client to request
82
+ #
83
+ def register_file(fn, content, once = false)
84
+ self.files << {
85
+ :name => fn,
86
+ :data => content,
87
+ :once => once
88
+ }
89
+ end
90
+
91
+
92
+ #
93
+ # Register an entire directory to serve files from
94
+ #
95
+ def set_tftproot(rootdir)
96
+ @tftproot = rootdir if ::File.directory?(rootdir)
97
+ end
98
+
99
+
100
+ #
101
+ # Register a directory to write uploaded files to
102
+ #
103
+ def set_output_dir(outdir)
104
+ @output_dir = outdir if ::File.directory?(outdir)
105
+ end
106
+
107
+
108
+ #
109
+ # Send an error packet w/the specified code and string
110
+ #
111
+ def send_error(from, num)
112
+ if (num < 1 or num >= ERRCODES.length)
113
+ # ignore..
114
+ return
115
+ end
116
+ pkt = [OpError, num].pack('nn')
117
+ pkt << ERRCODES[num]
118
+ pkt << "\x00"
119
+ send_packet(from, pkt)
120
+ end
121
+
122
+
123
+ #
124
+ # Send a single packet to the specified host
125
+ #
126
+ def send_packet(from, pkt)
127
+ self.sock.sendto(pkt, from[0], from[1])
128
+ end
129
+
130
+
131
+ #
132
+ # Find the hash entry for a file that may be offered
133
+ #
134
+ def find_file(fname)
135
+ # Files served via register_file() take precedence.
136
+ self.files.each do |f|
137
+ if (fname == f[:name])
138
+ return f
139
+ end
140
+ end
141
+
142
+ # Now, if we have a tftproot, see if it can serve from it
143
+ if @tftproot
144
+ return find_file_in_root(fname)
145
+ end
146
+
147
+ nil
148
+ end
149
+
150
+
151
+ #
152
+ # Find the file in the specified tftp root and add a temporary
153
+ # entry to the files hash.
154
+ #
155
+ def find_file_in_root(fname)
156
+ fn = ::File.expand_path(::File.join(@tftproot, fname))
157
+
158
+ # Don't allow directory traversal
159
+ return nil if fn.index(@tftproot) != 0
160
+
161
+ return nil if not ::File.file?(fn) or not ::File.readable?(fn)
162
+
163
+ # Read the file contents, and register it as being served once
164
+ data = data = ::File.open(fn, "rb") { |fd| fd.read(fd.stat.size) }
165
+ register_file(fname, data)
166
+
167
+ # Return the last file in the array
168
+ return self.files[-1]
169
+ end
170
+
171
+
172
+ attr_accessor :listen_host, :listen_port, :context
173
+ attr_accessor :sock, :files, :transfers, :uploaded
174
+ attr_accessor :thread
175
+
176
+ attr_accessor :incoming_file_hook
177
+
178
+ protected
179
+
180
+ def find_transfer(type, from, block)
181
+ self.transfers.each do |tr|
182
+ if (tr[:type] == type and tr[:from] == from and tr[:block] == block)
183
+ return tr
184
+ end
185
+ end
186
+ nil
187
+ end
188
+
189
+ def save_output(tr)
190
+ self.uploaded << tr[:file]
191
+
192
+ return incoming_file_hook.call(tr) if incoming_file_hook
193
+
194
+ if @output_dir
195
+ fn = tr[:file][:name].split(File::SEPARATOR)[-1]
196
+ if fn
197
+ fn = ::File.join(@output_dir, Rex::FileUtils.clean_path(fn))
198
+ ::File.open(fn, "wb") { |fd|
199
+ fd.write(tr[:file][:data])
200
+ }
201
+ end
202
+ end
203
+ end
204
+
205
+
206
+ def check_retransmission(tr)
207
+ elapsed = ::Time.now - tr[:last_sent]
208
+ if (elapsed >= tr[:timeout])
209
+ # max retries reached?
210
+ if (tr[:retries] < 3)
211
+ #if (tr[:type] == OpRead)
212
+ # puts "[-] ack timed out, resending block"
213
+ #else
214
+ # puts "[-] block timed out, resending ack"
215
+ #end
216
+ tr[:last_sent] = nil
217
+ tr[:retries] += 1
218
+ else
219
+ #puts "[-] maximum tries reached, terminating transfer"
220
+ self.transfers.delete(tr)
221
+ end
222
+ end
223
+ end
224
+
225
+
226
+ #
227
+ # See if there is anything to do.. If so, dispatch it.
228
+ #
229
+ def monitor_socket
230
+ while true
231
+ rds = [@sock]
232
+ wds = []
233
+ self.transfers.each do |tr|
234
+ if (not tr[:last_sent])
235
+ wds << @sock
236
+ break
237
+ end
238
+ end
239
+ eds = [@sock]
240
+
241
+ r,w,e = ::IO.select(rds,wds,eds,1)
242
+
243
+ if (r != nil and r[0] == self.sock)
244
+ buf,host,port = self.sock.recvfrom(65535)
245
+ # Lame compatabilitiy :-/
246
+ from = [host, port]
247
+ dispatch_request(from, buf)
248
+ end
249
+
250
+ #
251
+ # Check to see if transfers need maintenance
252
+ #
253
+ self.transfers.each do |tr|
254
+ # We handle RRQ and WRQ separately
255
+ #
256
+ if (tr[:type] == OpRead)
257
+ # Are we awaiting an ack?
258
+ if (tr[:last_sent])
259
+ check_retransmission(tr)
260
+ elsif (w != nil and w[0] == self.sock)
261
+ # No ack waiting, send next block..
262
+ chunk = tr[:file][:data].slice(tr[:offset], tr[:blksize])
263
+ if (chunk and chunk.length >= 0)
264
+ pkt = [OpData, tr[:block]].pack('nn')
265
+ pkt << chunk
266
+
267
+ send_packet(tr[:from], pkt)
268
+ tr[:last_sent] = ::Time.now
269
+
270
+ # If the file is a one-serve, mark it as started
271
+ tr[:file][:started] = true if (tr[:file][:once])
272
+ else
273
+ # No more chunks.. transfer is most likely done.
274
+ # However, we can only delete it once the last chunk has been
275
+ # acked.
276
+ end
277
+ end
278
+ else
279
+ # Are we awaiting data?
280
+ if (tr[:last_sent])
281
+ check_retransmission(tr)
282
+ elsif (w != nil and w[0] == self.sock)
283
+ # Not waiting for data, send an ack..
284
+ #puts "[*] sending ack for block %d" % [tr[:block]]
285
+ pkt = [OpAck, tr[:block]].pack('nn')
286
+
287
+ send_packet(tr[:from], pkt)
288
+ tr[:last_sent] = ::Time.now
289
+
290
+ # If we had a 0-511 byte chunk, we're done.
291
+ if (tr[:last_size] and tr[:last_size] < tr[:blksize])
292
+ #puts "[*] Transfer complete, saving output"
293
+ save_output(tr)
294
+ self.transfers.delete(tr)
295
+ end
296
+ end
297
+ end
298
+ end
299
+ end
300
+ end
301
+
302
+
303
+ def next_block(tr)
304
+ tr[:block] += 1
305
+ tr[:last_sent] = nil
306
+ tr[:retries] = 0
307
+ end
308
+
309
+
310
+ #
311
+ # Dispatch a packet that we received
312
+ #
313
+ def dispatch_request(from, buf)
314
+
315
+ op = buf.unpack('n')[0]
316
+ buf.slice!(0,2)
317
+
318
+ #XXX: todo - create call backs for status
319
+ #start = "[*] TFTP - %s:%u - %s" % [from[0], from[1], OPCODES[op]]
320
+
321
+ case op
322
+ when OpRead
323
+ # Process RRQ packets
324
+ fn = TFTP::get_string(buf)
325
+ mode = TFTP::get_string(buf).downcase
326
+
327
+ #puts "%s %s %s" % [start, fn, mode]
328
+
329
+ if (not @shutting_down) and (file = self.find_file(fn))
330
+ if (file[:once] and file[:started])
331
+ send_error(from, ErrFileNotFound)
332
+ else
333
+ transfer = {
334
+ :type => OpRead,
335
+ :from => from,
336
+ :file => file,
337
+ :block => 1,
338
+ :blksize => 512,
339
+ :offset => 0,
340
+ :timeout => 3,
341
+ :last_sent => nil,
342
+ :retries => 0
343
+ }
344
+
345
+ process_options(from, buf, transfer)
346
+
347
+ self.transfers << transfer
348
+ end
349
+ else
350
+ #puts "[-] file not found!"
351
+ send_error(from, ErrFileNotFound)
352
+ end
353
+
354
+ when OpWrite
355
+ # Process WRQ packets
356
+ fn = TFTP::get_string(buf)
357
+ mode = TFTP::get_string(buf).downcase
358
+
359
+ #puts "%s %s %s" % [start, fn, mode]
360
+
361
+ if not @shutting_down
362
+ transfer = {
363
+ :type => OpWrite,
364
+ :from => from,
365
+ :file => { :name => fn, :data => '' },
366
+ :block => 0, # WRQ starts at 0
367
+ :blksize => 512,
368
+ :timeout => 3,
369
+ :last_sent => nil,
370
+ :retries => 0
371
+ }
372
+
373
+ process_options(from, buf, transfer)
374
+
375
+ self.transfers << transfer
376
+ else
377
+ send_error(from, ErrIllegalOperation)
378
+ end
379
+
380
+ when OpAck
381
+ # Process ACK packets
382
+ block = buf.unpack('n')[0]
383
+
384
+ #puts "%s %d" % [start, block]
385
+
386
+ tr = find_transfer(OpRead, from, block)
387
+ if not tr
388
+ # NOTE: some clients, such as pxelinux, send an ack for block 0.
389
+ # To deal with this, we simply ignore it as we start with block 1.
390
+ return if block == 0
391
+
392
+ # If we didn't find it, send an error.
393
+ send_error(from, ErrUnknownTransferId)
394
+ else
395
+ # acked! send the next block
396
+ tr[:offset] += tr[:blksize]
397
+ next_block(tr)
398
+
399
+ # If the transfer is finished, delete it
400
+ if (tr[:offset] > tr[:file][:data].length)
401
+ #puts "[*] Transfer complete"
402
+ self.transfers.delete(tr)
403
+
404
+ # if the file is a one-serve, delete it from the files array
405
+ if tr[:file][:once]
406
+ #puts "[*] Removed one-serve file: #{tr[:file][:name]}"
407
+ self.files.delete(tr[:file])
408
+ end
409
+ end
410
+ end
411
+
412
+ when OpData
413
+ # Process Data packets
414
+ block = buf.unpack('n')[0]
415
+ data = buf.slice(2, buf.length)
416
+
417
+ #puts "%s %d %d bytes" % [start, block, data.length]
418
+
419
+ tr = find_transfer(OpWrite, from, (block-1))
420
+ if not tr
421
+ # If we didn't find it, send an error.
422
+ send_error(from, ErrUnknownTransferId)
423
+ else
424
+ tr[:file][:data] << data
425
+ tr[:last_size] = data.length
426
+ next_block(tr)
427
+
428
+ # Similar to RRQ transfers, we cannot detect that the
429
+ # transfer finished here. We must do so after transmitting
430
+ # the final ACK.
431
+ end
432
+
433
+ else
434
+ # Other packets are unsupported
435
+ #puts start
436
+ send_error(from, ErrAccessViolation)
437
+
438
+ end
439
+ end
440
+
441
+ def process_options(from, buf, tr)
442
+ found = 0
443
+ to_ack = []
444
+ while buf.length >= 4
445
+ opt = TFTP::get_string(buf)
446
+ break if not opt
447
+ val = TFTP::get_string(buf)
448
+ break if not val
449
+
450
+ found += 1
451
+
452
+ # Is it one we support?
453
+ opt.downcase!
454
+
455
+ case opt
456
+ when "blksize"
457
+ val = val.to_i
458
+ if val > 0
459
+ tr[:blksize] = val
460
+ to_ack << [ opt, val.to_s ]
461
+ end
462
+
463
+ when "timeout"
464
+ val = val.to_i
465
+ if val >= 1 and val <= 255
466
+ tr[:timeout] = val
467
+ to_ack << [ opt, val.to_s ]
468
+ end
469
+
470
+ when "tsize"
471
+ if tr[:type] == OpRead
472
+ len = tr[:file][:data].length
473
+ else
474
+ val = val.to_i
475
+ len = val
476
+ end
477
+ to_ack << [ opt, len.to_s ]
478
+
479
+ end
480
+ end
481
+
482
+ return if to_ack.length < 1
483
+
484
+ # if we have anything to ack, do it
485
+ data = [OpOptAck].pack('n')
486
+ to_ack.each { |el|
487
+ data << el[0] << "\x00" << el[1] << "\x00"
488
+ }
489
+
490
+ send_packet(from, data)
491
+ end
492
+
493
+ end
494
+
495
+ end
496
+ end
497
+ end