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
@@ -13,772 +13,767 @@ module Rex
13
13
  ###
14
14
  module Socket
15
15
 
16
- module Comm
17
- end
18
-
19
- require 'rex/socket/parameters'
20
- require 'rex/socket/tcp'
21
- require 'rex/socket/tcp_server'
22
-
23
- require 'rex/socket/comm'
24
- require 'rex/socket/comm/local'
25
-
26
- require 'rex/socket/switch_board'
27
- require 'rex/socket/subnet_walker'
28
- require 'rex/socket/range_walker'
29
-
30
- ##
31
- #
32
- # Factory methods
33
- #
34
- ##
35
-
36
- #
37
- # Create a socket instance using the supplied parameter hash.
38
- #
39
- def self.create(opts = {})
40
- return create_param(Rex::Socket::Parameters.from_hash(opts))
41
- end
42
-
43
- #
44
- # Create a socket using the supplied Rex::Socket::Parameter instance.
45
- #
46
- def self.create_param(param)
47
- return param.comm.create(param)
48
- end
49
-
50
- #
51
- # Create a TCP socket using the supplied parameter hash.
52
- #
53
- def self.create_tcp(opts = {})
54
- return create_param(Rex::Socket::Parameters.from_hash(opts.merge('Proto' => 'tcp')))
55
- end
56
-
57
- #
58
- # Create a TCP server socket using the supplied parameter hash.
59
- #
60
- def self.create_tcp_server(opts = {})
61
- return create_tcp(opts.merge('Server' => true))
62
- end
63
-
64
- #
65
- # Create a UDP socket using the supplied parameter hash.
66
- #
67
- def self.create_udp(opts = {})
68
- return create_param(Rex::Socket::Parameters.from_hash(opts.merge('Proto' => 'udp')))
69
- end
70
-
71
- #
72
- # Create a IP socket using the supplied parameter hash.
73
- #
74
- def self.create_ip(opts = {})
75
- return create_param(Rex::Socket::Parameters.from_hash(opts.merge('Proto' => 'ip')))
76
- end
77
-
78
-
79
- #
80
- # Common Regular Expressions
81
- #
82
-
83
- MATCH_IPV6 = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/
84
-
85
- MATCH_IPV4 = /^\s*(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))\s*$/
86
-
87
- MATCH_IPV4_PRIVATE = /^\s*(?:10\.|192\.168|172.(?:1[6-9]|2[0-9]|3[01])\.|169\.254)/
88
-
89
- ##
90
- #
91
- # Serialization
92
- #
93
- ##
94
-
95
-
96
- # Cache our IPv6 support flag
97
- @@support_ipv6 = nil
98
-
99
- #
100
- # Determine whether we support IPv6
101
- #
102
- def self.support_ipv6?
103
- return @@support_ipv6 if not @@support_ipv6.nil?
104
-
105
- @@support_ipv6 = false
106
-
107
- if (::Socket.const_defined?('AF_INET6'))
108
- begin
109
- s = ::Socket.new(::Socket::AF_INET6, ::Socket::SOCK_DGRAM, ::Socket::IPPROTO_UDP)
110
- s.close
111
- @@support_ipv6 = true
112
- rescue
113
- end
114
- end
115
-
116
- return @@support_ipv6
117
- end
118
-
119
- #
120
- # Determine whether this is an IPv4 address
121
- #
122
- def self.is_ipv4?(addr)
123
- ( addr =~ MATCH_IPV4 ) ? true : false
124
- end
125
-
126
- #
127
- # Determine whether this is an IPv6 address
128
- #
129
- def self.is_ipv6?(addr)
130
- ( addr =~ MATCH_IPV6 ) ? true : false
131
- end
132
-
133
- #
134
- # Checks to see if the supplied address is in "dotted" form
135
- #
136
- def self.dotted_ip?(addr)
137
- # Match IPv6
138
- return true if (support_ipv6? and addr =~ MATCH_IPV6)
139
-
140
- # Match IPv4
141
- return true if (addr =~ MATCH_IPV4)
142
-
143
- false
144
- end
145
-
146
- #
147
- # Return true if +addr+ is within the ranges specified in RFC1918, or
148
- # RFC5735/RFC3927
149
- #
150
- def self.is_internal?(addr)
151
- if self.dotted_ip?(addr)
152
- addr =~ MATCH_IPV4_PRIVATE
153
- else
154
- false
155
- end
156
- end
157
-
158
- #
159
- # Wrapper for Resolv.getaddress that takes special care to see if the
160
- # supplied address is already a dotted quad, for instance. This is
161
- # necessary to prevent calls to gethostbyaddr (which occurs on windows).
162
- # These calls can be quite slow. This also fixes an issue with the
163
- # Resolv.getaddress() call being non-functional on Ruby 1.9.1 (Win32).
164
- #
165
- def self.getaddress(addr, accept_ipv6 = true)
166
- begin
167
- if addr =~ MATCH_IPV4 or (accept_ipv6 and addr =~ MATCH_IPV6)
168
- return addr
169
- end
170
-
171
- res = ::Socket.gethostbyname(addr)
172
- return nil if not res
173
-
174
- # Shift the first three elements out
175
- rname = res.shift
176
- ralias = res.shift
177
- rtype = res.shift
178
-
179
- # Rubinius has a bug where gethostbyname returns dotted quads instead of
180
- # NBO, but that's what we want anyway, so just short-circuit here.
181
- if res[0] =~ MATCH_IPV4 || res[0] =~ MATCH_IPV6
182
- res.each { |r|
183
- # if the caller doesn't mind ipv6, just return whatever we have
184
- return r if accept_ipv6
185
- # otherwise, take the first v4 address
186
- return r if r =~ MATCH_IPV4
187
- }
188
- # didn't find one
189
- return nil
190
- end
191
-
192
- # Reject IPv6 addresses if we don't accept them
193
- if not accept_ipv6
194
- res.reject!{|nbo| nbo.length != 4}
195
- end
196
-
197
- # Make sure we have at least one name
198
- return nil if res.length == 0
199
-
200
- # Return the first address of the result
201
- self.addr_ntoa( res[0] )
202
- rescue ::ArgumentError # Win32 bug
203
- nil
204
- end
205
- end
206
-
207
- #
208
- # Wrapper for Resolv.getaddress that takes special care to see if the
209
- # supplied address is already a dotted quad, for instance. This is
210
- # necessary to prevent calls to gethostbyaddr (which occurs on windows).
211
- # These calls can be quite slow. This also fixes an issue with the
212
- # Resolv.getaddress() call being non-functional on Ruby 1.9.1 (Win32).
213
- #
214
- def self.getaddresses(addr, accept_ipv6 = true)
215
- begin
216
- if addr =~ MATCH_IPV4 or (accept_ipv6 and addr =~ MATCH_IPV6)
217
- return [addr]
218
- end
219
-
220
- res = ::Socket.gethostbyname(addr)
221
- return [] if not res
222
-
223
- # Shift the first three elements out
224
- rname = res.shift
225
- ralias = res.shift
226
- rtype = res.shift
227
-
228
- # Reject IPv6 addresses if we don't accept them
229
- if not accept_ipv6
230
- res.reject!{|nbo| nbo.length != 4}
231
- end
232
-
233
- # Make sure we have at least one name
234
- return [] if res.length == 0
235
-
236
- # Return an array of all addresses
237
- res.map{ |addr| self.addr_ntoa(addr) }
238
- rescue ::ArgumentError # Win32 bug
239
- []
240
- end
241
- end
242
-
243
- #
244
- # Wrapper for Socket.gethostbyname which takes into account whether or not
245
- # an IP address is supplied. If it is, then reverse DNS resolution does
246
- # not occur. This is done in order to prevent delays, such as would occur
247
- # on Windows.
248
- #
249
- def self.gethostbyname(host)
250
- if (is_ipv4?(host))
251
- return [ host, [], 2, host.split('.').map{ |c| c.to_i }.pack("C4") ]
252
- end
253
-
254
- if is_ipv6?(host)
255
- host, scope_id = host.split('%', 2)
256
- end
257
-
258
- ::Socket.gethostbyname(host)
259
- end
260
-
261
- #
262
- # Create a sockaddr structure using the supplied IP address, port, and
263
- # address family
264
- #
265
- def self.to_sockaddr(ip, port)
266
-
267
- if (ip == '::ffff:0.0.0.0')
268
- ip = support_ipv6?() ? '::' : '0.0.0.0'
269
- end
270
-
271
- return ::Socket.pack_sockaddr_in(port, ip)
272
- end
273
-
274
- #
275
- # Returns the address family, host, and port of the supplied sockaddr as
276
- # [ af, host, port ]
277
- #
278
- def self.from_sockaddr(saddr)
279
- port, host = ::Socket::unpack_sockaddr_in(saddr)
280
- af = ::Socket::AF_INET
281
- if (support_ipv6?() and is_ipv6?(host))
282
- af = ::Socket::AF_INET6
283
- end
284
- return [ af, host, port ]
285
- end
286
-
287
- #
288
- # Resolves a host to raw network-byte order.
289
- #
290
- def self.resolv_nbo(host)
291
- self.gethostbyname( Rex::Socket.getaddress(host, true) )[3]
292
- end
293
-
294
- #
295
- # Resolves a host to raw network-byte order.
296
- #
297
- def self.resolv_nbo_list(host)
298
- Rex::Socket.getaddresses(host).map{|addr| self.gethostbyname(addr)[3] }
299
- end
300
-
301
- #
302
- # Resolves a host to a network-byte order ruby integer.
303
- #
304
- def self.resolv_nbo_i(host)
305
- addr_ntoi(resolv_nbo(host))
306
- end
307
-
308
- #
309
- # Resolves a host to a list of network-byte order ruby integers.
310
- #
311
- def self.resolv_nbo_i_list(host)
312
- resolv_nbo_list(host).map{|addr| addr_ntoi(addr) }
313
- end
314
-
315
- #
316
- # Converts an ASCII IP address to a CIDR mask. Returns
317
- # nil if it's not convertable.
318
- #
319
- def self.addr_atoc(mask)
320
- mask_i = resolv_nbo_i(mask)
321
- cidr = nil
322
- 0.upto(32) do |i|
323
- if ((1 << i)-1) << (32-i) == mask_i
324
- cidr = i
325
- break
326
- end
327
- end
328
- return cidr
329
- end
330
-
331
- #
332
- # Resolves a CIDR bitmask into a dotted-quad. Returns
333
- # nil if it's not convertable.
334
- #
335
- def self.addr_ctoa(cidr)
336
- return nil unless (0..32) === cidr.to_i
337
- addr_itoa(((1 << cidr)-1) << 32-cidr)
338
- end
339
-
340
- #
341
- # Resolves a host to a dotted address.
342
- #
343
- def self.resolv_to_dotted(host)
344
- addr_ntoa(addr_aton(host))
345
- end
346
-
347
- #
348
- # Converts a ascii address into an integer
349
- #
350
- def self.addr_atoi(addr)
351
- resolv_nbo_i(addr)
352
- end
353
-
354
- #
355
- # Converts a ascii address into a list of addresses
356
- #
357
- def self.addr_atoi_list(addr)
358
- resolv_nbo_i_list(addr)
359
- end
360
-
361
- #
362
- # Converts an integer address into ascii
363
- #
364
- def self.addr_itoa(addr, v6=false)
365
-
366
- nboa = addr_iton(addr, v6)
367
-
368
- # IPv4
369
- if (addr < 0x100000000 and not v6)
370
- addr_ntoa(nboa)
371
- # IPv6
372
- else
373
- addr_ntoa(nboa)
374
- end
375
- end
376
-
377
- #
378
- # Converts a ascii address to network byte order
379
- #
380
- def self.addr_aton(addr)
381
- resolv_nbo(addr)
382
- end
383
-
384
- #
385
- # Converts a network byte order address to ascii
386
- #
387
- def self.addr_ntoa(addr)
388
- # IPv4
389
- if (addr.length == 4)
390
- return addr.unpack('C4').join('.')
391
- end
392
-
393
- # IPv6
394
- if (addr.length == 16)
395
- return compress_address(addr.unpack('n8').map{ |c| "%x" % c }.join(":"))
396
- end
397
-
398
- raise RuntimeError, "Invalid address format"
399
- end
400
-
401
- #
402
- # Implement zero compression for IPv6 addresses.
403
- # Uses the compression method from Marco Ceresa's IPAddress GEM
404
- # https://github.com/bluemonk/ipaddress/blob/master/lib/ipaddress/ipv6.rb
405
- #
406
- def self.compress_address(addr)
407
- return addr unless is_ipv6?(addr)
408
- addr = addr.dup
409
- while true
410
- break if addr.sub!(/\A0:0:0:0:0:0:0:0\Z/, '::')
411
- break if addr.sub!(/\b0:0:0:0:0:0:0\b/, ':')
412
- break if addr.sub!(/\b0:0:0:0:0:0\b/, ':')
413
- break if addr.sub!(/\b0:0:0:0:0\b/, ':')
414
- break if addr.sub!(/\b0:0:0:0\b/, ':')
415
- break if addr.sub!(/\b0:0:0\b/, ':')
416
- break if addr.sub!(/\b0:0\b/, ':')
417
- break
418
- end
419
- addr.sub(/:{3,}/, '::')
420
- end
421
-
422
- #
423
- # Converts a network byte order address to an integer
424
- #
425
- def self.addr_ntoi(addr)
426
-
427
- bits = addr.unpack("N*")
428
-
429
- if (bits.length == 1)
430
- return bits[0]
431
- end
432
-
433
- if (bits.length == 4)
434
- val = 0
435
- bits.each_index { |i| val += ( bits[i] << (96 - (i * 32)) ) }
436
- return val
437
- end
438
-
439
- raise RuntimeError, "Invalid address format"
440
- end
441
-
442
- #
443
- # Converts an integer into a network byte order address
444
- #
445
- def self.addr_iton(addr, v6=false)
446
- if(addr < 0x100000000 and not v6)
447
- return [addr].pack('N')
448
- else
449
- w = []
450
- w[0] = (addr >> 96) & 0xffffffff
451
- w[1] = (addr >> 64) & 0xffffffff
452
- w[2] = (addr >> 32) & 0xffffffff
453
- w[3] = addr & 0xffffffff
454
- return w.pack('N4')
455
- end
456
- end
457
-
458
- #
459
- # Converts a CIDR subnet into an array (base, bcast)
460
- #
461
- def self.cidr_crack(cidr, v6=false)
462
- tmp = cidr.split('/')
463
-
464
- tst,scope = tmp[0].split("%",2)
465
- scope = "%" + scope if scope
466
- scope ||= ""
467
-
468
- addr = addr_atoi(tst)
469
-
470
- bits = 32
471
- mask = 0
472
- use6 = false
473
-
474
- if (addr > 0xffffffff or v6 or cidr =~ /:/)
475
- use6 = true
476
- bits = 128
477
- end
478
-
479
- mask = (2 ** bits) - (2 ** (bits - tmp[1].to_i))
480
- base = addr & mask
481
-
482
- stop = base + (2 ** (bits - tmp[1].to_i)) - 1
483
- return [self.addr_itoa(base, use6) + scope, self.addr_itoa(stop, use6) + scope]
484
- end
485
-
486
- #
487
- # Converts a netmask (255.255.255.240) into a bitmask (28). This is the
488
- # lame kid way of doing it.
489
- #
490
- def self.net2bitmask(netmask)
491
-
492
- nmask = resolv_nbo(netmask)
493
- imask = addr_ntoi(nmask)
494
- bits = 32
495
-
496
- if (imask > 0xffffffff)
497
- bits = 128
498
- end
499
-
500
- 0.upto(bits-1) do |bit|
501
- p = 2 ** bit
502
- return (bits - bit) if ((imask & p) == p)
503
- end
504
-
505
- 0
506
- end
507
-
508
- #
509
- # Converts a bitmask (28) into a netmask (255.255.255.240)
510
- #
511
- def self.bit2netmask(bitmask, ipv6=false)
512
- if bitmask > 32 or ipv6
513
- i = ((~((2 ** (128 - bitmask)) - 1)) & (2**128-1))
514
- n = Rex::Socket.addr_iton(i, true)
515
- return Rex::Socket.addr_ntoa(n)
516
- else
517
- [ (~((2 ** (32 - bitmask)) - 1)) & 0xffffffff ].pack('N').unpack('CCCC').join('.')
518
- end
519
- end
520
-
521
-
522
- def self.portspec_crack(pspec)
523
- portspec_to_portlist(pspec)
524
- end
525
-
526
- #
527
- # Converts a port specification like "80,21-23,443" into a sorted,
528
- # unique array of valid port numbers like [21,22,23,80,443]
529
- #
530
- def self.portspec_to_portlist(pspec)
531
- ports = []
532
-
533
- # Build ports array from port specification
534
- pspec.split(/,/).each do |item|
535
- start, stop = item.split(/-/).map { |p| p.to_i }
536
-
537
- start ||= 0
538
- stop ||= item.match(/-/) ? 65535 : start
539
-
540
- start, stop = stop, start if stop < start
541
-
542
- start.upto(stop) { |p| ports << p }
543
- end
544
-
545
- # Sort, and remove dups and invalid ports
546
- ports.sort.uniq.delete_if { |p| p < 1 or p > 65535 }
547
- end
548
-
549
- #
550
- # Converts a port list like [1,2,3,4,5,100] into a
551
- # range specification like "1-5,100"
552
- #
553
- def self.portlist_to_portspec(parr)
554
- ranges = []
555
- range = []
556
- lastp = nil
557
-
558
- parr.uniq.sort{|a,b| a<=>b}.map{|a| a.to_i}.each do |n|
559
- next if (n < 1 or n > 65535)
560
- if not lastp
561
- range = [n]
562
- lastp = n
563
- next
564
- end
565
-
566
- if lastp == n - 1
567
- range << n
568
- else
569
- ranges << range
570
- range = [n]
571
- end
572
- lastp = n
573
- end
574
-
575
- ranges << range
576
- ranges.delete(nil)
577
- ranges.uniq.map{|x| x.length == 1 ? "#{x[0]}" : "#{x[0]}-#{x[-1]}"}.join(",")
578
- end
579
-
580
- ##
581
- #
582
- # Utility class methods
583
- #
584
- ##
585
-
586
- #
587
- # This method does NOT send any traffic to the destination, instead, it uses a
588
- # "bound" UDP socket to determine what source address we would use to
589
- # communicate with the specified destination. The destination defaults to
590
- # Google's DNS server to make the standard behavior determine which IP
591
- # we would use to communicate with the internet.
592
- #
593
- def self.source_address(dest='8.8.8.8', comm = ::Rex::Socket::Comm::Local)
594
- begin
595
- s = self.create_udp(
596
- 'PeerHost' => dest,
597
- 'PeerPort' => 31337,
598
- 'Comm' => comm
599
- )
600
- r = s.getsockname[1]
601
- s.close
602
-
603
- # Trim off the trailing interface ID for link-local IPv6
604
- return r.split('%').first
605
- rescue ::Exception
606
- return '127.0.0.1'
607
- end
608
- end
609
-
610
- #
611
- # Identifies the link-local address of a given interface (if IPv6 is enabled)
612
- #
613
- def self.ipv6_link_address(intf)
614
- r = source_address("FF02::1%#{intf}")
615
- return if not (r and r =~ /^fe80/i)
616
- r
617
- end
618
-
619
- #
620
- # Identifies the mac address of a given interface (if IPv6 is enabled)
621
- #
622
- def self.ipv6_mac(intf)
623
- r = ipv6_link_address(intf)
624
- return if not r
625
- raw = addr_aton(r)[-8, 8]
626
- (raw[0,3] + raw[5,3]).unpack("C*").map{|c| "%.2x" % c}.join(":")
627
- end
628
-
629
- #
630
- # Create a TCP socket pair.
631
- #
632
- # sf: This create a socket pair using native ruby sockets and will work
633
- # on Windows where ::Socket.pair is not implemented.
634
- # Note: OpenSSL requires native ruby sockets for its io.
635
- #
636
- # Note: Even though sub-threads are smashing the parent threads local, there
637
- # is no concurrent use of the same locals and this is safe.
638
- def self.tcp_socket_pair
639
- lsock = nil
640
- rsock = nil
641
- laddr = '127.0.0.1'
642
- lport = 0
643
- threads = []
644
- mutex = ::Mutex.new
645
-
646
- threads << Rex::ThreadFactory.spawn('TcpSocketPair', false) {
647
- server = nil
648
- mutex.synchronize {
649
- threads << Rex::ThreadFactory.spawn('TcpSocketPairClient', false) {
650
- mutex.synchronize {
651
- rsock = ::TCPSocket.new( laddr, lport )
652
- }
653
- }
654
- server = ::TCPServer.new(laddr, 0)
655
- if (server.getsockname =~ /127\.0\.0\.1:/)
656
- # JRuby ridiculousness
657
- caddr, lport = server.getsockname.split(":")
658
- caddr = caddr[1,caddr.length]
659
- lport = lport.to_i
660
- else
661
- # Sane implementations where Socket#getsockname returns a
662
- # sockaddr
663
- lport, caddr = ::Socket.unpack_sockaddr_in( server.getsockname )
664
- end
665
- }
666
- lsock, saddr = server.accept
667
- server.close
668
- }
669
-
670
- threads.each { |t| t.join }
671
-
672
- return [lsock, rsock]
673
- end
674
-
675
- #
676
- # Create a UDP socket pair using native ruby UDP sockets.
677
- #
678
- def self.udp_socket_pair
679
- laddr = '127.0.0.1'
680
-
681
- lsock = ::UDPSocket.new
682
- lsock.bind( laddr, 0 )
683
-
684
- rsock = ::UDPSocket.new
685
- rsock.bind( laddr, 0 )
686
-
687
- rsock.connect( *lsock.addr.values_at(3,1) )
688
-
689
- lsock.connect( *rsock.addr.values_at(3,1) )
690
-
691
- return [lsock, rsock]
692
- end
693
-
694
-
695
- ##
696
- #
697
- # Class initialization
698
- #
699
- ##
700
-
701
- #
702
- # Initialize general socket parameters.
703
- #
704
- def initsock(params = nil)
705
- if (params)
706
- self.peerhost = params.peerhost
707
- self.peerport = params.peerport
708
- self.localhost = params.localhost
709
- self.localport = params.localport
710
- self.context = params.context || {}
711
- self.ipv = params.v6 ? 6 : 4
712
- end
713
- end
714
-
715
- #
716
- # By default, all sockets are themselves selectable file descriptors.
717
- #
718
- def fd
719
- self
720
- end
721
-
722
- #
723
- # Returns local connection information.
724
- #
725
- def getsockname
726
- Socket.from_sockaddr(super)
727
- end
728
-
729
- #
730
- # Wrapper around getsockname
731
- #
732
- def getlocalname
733
- getsockname
734
- end
735
-
736
- #
737
- # Return peer connection information.
738
- #
739
- def getpeername
740
- return Socket.from_sockaddr(super)
741
- end
742
-
743
- #
744
- # Returns a string that indicates the type of the socket, such as 'tcp'.
745
- #
746
- def type?
747
- raise NotImplementedError, "Socket type is not supported."
748
- end
749
-
750
- #
751
- # The peer host of the connected socket.
752
- #
753
- attr_reader :peerhost
754
- #
755
- # The peer port of the connected socket.
756
- #
757
- attr_reader :peerport
758
- #
759
- # The local host of the connected socket.
760
- #
761
- attr_reader :localhost
762
- #
763
- # The local port of the connected socket.
764
- #
765
- attr_reader :localport
766
- #
767
- # The IP version of the socket
768
- #
769
- attr_reader :ipv
770
- #
771
- # Contextual information that describes the source and other
772
- # instance-specific attributes. This comes from the param.context
773
- # attribute.
774
- #
775
- attr_reader :context
16
+ module Comm
17
+ end
18
+
19
+ require 'rex/socket/parameters'
20
+ require 'rex/socket/tcp'
21
+ require 'rex/socket/tcp_server'
22
+
23
+ require 'rex/socket/comm'
24
+ require 'rex/socket/comm/local'
25
+
26
+ require 'rex/socket/switch_board'
27
+ require 'rex/socket/subnet_walker'
28
+ require 'rex/socket/range_walker'
29
+
30
+ ##
31
+ #
32
+ # Factory methods
33
+ #
34
+ ##
35
+
36
+ #
37
+ # Create a socket instance using the supplied parameter hash.
38
+ #
39
+ def self.create(opts = {})
40
+ return create_param(Rex::Socket::Parameters.from_hash(opts))
41
+ end
42
+
43
+ #
44
+ # Create a socket using the supplied Rex::Socket::Parameter instance.
45
+ #
46
+ def self.create_param(param)
47
+ return param.comm.create(param)
48
+ end
49
+
50
+ #
51
+ # Create a TCP socket using the supplied parameter hash.
52
+ #
53
+ def self.create_tcp(opts = {})
54
+ return create_param(Rex::Socket::Parameters.from_hash(opts.merge('Proto' => 'tcp')))
55
+ end
56
+
57
+ #
58
+ # Create a TCP server socket using the supplied parameter hash.
59
+ #
60
+ def self.create_tcp_server(opts = {})
61
+ return create_tcp(opts.merge('Server' => true))
62
+ end
63
+
64
+ #
65
+ # Create a UDP socket using the supplied parameter hash.
66
+ #
67
+ def self.create_udp(opts = {})
68
+ return create_param(Rex::Socket::Parameters.from_hash(opts.merge('Proto' => 'udp')))
69
+ end
70
+
71
+ #
72
+ # Create a IP socket using the supplied parameter hash.
73
+ #
74
+ def self.create_ip(opts = {})
75
+ return create_param(Rex::Socket::Parameters.from_hash(opts.merge('Proto' => 'ip')))
76
+ end
77
+
78
+
79
+ #
80
+ # Common Regular Expressions
81
+ #
82
+
83
+ MATCH_IPV6 = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/
84
+
85
+ MATCH_IPV4 = /^\s*(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))\s*$/
86
+
87
+ MATCH_IPV4_PRIVATE = /^\s*(?:10\.|192\.168|172.(?:1[6-9]|2[0-9]|3[01])\.|169\.254)/
88
+
89
+ ##
90
+ #
91
+ # Serialization
92
+ #
93
+ ##
94
+
95
+
96
+ # Cache our IPv6 support flag
97
+ @@support_ipv6 = nil
98
+
99
+ #
100
+ # Determine whether we support IPv6
101
+ #
102
+ def self.support_ipv6?
103
+ return @@support_ipv6 if not @@support_ipv6.nil?
104
+
105
+ @@support_ipv6 = false
106
+
107
+ if (::Socket.const_defined?('AF_INET6'))
108
+ begin
109
+ s = ::Socket.new(::Socket::AF_INET6, ::Socket::SOCK_DGRAM, ::Socket::IPPROTO_UDP)
110
+ s.close
111
+ @@support_ipv6 = true
112
+ rescue
113
+ end
114
+ end
115
+
116
+ return @@support_ipv6
117
+ end
118
+
119
+ #
120
+ # Determine whether this is an IPv4 address
121
+ #
122
+ def self.is_ipv4?(addr)
123
+ ( addr =~ MATCH_IPV4 ) ? true : false
124
+ end
125
+
126
+ #
127
+ # Determine whether this is an IPv6 address
128
+ #
129
+ def self.is_ipv6?(addr)
130
+ ( addr =~ MATCH_IPV6 ) ? true : false
131
+ end
132
+
133
+ #
134
+ # Checks to see if the supplied address is in "dotted" form
135
+ #
136
+ def self.dotted_ip?(addr)
137
+ # Match IPv6
138
+ return true if (support_ipv6? and addr =~ MATCH_IPV6)
139
+
140
+ # Match IPv4
141
+ return true if (addr =~ MATCH_IPV4)
142
+
143
+ false
144
+ end
145
+
146
+ #
147
+ # Return true if +addr+ is within the ranges specified in RFC1918, or
148
+ # RFC5735/RFC3927
149
+ #
150
+ def self.is_internal?(addr)
151
+ if self.dotted_ip?(addr)
152
+ addr =~ MATCH_IPV4_PRIVATE
153
+ else
154
+ false
155
+ end
156
+ end
157
+
158
+ # Get the first address returned by a DNS lookup for +hostname+.
159
+ #
160
+ # @see .getaddresses
161
+ #
162
+ # @param (see .getaddresses)
163
+ # @return [String] ASCII IP address
164
+ def self.getaddress(hostname, accept_ipv6 = true)
165
+ getaddresses(hostname, accept_ipv6).first
166
+ end
167
+
168
+ #
169
+ # Wrapper for +::Socket.gethostbyname+ that takes special care to see if the
170
+ # supplied address is already an ASCII IP address. This is necessary to
171
+ # prevent blocking while waiting on a DNS reverse lookup when we already
172
+ # have what we need.
173
+ #
174
+ # @param hostname [String] A hostname or ASCII IP address
175
+ # @return [Array<String>]
176
+ def self.getaddresses(hostname, accept_ipv6 = true)
177
+ if hostname =~ MATCH_IPV4 or (accept_ipv6 and hostname =~ MATCH_IPV6)
178
+ return [hostname]
179
+ end
180
+
181
+ res = ::Socket.gethostbyname(hostname)
182
+ return [] if not res
183
+
184
+ # Shift the first three elements out, leaving just the list of
185
+ # addresses
186
+ res.shift # name
187
+ res.shift # alias hostnames
188
+ res.shift # address_family
189
+
190
+ # Rubinius has a bug where gethostbyname returns dotted quads instead of
191
+ # NBO, but that's what we want anyway, so just short-circuit here.
192
+ if res[0] =~ MATCH_IPV4 || res[0] =~ MATCH_IPV6
193
+ unless accept_ipv6
194
+ res.reject!{ |ascii| ascii =~ MATCH_IPV6 }
195
+ end
196
+ else
197
+ unless accept_ipv6
198
+ res.reject!{ |nbo| nbo.length != 4 }
199
+ end
200
+ res.map!{ |nbo| self.addr_ntoa(nbo) }
201
+ end
202
+
203
+ res
204
+ end
205
+
206
+ #
207
+ # Wrapper for Socket.gethostbyname which takes into account whether or not
208
+ # an IP address is supplied. If it is, then reverse DNS resolution does
209
+ # not occur. This is done in order to prevent delays, such as would occur
210
+ # on Windows.
211
+ #
212
+ def self.gethostbyname(host)
213
+ if (is_ipv4?(host))
214
+ return [ host, [], 2, host.split('.').map{ |c| c.to_i }.pack("C4") ]
215
+ end
216
+
217
+ if is_ipv6?(host)
218
+ # pop off the scopeid since gethostbyname isn't smart enough to
219
+ # deal with it.
220
+ host, _ = host.split('%', 2)
221
+ end
222
+
223
+ ::Socket.gethostbyname(host)
224
+ end
225
+
226
+ #
227
+ # Create a sockaddr structure using the supplied IP address, port, and
228
+ # address family
229
+ #
230
+ def self.to_sockaddr(ip, port)
231
+
232
+ if (ip == '::ffff:0.0.0.0')
233
+ ip = support_ipv6?() ? '::' : '0.0.0.0'
234
+ end
235
+
236
+ return ::Socket.pack_sockaddr_in(port, ip)
237
+ end
238
+
239
+ #
240
+ # Returns the address family, host, and port of the supplied sockaddr as
241
+ # [ af, host, port ]
242
+ #
243
+ def self.from_sockaddr(saddr)
244
+ port, host = ::Socket::unpack_sockaddr_in(saddr)
245
+ af = ::Socket::AF_INET
246
+ if (support_ipv6?() and is_ipv6?(host))
247
+ af = ::Socket::AF_INET6
248
+ end
249
+ return [ af, host, port ]
250
+ end
251
+
252
+ #
253
+ # Resolves a host to raw network-byte order.
254
+ #
255
+ def self.resolv_nbo(host)
256
+ self.gethostbyname( Rex::Socket.getaddress(host, true) )[3]
257
+ end
258
+
259
+ #
260
+ # Resolves a host to raw network-byte order.
261
+ #
262
+ def self.resolv_nbo_list(host)
263
+ Rex::Socket.getaddresses(host).map{|addr| self.gethostbyname(addr)[3] }
264
+ end
265
+
266
+ #
267
+ # Resolves a host to a network-byte order ruby integer.
268
+ #
269
+ def self.resolv_nbo_i(host)
270
+ addr_ntoi(resolv_nbo(host))
271
+ end
272
+
273
+ #
274
+ # Resolves a host to a list of network-byte order ruby integers.
275
+ #
276
+ def self.resolv_nbo_i_list(host)
277
+ resolv_nbo_list(host).map{|addr| addr_ntoi(addr) }
278
+ end
279
+
280
+ #
281
+ # Converts an ASCII IP address to a CIDR mask. Returns
282
+ # nil if it's not convertable.
283
+ #
284
+ def self.addr_atoc(mask)
285
+ mask_i = resolv_nbo_i(mask)
286
+ cidr = nil
287
+ 0.upto(32) do |i|
288
+ if ((1 << i)-1) << (32-i) == mask_i
289
+ cidr = i
290
+ break
291
+ end
292
+ end
293
+ return cidr
294
+ end
295
+
296
+ #
297
+ # Resolves a CIDR bitmask into a dotted-quad. Returns
298
+ # nil if it's not convertable.
299
+ #
300
+ def self.addr_ctoa(cidr)
301
+ return nil unless (0..32) === cidr.to_i
302
+ addr_itoa(((1 << cidr)-1) << 32-cidr)
303
+ end
304
+
305
+ #
306
+ # Resolves a host to a dotted address.
307
+ #
308
+ def self.resolv_to_dotted(host)
309
+ addr_ntoa(addr_aton(host))
310
+ end
311
+
312
+ #
313
+ # Converts a ascii address into an integer
314
+ #
315
+ def self.addr_atoi(addr)
316
+ resolv_nbo_i(addr)
317
+ end
318
+
319
+ #
320
+ # Converts a ascii address into a list of addresses
321
+ #
322
+ def self.addr_atoi_list(addr)
323
+ resolv_nbo_i_list(addr)
324
+ end
325
+
326
+ #
327
+ # Converts an integer address into ascii
328
+ #
329
+ # @param (see #addr_iton)
330
+ # @return (see #addr_ntoa)
331
+ def self.addr_itoa(addr, v6=false)
332
+ nboa = addr_iton(addr, v6)
333
+
334
+ addr_ntoa(nboa)
335
+ end
336
+
337
+ #
338
+ # Converts a ascii address to network byte order
339
+ #
340
+ def self.addr_aton(addr)
341
+ resolv_nbo(addr)
342
+ end
343
+
344
+ #
345
+ # Converts a network byte order address to ascii
346
+ #
347
+ # @param addr [String] Packed network-byte-order address
348
+ # @return [String] Human readable IP address.
349
+ def self.addr_ntoa(addr)
350
+ # IPv4
351
+ if (addr.length == 4)
352
+ return addr.unpack('C4').join('.')
353
+ end
354
+
355
+ # IPv6
356
+ if (addr.length == 16)
357
+ return compress_address(addr.unpack('n8').map{ |c| "%x" % c }.join(":"))
358
+ end
359
+
360
+ raise RuntimeError, "Invalid address format"
361
+ end
362
+
363
+ #
364
+ # Implement zero compression for IPv6 addresses.
365
+ # Uses the compression method from Marco Ceresa's IPAddress GEM
366
+ #
367
+ # @see https://github.com/bluemonk/ipaddress/blob/master/lib/ipaddress/ipv6.rb
368
+ #
369
+ # @param addr [String] Human readable IPv6 address
370
+ # @return [String] Human readable IPv6 address with runs of 0s removed
371
+ def self.compress_address(addr)
372
+ return addr unless is_ipv6?(addr)
373
+ addr = addr.dup
374
+ while true
375
+ break if addr.sub!(/\A0:0:0:0:0:0:0:0\Z/, '::')
376
+ break if addr.sub!(/\b0:0:0:0:0:0:0\b/, ':')
377
+ break if addr.sub!(/\b0:0:0:0:0:0\b/, ':')
378
+ break if addr.sub!(/\b0:0:0:0:0\b/, ':')
379
+ break if addr.sub!(/\b0:0:0:0\b/, ':')
380
+ break if addr.sub!(/\b0:0:0\b/, ':')
381
+ break if addr.sub!(/\b0:0\b/, ':')
382
+ break
383
+ end
384
+ addr.sub(/:{3,}/, '::')
385
+ end
386
+
387
+ #
388
+ # Converts a network byte order address to an integer
389
+ #
390
+ def self.addr_ntoi(addr)
391
+
392
+ bits = addr.unpack("N*")
393
+
394
+ if (bits.length == 1)
395
+ return bits[0]
396
+ end
397
+
398
+ if (bits.length == 4)
399
+ val = 0
400
+ bits.each_index { |i| val += ( bits[i] << (96 - (i * 32)) ) }
401
+ return val
402
+ end
403
+
404
+ raise RuntimeError, "Invalid address format"
405
+ end
406
+
407
+ #
408
+ # Converts an integer into a network byte order address
409
+ #
410
+ # @param addr [Numeric] The address as a number
411
+ # @param v6 [Boolean] Whether +addr+ is IPv6
412
+ def self.addr_iton(addr, v6=false)
413
+ if(addr < 0x100000000 && !v6)
414
+ return [addr].pack('N')
415
+ else
416
+ w = []
417
+ w[0] = (addr >> 96) & 0xffffffff
418
+ w[1] = (addr >> 64) & 0xffffffff
419
+ w[2] = (addr >> 32) & 0xffffffff
420
+ w[3] = addr & 0xffffffff
421
+ return w.pack('N4')
422
+ end
423
+ end
424
+
425
+ #
426
+ # Converts a colon-delimited MAC address into a 6-byte binary string
427
+ #
428
+ def self.eth_aton(mac)
429
+ mac.split(":").map{|c| c.to_i(16) }.pack("C*")
430
+ end
431
+
432
+ #
433
+ # Converts a 6-byte binary string into a colon-delimited MAC address
434
+ #
435
+ def self.eth_ntoa(bin)
436
+ bin.unpack("C6").map{|x| "%.2x" % x }.join(":").upcase
437
+ end
438
+
439
+ #
440
+ # Converts a CIDR subnet into an array (base, bcast)
441
+ #
442
+ def self.cidr_crack(cidr, v6=false)
443
+ tmp = cidr.split('/')
444
+
445
+ tst,scope = tmp[0].split("%",2)
446
+ scope = "%" + scope if scope
447
+ scope ||= ""
448
+
449
+ addr = addr_atoi(tst)
450
+
451
+ bits = 32
452
+ mask = 0
453
+ use6 = false
454
+
455
+ if (addr > 0xffffffff or v6 or cidr =~ /:/)
456
+ use6 = true
457
+ bits = 128
458
+ end
459
+
460
+ mask = (2 ** bits) - (2 ** (bits - tmp[1].to_i))
461
+ base = addr & mask
462
+
463
+ stop = base + (2 ** (bits - tmp[1].to_i)) - 1
464
+ return [self.addr_itoa(base, use6) + scope, self.addr_itoa(stop, use6) + scope]
465
+ end
466
+
467
+ #
468
+ # Converts a netmask (255.255.255.240) into a bitmask (28). This is the
469
+ # lame kid way of doing it.
470
+ #
471
+ def self.net2bitmask(netmask)
472
+
473
+ nmask = resolv_nbo(netmask)
474
+ imask = addr_ntoi(nmask)
475
+ bits = 32
476
+
477
+ if (imask > 0xffffffff)
478
+ bits = 128
479
+ end
480
+
481
+ 0.upto(bits-1) do |bit|
482
+ p = 2 ** bit
483
+ return (bits - bit) if ((imask & p) == p)
484
+ end
485
+
486
+ 0
487
+ end
488
+
489
+ #
490
+ # Converts a bitmask (28) into a netmask (255.255.255.240)
491
+ #
492
+ def self.bit2netmask(bitmask, ipv6=false)
493
+ if bitmask > 32 or ipv6
494
+ i = ((~((2 ** (128 - bitmask)) - 1)) & (2**128-1))
495
+ n = Rex::Socket.addr_iton(i, true)
496
+ return Rex::Socket.addr_ntoa(n)
497
+ else
498
+ [ (~((2 ** (32 - bitmask)) - 1)) & 0xffffffff ].pack('N').unpack('CCCC').join('.')
499
+ end
500
+ end
501
+
502
+
503
+ def self.portspec_crack(pspec)
504
+ portspec_to_portlist(pspec)
505
+ end
506
+
507
+ #
508
+ # Converts a port specification like "80,21-25,!24,443" into a sorted,
509
+ # unique array of valid port numbers like [21,22,23,25,80,443]
510
+ #
511
+ def self.portspec_to_portlist(pspec)
512
+ ports = []
513
+ remove = []
514
+
515
+ # Build ports array from port specification
516
+ pspec.split(/,/).each do |item|
517
+ target = ports
518
+
519
+ item.strip!
520
+
521
+ if item.start_with? '!'
522
+ item.delete! '!'
523
+ target = remove
524
+ end
525
+
526
+ start, stop = item.split(/-/).map { |p| p.to_i }
527
+
528
+ start ||= 0
529
+ stop ||= item.match(/-/) ? 65535 : start
530
+
531
+ start, stop = stop, start if stop < start
532
+
533
+ start.upto(stop) { |p| target << p }
534
+ end
535
+
536
+ if ports.empty? and not remove.empty? then
537
+ ports = 1.upto 65535
538
+ end
539
+
540
+ # Sort, and remove dups and invalid ports
541
+ ports.sort.uniq.delete_if { |p| p < 1 or p > 65535 or remove.include? p }
542
+ end
543
+
544
+ #
545
+ # Converts a port list like [1,2,3,4,5,100] into a
546
+ # range specification like "1-5,100"
547
+ #
548
+ def self.portlist_to_portspec(parr)
549
+ ranges = []
550
+ range = []
551
+ lastp = nil
552
+
553
+ parr.uniq.sort{|a,b| a<=>b}.map{|a| a.to_i}.each do |n|
554
+ next if (n < 1 or n > 65535)
555
+ if not lastp
556
+ range = [n]
557
+ lastp = n
558
+ next
559
+ end
560
+
561
+ if lastp == n - 1
562
+ range << n
563
+ else
564
+ ranges << range
565
+ range = [n]
566
+ end
567
+ lastp = n
568
+ end
569
+
570
+ ranges << range
571
+ ranges.delete(nil)
572
+ ranges.uniq.map{|x| x.length == 1 ? "#{x[0]}" : "#{x[0]}-#{x[-1]}"}.join(",")
573
+ end
574
+
575
+ ##
576
+ #
577
+ # Utility class methods
578
+ #
579
+ ##
580
+
581
+ #
582
+ # This method does NOT send any traffic to the destination, instead, it uses a
583
+ # "bound" UDP socket to determine what source address we would use to
584
+ # communicate with the specified destination. The destination defaults to
585
+ # Google's DNS server to make the standard behavior determine which IP
586
+ # we would use to communicate with the internet.
587
+ #
588
+ def self.source_address(dest='8.8.8.8', comm = ::Rex::Socket::Comm::Local)
589
+ begin
590
+ s = self.create_udp(
591
+ 'PeerHost' => dest,
592
+ 'PeerPort' => 31337,
593
+ 'Comm' => comm
594
+ )
595
+ r = s.getsockname[1]
596
+ s.close
597
+
598
+ # Trim off the trailing interface ID for link-local IPv6
599
+ return r.split('%').first
600
+ rescue ::Exception
601
+ return '127.0.0.1'
602
+ end
603
+ end
604
+
605
+ #
606
+ # Identifies the link-local address of a given interface (if IPv6 is enabled)
607
+ #
608
+ def self.ipv6_link_address(intf)
609
+ r = source_address("FF02::1%#{intf}")
610
+ return nil if r.nil? || r !~ /^fe80/i
611
+ r
612
+ end
613
+
614
+ #
615
+ # Identifies the mac address of a given interface (if IPv6 is enabled)
616
+ #
617
+ def self.ipv6_mac(intf)
618
+ r = ipv6_link_address(intf)
619
+ return if not r
620
+ raw = addr_aton(r)[-8, 8]
621
+ (raw[0,3] + raw[5,3]).unpack("C*").map{|c| "%.2x" % c}.join(":")
622
+ end
623
+
624
+ #
625
+ # Create a TCP socket pair.
626
+ #
627
+ # sf: This create a socket pair using native ruby sockets and will work
628
+ # on Windows where ::Socket.pair is not implemented.
629
+ # Note: OpenSSL requires native ruby sockets for its io.
630
+ #
631
+ # Note: Even though sub-threads are smashing the parent threads local, there
632
+ # is no concurrent use of the same locals and this is safe.
633
+ def self.tcp_socket_pair
634
+ lsock = nil
635
+ rsock = nil
636
+ laddr = '127.0.0.1'
637
+ lport = 0
638
+ threads = []
639
+ mutex = ::Mutex.new
640
+
641
+ threads << Rex::ThreadFactory.spawn('TcpSocketPair', false) {
642
+ server = nil
643
+ mutex.synchronize {
644
+ threads << Rex::ThreadFactory.spawn('TcpSocketPairClient', false) {
645
+ mutex.synchronize {
646
+ rsock = ::TCPSocket.new( laddr, lport )
647
+ }
648
+ }
649
+ server = ::TCPServer.new(laddr, 0)
650
+ if (server.getsockname =~ /127\.0\.0\.1:/)
651
+ # JRuby ridiculousness
652
+ caddr, lport = server.getsockname.split(":")
653
+ caddr = caddr[1,caddr.length]
654
+ lport = lport.to_i
655
+ else
656
+ # Sane implementations where Socket#getsockname returns a
657
+ # sockaddr
658
+ lport, caddr = ::Socket.unpack_sockaddr_in( server.getsockname )
659
+ end
660
+ }
661
+ lsock, _ = server.accept
662
+ server.close
663
+ }
664
+
665
+ threads.each { |t| t.join }
666
+
667
+ return [lsock, rsock]
668
+ end
669
+
670
+ #
671
+ # Create a UDP socket pair using native ruby UDP sockets.
672
+ #
673
+ def self.udp_socket_pair
674
+ laddr = '127.0.0.1'
675
+
676
+ lsock = ::UDPSocket.new
677
+ lsock.bind( laddr, 0 )
678
+
679
+ rsock = ::UDPSocket.new
680
+ rsock.bind( laddr, 0 )
681
+
682
+ rsock.connect( *lsock.addr.values_at(3,1) )
683
+
684
+ lsock.connect( *rsock.addr.values_at(3,1) )
685
+
686
+ return [lsock, rsock]
687
+ end
688
+
689
+
690
+ ##
691
+ #
692
+ # Class initialization
693
+ #
694
+ ##
695
+
696
+ #
697
+ # Initialize general socket parameters.
698
+ #
699
+ def initsock(params = nil)
700
+ if (params)
701
+ self.peerhost = params.peerhost
702
+ self.peerport = params.peerport
703
+ self.localhost = params.localhost
704
+ self.localport = params.localport
705
+ self.context = params.context || {}
706
+ self.ipv = params.v6 ? 6 : 4
707
+ end
708
+ end
709
+
710
+ #
711
+ # By default, all sockets are themselves selectable file descriptors.
712
+ #
713
+ def fd
714
+ self
715
+ end
716
+
717
+ #
718
+ # Returns local connection information.
719
+ #
720
+ def getsockname
721
+ Socket.from_sockaddr(super)
722
+ end
723
+
724
+ #
725
+ # Wrapper around getsockname
726
+ #
727
+ def getlocalname
728
+ getsockname
729
+ end
730
+
731
+ #
732
+ # Return peer connection information.
733
+ #
734
+ def getpeername
735
+ return Socket.from_sockaddr(super)
736
+ end
737
+
738
+ #
739
+ # Returns a string that indicates the type of the socket, such as 'tcp'.
740
+ #
741
+ def type?
742
+ raise NotImplementedError, "Socket type is not supported."
743
+ end
744
+
745
+ #
746
+ # The peer host of the connected socket.
747
+ #
748
+ attr_reader :peerhost
749
+ #
750
+ # The peer port of the connected socket.
751
+ #
752
+ attr_reader :peerport
753
+ #
754
+ # The local host of the connected socket.
755
+ #
756
+ attr_reader :localhost
757
+ #
758
+ # The local port of the connected socket.
759
+ #
760
+ attr_reader :localport
761
+ #
762
+ # The IP version of the socket
763
+ #
764
+ attr_reader :ipv
765
+ #
766
+ # Contextual information that describes the source and other
767
+ # instance-specific attributes. This comes from the param.context
768
+ # attribute.
769
+ #
770
+ attr_reader :context
776
771
 
777
772
  protected
778
773
 
779
- attr_writer :peerhost, :peerport, :localhost, :localport # :nodoc:
780
- attr_writer :context # :nodoc:
781
- attr_writer :ipv # :nodoc:
774
+ attr_writer :peerhost, :peerport, :localhost, :localport # :nodoc:
775
+ attr_writer :context # :nodoc:
776
+ attr_writer :ipv # :nodoc:
782
777
 
783
778
  end
784
779