librex 0.0.68 → 0.0.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (528) hide show
  1. checksums.yaml +15 -0
  2. data/README.markdown +1 -1
  3. data/Rakefile +18 -16
  4. data/lib/rex.rb +14 -10
  5. data/lib/rex/LICENSE +2 -2
  6. data/lib/rex/arch.rb +76 -76
  7. data/lib/rex/arch/sparc.rb +57 -58
  8. data/lib/rex/arch/x86.rb +506 -496
  9. data/lib/rex/assembly/nasm.rb +83 -84
  10. data/lib/rex/compat.rb +228 -173
  11. data/lib/rex/constants.rb +47 -37
  12. data/lib/rex/elfparsey.rb +0 -3
  13. data/lib/rex/elfparsey/elf.rb +107 -110
  14. data/lib/rex/elfparsey/elfbase.rb +244 -247
  15. data/lib/rex/elfparsey/exceptions.rb +0 -3
  16. data/lib/rex/elfscan.rb +0 -3
  17. data/lib/rex/elfscan/scanner.rb +184 -166
  18. data/lib/rex/elfscan/search.rb +35 -38
  19. data/lib/rex/encoder/alpha2.rb +1 -2
  20. data/lib/rex/encoder/alpha2/alpha_mixed.rb +52 -53
  21. data/lib/rex/encoder/alpha2/alpha_upper.rb +62 -63
  22. data/lib/rex/encoder/alpha2/generic.rb +77 -78
  23. data/lib/rex/encoder/alpha2/unicode_mixed.rb +101 -97
  24. data/lib/rex/encoder/alpha2/unicode_upper.rb +106 -107
  25. data/lib/rex/encoder/bloxor/bloxor.rb +326 -0
  26. data/lib/rex/encoder/ndr.rb +68 -68
  27. data/lib/rex/encoder/nonalpha.rb +50 -51
  28. data/lib/rex/encoder/nonupper.rb +50 -51
  29. data/lib/rex/encoder/xdr.rb +78 -78
  30. data/lib/rex/encoder/xor.rb +52 -53
  31. data/lib/rex/encoder/xor/dword.rb +1 -2
  32. data/lib/rex/encoder/xor/dword_additive.rb +1 -2
  33. data/lib/rex/encoders/xor_dword.rb +17 -18
  34. data/lib/rex/encoders/xor_dword_additive.rb +35 -36
  35. data/lib/rex/encoding/xor.rb +0 -1
  36. data/lib/rex/encoding/xor/byte.rb +3 -4
  37. data/lib/rex/encoding/xor/dword.rb +3 -4
  38. data/lib/rex/encoding/xor/dword_additive.rb +72 -73
  39. data/lib/rex/encoding/xor/exceptions.rb +2 -3
  40. data/lib/rex/encoding/xor/generic.rb +129 -130
  41. data/lib/rex/encoding/xor/qword.rb +3 -4
  42. data/lib/rex/encoding/xor/word.rb +3 -4
  43. data/lib/rex/exceptions.rb +100 -101
  44. data/lib/rex/exploitation/cmdstager.rb +3 -3
  45. data/lib/rex/exploitation/cmdstager/base.rb +170 -156
  46. data/lib/rex/exploitation/cmdstager/bourne.rb +105 -0
  47. data/lib/rex/exploitation/cmdstager/debug_asm.rb +110 -113
  48. data/lib/rex/exploitation/cmdstager/debug_write.rb +106 -109
  49. data/lib/rex/exploitation/cmdstager/echo.rb +164 -0
  50. data/lib/rex/exploitation/cmdstager/printf.rb +122 -0
  51. data/lib/rex/exploitation/cmdstager/tftp.rb +34 -27
  52. data/lib/rex/exploitation/cmdstager/vbs.rb +95 -98
  53. data/lib/rex/exploitation/egghunter.rb +359 -346
  54. data/lib/rex/exploitation/encryptjs.rb +60 -60
  55. data/lib/rex/exploitation/heaplib.rb +76 -76
  56. data/lib/rex/exploitation/js.rb +6 -0
  57. data/lib/rex/exploitation/js/detect.rb +69 -0
  58. data/lib/rex/exploitation/js/memory.rb +81 -0
  59. data/lib/rex/exploitation/js/network.rb +84 -0
  60. data/lib/rex/exploitation/js/utils.rb +33 -0
  61. data/lib/rex/exploitation/jsobfu.rb +448 -424
  62. data/lib/rex/exploitation/obfuscatejs.rb +301 -301
  63. data/lib/rex/exploitation/omelet.rb +257 -257
  64. data/lib/rex/exploitation/opcodedb.rb +699 -699
  65. data/lib/rex/exploitation/ropdb.rb +189 -0
  66. data/lib/rex/exploitation/seh.rb +68 -68
  67. data/lib/rex/file.rb +96 -49
  68. data/lib/rex/image_source.rb +0 -3
  69. data/lib/rex/image_source/disk.rb +45 -48
  70. data/lib/rex/image_source/image_source.rb +33 -36
  71. data/lib/rex/image_source/memory.rb +17 -20
  72. data/lib/rex/io/bidirectional_pipe.rb +118 -115
  73. data/lib/rex/io/datagram_abstraction.rb +13 -14
  74. data/lib/rex/io/ring_buffer.rb +273 -273
  75. data/lib/rex/io/stream.rb +284 -284
  76. data/lib/rex/io/stream_abstraction.rb +183 -181
  77. data/lib/rex/io/stream_server.rb +193 -193
  78. data/lib/rex/job_container.rb +167 -167
  79. data/lib/rex/logging.rb +0 -1
  80. data/lib/rex/logging/log_dispatcher.rb +113 -113
  81. data/lib/rex/logging/log_sink.rb +17 -17
  82. data/lib/rex/logging/sinks/flatfile.rb +36 -36
  83. data/lib/rex/logging/sinks/stderr.rb +27 -27
  84. data/lib/rex/mac_oui.rb +16572 -16571
  85. data/lib/rex/machparsey.rb +0 -1
  86. data/lib/rex/machparsey/exceptions.rb +0 -1
  87. data/lib/rex/machparsey/mach.rb +160 -161
  88. data/lib/rex/machparsey/machbase.rb +367 -368
  89. data/lib/rex/machscan.rb +0 -1
  90. data/lib/rex/machscan/scanner.rb +175 -176
  91. data/lib/rex/mime/encoding.rb +17 -0
  92. data/lib/rex/mime/header.rb +58 -58
  93. data/lib/rex/mime/message.rb +140 -137
  94. data/lib/rex/mime/part.rb +41 -12
  95. data/lib/rex/nop/opty2.rb +90 -90
  96. data/lib/rex/nop/opty2_tables.rb +273 -273
  97. data/lib/rex/ole.rb +0 -4
  98. data/lib/rex/ole/clsid.rb +26 -30
  99. data/lib/rex/ole/difat.rb +121 -125
  100. data/lib/rex/ole/directory.rb +205 -209
  101. data/lib/rex/ole/direntry.rb +217 -221
  102. data/lib/rex/ole/fat.rb +79 -83
  103. data/lib/rex/ole/header.rb +178 -182
  104. data/lib/rex/ole/minifat.rb +49 -53
  105. data/lib/rex/ole/propset.rb +113 -117
  106. data/lib/rex/ole/samples/create_ole.rb +8 -9
  107. data/lib/rex/ole/samples/dir.rb +10 -11
  108. data/lib/rex/ole/samples/dump_stream.rb +14 -15
  109. data/lib/rex/ole/samples/ole_info.rb +5 -6
  110. data/lib/rex/ole/storage.rb +372 -376
  111. data/lib/rex/ole/stream.rb +33 -37
  112. data/lib/rex/ole/substorage.rb +20 -24
  113. data/lib/rex/ole/util.rb +137 -141
  114. data/lib/rex/parser/acunetix_nokogiri.rb +398 -398
  115. data/lib/rex/parser/apple_backup_manifestdb.rb +116 -116
  116. data/lib/rex/parser/appscan_nokogiri.rb +359 -359
  117. data/lib/rex/parser/arguments.rb +88 -88
  118. data/lib/rex/parser/burp_session_nokogiri.rb +258 -258
  119. data/lib/rex/parser/ci_nokogiri.rb +184 -184
  120. data/lib/rex/parser/foundstone_nokogiri.rb +334 -333
  121. data/lib/rex/parser/fusionvm_nokogiri.rb +94 -94
  122. data/lib/rex/parser/ini.rb +167 -167
  123. data/lib/rex/parser/ip360_aspl_xml.rb +84 -84
  124. data/lib/rex/parser/ip360_xml.rb +77 -77
  125. data/lib/rex/parser/mbsa_nokogiri.rb +224 -224
  126. data/lib/rex/parser/nessus_xml.rb +100 -100
  127. data/lib/rex/parser/netsparker_xml.rb +89 -75
  128. data/lib/rex/parser/nexpose_raw_nokogiri.rb +677 -677
  129. data/lib/rex/parser/nexpose_simple_nokogiri.rb +322 -322
  130. data/lib/rex/parser/nexpose_xml.rb +105 -105
  131. data/lib/rex/parser/nmap_nokogiri.rb +386 -386
  132. data/lib/rex/parser/nmap_xml.rb +116 -116
  133. data/lib/rex/parser/nokogiri_doc_mixin.rb +223 -221
  134. data/lib/rex/parser/openvas_nokogiri.rb +162 -162
  135. data/lib/rex/parser/outpost24_nokogiri.rb +239 -0
  136. data/lib/rex/parser/retina_xml.rb +90 -90
  137. data/lib/rex/parser/unattend.rb +171 -0
  138. data/lib/rex/parser/wapiti_nokogiri.rb +89 -89
  139. data/lib/rex/payloads/win32/common.rb +14 -14
  140. data/lib/rex/payloads/win32/kernel.rb +36 -36
  141. data/lib/rex/payloads/win32/kernel/common.rb +32 -32
  142. data/lib/rex/payloads/win32/kernel/recovery.rb +27 -27
  143. data/lib/rex/payloads/win32/kernel/stager.rb +170 -170
  144. data/lib/rex/peparsey.rb +0 -3
  145. data/lib/rex/peparsey/exceptions.rb +0 -3
  146. data/lib/rex/peparsey/pe.rb +196 -199
  147. data/lib/rex/peparsey/pe_memdump.rb +35 -38
  148. data/lib/rex/peparsey/pebase.rb +1633 -1652
  149. data/lib/rex/peparsey/section.rb +115 -124
  150. data/lib/rex/pescan.rb +0 -3
  151. data/lib/rex/pescan/analyze.rb +351 -351
  152. data/lib/rex/pescan/scanner.rb +182 -182
  153. data/lib/rex/pescan/search.rb +59 -59
  154. data/lib/rex/platforms/windows.rb +37 -37
  155. data/lib/rex/poly.rb +111 -110
  156. data/lib/rex/poly/block.rb +419 -417
  157. data/lib/rex/poly/machine.rb +12 -0
  158. data/lib/rex/poly/machine/machine.rb +829 -0
  159. data/lib/rex/poly/machine/x86.rb +508 -0
  160. data/lib/rex/poly/register.rb +70 -70
  161. data/lib/rex/poly/register/x86.rb +22 -22
  162. data/lib/rex/post.rb +0 -1
  163. data/lib/rex/post/dir.rb +35 -36
  164. data/lib/rex/post/file.rb +140 -141
  165. data/lib/rex/post/file_stat.rb +198 -199
  166. data/lib/rex/post/io.rb +167 -168
  167. data/lib/rex/post/meterpreter.rb +1 -1
  168. data/lib/rex/post/meterpreter/channel.rb +389 -390
  169. data/lib/rex/post/meterpreter/channel_container.rb +33 -34
  170. data/lib/rex/post/meterpreter/channels/pool.rb +129 -130
  171. data/lib/rex/post/meterpreter/channels/pools/file.rb +35 -36
  172. data/lib/rex/post/meterpreter/channels/pools/stream_pool.rb +72 -73
  173. data/lib/rex/post/meterpreter/channels/stream.rb +62 -63
  174. data/lib/rex/post/meterpreter/client.rb +442 -436
  175. data/lib/rex/post/meterpreter/client_core.rb +326 -310
  176. data/lib/rex/post/meterpreter/dependencies.rb +0 -1
  177. data/lib/rex/post/meterpreter/extension.rb +12 -13
  178. data/lib/rex/post/meterpreter/extensions/espia/espia.rb +35 -36
  179. data/lib/rex/post/meterpreter/extensions/extapi/adsi/adsi.rb +71 -0
  180. data/lib/rex/post/meterpreter/extensions/extapi/clipboard/clipboard.rb +169 -0
  181. data/lib/rex/post/meterpreter/extensions/extapi/extapi.rb +45 -0
  182. data/lib/rex/post/meterpreter/extensions/extapi/service/service.rb +104 -0
  183. data/lib/rex/post/meterpreter/extensions/extapi/tlv.rb +77 -0
  184. data/lib/rex/post/meterpreter/extensions/extapi/window/window.rb +56 -0
  185. data/lib/rex/post/meterpreter/extensions/extapi/wmi/wmi.rb +75 -0
  186. data/lib/rex/post/meterpreter/extensions/incognito/incognito.rb +70 -71
  187. data/lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb +361 -0
  188. data/lib/rex/post/meterpreter/extensions/kiwi/tlv.rb +76 -0
  189. data/lib/rex/post/meterpreter/extensions/lanattacks/dhcp/dhcp.rb +78 -0
  190. data/lib/rex/post/meterpreter/extensions/lanattacks/lanattacks.rb +22 -78
  191. data/lib/rex/post/meterpreter/extensions/lanattacks/tftp/tftp.rb +49 -0
  192. data/lib/rex/post/meterpreter/extensions/lanattacks/tlv.rb +4 -4
  193. data/lib/rex/post/meterpreter/extensions/mimikatz/mimikatz.rb +128 -0
  194. data/lib/rex/post/meterpreter/extensions/mimikatz/tlv.rb +16 -0
  195. data/lib/rex/post/meterpreter/extensions/networkpug/networkpug.rb +38 -39
  196. data/lib/rex/post/meterpreter/extensions/networkpug/tlv.rb +1 -1
  197. data/lib/rex/post/meterpreter/extensions/priv/fs.rb +95 -96
  198. data/lib/rex/post/meterpreter/extensions/priv/passwd.rb +39 -40
  199. data/lib/rex/post/meterpreter/extensions/priv/priv.rb +80 -85
  200. data/lib/rex/post/meterpreter/extensions/sniffer/sniffer.rb +94 -95
  201. data/lib/rex/post/meterpreter/extensions/stdapi/constants.rb +207 -147
  202. data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +258 -259
  203. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +366 -301
  204. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file_stat.rb +72 -73
  205. data/lib/rex/post/meterpreter/extensions/stdapi/fs/io.rb +24 -25
  206. data/lib/rex/post/meterpreter/extensions/stdapi/net/arp.rb +59 -0
  207. data/lib/rex/post/meterpreter/extensions/stdapi/net/config.rb +227 -149
  208. data/lib/rex/post/meterpreter/extensions/stdapi/net/interface.rb +107 -108
  209. data/lib/rex/post/meterpreter/extensions/stdapi/net/netstat.rb +97 -0
  210. data/lib/rex/post/meterpreter/extensions/stdapi/net/resolve.rb +106 -0
  211. data/lib/rex/post/meterpreter/extensions/stdapi/net/route.rb +41 -42
  212. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +102 -101
  213. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +151 -152
  214. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_server_channel.rb +142 -142
  215. data/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +185 -185
  216. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb +38118 -38117
  217. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb +7 -7
  218. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_advapi32.rb +2086 -2084
  219. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_crypt32.rb +15 -15
  220. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_iphlpapi.rb +80 -80
  221. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +3835 -3833
  222. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_netapi32.rb +84 -28
  223. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ntdll.rb +151 -137
  224. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_shell32.rb +15 -6
  225. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_user32.rb +3155 -3155
  226. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_version.rb +41 -0
  227. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wlanapi.rb +70 -70
  228. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_wldap32.rb +128 -0
  229. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_ws2_32.rb +596 -596
  230. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb +310 -301
  231. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb +71 -61
  232. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb +100 -100
  233. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_wrapper.rb +14 -14
  234. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/mock_magic.rb +488 -488
  235. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/multicall.rb +273 -264
  236. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/platform_util.rb +5 -5
  237. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb +240 -238
  238. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/tlv.rb +17 -15
  239. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/type/pointer_util.rb +61 -61
  240. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb +654 -635
  241. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb +49 -49
  242. data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +103 -102
  243. data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +98 -68
  244. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +165 -166
  245. data/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log_subsystem/event_record.rb +16 -17
  246. data/lib/rex/post/meterpreter/extensions/stdapi/sys/power.rb +34 -36
  247. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +363 -364
  248. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/image.rb +102 -103
  249. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/io.rb +28 -29
  250. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/memory.rb +303 -304
  251. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process_subsystem/thread.rb +113 -114
  252. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +260 -261
  253. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +165 -166
  254. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_value.rb +69 -70
  255. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/remote_registry_key.rb +160 -161
  256. data/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +143 -144
  257. data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +29 -12
  258. data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +230 -231
  259. data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +181 -44
  260. data/lib/rex/post/meterpreter/inbound_packet_handler.rb +12 -13
  261. data/lib/rex/post/meterpreter/object_aliases.rb +56 -57
  262. data/lib/rex/post/meterpreter/packet.rb +591 -592
  263. data/lib/rex/post/meterpreter/packet_dispatcher.rb +506 -496
  264. data/lib/rex/post/meterpreter/packet_parser.rb +72 -73
  265. data/lib/rex/post/meterpreter/packet_response_waiter.rb +56 -57
  266. data/lib/rex/post/meterpreter/ui/console.rb +112 -112
  267. data/lib/rex/post/meterpreter/ui/console/command_dispatcher.rb +53 -53
  268. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +911 -854
  269. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/espia.rb +86 -86
  270. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi.rb +65 -0
  271. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/adsi.rb +198 -0
  272. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/clipboard.rb +444 -0
  273. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/service.rb +199 -0
  274. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/window.rb +118 -0
  275. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/wmi.rb +108 -0
  276. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/incognito.rb +220 -220
  277. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb +509 -0
  278. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks.rb +60 -0
  279. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/dhcp.rb +254 -0
  280. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/tftp.rb +159 -0
  281. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +182 -0
  282. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/networkpug.rb +173 -173
  283. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv.rb +40 -40
  284. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +75 -77
  285. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/passwd.rb +30 -30
  286. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +105 -105
  287. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/sniffer.rb +182 -182
  288. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi.rb +37 -37
  289. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +504 -482
  290. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +401 -330
  291. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +883 -581
  292. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +296 -299
  293. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +320 -153
  294. data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +78 -78
  295. data/lib/rex/post/permission.rb +0 -1
  296. data/lib/rex/post/process.rb +39 -40
  297. data/lib/rex/post/thread.rb +41 -42
  298. data/lib/rex/post/ui.rb +35 -36
  299. data/lib/rex/proto/addp.rb +218 -0
  300. data/lib/rex/proto/dcerpc/client.rb +344 -344
  301. data/lib/rex/proto/dcerpc/exceptions.rb +128 -128
  302. data/lib/rex/proto/dcerpc/handle.rb +32 -32
  303. data/lib/rex/proto/dcerpc/ndr.rb +56 -56
  304. data/lib/rex/proto/dcerpc/packet.rb +249 -245
  305. data/lib/rex/proto/dcerpc/response.rb +170 -170
  306. data/lib/rex/proto/dcerpc/uuid.rb +65 -65
  307. data/lib/rex/proto/dcerpc/wdscp.rb +3 -0
  308. data/lib/rex/proto/dcerpc/wdscp/constants.rb +89 -0
  309. data/lib/rex/proto/dcerpc/wdscp/packet.rb +94 -0
  310. data/lib/rex/proto/dhcp.rb +0 -1
  311. data/lib/rex/proto/dhcp/constants.rb +0 -1
  312. data/lib/rex/proto/dhcp/server.rb +303 -304
  313. data/lib/rex/proto/drda/constants.rb +1 -1
  314. data/lib/rex/proto/drda/packet.rb +186 -186
  315. data/lib/rex/proto/drda/utils.rb +104 -104
  316. data/lib/rex/proto/http.rb +1 -0
  317. data/lib/rex/proto/http/client.rb +692 -820
  318. data/lib/rex/proto/http/client_request.rb +472 -0
  319. data/lib/rex/proto/http/handler.rb +25 -25
  320. data/lib/rex/proto/http/handler/erb.rb +104 -104
  321. data/lib/rex/proto/http/handler/proc.rb +37 -37
  322. data/lib/rex/proto/http/header.rb +149 -149
  323. data/lib/rex/proto/http/packet.rb +388 -382
  324. data/lib/rex/proto/http/request.rb +332 -335
  325. data/lib/rex/proto/http/response.rb +132 -72
  326. data/lib/rex/proto/http/server.rb +348 -338
  327. data/lib/rex/proto/iax2/call.rb +310 -310
  328. data/lib/rex/proto/iax2/client.rb +197 -197
  329. data/lib/rex/proto/iax2/codecs/alaw.rb +4 -4
  330. data/lib/rex/proto/iax2/codecs/mulaw.rb +4 -4
  331. data/lib/rex/proto/ipmi.rb +57 -0
  332. data/lib/rex/proto/ipmi/channel_auth_reply.rb +88 -0
  333. data/lib/rex/proto/ipmi/open_session_reply.rb +35 -0
  334. data/lib/rex/proto/ipmi/rakp2.rb +35 -0
  335. data/lib/rex/proto/ipmi/utils.rb +125 -0
  336. data/lib/rex/proto/natpmp.rb +1 -5
  337. data/lib/rex/proto/natpmp/constants.rb +4 -4
  338. data/lib/rex/proto/natpmp/packet.rb +25 -25
  339. data/lib/rex/proto/ntlm/base.rb +271 -271
  340. data/lib/rex/proto/ntlm/constants.rb +61 -61
  341. data/lib/rex/proto/ntlm/crypt.rb +348 -352
  342. data/lib/rex/proto/ntlm/exceptions.rb +3 -3
  343. data/lib/rex/proto/ntlm/message.rb +468 -471
  344. data/lib/rex/proto/ntlm/utils.rb +746 -746
  345. data/lib/rex/proto/pjl.rb +30 -0
  346. data/lib/rex/proto/pjl/client.rb +162 -0
  347. data/lib/rex/proto/proxy/socks4a.rb +440 -440
  348. data/lib/rex/proto/rfb.rb +1 -8
  349. data/lib/rex/proto/rfb/cipher.rb +46 -49
  350. data/lib/rex/proto/rfb/client.rb +179 -182
  351. data/lib/rex/proto/rfb/constants.rb +18 -21
  352. data/lib/rex/proto/smb/client.rb +1954 -1843
  353. data/lib/rex/proto/smb/constants.rb +533 -516
  354. data/lib/rex/proto/smb/crypt.rb +21 -21
  355. data/lib/rex/proto/smb/evasions.rb +43 -43
  356. data/lib/rex/proto/smb/exceptions.rb +791 -791
  357. data/lib/rex/proto/smb/simpleclient.rb +142 -286
  358. data/lib/rex/proto/smb/simpleclient/open_file.rb +106 -0
  359. data/lib/rex/proto/smb/simpleclient/open_pipe.rb +57 -0
  360. data/lib/rex/proto/smb/utils.rb +81 -81
  361. data/lib/rex/proto/sunrpc/client.rb +158 -158
  362. data/lib/rex/proto/tftp.rb +0 -1
  363. data/lib/rex/proto/tftp/client.rb +289 -289
  364. data/lib/rex/proto/tftp/constants.rb +9 -10
  365. data/lib/rex/proto/tftp/server.rb +466 -467
  366. data/lib/rex/random_identifier_generator.rb +176 -0
  367. data/lib/rex/registry.rb +1 -1
  368. data/lib/rex/registry/hive.rb +88 -88
  369. data/lib/rex/registry/lfkey.rb +25 -25
  370. data/lib/rex/registry/nodekey.rb +30 -30
  371. data/lib/rex/registry/regf.rb +10 -10
  372. data/lib/rex/registry/valuekey.rb +43 -43
  373. data/lib/rex/registry/valuelist.rb +13 -13
  374. data/lib/rex/ropbuilder/rop.rb +254 -253
  375. data/lib/rex/script.rb +21 -22
  376. data/lib/rex/script/base.rb +51 -50
  377. data/lib/rex/script/meterpreter.rb +2 -2
  378. data/lib/rex/service.rb +24 -24
  379. data/lib/rex/service_manager.rb +132 -132
  380. data/lib/rex/services/local_relay.rb +398 -398
  381. data/lib/rex/socket.rb +758 -763
  382. data/lib/rex/socket/comm.rb +95 -95
  383. data/lib/rex/socket/comm/local.rb +507 -440
  384. data/lib/rex/socket/ip.rb +118 -118
  385. data/lib/rex/socket/parameters.rb +351 -350
  386. data/lib/rex/socket/range_walker.rb +445 -368
  387. data/lib/rex/socket/ssl_tcp.rb +323 -317
  388. data/lib/rex/socket/ssl_tcp_server.rb +173 -158
  389. data/lib/rex/socket/subnet_walker.rb +48 -48
  390. data/lib/rex/socket/switch_board.rb +259 -259
  391. data/lib/rex/socket/tcp.rb +58 -56
  392. data/lib/rex/socket/tcp_server.rb +42 -42
  393. data/lib/rex/socket/udp.rb +152 -152
  394. data/lib/rex/sslscan/result.rb +200 -0
  395. data/lib/rex/sslscan/scanner.rb +205 -0
  396. data/lib/rex/struct2.rb +0 -1
  397. data/lib/rex/struct2/c_struct.rb +162 -163
  398. data/lib/rex/struct2/c_struct_template.rb +21 -22
  399. data/lib/rex/struct2/constant.rb +6 -7
  400. data/lib/rex/struct2/element.rb +30 -31
  401. data/lib/rex/struct2/generic.rb +60 -61
  402. data/lib/rex/struct2/restraint.rb +40 -41
  403. data/lib/rex/struct2/s_string.rb +60 -61
  404. data/lib/rex/struct2/s_struct.rb +97 -98
  405. data/lib/rex/sync.rb +0 -1
  406. data/lib/rex/sync/event.rb +62 -72
  407. data/lib/rex/sync/read_write_lock.rb +149 -149
  408. data/lib/rex/sync/ref.rb +42 -42
  409. data/lib/rex/sync/thread_safe.rb +59 -59
  410. data/lib/rex/text.rb +1803 -1315
  411. data/lib/rex/thread_factory.rb +25 -25
  412. data/lib/rex/time.rb +44 -44
  413. data/lib/rex/transformer.rb +91 -91
  414. data/lib/rex/ui/interactive.rb +265 -265
  415. data/lib/rex/ui/output.rb +66 -60
  416. data/lib/rex/ui/progress_tracker.rb +79 -79
  417. data/lib/rex/ui/subscriber.rb +144 -134
  418. data/lib/rex/ui/text/color.rb +76 -76
  419. data/lib/rex/ui/text/dispatcher_shell.rb +512 -505
  420. data/lib/rex/ui/text/input.rb +96 -96
  421. data/lib/rex/ui/text/input/buffer.rb +58 -58
  422. data/lib/rex/ui/text/input/readline.rb +114 -114
  423. data/lib/rex/ui/text/input/socket.rb +77 -77
  424. data/lib/rex/ui/text/input/stdio.rb +24 -24
  425. data/lib/rex/ui/text/irb_shell.rb +45 -41
  426. data/lib/rex/ui/text/output.rb +64 -60
  427. data/lib/rex/ui/text/output/buffer.rb +42 -42
  428. data/lib/rex/ui/text/output/buffer/stdout.rb +25 -0
  429. data/lib/rex/ui/text/output/file.rb +24 -24
  430. data/lib/rex/ui/text/output/socket.rb +24 -24
  431. data/lib/rex/ui/text/output/stdio.rb +29 -29
  432. data/lib/rex/ui/text/output/tee.rb +36 -36
  433. data/lib/rex/ui/text/progress_tracker.rb +37 -37
  434. data/lib/rex/ui/text/shell.rb +371 -361
  435. data/lib/rex/ui/text/table.rb +320 -284
  436. data/lib/rex/zip.rb +0 -1
  437. data/lib/rex/zip/archive.rb +115 -94
  438. data/lib/rex/zip/blocks.rb +101 -100
  439. data/lib/rex/zip/entry.rb +108 -99
  440. data/lib/rex/zip/jar.rb +261 -206
  441. data/lib/rex/zip/samples/comment.rb +1 -2
  442. data/lib/rex/zip/samples/mkwar.rb +12 -13
  443. data/lib/rex/zip/samples/mkzip.rb +1 -2
  444. data/lib/rex/zip/samples/recursive.rb +29 -30
  445. metadata +424 -446
  446. data/lib/rex/arch/sparc.rb.ut.rb +0 -19
  447. data/lib/rex/arch/x86.rb.ut.rb +0 -94
  448. data/lib/rex/assembly/nasm.rb.ut.rb +0 -23
  449. data/lib/rex/encoder/ndr.rb.ut.rb +0 -45
  450. data/lib/rex/encoder/xdr.rb.ut.rb +0 -30
  451. data/lib/rex/encoders/xor_dword_additive.rb.ut.rb +0 -13
  452. data/lib/rex/encoding/xor.rb.ts.rb +0 -15
  453. data/lib/rex/encoding/xor/byte.rb.ut.rb +0 -22
  454. data/lib/rex/encoding/xor/dword.rb.ut.rb +0 -16
  455. data/lib/rex/encoding/xor/dword_additive.rb.ut.rb +0 -16
  456. data/lib/rex/encoding/xor/generic.rb.ut.rb +0 -121
  457. data/lib/rex/encoding/xor/word.rb.ut.rb +0 -14
  458. data/lib/rex/exceptions.rb.ut.rb +0 -45
  459. data/lib/rex/exploitation/egghunter.rb.ut.rb +0 -28
  460. data/lib/rex/exploitation/javascriptosdetect.js +0 -1014
  461. data/lib/rex/exploitation/javascriptosdetect.rb +0 -43
  462. data/lib/rex/exploitation/omelet.rb.ut.rb +0 -27
  463. data/lib/rex/exploitation/opcodedb.rb.ut.rb +0 -280
  464. data/lib/rex/exploitation/seh.rb.ut.rb +0 -20
  465. data/lib/rex/file.rb.ut.rb +0 -17
  466. data/lib/rex/io/ring_buffer.rb.ut.rb +0 -135
  467. data/lib/rex/nop/opty2.rb.ut.rb +0 -24
  468. data/lib/rex/parser/arguments.rb.ut.rb +0 -68
  469. data/lib/rex/parser/ini.rb.ut.rb +0 -30
  470. data/lib/rex/post/meterpreter/extensions/stdapi/railgun.rb.ts.rb +0 -18
  471. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb.ut.rb +0 -39
  472. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb.ut.rb +0 -37
  473. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb.ut.rb +0 -52
  474. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb.ut.rb +0 -43
  475. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb.ut.rb +0 -128
  476. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_wrapper.rb.ut.rb +0 -64
  477. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/platform_util.rb.ut.rb +0 -29
  478. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb.ut.rb +0 -155
  479. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/type/pointer_util.rb.ut.rb +0 -128
  480. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb.ut.rb +0 -124
  481. data/lib/rex/proto.rb.ts.rb +0 -9
  482. data/lib/rex/proto/dcerpc.rb.ts.rb +0 -10
  483. data/lib/rex/proto/dcerpc/client.rb.ut.rb +0 -492
  484. data/lib/rex/proto/dcerpc/handle.rb.ut.rb +0 -86
  485. data/lib/rex/proto/dcerpc/ndr.rb.ut.rb +0 -42
  486. data/lib/rex/proto/dcerpc/packet.rb.ut.rb +0 -57
  487. data/lib/rex/proto/dcerpc/response.rb.ut.rb +0 -16
  488. data/lib/rex/proto/dcerpc/uuid.rb.ut.rb +0 -47
  489. data/lib/rex/proto/drda.rb.ts.rb +0 -18
  490. data/lib/rex/proto/drda/constants.rb.ut.rb +0 -24
  491. data/lib/rex/proto/drda/packet.rb.ut.rb +0 -110
  492. data/lib/rex/proto/drda/utils.rb.ut.rb +0 -85
  493. data/lib/rex/proto/http.rb.ts.rb +0 -13
  494. data/lib/rex/proto/http/client.rb.ut.rb +0 -96
  495. data/lib/rex/proto/http/handler/erb.rb.ut.rb +0 -22
  496. data/lib/rex/proto/http/handler/erb.rb.ut.rb.rhtml +0 -1
  497. data/lib/rex/proto/http/handler/proc.rb.ut.rb +0 -25
  498. data/lib/rex/proto/http/header.rb.ut.rb +0 -47
  499. data/lib/rex/proto/http/packet.rb.ut.rb +0 -166
  500. data/lib/rex/proto/http/request.rb.ut.rb +0 -215
  501. data/lib/rex/proto/http/response.rb.ut.rb +0 -150
  502. data/lib/rex/proto/http/server.rb.ut.rb +0 -80
  503. data/lib/rex/proto/ntlm.rb.ut.rb +0 -181
  504. data/lib/rex/proto/rfb.rb.ut.rb +0 -40
  505. data/lib/rex/proto/smb.rb.ts.rb +0 -9
  506. data/lib/rex/proto/smb/client.rb.ut.rb +0 -224
  507. data/lib/rex/proto/smb/constants.rb.ut.rb +0 -19
  508. data/lib/rex/proto/smb/simpleclient.rb.ut.rb +0 -129
  509. data/lib/rex/proto/smb/utils.rb.ut.rb +0 -21
  510. data/lib/rex/proto/tftp/server.rb.ut.rb +0 -29
  511. data/lib/rex/service_manager.rb.ut.rb +0 -33
  512. data/lib/rex/socket.rb.ut.rb +0 -108
  513. data/lib/rex/socket/comm/local.rb.ut.rb +0 -76
  514. data/lib/rex/socket/parameters.rb.ut.rb +0 -52
  515. data/lib/rex/socket/range_walker.rb.ut.rb +0 -56
  516. data/lib/rex/socket/ssl_tcp.rb.ut.rb +0 -40
  517. data/lib/rex/socket/ssl_tcp_server.rb.ut.rb +0 -62
  518. data/lib/rex/socket/subnet_walker.rb.ut.rb +0 -29
  519. data/lib/rex/socket/switch_board.rb.ut.rb +0 -53
  520. data/lib/rex/socket/tcp.rb.ut.rb +0 -65
  521. data/lib/rex/socket/tcp_server.rb.ut.rb +0 -45
  522. data/lib/rex/socket/udp.rb.ut.rb +0 -45
  523. data/lib/rex/test.rb +0 -36
  524. data/lib/rex/text.rb.ut.rb +0 -193
  525. data/lib/rex/transformer.rb.ut.rb +0 -39
  526. data/lib/rex/ui/text/color.rb.ut.rb +0 -19
  527. data/lib/rex/ui/text/progress_tracker.rb.ut.rb +0 -35
  528. data/lib/rex/ui/text/table.rb.ut.rb +0 -56
