librex 0.0.18 → 0.0.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (435) hide show
  1. data/Rakefile +2 -2
  2. data/lib/rex/LICENSE +29 -0
  3. data/lib/rex/arch.rb +103 -0
  4. data/lib/rex/arch/sparc.rb +75 -0
  5. data/lib/rex/arch/sparc.rb.ut.rb +18 -0
  6. data/lib/rex/arch/x86.rb +513 -0
  7. data/lib/rex/arch/x86.rb.ut.rb +93 -0
  8. data/lib/rex/assembly/nasm.rb +104 -0
  9. data/lib/rex/assembly/nasm.rb.ut.rb +22 -0
  10. data/lib/rex/codepage.map +104 -0
  11. data/lib/rex/compat.rb +311 -0
  12. data/lib/rex/constants.rb +113 -0
  13. data/lib/rex/elfparsey.rb +11 -0
  14. data/lib/rex/elfparsey/elf.rb +123 -0
  15. data/lib/rex/elfparsey/elfbase.rb +258 -0
  16. data/lib/rex/elfparsey/exceptions.rb +27 -0
  17. data/lib/rex/elfscan.rb +12 -0
  18. data/lib/rex/elfscan/scanner.rb +207 -0
  19. data/lib/rex/elfscan/search.rb +46 -0
  20. data/lib/rex/encoder/alpha2.rb +31 -0
  21. data/lib/rex/encoder/alpha2/alpha_mixed.rb +68 -0
  22. data/lib/rex/encoder/alpha2/alpha_upper.rb +79 -0
  23. data/lib/rex/encoder/alpha2/generic.rb +114 -0
  24. data/lib/rex/encoder/alpha2/unicode_mixed.rb +117 -0
  25. data/lib/rex/encoder/alpha2/unicode_upper.rb +129 -0
  26. data/lib/rex/encoder/ndr.rb +89 -0
  27. data/lib/rex/encoder/ndr.rb.ut.rb +44 -0
  28. data/lib/rex/encoder/nonalpha.rb +61 -0
  29. data/lib/rex/encoder/nonupper.rb +64 -0
  30. data/lib/rex/encoder/xdr.rb +106 -0
  31. data/lib/rex/encoder/xdr.rb.ut.rb +29 -0
  32. data/lib/rex/encoder/xor.rb +69 -0
  33. data/lib/rex/encoder/xor/dword.rb +13 -0
  34. data/lib/rex/encoder/xor/dword_additive.rb +13 -0
  35. data/lib/rex/encoders/xor_dword.rb +35 -0
  36. data/lib/rex/encoders/xor_dword_additive.rb +53 -0
  37. data/lib/rex/encoders/xor_dword_additive.rb.ut.rb +12 -0
  38. data/lib/rex/encoding/xor.rb +20 -0
  39. data/lib/rex/encoding/xor.rb.ts.rb +14 -0
  40. data/lib/rex/encoding/xor/byte.rb +15 -0
  41. data/lib/rex/encoding/xor/byte.rb.ut.rb +21 -0
  42. data/lib/rex/encoding/xor/dword.rb +21 -0
  43. data/lib/rex/encoding/xor/dword.rb.ut.rb +15 -0
  44. data/lib/rex/encoding/xor/dword_additive.rb +92 -0
  45. data/lib/rex/encoding/xor/dword_additive.rb.ut.rb +15 -0
  46. data/lib/rex/encoding/xor/exceptions.rb +17 -0
  47. data/lib/rex/encoding/xor/generic.rb +146 -0
  48. data/lib/rex/encoding/xor/generic.rb.ut.rb +120 -0
  49. data/lib/rex/encoding/xor/qword.rb +15 -0
  50. data/lib/rex/encoding/xor/word.rb +21 -0
  51. data/lib/rex/encoding/xor/word.rb.ut.rb +13 -0
  52. data/lib/rex/exceptions.rb +275 -0
  53. data/lib/rex/exceptions.rb.ut.rb +44 -0
  54. data/lib/rex/exploitation/cmdstager.rb +9 -0
  55. data/lib/rex/exploitation/cmdstager/base.rb +175 -0
  56. data/lib/rex/exploitation/cmdstager/debug_asm.rb +142 -0
  57. data/lib/rex/exploitation/cmdstager/debug_write.rb +136 -0
  58. data/lib/rex/exploitation/cmdstager/tftp.rb +63 -0
  59. data/lib/rex/exploitation/cmdstager/vbs.rb +128 -0
  60. data/lib/rex/exploitation/egghunter.rb +277 -0
  61. data/lib/rex/exploitation/egghunter.rb.ut.rb +25 -0
  62. data/lib/rex/exploitation/encryptjs.rb +77 -0
  63. data/lib/rex/exploitation/heaplib.js.b64 +331 -0
  64. data/lib/rex/exploitation/heaplib.rb +94 -0
  65. data/lib/rex/exploitation/javascriptosdetect.rb +897 -0
  66. data/lib/rex/exploitation/obfuscatejs.rb +335 -0
  67. data/lib/rex/exploitation/omelet.rb +320 -0
  68. data/lib/rex/exploitation/omelet.rb.ut.rb +13 -0
  69. data/lib/rex/exploitation/opcodedb.rb +818 -0
  70. data/lib/rex/exploitation/opcodedb.rb.ut.rb +279 -0
  71. data/lib/rex/exploitation/seh.rb +92 -0
  72. data/lib/rex/exploitation/seh.rb.ut.rb +19 -0
  73. data/lib/rex/file.rb +112 -0
  74. data/lib/rex/file.rb.ut.rb +16 -0
  75. data/lib/rex/image_source.rb +12 -0
  76. data/lib/rex/image_source/disk.rb +60 -0
  77. data/lib/rex/image_source/image_source.rb +46 -0
  78. data/lib/rex/image_source/memory.rb +37 -0
  79. data/lib/rex/io/bidirectional_pipe.rb +157 -0
  80. data/lib/rex/io/datagram_abstraction.rb +35 -0
  81. data/lib/rex/io/ring_buffer.rb +364 -0
  82. data/lib/rex/io/stream.rb +319 -0
  83. data/lib/rex/io/stream_abstraction.rb +197 -0
  84. data/lib/rex/io/stream_server.rb +211 -0
  85. data/lib/rex/job_container.rb +187 -0
  86. data/lib/rex/logging.rb +4 -0
  87. data/lib/rex/logging/log_dispatcher.rb +179 -0
  88. data/lib/rex/logging/log_sink.rb +42 -0
  89. data/lib/rex/logging/sinks/flatfile.rb +55 -0
  90. data/lib/rex/logging/sinks/stderr.rb +43 -0
  91. data/lib/rex/machparsey.rb +9 -0
  92. data/lib/rex/machparsey/exceptions.rb +34 -0
  93. data/lib/rex/machparsey/mach.rb +209 -0
  94. data/lib/rex/machparsey/machbase.rb +408 -0
  95. data/lib/rex/machscan.rb +9 -0
  96. data/lib/rex/machscan/scanner.rb +217 -0
  97. data/lib/rex/mime.rb +9 -0
  98. data/lib/rex/mime/header.rb +77 -0
  99. data/lib/rex/mime/message.rb +144 -0
  100. data/lib/rex/mime/part.rb +20 -0
  101. data/lib/rex/nop/opty2.rb +108 -0
  102. data/lib/rex/nop/opty2.rb.ut.rb +23 -0
  103. data/lib/rex/nop/opty2_tables.rb +300 -0
  104. data/lib/rex/ole.rb +205 -0
  105. data/lib/rex/ole/clsid.rb +47 -0
  106. data/lib/rex/ole/difat.rb +141 -0
  107. data/lib/rex/ole/directory.rb +231 -0
  108. data/lib/rex/ole/direntry.rb +240 -0
  109. data/lib/rex/ole/docs/dependencies.txt +8 -0
  110. data/lib/rex/ole/docs/references.txt +1 -0
  111. data/lib/rex/ole/fat.rb +99 -0
  112. data/lib/rex/ole/header.rb +204 -0
  113. data/lib/rex/ole/minifat.rb +77 -0
  114. data/lib/rex/ole/propset.rb +144 -0
  115. data/lib/rex/ole/samples/create_ole.rb +27 -0
  116. data/lib/rex/ole/samples/dir.rb +35 -0
  117. data/lib/rex/ole/samples/dump_stream.rb +34 -0
  118. data/lib/rex/ole/samples/ole_info.rb +23 -0
  119. data/lib/rex/ole/storage.rb +395 -0
  120. data/lib/rex/ole/stream.rb +53 -0
  121. data/lib/rex/ole/substorage.rb +49 -0
  122. data/lib/rex/ole/util.rb +157 -0
  123. data/lib/rex/parser/arguments.rb +97 -0
  124. data/lib/rex/parser/arguments.rb.ut.rb +67 -0
  125. data/lib/rex/parser/ini.rb +185 -0
  126. data/lib/rex/parser/ini.rb.ut.rb +29 -0
  127. data/lib/rex/parser/ip360_aspl_xml.rb +102 -0
  128. data/lib/rex/parser/ip360_xml.rb +97 -0
  129. data/lib/rex/parser/nessus_xml.rb +118 -0
  130. data/lib/rex/parser/netsparker_xml.rb +94 -0
  131. data/lib/rex/parser/nexpose_xml.rb +136 -0
  132. data/lib/rex/parser/nmap_xml.rb +137 -0
  133. data/lib/rex/parser/retina_xml.rb +109 -0
  134. data/lib/rex/payloads.rb +1 -0
  135. data/lib/rex/payloads/win32.rb +2 -0
  136. data/lib/rex/payloads/win32/common.rb +26 -0
  137. data/lib/rex/payloads/win32/kernel.rb +53 -0
  138. data/lib/rex/payloads/win32/kernel/common.rb +54 -0
  139. data/lib/rex/payloads/win32/kernel/migration.rb +12 -0
  140. data/lib/rex/payloads/win32/kernel/recovery.rb +50 -0
  141. data/lib/rex/payloads/win32/kernel/stager.rb +194 -0
  142. data/lib/rex/peparsey.rb +12 -0
  143. data/lib/rex/peparsey/exceptions.rb +32 -0
  144. data/lib/rex/peparsey/pe.rb +212 -0
  145. data/lib/rex/peparsey/pe_memdump.rb +63 -0
  146. data/lib/rex/peparsey/pebase.rb +1680 -0
  147. data/lib/rex/peparsey/section.rb +136 -0
  148. data/lib/rex/pescan.rb +13 -0
  149. data/lib/rex/pescan/analyze.rb +309 -0
  150. data/lib/rex/pescan/scanner.rb +206 -0
  151. data/lib/rex/pescan/search.rb +56 -0
  152. data/lib/rex/platforms.rb +1 -0
  153. data/lib/rex/platforms/windows.rb +51 -0
  154. data/lib/rex/poly.rb +132 -0
  155. data/lib/rex/poly/block.rb +477 -0
  156. data/lib/rex/poly/register.rb +100 -0
  157. data/lib/rex/poly/register/x86.rb +40 -0
  158. data/lib/rex/post.rb +8 -0
  159. data/lib/rex/post/dir.rb +51 -0
  160. data/lib/rex/post/file.rb +172 -0
  161. data/lib/rex/post/file_stat.rb +220 -0
  162. data/lib/rex/post/gen.pl +13 -0
  163. data/lib/rex/post/io.rb +182 -0
  164. data/lib/rex/post/meterpreter.rb +4 -0
  165. data/lib/rex/post/meterpreter/channel.rb +445 -0
  166. data/lib/rex/post/meterpreter/channel_container.rb +54 -0
  167. data/lib/rex/post/meterpreter/channels/pool.rb +160 -0
  168. data/lib/rex/post/meterpreter/channels/pools/file.rb +62 -0
  169. data/lib/rex/post/meterpreter/channels/pools/stream_pool.rb +103 -0
  170. data/lib/rex/post/meterpreter/channels/stream.rb +87 -0
  171. data/lib/rex/post/meterpreter/client.rb +364 -0
  172. data/lib/rex/post/meterpreter/client_core.rb +274 -0
  173. data/lib/rex/post/meterpreter/dependencies.rb +3 -0
  174. data/lib/rex/post/meterpreter/extension.rb +32 -0
  175. data/lib/rex/post/meterpreter/extensions/espia/espia.rb +58 -0
  176. data/lib/rex/post/meterpreter/extensions/espia/tlv.rb +16 -0
  177. data/lib/rex/post/meterpreter/extensions/incognito/incognito.rb +94 -0
  178. data/lib/rex/post/meterpreter/extensions/incognito/tlv.rb +21 -0
  179. data/lib/rex/post/meterpreter/extensions/networkpug/networkpug.rb +57 -0
  180. data/lib/rex/post/meterpreter/extensions/networkpug/tlv.rb +15 -0
  181. data/lib/rex/post/meterpreter/extensions/priv/fs.rb +118 -0
  182. data/lib/rex/post/meterpreter/extensions/priv/passwd.rb +61 -0
  183. data/lib/rex/post/meterpreter/extensions/priv/priv.rb +111 -0
  184. data/lib/rex/post/meterpreter/extensions/priv/tlv.rb +28 -0
  185. data/lib/rex/post/meterpreter/extensions/sniffer/sniffer.rb +101 -0
  186. data/lib/rex/post/meterpreter/extensions/sniffer/tlv.rb +26 -0
  187. data/lib/rex/post/meterpreter/extensions/stdapi/constants.rb +333 -0
  188. data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +282 -0
  189. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +266 -0
  190. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file_stat.rb +103 -0
  191. data/lib/rex/post/meterpreter/extensions/stdapi/fs/io.rb +48 -0
  192. data/lib/rex/post/meterpreter/extensions/stdapi/net/config.rb +144 -0
  193. data/lib/rex/post/meterpreter/extensions/stdapi/net/interface.rb +73 -0
  194. data/lib/rex/post/meterpreter/extensions/stdapi/net/route.rb +56 -0
  195. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +137 -0
  196. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +180 -0
  197. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb +167 -0
  198. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +208 -0
  199. data/lib/rex/post/meterpreter/extensions/stdapi/railgun.rb.ts.rb +6 -0
  200. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb +38106 -0
  201. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb.ut.rb +31 -0
  202. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb +47 -0
  203. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb.ut.rb +36 -0
  204. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_advapi32.rb +1818 -0
  205. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_iphlpapi.rb +96 -0
  206. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +3848 -0
  207. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_netapi32.rb +26 -0
  208. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ntdll.rb +153 -0
  209. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_shell32.rb +21 -0
  210. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_user32.rb +3169 -0
  211. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ws2_32.rb +599 -0
  212. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb +318 -0
  213. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb +100 -0
  214. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb.ut.rb +42 -0
  215. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb +148 -0
  216. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb.ut.rb +127 -0
  217. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/multicall.rb +309 -0
  218. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb +204 -0
  219. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/tlv.rb +51 -0
  220. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb +630 -0
  221. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb +75 -0
  222. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb.ut.rb +103 -0
  223. data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +149 -0
  224. data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +97 -0
  225. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +192 -0
  226. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log_subsystem/event_record.rb +41 -0
  227. data/lib/rex/post/meterpreter/extensions/stdapi/sys/power.rb +61 -0
  228. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +370 -0
  229. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/image.rb +129 -0
  230. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/io.rb +55 -0
  231. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/memory.rb +336 -0
  232. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/thread.rb +141 -0
  233. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +279 -0
  234. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +193 -0
  235. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_value.rb +102 -0
  236. data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +180 -0
  237. data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +211 -0
  238. data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +227 -0
  239. data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +63 -0
  240. data/lib/rex/post/meterpreter/inbound_packet_handler.rb +30 -0
  241. data/lib/rex/post/meterpreter/object_aliases.rb +83 -0
  242. data/lib/rex/post/meterpreter/packet.rb +688 -0
  243. data/lib/rex/post/meterpreter/packet_dispatcher.rb +431 -0
  244. data/lib/rex/post/meterpreter/packet_parser.rb +94 -0
  245. data/lib/rex/post/meterpreter/packet_response_waiter.rb +83 -0
  246. data/lib/rex/post/meterpreter/ui/console.rb +137 -0
  247. data/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb +62 -0
  248. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +730 -0
  249. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/espia.rb +108 -0
  250. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/incognito.rb +241 -0
  251. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/networkpug.rb +231 -0
  252. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv.rb +61 -0
  253. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +98 -0
  254. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/passwd.rb +51 -0
  255. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +132 -0
  256. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +187 -0
  257. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi.rb +65 -0
  258. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +442 -0
  259. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +298 -0
  260. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +486 -0
  261. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +315 -0
  262. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +157 -0
  263. data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +95 -0
  264. data/lib/rex/post/permission.rb +26 -0
  265. data/lib/rex/post/process.rb +57 -0
  266. data/lib/rex/post/thread.rb +57 -0
  267. data/lib/rex/post/ui.rb +52 -0
  268. data/lib/rex/proto.rb +13 -0
  269. data/lib/rex/proto.rb.ts.rb +8 -0
  270. data/lib/rex/proto/dcerpc.rb +6 -0
  271. data/lib/rex/proto/dcerpc.rb.ts.rb +9 -0
  272. data/lib/rex/proto/dcerpc/client.rb +361 -0
  273. data/lib/rex/proto/dcerpc/client.rb.ut.rb +491 -0
  274. data/lib/rex/proto/dcerpc/exceptions.rb +150 -0
  275. data/lib/rex/proto/dcerpc/handle.rb +47 -0
  276. data/lib/rex/proto/dcerpc/handle.rb.ut.rb +85 -0
  277. data/lib/rex/proto/dcerpc/ndr.rb +72 -0
  278. data/lib/rex/proto/dcerpc/ndr.rb.ut.rb +41 -0
  279. data/lib/rex/proto/dcerpc/packet.rb +253 -0
  280. data/lib/rex/proto/dcerpc/packet.rb.ut.rb +56 -0
  281. data/lib/rex/proto/dcerpc/response.rb +187 -0
  282. data/lib/rex/proto/dcerpc/response.rb.ut.rb +15 -0
  283. data/lib/rex/proto/dcerpc/uuid.rb +84 -0
  284. data/lib/rex/proto/dcerpc/uuid.rb.ut.rb +46 -0
  285. data/lib/rex/proto/dhcp.rb +7 -0
  286. data/lib/rex/proto/dhcp/constants.rb +33 -0
  287. data/lib/rex/proto/dhcp/server.rb +292 -0
  288. data/lib/rex/proto/drda.rb +5 -0
  289. data/lib/rex/proto/drda.rb.ts.rb +17 -0
  290. data/lib/rex/proto/drda/constants.rb +49 -0
  291. data/lib/rex/proto/drda/constants.rb.ut.rb +23 -0
  292. data/lib/rex/proto/drda/packet.rb +252 -0
  293. data/lib/rex/proto/drda/packet.rb.ut.rb +109 -0
  294. data/lib/rex/proto/drda/utils.rb +123 -0
  295. data/lib/rex/proto/drda/utils.rb.ut.rb +84 -0
  296. data/lib/rex/proto/http.rb +5 -0
  297. data/lib/rex/proto/http.rb.ts.rb +12 -0
  298. data/lib/rex/proto/http/client.rb +821 -0
  299. data/lib/rex/proto/http/client.rb.ut.rb +95 -0
  300. data/lib/rex/proto/http/handler.rb +46 -0
  301. data/lib/rex/proto/http/handler/erb.rb +128 -0
  302. data/lib/rex/proto/http/handler/erb.rb.ut.rb +21 -0
  303. data/lib/rex/proto/http/handler/erb.rb.ut.rb.rhtml +1 -0
  304. data/lib/rex/proto/http/handler/proc.rb +60 -0
  305. data/lib/rex/proto/http/handler/proc.rb.ut.rb +24 -0
  306. data/lib/rex/proto/http/header.rb +161 -0
  307. data/lib/rex/proto/http/header.rb.ut.rb +46 -0
  308. data/lib/rex/proto/http/packet.rb +407 -0
  309. data/lib/rex/proto/http/packet.rb.ut.rb +165 -0
  310. data/lib/rex/proto/http/request.rb +356 -0
  311. data/lib/rex/proto/http/request.rb.ut.rb +214 -0
  312. data/lib/rex/proto/http/response.rb +90 -0
  313. data/lib/rex/proto/http/response.rb.ut.rb +149 -0
  314. data/lib/rex/proto/http/server.rb +369 -0
  315. data/lib/rex/proto/http/server.rb.ut.rb +79 -0
  316. data/lib/rex/proto/ntlm.rb +7 -0
  317. data/lib/rex/proto/ntlm.rb.ut.rb +177 -0
  318. data/lib/rex/proto/ntlm/base.rb +326 -0
  319. data/lib/rex/proto/ntlm/constants.rb +74 -0
  320. data/lib/rex/proto/ntlm/crypt.rb +415 -0
  321. data/lib/rex/proto/ntlm/exceptions.rb +16 -0
  322. data/lib/rex/proto/ntlm/message.rb +536 -0
  323. data/lib/rex/proto/ntlm/utils.rb +764 -0
  324. data/lib/rex/proto/proxy/socks4a.rb +440 -0
  325. data/lib/rex/proto/rfb.rb +19 -0
  326. data/lib/rex/proto/rfb.rb.ut.rb +37 -0
  327. data/lib/rex/proto/rfb/cipher.rb +84 -0
  328. data/lib/rex/proto/rfb/client.rb +207 -0
  329. data/lib/rex/proto/rfb/constants.rb +52 -0
  330. data/lib/rex/proto/smb.rb +7 -0
  331. data/lib/rex/proto/smb.rb.ts.rb +8 -0
  332. data/lib/rex/proto/smb/client.rb +1952 -0
  333. data/lib/rex/proto/smb/client.rb.ut.rb +223 -0
  334. data/lib/rex/proto/smb/constants.rb +1047 -0
  335. data/lib/rex/proto/smb/constants.rb.ut.rb +18 -0
  336. data/lib/rex/proto/smb/crypt.rb +36 -0
  337. data/lib/rex/proto/smb/evasions.rb +66 -0
  338. data/lib/rex/proto/smb/exceptions.rb +858 -0
  339. data/lib/rex/proto/smb/simpleclient.rb +306 -0
  340. data/lib/rex/proto/smb/simpleclient.rb.ut.rb +128 -0
  341. data/lib/rex/proto/smb/utils.rb +103 -0
  342. data/lib/rex/proto/smb/utils.rb.ut.rb +20 -0
  343. data/lib/rex/proto/sunrpc.rb +1 -0
  344. data/lib/rex/proto/sunrpc/client.rb +195 -0
  345. data/lib/rex/proto/tftp.rb +12 -0
  346. data/lib/rex/proto/tftp/constants.rb +39 -0
  347. data/lib/rex/proto/tftp/server.rb +497 -0
  348. data/lib/rex/proto/tftp/server.rb.ut.rb +28 -0
  349. data/lib/rex/script.rb +42 -0
  350. data/lib/rex/script/base.rb +59 -0
  351. data/lib/rex/script/meterpreter.rb +15 -0
  352. data/lib/rex/script/shell.rb +9 -0
  353. data/lib/rex/service.rb +48 -0
  354. data/lib/rex/service_manager.rb +141 -0
  355. data/lib/rex/service_manager.rb.ut.rb +32 -0
  356. data/lib/rex/services/local_relay.rb +423 -0
  357. data/lib/rex/socket.rb +684 -0
  358. data/lib/rex/socket.rb.ut.rb +107 -0
  359. data/lib/rex/socket/comm.rb +119 -0
  360. data/lib/rex/socket/comm/local.rb +412 -0
  361. data/lib/rex/socket/comm/local.rb.ut.rb +75 -0
  362. data/lib/rex/socket/ip.rb +130 -0
  363. data/lib/rex/socket/parameters.rb +345 -0
  364. data/lib/rex/socket/parameters.rb.ut.rb +51 -0
  365. data/lib/rex/socket/range_walker.rb +346 -0
  366. data/lib/rex/socket/range_walker.rb.ut.rb +55 -0
  367. data/lib/rex/socket/ssl_tcp.rb +184 -0
  368. data/lib/rex/socket/ssl_tcp.rb.ut.rb +39 -0
  369. data/lib/rex/socket/ssl_tcp_server.rb +122 -0
  370. data/lib/rex/socket/ssl_tcp_server.rb.ut.rb +61 -0
  371. data/lib/rex/socket/subnet_walker.rb +75 -0
  372. data/lib/rex/socket/subnet_walker.rb.ut.rb +28 -0
  373. data/lib/rex/socket/switch_board.rb +278 -0
  374. data/lib/rex/socket/switch_board.rb.ut.rb +52 -0
  375. data/lib/rex/socket/tcp.rb +76 -0
  376. data/lib/rex/socket/tcp.rb.ut.rb +64 -0
  377. data/lib/rex/socket/tcp_server.rb +66 -0
  378. data/lib/rex/socket/tcp_server.rb.ut.rb +44 -0
  379. data/lib/rex/socket/udp.rb +164 -0
  380. data/lib/rex/socket/udp.rb.ut.rb +44 -0
  381. data/lib/rex/struct2.rb +5 -0
  382. data/lib/rex/struct2/c_struct.rb +181 -0
  383. data/lib/rex/struct2/c_struct_template.rb +39 -0
  384. data/lib/rex/struct2/constant.rb +26 -0
  385. data/lib/rex/struct2/element.rb +44 -0
  386. data/lib/rex/struct2/generic.rb +73 -0
  387. data/lib/rex/struct2/restraint.rb +54 -0
  388. data/lib/rex/struct2/s_string.rb +72 -0
  389. data/lib/rex/struct2/s_struct.rb +111 -0
  390. data/lib/rex/sync.rb +6 -0
  391. data/lib/rex/sync/event.rb +94 -0
  392. data/lib/rex/sync/read_write_lock.rb +176 -0
  393. data/lib/rex/sync/ref.rb +57 -0
  394. data/lib/rex/sync/thread_safe.rb +82 -0
  395. data/lib/rex/test.rb +35 -0
  396. data/lib/rex/text.rb +1163 -0
  397. data/lib/rex/text.rb.ut.rb +190 -0
  398. data/lib/rex/thread_factory.rb +42 -0
  399. data/lib/rex/time.rb +65 -0
  400. data/lib/rex/transformer.rb +115 -0
  401. data/lib/rex/transformer.rb.ut.rb +38 -0
  402. data/lib/rex/ui.rb +21 -0
  403. data/lib/rex/ui/interactive.rb +298 -0
  404. data/lib/rex/ui/output.rb +78 -0
  405. data/lib/rex/ui/output/none.rb +18 -0
  406. data/lib/rex/ui/progress_tracker.rb +96 -0
  407. data/lib/rex/ui/subscriber.rb +149 -0
  408. data/lib/rex/ui/text/color.rb +97 -0
  409. data/lib/rex/ui/text/color.rb.ut.rb +18 -0
  410. data/lib/rex/ui/text/dispatcher_shell.rb +467 -0
  411. data/lib/rex/ui/text/input.rb +117 -0
  412. data/lib/rex/ui/text/input/buffer.rb +75 -0
  413. data/lib/rex/ui/text/input/readline.rb +129 -0
  414. data/lib/rex/ui/text/input/socket.rb +95 -0
  415. data/lib/rex/ui/text/input/stdio.rb +45 -0
  416. data/lib/rex/ui/text/irb_shell.rb +57 -0
  417. data/lib/rex/ui/text/output.rb +80 -0
  418. data/lib/rex/ui/text/output/buffer.rb +61 -0
  419. data/lib/rex/ui/text/output/file.rb +43 -0
  420. data/lib/rex/ui/text/output/socket.rb +43 -0
  421. data/lib/rex/ui/text/output/stdio.rb +40 -0
  422. data/lib/rex/ui/text/progress_tracker.rb +56 -0
  423. data/lib/rex/ui/text/progress_tracker.rb.ut.rb +34 -0
  424. data/lib/rex/ui/text/shell.rb +328 -0
  425. data/lib/rex/ui/text/table.rb +279 -0
  426. data/lib/rex/ui/text/table.rb.ut.rb +55 -0
  427. data/lib/rex/zip.rb +93 -0
  428. data/lib/rex/zip/archive.rb +184 -0
  429. data/lib/rex/zip/blocks.rb +182 -0
  430. data/lib/rex/zip/entry.rb +104 -0
  431. data/lib/rex/zip/samples/comment.rb +32 -0
  432. data/lib/rex/zip/samples/mkwar.rb +138 -0
  433. data/lib/rex/zip/samples/mkzip.rb +19 -0
  434. data/lib/rex/zip/samples/recursive.rb +58 -0
  435. metadata +434 -1
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.join(File.dirname(__FILE__), '..', '..', '..'))
4
+
5
+ require 'rex/test'
6
+ require 'rex/proto/smb/utils'
7
+
8
+ class Rex::Proto::SMB::Utils::UnitTest < Test::Unit::TestCase
9
+
10
+ Klass = Rex::Proto::SMB::Utils
11
+
12
+ def test_nbname
13
+
14
+ nbdecoded = 'METASPLOITROCKS!'
15
+ nbencoded = 'ENEFFEEBFDFAEMEPEJFEFCEPEDELFDCB'
16
+
17
+ assert_equal(Klass.nbname_encode(nbdecoded), nbencoded )
18
+ assert_equal(Klass.nbname_decode(nbencoded), nbdecoded )
19
+ end
20
+ end
@@ -0,0 +1 @@
1
+ require 'rex/proto/sunrpc/client'
@@ -0,0 +1,195 @@
1
+ require 'rex/socket'
2
+ require 'rex/encoder/xdr'
3
+
4
+ module Rex
5
+ module Proto
6
+ module SunRPC
7
+
8
+ class RPCTimeout < ::Interrupt
9
+ def initialize(msg = 'Operation timed out.')
10
+ @msg = msg
11
+ end
12
+
13
+ def to_s
14
+ @msg
15
+ end
16
+ end
17
+
18
+ # XXX: CPORT!
19
+ class Client
20
+ AUTH_NULL = 0
21
+ AUTH_UNIX = 1
22
+
23
+ PMAP_PROG = 100000
24
+ PMAP_VERS = 2
25
+ PMAP_GETPORT = 3
26
+
27
+ CALL = 0
28
+
29
+ attr_accessor :rhost, :rport, :proto, :program, :version
30
+ attr_accessor :pport, :call_sock, :timeout, :context
31
+
32
+ attr_accessor :should_fragment
33
+
34
+ def initialize(opts)
35
+ self.rhost = opts[:rhost]
36
+ self.rport = opts[:rport]
37
+ self.program = opts[:program]
38
+ self.version = opts[:version]
39
+ self.timeout = opts[:timeout] || 20
40
+ self.context = opts[:context] || {}
41
+ self.proto = opts[:proto]
42
+
43
+ if self.proto.downcase !~ /^(tcp|udp)$/
44
+ raise ::Rex::ArgumentError, 'Protocol is not "tcp" or "udp"'
45
+ end
46
+
47
+ @pport = nil
48
+
49
+ @auth_type = AUTH_NULL
50
+ @auth_data = ''
51
+
52
+ @call_sock = nil
53
+ end
54
+
55
+ # XXX: Add optional parameter to have proto be something else
56
+ def create()
57
+ proto_num = 0
58
+ if @proto.eql?('tcp')
59
+ proto_num = 6
60
+ elsif @proto.eql?('udp')
61
+ proto_num = 17
62
+ end
63
+
64
+ buf =
65
+ Rex::Encoder::XDR.encode(CALL, 2, PMAP_PROG, PMAP_VERS, PMAP_GETPORT,
66
+ @auth_type, [@auth_data, 400], AUTH_NULL, '',
67
+ @program, @version, proto_num, 0)
68
+
69
+ sock = make_rpc(@proto, @rhost, @rport)
70
+ send_rpc(sock, buf)
71
+ ret = recv_rpc(sock)
72
+ close_rpc(sock)
73
+
74
+ return ret
75
+ end
76
+
77
+ def call(procedure, buffer, maxwait = self.timeout)
78
+ buf =
79
+ Rex::Encoder::XDR.encode(CALL, 2, @program, @version, procedure,
80
+ @auth_type, [@auth_data, 400], AUTH_NULL, '')+
81
+ buffer
82
+
83
+ if ! @call_sock
84
+ @call_sock = make_rpc(@proto, @rhost, @pport)
85
+ end
86
+
87
+ send_rpc(@call_sock, buf)
88
+ recv_rpc(@call_sock, maxwait)
89
+ end
90
+
91
+ def destroy
92
+ close_rpc(@call_sock) if @call_sock
93
+ @call_sock = nil
94
+ end
95
+
96
+ def authnull_create
97
+ @auth_type = AUTH_NULL
98
+ @auth_data = ''
99
+ end
100
+
101
+ def authunix_create(host, uid, gid, groupz)
102
+ raise ::Rex::ArgumentError, 'Hostname length is too long' if host.length > 255
103
+ # 10?
104
+ raise ::Rex::ArgumentError, 'Too many groups' if groupz.length > 10
105
+
106
+ @auth_type = AUTH_UNIX
107
+ @auth_data =
108
+ Rex::Encoder::XDR.encode(0, host, uid, gid, groupz) # XXX: TIME! GROUPZ?!
109
+ end
110
+
111
+ # XXX: Dirty, integrate some sort of request system into create/call?
112
+ def portmap_req(host, port, rpc_vers, procedure, buffer)
113
+ buf = Rex::Encoder::XDR.encode(CALL, 2, PMAP_PROG, rpc_vers, procedure,
114
+ AUTH_NULL, '', AUTH_NULL, '') + buffer
115
+
116
+ sock = make_rpc('tcp', host, port)
117
+ send_rpc(sock, buf)
118
+ ret = recv_rpc(sock)
119
+ close_rpc(sock)
120
+
121
+ return ret
122
+ end
123
+
124
+ private
125
+ def make_rpc(proto, host, port)
126
+ Rex::Socket.create(
127
+ 'PeerHost' => host,
128
+ 'PeerPort' => port,
129
+ 'Proto' => proto,
130
+ 'Timeout' => self.timeout,
131
+ 'Context' => self.context
132
+ )
133
+ end
134
+
135
+ def build_tcp(buf)
136
+ if !self.should_fragment
137
+ return Rex::Encoder::XDR.encode(0x80000000 | buf.length) + buf
138
+ end
139
+
140
+ str = buf.dup
141
+
142
+ fragmented = ''
143
+
144
+ while (str.size > 0)
145
+ frag = str.slice!(0, rand(3) + 1)
146
+ len = frag.size
147
+ if str.size == 0
148
+ len |= 0x80000000
149
+ end
150
+
151
+ fragmented += Rex::Encoder::XDR.encode(len) + frag
152
+ end
153
+
154
+ return fragmented
155
+ end
156
+
157
+ def send_rpc(sock, buf)
158
+ buf = gen_xid() + buf
159
+ if sock.type?.eql?('tcp')
160
+ buf = build_tcp(buf)
161
+ end
162
+ sock.put(buf)
163
+ end
164
+
165
+ def recv_rpc(sock, maxwait=self.timeout)
166
+
167
+ buf = nil
168
+ begin
169
+ Timeout.timeout(maxwait) { buf = sock.get }
170
+ rescue ::Timeout
171
+ end
172
+
173
+ return nil if not buf
174
+
175
+ buf.slice!(0..3)
176
+ if sock.type?.eql?('tcp')
177
+ buf.slice!(0..3)
178
+ end
179
+ return buf if buf.length > 1
180
+ return nil
181
+ end
182
+
183
+ def close_rpc(sock)
184
+ sock.close
185
+ end
186
+
187
+ def gen_xid
188
+ return Rex::Encoder::XDR.encode(rand(0xffffffff) + 1)
189
+ end
190
+ end
191
+
192
+ end
193
+ end
194
+ end
195
+
@@ -0,0 +1,12 @@
1
+ # $Id: tftp.rb 9962 2010-08-06 17:21:22Z jduck $
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'
@@ -0,0 +1,39 @@
1
+ # $Id: constants.rb 9962 2010-08-06 17:21:22Z jduck $
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
+ # $Id: server.rb 11636 2011-01-25 02:24:37Z hdm $
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, true)
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