@@ -0,0 +1,3 @@
1
+ # -*- coding: binary -*-
2
+ require 'rex/proto/dcerpc/wdscp/constants'
3
+ require 'rex/proto/dcerpc/wdscp/packet'
@@ -0,0 +1,89 @@
1
+ # -*- coding: binary -*-
2
+ module Rex
3
+ module Proto
4
+ module DCERPC
5
+ module WDSCP
6
+ # http://msdn.microsoft.com/en-us/library/dd891406(prot.20).aspx
7
+ # http://msdn.microsoft.com/en-us/library/dd541332(prot.20).aspx
8
+ # Not all values defined by the spec have been imported...
9
+ class Constants
10
+ WDSCP_RPC_UUID = "1A927394-352E-4553-AE3F-7CF4AAFCA620"
11
+ OS_DEPLOYMENT_GUID = "\x5a\xeb\xde\xd8\xfd\xef\xb2\x43\x99\xfc\x1a\x8a\x59\x21\xc2\x27"
12
+
13
+ VAR_NAME_ARCHITECTURE = "ARCHITECTURE"
14
+ VAR_NAME_CLIENT_GUID = "CLIENT_GUID"
15
+ VAR_NAME_CLIENT_MAC = "CLIENT_MAC"
16
+ VAR_NAME_VERSION = "VERSION"
17
+ VAR_NAME_MESSAGE_TYPE = "MESSAGE_TYPE"
18
+ VAR_NAME_TRANSACTION_ID = "TRANSACTION_ID"
19
+ VAR_NAME_FLAGS = "FLAGS"
20
+ VAR_NAME_CC = "CC" #Client Capabilities
21
+ VAR_NAME_IMDC = "IMDC"
22
+
23
+ VAR_TYPE_LOOKUP = {
24
+ VAR_NAME_ARCHITECTURE => :ULONG,
25
+ VAR_NAME_CLIENT_GUID => :WSTRING,
26
+ VAR_NAME_CLIENT_MAC => :WSTRING,
27
+ VAR_NAME_VERSION => :ULONG,
28
+ VAR_NAME_MESSAGE_TYPE => :ULONG,
29
+ VAR_NAME_TRANSACTION_ID => :WSTRING,
30
+ VAR_NAME_FLAGS => :ULONG,
31
+ VAR_NAME_CC => :ULONG,
32
+ VAR_NAME_IMDC => :ULONG
33
+ }
34
+
35
+ CC_FLAGS = {
36
+ :V2 => 1,
37
+ :VHDX => 2
38
+ }
39
+
40
+ DOMAIN_JOIN_FLAGS = {
41
+ :JOIN_DOMAIN => 1,
42
+ :ACCOUNT_EXISTS => 2,
43
+ :PRESTAGE_USING_MAC => 3,
44
+ :RESET_BOOT_PROGRAM => 256
45
+ }
46
+
47
+ ARCHITECTURE = {
48
+ :X64 => 9,
49
+ :X86 => 0,
50
+ :IA64 => 6,
51
+ :ARM => 5
52
+ }
53
+
54
+ PACKET_TYPE = {
55
+ :REQUEST => 1,
56
+ :REPLY => 2
57
+ }
58
+
59
+ OPCODE = {
60
+ :IMG_ENUMERATE => 2,
61
+ :LOG_INIT => 3,
62
+ :LOG_MSG => 4,
63
+ :GET_CLIENT_UNATTEND => 5,
64
+ :GET_UNATTEND_VARIABLES => 6,
65
+ :GET_DOMAIN_JOIN_INFORMATION => 7,
66
+ :RESET_BOOT_PROGRAM => 8,
67
+ :GET_MACHINE_DRIVER_PACKAGES => 200
68
+ }
69
+
70
+ BASE_TYPE = {
71
+ :BYTE => 0x0001,
72
+ :USHORT => 0x0002,
73
+ :ULONG => 0x0004,
74
+ :ULONG64 => 0x0008,
75
+ :STRING => 0x0010,
76
+ :WSTRING => 0x0020,
77
+ :BLOB => 0x0040
78
+ }
79
+
80
+ TYPE_MODIFIER = {
81
+ :NONE => 0x0000,
82
+ :ARRAY => 0x1000
83
+ }
84
+
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,94 @@
1
+ # -*- coding: binary -*-
2
+ module Rex
3
+ module Proto
4
+ module DCERPC
5
+ module WDSCP
6
+ class Packet
7
+
8
+ WDS_CONST = Rex::Proto::DCERPC::WDSCP::Constants
9
+
10
+ def initialize(packet_type, opcode)
11
+ if opcode.nil? || packet_type.nil?
12
+ raise(ArgumentError, "Packet arguments cannot be nil")
13
+ end
14
+
15
+ @variables = []
16
+ @packet_type = WDS_CONST::PACKET_TYPE[packet_type]
17
+ @opcode = WDS_CONST::OPCODE[opcode]
18
+ end
19
+
20
+ def add_var(name, type_mod=0, value_length=nil, array_size=0, value)
21
+ padding = 0
22
+ vt = WDS_CONST::VAR_TYPE_LOOKUP[name]
23
+ value_type = WDS_CONST::BASE_TYPE[vt]
24
+ name = Rex::Text.to_unicode(name).unpack('H*')[0]
25
+
26
+ # Terminate strings with null char
27
+ if vt == :STRING
28
+ value << "\x00"
29
+ elsif vt == :WSTRING
30
+ value = Rex::Text.to_unicode(value)
31
+ value << "\x00\x00"
32
+ end
33
+
34
+ value_length ||= value.length
35
+ # Variable block total size should be evenly divisible by 16.
36
+ len = 16 * (1 + (value_length/16))
37
+ @variables <<
38
+ [ name,
39
+ padding,
40
+ value_type,
41
+ type_mod,
42
+ value_length,
43
+ array_size,
44
+ value
45
+ ].pack('H132vvvVVa%i' % len)
46
+ end
47
+
48
+ def create
49
+ packet = []
50
+ var_count = @variables.count
51
+
52
+ packet_size = 0
53
+ @variables.each do |var|
54
+ packet_size += var.length
55
+ end
56
+
57
+ # variables + operation
58
+ packet_size += 16
59
+
60
+ # These bytes are not part of the spec but are not part of DCERPC according to Wireshark
61
+ # Perhaps something from MSRPC specific? Basically length of the WDSCP packet twice...
62
+ packet << [(packet_size+40)].pack('V') * 2
63
+ packet << create_endpoint_header(packet_size)
64
+ packet << create_operation_header(packet_size, var_count, @packet_type, @opcode)
65
+ packet.concat(@variables)
66
+
67
+ return packet.join
68
+ end
69
+
70
+ def create_operation_header(packet_size, var_count, packet_type=:REQUEST, opcode)
71
+ return [
72
+ packet_size, # PacketSize
73
+ 256, # Version
74
+ packet_type, # Packet_Type
75
+ 0, # Padding
76
+ opcode, # Opcode
77
+ var_count, # Variable Count
78
+ ].pack('VvCCVV')
79
+ end
80
+
81
+ def create_endpoint_header(packet_size)
82
+ return [
83
+ 40, # Header_Size
84
+ 256, # Version
85
+ packet_size, # Packet_Size - This doesn't differ from operation header despite the spec...
86
+ WDS_CONST::OS_DEPLOYMENT_GUID, # GUID
87
+ "\x00"*16, # Reserved
88
+ ].pack('vvVa16a16')
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -1,5 +1,4 @@
1
1
  # -*- coding: binary -*-
2
- # $Id: dhcp.rb 15548 2012-06-29 06:08:20Z rapid7 $
3
2
  #
4
3
  # DHCP Server support written by scriptjunkie
5
4
  #
@@ -1,5 +1,4 @@
1
1
  # -*- coding: binary -*-
2
- # $Id: constants.rb 15548 2012-06-29 06:08:20Z rapid7 $
3
2
  require 'rex/proto/dhcp'
4
3
 
5
4
  module Rex
@@ -1,5 +1,4 @@
1
1
  # -*- coding: binary -*-
2
- # $Id: server.rb 15548 2012-06-29 06:08:20Z rapid7 $
3
2
 
4
3
  require 'rex/socket'
5
4
  require 'rex/proto/dhcp'
@@ -20,313 +19,313 @@ module DHCP
20
19
 
21
20
  class Server
22
21
 
23
- include Rex::Socket
24
-
25
- def initialize(hash, context = {})
26
- self.listen_host = '0.0.0.0' # clients don't already have addresses. Needs to be 0.0.0.0
27
- self.listen_port = 67 # mandatory (bootps)
28
- self.context = context
29
- self.sock = nil
30
-
31
- self.myfilename = hash['FILENAME'] || ""
32
- self.myfilename << ("\x00" * (128 - self.myfilename.length))
33
-
34
- source = hash['SRVHOST'] || Rex::Socket.source_address
35
- self.ipstring = Rex::Socket.addr_aton(source)
36
-
37
- ipstart = hash['DHCPIPSTART']
38
- if ipstart
39
- self.start_ip = Rex::Socket.addr_atoi(ipstart)
40
- else
41
- # Use the first 3 octects of the server's IP to construct the
42
- # default range of x.x.x.32-254
43
- self.start_ip = "#{self.ipstring[0..2]}\x20".unpack("N").first
44
- end
45
- self.current_ip = start_ip
46
-
47
- ipend = hash['DHCPIPEND']
48
- if ipend
49
- self.end_ip = Rex::Socket.addr_atoi(ipend)
50
- else
51
- # Use the first 3 octects of the server's IP to construct the
52
- # default range of x.x.x.32-254
53
- self.end_ip = "#{self.ipstring[0..2]}\xfe".unpack("N").first
54
- end
55
-
56
- # netmask
57
- netmask = hash['NETMASK'] || "255.255.255.0"
58
- self.netmaskn = Rex::Socket.addr_aton(netmask)
59
-
60
- # router
61
- router = hash['ROUTER'] || source
62
- self.router = Rex::Socket.addr_aton(router)
63
-
64
- # dns
65
- dnsserv = hash['DNSSERVER'] || source
66
- self.dnsserv = Rex::Socket.addr_aton(dnsserv)
67
-
68
- # broadcast
69
- if hash['BROADCAST']
70
- self.broadcasta = Rex::Socket.addr_aton(hash['BROADCAST'])
71
- else
72
- self.broadcasta = Rex::Socket.addr_itoa( self.start_ip | (Rex::Socket.addr_ntoi(self.netmaskn) ^ 0xffffffff) )
73
- end
74
-
75
- self.served = {}
76
- self.serveOnce = hash.include?('SERVEONCE')
77
-
78
- self.servePXE = (hash.include?('PXE') or hash.include?('FILENAME') or hash.include?('PXEONLY'))
79
- self.serveOnlyPXE = hash.include?('PXEONLY')
80
-
81
- # Always assume we don't give out hostnames ...
82
- self.give_hostname = false
83
- self.served_over = 0
84
- if (hash['HOSTNAME'])
85
- self.give_hostname = true
86
- self.served_hostname = hash['HOSTNAME']
87
- if ( hash['HOSTSTART'] )
88
- self.served_over = hash['HOSTSTART'].to_i
89
- end
90
- end
91
-
92
- self.leasetime = 600
93
- self.relayip = "\x00\x00\x00\x00" # relay ip - not currently suported
94
- self.pxeconfigfile = "update2"
95
- self.pxealtconfigfile = "update0"
96
- self.pxepathprefix = ""
97
- self.pxereboottime = 2000
98
- end
99
-
100
- def report(&block)
101
- self.reporter = block
102
- end
103
-
104
- # Start the DHCP server
105
- def start
106
- self.sock = Rex::Socket::Udp.create(
107
- 'LocalHost' => listen_host,
108
- 'LocalPort' => listen_port,
109
- 'Context' => context
110
- )
111
-
112
- self.thread = Rex::ThreadFactory.spawn("DHCPServerMonitor", false) {
113
- monitor_socket
114
- }
115
- end
116
-
117
- # Stop the DHCP server
118
- def stop
119
- self.thread.kill
120
- self.served = {}
121
- self.sock.close rescue nil
122
- end
123
-
124
-
125
- # Set an option
126
- def set_option(opts)
127
- allowed_options = [
128
- :serveOnce, :pxealtconfigfile, :servePXE, :relayip, :leasetime, :dnsserv,
129
- :pxeconfigfile, :pxepathprefix, :pxereboottime, :router,
130
- :give_hostname, :served_hostname, :served_over, :serveOnlyPXE
131
- ]
132
-
133
- opts.each_pair { |k,v|
134
- next if not v
135
- if allowed_options.include?(k)
136
- self.instance_variable_set("@#{k}", v)
137
- end
138
- }
139
- end
140
-
141
-
142
- # Send a single packet to the specified host
143
- def send_packet(ip, pkt)
144
- port = 68 # bootpc
145
- if ip
146
- self.sock.sendto( pkt, ip, port )
147
- else
148
- if not self.sock.sendto( pkt, '255.255.255.255', port )
149
- self.sock.sendto( pkt, self.broadcasta, port )
150
- end
151
- end
152
- end
153
-
154
- attr_accessor :listen_host, :listen_port, :context, :leasetime, :relayip, :router, :dnsserv
155
- attr_accessor :sock, :thread, :myfilename, :ipstring, :served, :serveOnce
156
- attr_accessor :current_ip, :start_ip, :end_ip, :broadcasta, :netmaskn
157
- attr_accessor :servePXE, :pxeconfigfile, :pxealtconfigfile, :pxepathprefix, :pxereboottime, :serveOnlyPXE
158
- attr_accessor :give_hostname, :served_hostname, :served_over, :reporter
22
+ include Rex::Socket
23
+
24
+ def initialize(hash, context = {})
25
+ self.listen_host = '0.0.0.0' # clients don't already have addresses. Needs to be 0.0.0.0
26
+ self.listen_port = 67 # mandatory (bootps)
27
+ self.context = context
28
+ self.sock = nil
29
+
30
+ self.myfilename = hash['FILENAME'] || ""
31
+ self.myfilename << ("\x00" * (128 - self.myfilename.length))
32
+
33
+ source = hash['SRVHOST'] || Rex::Socket.source_address
34
+ self.ipstring = Rex::Socket.addr_aton(source)
35
+
36
+ ipstart = hash['DHCPIPSTART']
37
+ if ipstart
38
+ self.start_ip = Rex::Socket.addr_atoi(ipstart)
39
+ else
40
+ # Use the first 3 octects of the server's IP to construct the
41
+ # default range of x.x.x.32-254
42
+ self.start_ip = "#{self.ipstring[0..2]}\x20".unpack("N").first
43
+ end
44
+ self.current_ip = start_ip
45
+
46
+ ipend = hash['DHCPIPEND']
47
+ if ipend
48
+ self.end_ip = Rex::Socket.addr_atoi(ipend)
49
+ else
50
+ # Use the first 3 octects of the server's IP to construct the
51
+ # default range of x.x.x.32-254
52
+ self.end_ip = "#{self.ipstring[0..2]}\xfe".unpack("N").first
53
+ end
54
+
55
+ # netmask
56
+ netmask = hash['NETMASK'] || "255.255.255.0"
57
+ self.netmaskn = Rex::Socket.addr_aton(netmask)
58
+
59
+ # router
60
+ router = hash['ROUTER'] || source
61
+ self.router = Rex::Socket.addr_aton(router)
62
+
63
+ # dns
64
+ dnsserv = hash['DNSSERVER'] || source
65
+ self.dnsserv = Rex::Socket.addr_aton(dnsserv)
66
+
67
+ # broadcast
68
+ if hash['BROADCAST']
69
+ self.broadcasta = Rex::Socket.addr_aton(hash['BROADCAST'])
70
+ else
71
+ self.broadcasta = Rex::Socket.addr_itoa( self.start_ip | (Rex::Socket.addr_ntoi(self.netmaskn) ^ 0xffffffff) )
72
+ end
73
+
74
+ self.served = {}
75
+ self.serveOnce = hash.include?('SERVEONCE')
76
+
77
+ self.servePXE = (hash.include?('PXE') or hash.include?('FILENAME') or hash.include?('PXEONLY'))
78
+ self.serveOnlyPXE = hash.include?('PXEONLY')
79
+
80
+ # Always assume we don't give out hostnames ...
81
+ self.give_hostname = false
82
+ self.served_over = 0
83
+ if (hash['HOSTNAME'])
84
+ self.give_hostname = true
85
+ self.served_hostname = hash['HOSTNAME']
86
+ if ( hash['HOSTSTART'] )
87
+ self.served_over = hash['HOSTSTART'].to_i
88
+ end
89
+ end
90
+
91
+ self.leasetime = 600
92
+ self.relayip = "\x00\x00\x00\x00" # relay ip - not currently suported
93
+ self.pxeconfigfile = "update2"
94
+ self.pxealtconfigfile = "update0"
95
+ self.pxepathprefix = ""
96
+ self.pxereboottime = 2000
97
+ end
98
+
99
+ def report(&block)
100
+ self.reporter = block
101
+ end
102
+
103
+ # Start the DHCP server
104
+ def start
105
+ self.sock = Rex::Socket::Udp.create(
106
+ 'LocalHost' => listen_host,
107
+ 'LocalPort' => listen_port,
108
+ 'Context' => context
109
+ )
110
+
111
+ self.thread = Rex::ThreadFactory.spawn("DHCPServerMonitor", false) {
112
+ monitor_socket
113
+ }
114
+ end
115
+
116
+ # Stop the DHCP server
117
+ def stop
118
+ self.thread.kill
119
+ self.served = {}
120
+ self.sock.close rescue nil
121
+ end
122
+
123
+
124
+ # Set an option
125
+ def set_option(opts)
126
+ allowed_options = [
127
+ :serveOnce, :pxealtconfigfile, :servePXE, :relayip, :leasetime, :dnsserv,
128
+ :pxeconfigfile, :pxepathprefix, :pxereboottime, :router,
129
+ :give_hostname, :served_hostname, :served_over, :serveOnlyPXE
130
+ ]
131
+
132
+ opts.each_pair { |k,v|
133
+ next if not v
134
+ if allowed_options.include?(k)
135
+ self.instance_variable_set("@#{k}", v)
136
+ end
137
+ }
138
+ end
139
+
140
+
141
+ # Send a single packet to the specified host
142
+ def send_packet(ip, pkt)
143
+ port = 68 # bootpc
144
+ if ip
145
+ self.sock.sendto( pkt, ip, port )
146
+ else
147
+ if not self.sock.sendto( pkt, '255.255.255.255', port )
148
+ self.sock.sendto( pkt, self.broadcasta, port )
149
+ end
150
+ end
151
+ end
152
+
153
+ attr_accessor :listen_host, :listen_port, :context, :leasetime, :relayip, :router, :dnsserv
154
+ attr_accessor :sock, :thread, :myfilename, :ipstring, :served, :serveOnce
155
+ attr_accessor :current_ip, :start_ip, :end_ip, :broadcasta, :netmaskn
156
+ attr_accessor :servePXE, :pxeconfigfile, :pxealtconfigfile, :pxepathprefix, :pxereboottime, :serveOnlyPXE
157
+ attr_accessor :give_hostname, :served_hostname, :served_over, :reporter
159
158
 
160
159
  protected
161
160
 
162
161
 
163
- # See if there is anything to do.. If so, dispatch it.
164
- def monitor_socket
165
- while true
166
- rds = [@sock]
167
- wds = []
168
- eds = [@sock]
169
-
170
- r,w,e = ::IO.select(rds,wds,eds,1)
171
-
172
- if (r != nil and r[0] == self.sock)
173
- buf,host,port = self.sock.recvfrom(65535)
174
- # Lame compatabilitiy :-/
175
- from = [host, port]
176
- dispatch_request(from, buf)
177
- end
178
-
179
- end
180
- end
181
-
182
- def dhcpoption(type, val = nil)
183
- ret = ''
184
- ret << [type].pack('C')
185
-
186
- if val
187
- ret << [val.length].pack('C') + val
188
- end
189
-
190
- ret
191
- end
192
-
193
- # Dispatch a packet that we received
194
- def dispatch_request(from, buf)
195
- type = buf.unpack('C').first
196
- if (type != Request)
197
- #dlog("Unknown DHCP request type: #{type}")
198
- return
199
- end
200
-
201
- # parse out the members
202
- hwtype = buf[1,1]
203
- hwlen = buf[2,1].unpack("C").first
204
- hops = buf[3,1]
205
- txid = buf[4..7]
206
- elapsed = buf[8..9]
207
- flags = buf[10..11]
208
- clientip = buf[12..15]
209
- givenip = buf[16..19]
210
- nextip = buf[20..23]
211
- relayip = buf[24..27]
212
- clienthwaddr = buf[28..(27+hwlen)]
213
- servhostname = buf[44..107]
214
- filename = buf[108..235]
215
- magic = buf[236..239]
216
-
217
- if (magic != DHCPMagic)
218
- #dlog("Invalid DHCP request - bad magic.")
219
- return
220
- end
221
-
222
- messageType = 0
223
- pxeclient = false
224
-
225
- # options parsing loop
226
- spot = 240
227
- while (spot < buf.length - 3)
228
- optionType = buf[spot,1].unpack("C").first
229
- break if optionType == 0xff
230
-
231
- optionLen = buf[spot + 1,1].unpack("C").first
232
- optionValue = buf[(spot + 2)..(spot + optionLen + 1)]
233
- spot = spot + optionLen + 2
234
- if optionType == 53
235
- messageType = optionValue.unpack("C").first
236
- elsif optionType == 150 or (optionType == 60 and optionValue.include? "PXEClient")
237
- pxeclient = true
238
- end
239
- end
240
-
241
- # don't serve if only serving PXE and not PXE request
242
- return if pxeclient == false and self.serveOnlyPXE == true
243
-
244
- # prepare response
245
- pkt = [Response].pack('C')
246
- pkt << buf[1..7] #hwtype, hwlen, hops, txid
247
- pkt << "\x00\x00\x00\x00" #elapsed, flags
248
- pkt << clientip
249
-
250
- # if this is somebody we've seen before, use the saved IP
251
- if self.served.include?( buf[28..43] )
252
- pkt << Rex::Socket.addr_iton(self.served[buf[28..43]][0])
253
- else # otherwise go to next ip address
254
- self.current_ip += 1
255
- if self.current_ip > self.end_ip
256
- self.current_ip = self.start_ip
257
- end
258
- self.served.merge!( buf[28..43] => [ self.current_ip, messageType == DHCPRequest ] )
259
- pkt << Rex::Socket.addr_iton(self.current_ip)
260
- end
261
- pkt << self.ipstring #next server ip
262
- pkt << self.relayip
263
- pkt << buf[28..43] #client hw address
264
- pkt << servhostname
265
- pkt << self.myfilename
266
- pkt << magic
267
- pkt << "\x35\x01" #Option
268
-
269
- if messageType == DHCPDiscover #DHCP Discover - send DHCP Offer
270
- pkt << [DHCPOffer].pack('C')
271
- # check if already served an Ack based on hw addr (MAC address)
272
- # if serveOnce & PXE, don't reply to another PXE request
273
- # if serveOnce & ! PXE, don't reply to anything
274
- if self.serveOnce == true and self.served.has_key?(buf[28..43]) and
275
- self.served[buf[28..43]][1] and (pxeclient == false or self.servePXE == false)
276
- return
277
- end
278
- elsif messageType == DHCPRequest #DHCP Request - send DHCP ACK
279
- pkt << [DHCPAck].pack('C')
280
- # now we ignore their discovers (but we'll respond to requests in case a packet was lost)
281
- if ( self.served_over != 0 )
282
- # NOTE: this is sufficient for low-traffic net
283
- # for high-traffic, this will probably lead to
284
- # hostname collision
285
- self.served_over += 1
286
- end
287
- else
288
- return # ignore unknown DHCP request
289
- end
290
-
291
- # Options!
292
- pkt << dhcpoption(OpDHCPServer, self.ipstring)
293
- pkt << dhcpoption(OpLeaseTime, [self.leasetime].pack('N'))
294
- pkt << dhcpoption(OpSubnetMask, self.netmaskn)
295
- pkt << dhcpoption(OpRouter, self.router)
296
- pkt << dhcpoption(OpDns, self.dnsserv)
297
- if self.servePXE # PXE options
298
- pkt << dhcpoption(OpPXEMagic, PXEMagic)
299
- # We already got this one, serve localboot file
300
- if self.serveOnce == true and self.served.has_key?(buf[28..43]) and
301
- self.served[buf[28..43]][1] and pxeclient == true
302
- pkt << dhcpoption(OpPXEConfigFile, self.pxealtconfigfile)
303
- else
304
- # We are handing out an IP and our PXE attack
305
- if(self.reporter)
306
- self.reporter.call(buf[28..43],self.ipstring)
307
- end
308
- pkt << dhcpoption(OpPXEConfigFile, self.pxeconfigfile)
309
- end
310
- pkt << dhcpoption(OpPXEPathPrefix, self.pxepathprefix)
311
- pkt << dhcpoption(OpPXERebootTime, [self.pxereboottime].pack('N'))
312
- if ( self.give_hostname == true )
313
- send_hostname = self.served_hostname
314
- if ( self.served_over != 0 )
315
- # NOTE : see above comments for the 'uniqueness' of this value
316
- send_hostname += self.served_over.to_s
317
- end
318
- pkt << dhcpoption(OpHostname, send_hostname)
319
- end
320
- end
321
- pkt << dhcpoption(OpEnd)
322
-
323
- pkt << ("\x00" * 32) #padding
324
-
325
- # And now we mark as requested
326
- self.served[buf[28..43]][1] = true if messageType == DHCPRequest
327
-
328
- send_packet(nil, pkt)
329
- end
162
+ # See if there is anything to do.. If so, dispatch it.
163
+ def monitor_socket
164
+ while true
165
+ rds = [@sock]
166
+ wds = []
167
+ eds = [@sock]
168
+
169
+ r,w,e = ::IO.select(rds,wds,eds,1)
170
+
171
+ if (r != nil and r[0] == self.sock)
172
+ buf,host,port = self.sock.recvfrom(65535)
173
+ # Lame compatabilitiy :-/
174
+ from = [host, port]
175
+ dispatch_request(from, buf)
176
+ end
177
+
178
+ end
179
+ end
180
+
181
+ def dhcpoption(type, val = nil)
182
+ ret = ''
183
+ ret << [type].pack('C')
184
+
185
+ if val
186
+ ret << [val.length].pack('C') + val
187
+ end
188
+
189
+ ret
190
+ end
191
+
192
+ # Dispatch a packet that we received
193
+ def dispatch_request(from, buf)
194
+ type = buf.unpack('C').first
195
+ if (type != Request)
196
+ #dlog("Unknown DHCP request type: #{type}")
197
+ return
198
+ end
199
+
200
+ # parse out the members
201
+ hwtype = buf[1,1]
202
+ hwlen = buf[2,1].unpack("C").first
203
+ hops = buf[3,1]
204
+ txid = buf[4..7]
205
+ elapsed = buf[8..9]
206
+ flags = buf[10..11]
207
+ clientip = buf[12..15]
208
+ givenip = buf[16..19]
209
+ nextip = buf[20..23]
210
+ relayip = buf[24..27]
211
+ clienthwaddr = buf[28..(27+hwlen)]
212
+ servhostname = buf[44..107]
213
+ filename = buf[108..235]
214
+ magic = buf[236..239]
215
+
216
+ if (magic != DHCPMagic)
217
+ #dlog("Invalid DHCP request - bad magic.")
218
+ return
219
+ end
220
+
221
+ messageType = 0
222
+ pxeclient = false
223
+
224
+ # options parsing loop
225
+ spot = 240
226
+ while (spot < buf.length - 3)
227
+ optionType = buf[spot,1].unpack("C").first
228
+ break if optionType == 0xff
229
+
230
+ optionLen = buf[spot + 1,1].unpack("C").first
231
+ optionValue = buf[(spot + 2)..(spot + optionLen + 1)]
232
+ spot = spot + optionLen + 2
233
+ if optionType == 53
234
+ messageType = optionValue.unpack("C").first
235
+ elsif optionType == 150 or (optionType == 60 and optionValue.include? "PXEClient")
236
+ pxeclient = true
237
+ end
238
+ end
239
+
240
+ # don't serve if only serving PXE and not PXE request
241
+ return if pxeclient == false and self.serveOnlyPXE == true
242
+
243
+ # prepare response
244
+ pkt = [Response].pack('C')
245
+ pkt << buf[1..7] #hwtype, hwlen, hops, txid
246
+ pkt << "\x00\x00\x00\x00" #elapsed, flags
247
+ pkt << clientip
248
+
249
+ # if this is somebody we've seen before, use the saved IP
250
+ if self.served.include?( buf[28..43] )
251
+ pkt << Rex::Socket.addr_iton(self.served[buf[28..43]][0])
252
+ else # otherwise go to next ip address
253
+ self.current_ip += 1
254
+ if self.current_ip > self.end_ip
255
+ self.current_ip = self.start_ip
256
+ end
257
+ self.served.merge!( buf[28..43] => [ self.current_ip, messageType == DHCPRequest ] )
258
+ pkt << Rex::Socket.addr_iton(self.current_ip)
259
+ end
260
+ pkt << self.ipstring #next server ip
261
+ pkt << self.relayip
262
+ pkt << buf[28..43] #client hw address
263
+ pkt << servhostname
264
+ pkt << self.myfilename
265
+ pkt << magic
266
+ pkt << "\x35\x01" #Option
267
+
268
+ if messageType == DHCPDiscover #DHCP Discover - send DHCP Offer
269
+ pkt << [DHCPOffer].pack('C')
270
+ # check if already served an Ack based on hw addr (MAC address)
271
+ # if serveOnce & PXE, don't reply to another PXE request
272
+ # if serveOnce & ! PXE, don't reply to anything
273
+ if self.serveOnce == true and self.served.has_key?(buf[28..43]) and
274
+ self.served[buf[28..43]][1] and (pxeclient == false or self.servePXE == false)
275
+ return
276
+ end
277
+ elsif messageType == DHCPRequest #DHCP Request - send DHCP ACK
278
+ pkt << [DHCPAck].pack('C')
279
+ # now we ignore their discovers (but we'll respond to requests in case a packet was lost)
280
+ if ( self.served_over != 0 )
281
+ # NOTE: this is sufficient for low-traffic net
282
+ # for high-traffic, this will probably lead to
283
+ # hostname collision
284
+ self.served_over += 1
285
+ end
286
+ else
287
+ return # ignore unknown DHCP request
288
+ end
289
+
290
+ # Options!
291
+ pkt << dhcpoption(OpDHCPServer, self.ipstring)
292
+ pkt << dhcpoption(OpLeaseTime, [self.leasetime].pack('N'))
293
+ pkt << dhcpoption(OpSubnetMask, self.netmaskn)
294
+ pkt << dhcpoption(OpRouter, self.router)
295
+ pkt << dhcpoption(OpDns, self.dnsserv)
296
+ if self.servePXE # PXE options
297
+ pkt << dhcpoption(OpPXEMagic, PXEMagic)
298
+ # We already got this one, serve localboot file
299
+ if self.serveOnce == true and self.served.has_key?(buf[28..43]) and
300
+ self.served[buf[28..43]][1] and pxeclient == true
301
+ pkt << dhcpoption(OpPXEConfigFile, self.pxealtconfigfile)
302
+ else
303
+ # We are handing out an IP and our PXE attack
304
+ if(self.reporter)
305
+ self.reporter.call(buf[28..43],self.ipstring)
306
+ end
307
+ pkt << dhcpoption(OpPXEConfigFile, self.pxeconfigfile)
308
+ end
309
+ pkt << dhcpoption(OpPXEPathPrefix, self.pxepathprefix)
310
+ pkt << dhcpoption(OpPXERebootTime, [self.pxereboottime].pack('N'))
311
+ if ( self.give_hostname == true )
312
+ send_hostname = self.served_hostname
313
+ if ( self.served_over != 0 )
314
+ # NOTE : see above comments for the 'uniqueness' of this value
315
+ send_hostname += self.served_over.to_s
316
+ end
317
+ pkt << dhcpoption(OpHostname, send_hostname)
318
+ end
319
+ end
320
+ pkt << dhcpoption(OpEnd)
321
+
322
+ pkt << ("\x00" * 32) #padding
323
+
324
+ # And now we mark as requested
325
+ self.served[buf[28..43]][1] = true if messageType == DHCPRequest
326
+
327
+ send_packet(nil, pkt)
328
+ end
330
329
 
331
330
  end
332
331