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,30 @@
1
+ # https://en.wikipedia.org/wiki/Printer_Job_Language
2
+ # See external links for PJL spec
3
+
4
+ module Rex::Proto::PJL
5
+
6
+ require "rex/proto/pjl/client"
7
+
8
+ DEFAULT_PORT = 9100
9
+ DEFAULT_TIMEOUT = 5
10
+
11
+ COUNT_MAX = 2_147_483_647
12
+ SIZE_MAX = 2_147_483_647
13
+
14
+ UEL = "\e%-12345X" # Universal Exit Language
15
+ PREFIX = "@PJL"
16
+
17
+ module Info
18
+ ID = "#{PREFIX} INFO ID"
19
+ STATUS = "#{PREFIX} INFO STATUS"
20
+ VARIABLES = "#{PREFIX} INFO VARIABLES"
21
+ FILESYS = "#{PREFIX} INFO FILESYS"
22
+ end
23
+
24
+ RDYMSG = "#{PREFIX} RDYMSG"
25
+
26
+ FSINIT = "#{PREFIX} FSINIT"
27
+ FSDIRLIST = "#{PREFIX} FSDIRLIST"
28
+ FSUPLOAD = "#{PREFIX} FSUPLOAD"
29
+
30
+ end
@@ -0,0 +1,162 @@
1
+ # https://en.wikipedia.org/wiki/Printer_Job_Language
2
+ # See external links for PJL spec
3
+
4
+ module Rex::Proto::PJL
5
+ class Client
6
+
7
+ attr_reader :sock
8
+
9
+ def initialize(sock)
10
+ @sock = sock
11
+ end
12
+
13
+ # Begin a PJL job
14
+ #
15
+ # @return [void]
16
+ def begin_job
17
+ @sock.put("#{UEL}#{PREFIX}\n")
18
+ end
19
+
20
+ # End a PJL job
21
+ #
22
+ # @return [void]
23
+ def end_job
24
+ @sock.put(UEL)
25
+ end
26
+
27
+ # Send an INFO request and read the response
28
+ #
29
+ # @param category [String] INFO category
30
+ # @return [String] INFO response
31
+ def info(category)
32
+ categories = {
33
+ :id => Info::ID,
34
+ :status => Info::STATUS,
35
+ :variables => Info::VARIABLES,
36
+ :filesys => Info::FILESYS
37
+ }
38
+
39
+ unless categories.has_key?(category)
40
+ raise ArgumentError, "Unknown INFO category"
41
+ end
42
+
43
+ @sock.put("#{categories[category]}\n")
44
+ @sock.get(DEFAULT_TIMEOUT)
45
+ end
46
+
47
+ # Get version information
48
+ #
49
+ # @return [String] Version information
50
+ def info_id
51
+ id = nil
52
+
53
+ if info(:id) =~ /"(.*?)"/m
54
+ id = $1
55
+ end
56
+
57
+ id
58
+ end
59
+
60
+ # Get environment variables
61
+ #
62
+ # @return [String] Environment variables
63
+ def info_variables
64
+ env_vars = nil
65
+
66
+ if info(:variables) =~ /#{Info::VARIABLES}\r?\n(.*?)\f/m
67
+ env_vars = $1
68
+ end
69
+
70
+ env_vars
71
+ end
72
+
73
+ # List volumes
74
+ #
75
+ # @return [String] Volume listing
76
+ def info_filesys
77
+ filesys = nil
78
+
79
+ if info(:filesys) =~ /\[\d+ TABLE\]\r?\n(.*?)\f/m
80
+ filesys = $1
81
+ end
82
+
83
+ filesys
84
+ end
85
+
86
+ # Get the ready message
87
+ #
88
+ # @return [String] Ready message
89
+ def get_rdymsg
90
+ rdymsg = nil
91
+
92
+ if info(:status) =~ /DISPLAY="(.*?)"/m
93
+ rdymsg = $1
94
+ end
95
+
96
+ rdymsg
97
+ end
98
+
99
+ # Set the ready message
100
+ #
101
+ # @param message [String] Ready message
102
+ # @return [void]
103
+ def set_rdymsg(message)
104
+ @sock.put(%Q{#{RDYMSG} DISPLAY = "#{message}"\n})
105
+ end
106
+
107
+ # Initialize a volume
108
+ #
109
+ # @param volume [String] Volume
110
+ # @return [void]
111
+ def fsinit(volume)
112
+ if volume !~ /^[0-2]:$/
113
+ raise ArgumentError, "Volume must be 0:, 1:, or 2:"
114
+ end
115
+
116
+ @sock.put(%Q{#{FSINIT} VOLUME = "#{volume}"\n})
117
+ end
118
+
119
+ # List a directory
120
+ #
121
+ # @param pathname [String] Pathname
122
+ # @param count [Fixnum] Number of entries to list
123
+ # @return [String] Directory listing
124
+ def fsdirlist(pathname, count = COUNT_MAX)
125
+ if pathname !~ /^[0-2]:/
126
+ raise ArgumentError, "Pathname must begin with 0:, 1:, or 2:"
127
+ end
128
+
129
+ listing = nil
130
+
131
+ @sock.put(%Q{#{FSDIRLIST} NAME = "#{pathname}" ENTRY=1 COUNT=#{count}\n})
132
+
133
+ if @sock.get(DEFAULT_TIMEOUT) =~ /ENTRY=1\r?\n(.*?)\f/m
134
+ listing = $1
135
+ end
136
+
137
+ listing
138
+ end
139
+
140
+ # Download a file
141
+ #
142
+ # @param pathname [String] Pathname
143
+ # @param size [Fixnum] Size of file
144
+ # @return [String] File as a string
145
+ def fsupload(pathname, size = SIZE_MAX)
146
+ if pathname !~ /^[0-2]:/
147
+ raise ArgumentError, "Pathname must begin with 0:, 1:, or 2:"
148
+ end
149
+
150
+ file = nil
151
+
152
+ @sock.put(%Q{#{FSUPLOAD} NAME = "#{pathname}" OFFSET=0 SIZE=#{size}\n})
153
+
154
+ if @sock.get(DEFAULT_TIMEOUT) =~ /SIZE=\d+\r?\n(.*)\f/m
155
+ file = $1
156
+ end
157
+
158
+ file
159
+ end
160
+
161
+ end
162
+ end
@@ -1,441 +1,441 @@
1
1
  # -*- coding: binary -*-
2
- #
3
- # sf - Sept 2010
4
- #
5
- require 'thread'
6
- require 'rex/logging'
7
- require 'rex/socket'
8
-
9
- module Rex
10
- module Proto
11
- module Proxy
12
-
13
- #
14
- # A Socks4a proxy server.
15
- #
16
- class Socks4a
17
-
18
- #
19
- # A client connected to the Socks4a server.
20
- #
21
- class Client
22
-
23
- REQUEST_VERSION = 4
24
- REPLY_VERSION = 0
25
-
26
- COMMAND_CONNECT = 1
27
- COMMAND_BIND = 2
28
-
29
- REQUEST_GRANTED = 90
30
- REQUEST_REJECT_FAILED = 91
31
- REQUEST_REJECT_CONNECT = 92
32
- REQUEST_REJECT_USERID = 93
33
-
34
- HOST = 1
35
- PORT = 2
36
-
37
- #
38
- # A Socks4a packet.
39
- #
40
- class Packet
41
-
42
- def initialize
43
- @version = REQUEST_VERSION
44
- @command = 0
45
- @dest_port = 0
46
- @dest_ip = '0.0.0.0'
47
- @userid = ''
48
- end
49
-
50
- #
51
- # A helper function to recv in a Socks4a packet byte by byte.
52
- #
53
- # sf: we could just call raw = sock.get_once but some clients
54
- # seem to need reading this byte by byte instead.
55
- #
56
- def Packet.recv( sock, timeout=30 )
57
- raw = ''
58
- # read in the 8 byte header
59
- while( raw.length < 8 )
60
- raw << sock.read( 1 )
61
- end
62
- # if its a request there will be more data
63
- if( raw[0..0].unpack( 'C' ).first == REQUEST_VERSION )
64
- # read in the userid
65
- while( raw[8..raw.length].index( "\x00" ) == nil )
66
- raw << sock.read( 1 )
67
- end
68
- # if a hostname is going to be present, read it in
69
- ip = raw[4..7].unpack( 'N' ).first
70
- if( ( ip & 0xFFFFFF00 ) == 0x00000000 and ( ip & 0x000000FF ) != 0x00 )
71
- hostname = ''
72
- while( hostname.index( "\x00" ) == nil )
73
- hostname += sock.read( 1 )
74
- end
75
- raw << hostname
76
- end
77
- end
78
- # create a packet from this raw data...
79
- packet = Packet.new
80
- packet.from_r( raw ) ? packet : nil
81
- end
82
-
83
- #
84
- # Pack a packet into raw bytes for transmitting on the wire.
85
- #
86
- def to_r
87
- raw = [ @version, @command, @dest_port, Rex::Socket.addr_atoi( @dest_ip ) ].pack( 'CCnN' )
88
- return raw if( @userid.empty? )
89
- return raw + [ @userid ].pack( 'Z*' )
90
- end
91
-
92
- #
93
- # Unpack a raw packet into its components.
94
- #
95
- def from_r( raw )
96
- return false if( raw.length < 8 )
97
- @version = raw[0..0].unpack( 'C' ).first
98
- return false if( @version != REQUEST_VERSION and @version != REPLY_VERSION )
99
- @command = raw[1..1].unpack( 'C' ).first
100
- @dest_port = raw[2..3].unpack( 'n' ).first
101
- @dest_ip = Rex::Socket.addr_itoa( raw[4..7].unpack( 'N' ).first )
102
- if( raw.length > 8 )
103
- @userid = raw[8..raw.length].unpack( 'Z*' ).first
104
- # if this is a socks4a request we can resolve the provided hostname
105
- if( self.is_hostname? )
106
- hostname = raw[(8+@userid.length+1)..raw.length].unpack( 'Z*' ).first
107
- @dest_ip = self.resolve( hostname )
108
- # fail if we couldnt resolve the hostname
109
- return false if( not @dest_ip )
110
- end
111
- else
112
- @userid = ''
113
- end
114
- return true
115
- end
116
-
117
- def is_connect?
118
- @command == COMMAND_CONNECT ? true : false
119
- end
120
-
121
- def is_bind?
122
- @command == COMMAND_BIND ? true : false
123
- end
124
-
125
- attr_accessor :version, :command, :dest_port, :dest_ip, :userid
126
-
127
- protected
128
-
129
- #
130
- # Resolve the given hostname into a dotted IP address.
131
- #
132
- def resolve( hostname )
133
- if( not hostname.empty? )
134
- begin
135
- return Rex::Socket.addr_itoa( Rex::Socket.gethostbyname( hostname )[3].unpack( 'N' ).first )
136
- rescue ::SocketError
137
- return nil
138
- end
139
- end
140
- return nil
141
- end
142
-
143
- #
144
- # As per the Socks4a spec, check to see if the provided dest_ip is 0.0.0.XX
145
- # which indicates after the @userid field contains a hostname to resolve.
146
- #
147
- def is_hostname?
148
- ip = Rex::Socket.addr_atoi( @dest_ip )
149
- if( ip & 0xFFFFFF00 == 0x00000000 )
150
- return true if( ip & 0x000000FF != 0x00 )
151
- end
152
- return false
153
- end
154
-
155
- end
156
-
157
- #
158
- # A mixin for a socket to perform a relay to another socket.
159
- #
160
- module Relay
161
-
162
- #
163
- # Relay data coming in from relay_sock to this socket.
164
- #
165
- def relay( relay_client, relay_sock )
166
- @relay_client = relay_client
167
- @relay_sock = relay_sock
168
- # start the relay thread (modified from Rex::IO::StreamAbstraction)
169
- @relay_thread = Rex::ThreadFactory.spawn("SOCKS4AProxyServerRelay", false) do
170
- loop do
171
- closed = false
172
- buf = nil
173
-
174
- begin
175
- s = Rex::ThreadSafe.select( [ @relay_sock ], nil, nil, 0.2 )
176
- if( s == nil || s[0] == nil )
177
- next
178
- end
179
- rescue
180
- closed = true
181
- end
182
-
183
- if( closed == false )
184
- begin
185
- buf = @relay_sock.sysread( 32768 )
186
- closed = true if( buf == nil )
187
- rescue
188
- closed = true
189
- end
190
- end
191
-
192
- if( closed == false )
193
- total_sent = 0
194
- total_length = buf.length
195
- while( total_sent < total_length )
196
- begin
197
- data = buf[total_sent, buf.length]
198
- sent = self.write( data )
199
- if( sent > 0 )
200
- total_sent += sent
201
- end
202
- rescue
203
- closed = true
204
- break
205
- end
206
- end
207
- end
208
-
209
- if( closed )
210
- @relay_client.stop
211
- ::Thread.exit
212
- end
213
- end
214
- end
215
-
216
- end
217
-
218
- end
219
-
220
- #
221
- # Create a new client connected to the server.
222
- #
223
- def initialize( server, sock )
224
- @server = server
225
- @lsock = sock
226
- @rsock = nil
227
- @client_thread = nil
228
- @mutex = ::Mutex.new
229
- end
230
-
231
- #
232
- # Start handling the client connection.
233
- #
234
- def start
235
- # create a thread to handle this client request so as to not block the socks4a server
236
- @client_thread = Rex::ThreadFactory.spawn("SOCKS4AProxyClient", false) do
237
- begin
238
- @server.add_client( self )
239
- # get the initial client request packet
240
- request = Packet.recv( @lsock )
241
- raise "Invalid Socks4 request packet received." if not request
242
- # handle the request
243
- begin
244
- # handle socks4a conenct requests
245
- if( request.is_connect? )
246
- # perform the connection request
247
- params = {
248
- 'PeerHost' => request.dest_ip,
249
- 'PeerPort' => request.dest_port,
250
- }
251
- params['Context'] = @server.opts['Context'] if @server.opts.has_key?('Context')
252
-
253
- @rsock = Rex::Socket::Tcp.create( params )
254
- # and send back success to the client
255
- response = Packet.new
256
- response.version = REPLY_VERSION
257
- response.command = REQUEST_GRANTED
258
- @lsock.put( response.to_r )
259
- # handle socks4a bind requests
260
- elsif( request.is_bind? )
261
- # create a server socket for this request
262
- params = {
263
- 'LocalHost' => '0.0.0.0',
264
- 'LocalPort' => 0,
265
- }
266
- params['Context'] = @server.opts['Context'] if @server.opts.has_key?('Context')
267
- bsock = Rex::Socket::TcpServer.create( params )
268
- # send back the bind success to the client
269
- response = Packet.new
270
- response.version = REPLY_VERSION
271
- response.command = REQUEST_GRANTED
272
- response.dest_ip = '0.0.0.0'
273
- response.dest_port = bsock.getlocalname()[PORT]
274
- @lsock.put( response.to_r )
275
- # accept a client connection (2 minute timeout as per spec)
276
- begin
277
- ::Timeout.timeout( 120 ) do
278
- @rsock = bsock.accept
279
- end
280
- rescue ::Timeout::Error
281
- raise "Timeout reached on accept request."
282
- end
283
- # close the listening socket
284
- bsock.close
285
- # verify the connection is from the dest_ip origionally specified by the client
286
- rpeer = @rsock.getpeername
287
- raise "Got connection from an invalid peer." if( rpeer[HOST] != request.dest_ip )
288
- # send back the client connect success to the client
289
- #
290
- # sf: according to the spec we send this response back to the client, however
291
- # I have seen some clients who bawk if they get this second response.
292
- #
293
- response = Packet.new
294
- response.version = REPLY_VERSION
295
- response.command = REQUEST_GRANTED
296
- response.dest_ip = rpeer[HOST]
297
- response.dest_port = rpeer[PORT]
298
- @lsock.put( response.to_r )
299
- else
300
- raise "Unknown request command received #{request.command} received."
301
- end
302
- rescue
303
- # send back failure to the client
304
- response = Packet.new
305
- response.version = REPLY_VERSION
306
- response.command = REQUEST_REJECT_FAILED
307
- @lsock.put( response.to_r )
308
- # raise an exception to close this client connection
309
- raise "Failed to handle the clients request."
310
- end
311
- # setup the two way relay for full duplex io
312
- @lsock.extend( Relay )
313
- @rsock.extend( Relay )
314
- # start the socket relays...
315
- @lsock.relay( self, @rsock )
316
- @rsock.relay( self, @lsock )
317
- rescue
318
- wlog( "Client.start - #{$!}" )
319
- self.stop
320
- end
321
- end
322
- end
323
-
324
- #
325
- # Stop handling the client connection.
326
- #
327
- def stop
328
- @mutex.synchronize do
329
- if( not @closed )
330
-
331
- begin
332
- @lsock.close if @lsock
333
- rescue
334
- end
335
-
336
- begin
337
- @rsock.close if @rsock
338
- rescue
339
- end
340
-
341
- @client_thread.kill if( @client_thread and @client_thread.alive? )
342
-
343
- @server.remove_client( self )
344
-
345
- @closed = true
346
- end
347
- end
348
- end
349
-
350
- end
351
-
352
- #
353
- # Create a new Socks4a server.
354
- #
355
- def initialize( opts={} )
356
- @opts = { 'ServerHost' => '0.0.0.0', 'ServerPort' => 1080 }
357
- @opts = @opts.merge( opts )
358
- @server = nil
359
- @clients = ::Array.new
360
- @running = false
361
- @server_thread = nil
362
- end
363
-
364
- #
365
- # Check if the server is running.
366
- #
367
- def is_running?
368
- return @running
369
- end
370
-
371
- #
372
- # Start the Socks4a server.
373
- #
374
- def start
375
- begin
376
- # create the servers main socket (ignore the context here because we don't want a remote bind)
377
- @server = Rex::Socket::TcpServer.create( 'LocalHost' => @opts['ServerHost'], 'LocalPort' => @opts['ServerPort'] )
378
- # signal we are now running
379
- @running = true
380
- # start the servers main thread to pick up new clients
381
- @server_thread = Rex::ThreadFactory.spawn("SOCKS4AProxyServer", false) do
382
- while( @running ) do
383
- begin
384
- # accept the client connection
385
- sock = @server.accept
386
- # and fire off a new client instance to handle it
387
- Client.new( self, sock ).start
388
- rescue
389
- wlog( "Socks4a.start - server_thread - #{$!}" )
390
- end
391
- end
392
- end
393
- rescue
394
- wlog( "Socks4a.start - #{$!}" )
395
- return false
396
- end
397
- return true
398
- end
399
-
400
- #
401
- # Block while the server is running.
402
- #
403
- def join
404
- @server_thread.join if @server_thread
405
- end
406
-
407
- #
408
- # Stop the Socks4a server.
409
- #
410
- def stop
411
- if( @running )
412
- # signal we are no longer running
413
- @running = false
414
- # stop any clients we have (create a new client array as client.stop will delete from @clients)
415
- clients = []
416
- clients.concat( @clients )
417
- clients.each do | client |
418
- client.stop
419
- end
420
- # close the server socket
421
- @server.close if @server
422
- # if the server thread did not terminate gracefully, kill it.
423
- @server_thread.kill if( @server_thread and @server_thread.alive? )
424
- end
425
- return !@running
426
- end
427
-
428
- def add_client( client )
429
- @clients << client
430
- end
431
-
432
- def remove_client( client )
433
- @clients.delete( client )
434
- end
435
-
436
- attr_reader :opts
437
-
438
- end
439
-
440
- end; end; end
441
-
2
+ #
3
+ # sf - Sept 2010
4
+ #
5
+ require 'thread'
6
+ require 'rex/logging'
7
+ require 'rex/socket'
8
+
9
+ module Rex
10
+ module Proto
11
+ module Proxy
12
+
13
+ #
14
+ # A Socks4a proxy server.
15
+ #
16
+ class Socks4a
17
+
18
+ #
19
+ # A client connected to the Socks4a server.
20
+ #
21
+ class Client
22
+
23
+ REQUEST_VERSION = 4
24
+ REPLY_VERSION = 0
25
+
26
+ COMMAND_CONNECT = 1
27
+ COMMAND_BIND = 2
28
+
29
+ REQUEST_GRANTED = 90
30
+ REQUEST_REJECT_FAILED = 91
31
+ REQUEST_REJECT_CONNECT = 92
32
+ REQUEST_REJECT_USERID = 93
33
+
34
+ HOST = 1
35
+ PORT = 2
36
+
37
+ #
38
+ # A Socks4a packet.
39
+ #
40
+ class Packet
41
+
42
+ def initialize
43
+ @version = REQUEST_VERSION
44
+ @command = 0
45
+ @dest_port = 0
46
+ @dest_ip = '0.0.0.0'
47
+ @userid = ''
48
+ end
49
+
50
+ #
51
+ # A helper function to recv in a Socks4a packet byte by byte.
52
+ #
53
+ # sf: we could just call raw = sock.get_once but some clients
54
+ # seem to need reading this byte by byte instead.
55
+ #
56
+ def Packet.recv( sock, timeout=30 )
57
+ raw = ''
58
+ # read in the 8 byte header
59
+ while( raw.length < 8 )
60
+ raw << sock.read( 1 )
61
+ end
62
+ # if its a request there will be more data
63
+ if( raw[0..0].unpack( 'C' ).first == REQUEST_VERSION )
64
+ # read in the userid
65
+ while( raw[8..raw.length].index( "\x00" ) == nil )
66
+ raw << sock.read( 1 )
67
+ end
68
+ # if a hostname is going to be present, read it in
69
+ ip = raw[4..7].unpack( 'N' ).first
70
+ if( ( ip & 0xFFFFFF00 ) == 0x00000000 and ( ip & 0x000000FF ) != 0x00 )
71
+ hostname = ''
72
+ while( hostname.index( "\x00" ) == nil )
73
+ hostname += sock.read( 1 )
74
+ end
75
+ raw << hostname
76
+ end
77
+ end
78
+ # create a packet from this raw data...
79
+ packet = Packet.new
80
+ packet.from_r( raw ) ? packet : nil
81
+ end
82
+
83
+ #
84
+ # Pack a packet into raw bytes for transmitting on the wire.
85
+ #
86
+ def to_r
87
+ raw = [ @version, @command, @dest_port, Rex::Socket.addr_atoi( @dest_ip ) ].pack( 'CCnN' )
88
+ return raw if( @userid.empty? )
89
+ return raw + [ @userid ].pack( 'Z*' )
90
+ end
91
+
92
+ #
93
+ # Unpack a raw packet into its components.
94
+ #
95
+ def from_r( raw )
96
+ return false if( raw.length < 8 )
97
+ @version = raw[0..0].unpack( 'C' ).first
98
+ return false if( @version != REQUEST_VERSION and @version != REPLY_VERSION )
99
+ @command = raw[1..1].unpack( 'C' ).first
100
+ @dest_port = raw[2..3].unpack( 'n' ).first
101
+ @dest_ip = Rex::Socket.addr_itoa( raw[4..7].unpack( 'N' ).first )
102
+ if( raw.length > 8 )
103
+ @userid = raw[8..raw.length].unpack( 'Z*' ).first
104
+ # if this is a socks4a request we can resolve the provided hostname
105
+ if( self.is_hostname? )
106
+ hostname = raw[(8+@userid.length+1)..raw.length].unpack( 'Z*' ).first
107
+ @dest_ip = self.resolve( hostname )
108
+ # fail if we couldnt resolve the hostname
109
+ return false if( not @dest_ip )
110
+ end
111
+ else
112
+ @userid = ''
113
+ end
114
+ return true
115
+ end
116
+
117
+ def is_connect?
118
+ @command == COMMAND_CONNECT ? true : false
119
+ end
120
+
121
+ def is_bind?
122
+ @command == COMMAND_BIND ? true : false
123
+ end
124
+
125
+ attr_accessor :version, :command, :dest_port, :dest_ip, :userid
126
+
127
+ protected
128
+
129
+ #
130
+ # Resolve the given hostname into a dotted IP address.
131
+ #
132
+ def resolve( hostname )
133
+ if( not hostname.empty? )
134
+ begin
135
+ return Rex::Socket.addr_itoa( Rex::Socket.gethostbyname( hostname )[3].unpack( 'N' ).first )
136
+ rescue ::SocketError
137
+ return nil
138
+ end
139
+ end
140
+ return nil
141
+ end
142
+
143
+ #
144
+ # As per the Socks4a spec, check to see if the provided dest_ip is 0.0.0.XX
145
+ # which indicates after the @userid field contains a hostname to resolve.
146
+ #
147
+ def is_hostname?
148
+ ip = Rex::Socket.addr_atoi( @dest_ip )
149
+ if( ip & 0xFFFFFF00 == 0x00000000 )
150
+ return true if( ip & 0x000000FF != 0x00 )
151
+ end
152
+ return false
153
+ end
154
+
155
+ end
156
+
157
+ #
158
+ # A mixin for a socket to perform a relay to another socket.
159
+ #
160
+ module Relay
161
+
162
+ #
163
+ # Relay data coming in from relay_sock to this socket.
164
+ #
165
+ def relay( relay_client, relay_sock )
166
+ @relay_client = relay_client
167
+ @relay_sock = relay_sock
168
+ # start the relay thread (modified from Rex::IO::StreamAbstraction)
169
+ @relay_thread = Rex::ThreadFactory.spawn("SOCKS4AProxyServerRelay", false) do
170
+ loop do
171
+ closed = false
172
+ buf = nil
173
+
174
+ begin
175
+ s = Rex::ThreadSafe.select( [ @relay_sock ], nil, nil, 0.2 )
176
+ if( s == nil || s[0] == nil )
177
+ next
178
+ end
179
+ rescue
180
+ closed = true
181
+ end
182
+
183
+ if( closed == false )
184
+ begin
185
+ buf = @relay_sock.sysread( 32768 )
186
+ closed = true if( buf == nil )
187
+ rescue
188
+ closed = true
189
+ end
190
+ end
191
+
192
+ if( closed == false )
193
+ total_sent = 0
194
+ total_length = buf.length
195
+ while( total_sent < total_length )
196
+ begin
197
+ data = buf[total_sent, buf.length]
198
+ sent = self.write( data )
199
+ if( sent > 0 )
200
+ total_sent += sent
201
+ end
202
+ rescue
203
+ closed = true
204
+ break
205
+ end
206
+ end
207
+ end
208
+
209
+ if( closed )
210
+ @relay_client.stop
211
+ ::Thread.exit
212
+ end
213
+ end
214
+ end
215
+
216
+ end
217
+
218
+ end
219
+
220
+ #
221
+ # Create a new client connected to the server.
222
+ #
223
+ def initialize( server, sock )
224
+ @server = server
225
+ @lsock = sock
226
+ @rsock = nil
227
+ @client_thread = nil
228
+ @mutex = ::Mutex.new
229
+ end
230
+
231
+ #
232
+ # Start handling the client connection.
233
+ #
234
+ def start
235
+ # create a thread to handle this client request so as to not block the socks4a server
236
+ @client_thread = Rex::ThreadFactory.spawn("SOCKS4AProxyClient", false) do
237
+ begin
238
+ @server.add_client( self )
239
+ # get the initial client request packet
240
+ request = Packet.recv( @lsock )
241
+ raise "Invalid Socks4 request packet received." if not request
242
+ # handle the request
243
+ begin
244
+ # handle socks4a conenct requests
245
+ if( request.is_connect? )
246
+ # perform the connection request
247
+ params = {
248
+ 'PeerHost' => request.dest_ip,
249
+ 'PeerPort' => request.dest_port,
250
+ }
251
+ params['Context'] = @server.opts['Context'] if @server.opts.has_key?('Context')
252
+
253
+ @rsock = Rex::Socket::Tcp.create( params )
254
+ # and send back success to the client
255
+ response = Packet.new
256
+ response.version = REPLY_VERSION
257
+ response.command = REQUEST_GRANTED
258
+ @lsock.put( response.to_r )
259
+ # handle socks4a bind requests
260
+ elsif( request.is_bind? )
261
+ # create a server socket for this request
262
+ params = {
263
+ 'LocalHost' => '0.0.0.0',
264
+ 'LocalPort' => 0,
265
+ }
266
+ params['Context'] = @server.opts['Context'] if @server.opts.has_key?('Context')
267
+ bsock = Rex::Socket::TcpServer.create( params )
268
+ # send back the bind success to the client
269
+ response = Packet.new
270
+ response.version = REPLY_VERSION
271
+ response.command = REQUEST_GRANTED
272
+ response.dest_ip = '0.0.0.0'
273
+ response.dest_port = bsock.getlocalname()[PORT]
274
+ @lsock.put( response.to_r )
275
+ # accept a client connection (2 minute timeout as per spec)
276
+ begin
277
+ ::Timeout.timeout( 120 ) do
278
+ @rsock = bsock.accept
279
+ end
280
+ rescue ::Timeout::Error
281
+ raise "Timeout reached on accept request."
282
+ end
283
+ # close the listening socket
284
+ bsock.close
285
+ # verify the connection is from the dest_ip origionally specified by the client
286
+ rpeer = @rsock.getpeername
287
+ raise "Got connection from an invalid peer." if( rpeer[HOST] != request.dest_ip )
288
+ # send back the client connect success to the client
289
+ #
290
+ # sf: according to the spec we send this response back to the client, however
291
+ # I have seen some clients who bawk if they get this second response.
292
+ #
293
+ response = Packet.new
294
+ response.version = REPLY_VERSION
295
+ response.command = REQUEST_GRANTED
296
+ response.dest_ip = rpeer[HOST]
297
+ response.dest_port = rpeer[PORT]
298
+ @lsock.put( response.to_r )
299
+ else
300
+ raise "Unknown request command received #{request.command} received."
301
+ end
302
+ rescue
303
+ # send back failure to the client
304
+ response = Packet.new
305
+ response.version = REPLY_VERSION
306
+ response.command = REQUEST_REJECT_FAILED
307
+ @lsock.put( response.to_r )
308
+ # raise an exception to close this client connection
309
+ raise "Failed to handle the clients request."
310
+ end
311
+ # setup the two way relay for full duplex io
312
+ @lsock.extend( Relay )
313
+ @rsock.extend( Relay )
314
+ # start the socket relays...
315
+ @lsock.relay( self, @rsock )
316
+ @rsock.relay( self, @lsock )
317
+ rescue
318
+ wlog( "Client.start - #{$!}" )
319
+ self.stop
320
+ end
321
+ end
322
+ end
323
+
324
+ #
325
+ # Stop handling the client connection.
326
+ #
327
+ def stop
328
+ @mutex.synchronize do
329
+ if( not @closed )
330
+
331
+ begin
332
+ @lsock.close if @lsock
333
+ rescue
334
+ end
335
+
336
+ begin
337
+ @rsock.close if @rsock
338
+ rescue
339
+ end
340
+
341
+ @client_thread.kill if( @client_thread and @client_thread.alive? )
342
+
343
+ @server.remove_client( self )
344
+
345
+ @closed = true
346
+ end
347
+ end
348
+ end
349
+
350
+ end
351
+
352
+ #
353
+ # Create a new Socks4a server.
354
+ #
355
+ def initialize( opts={} )
356
+ @opts = { 'ServerHost' => '0.0.0.0', 'ServerPort' => 1080 }
357
+ @opts = @opts.merge( opts )
358
+ @server = nil
359
+ @clients = ::Array.new
360
+ @running = false
361
+ @server_thread = nil
362
+ end
363
+
364
+ #
365
+ # Check if the server is running.
366
+ #
367
+ def is_running?
368
+ return @running
369
+ end
370
+
371
+ #
372
+ # Start the Socks4a server.
373
+ #
374
+ def start
375
+ begin
376
+ # create the servers main socket (ignore the context here because we don't want a remote bind)
377
+ @server = Rex::Socket::TcpServer.create( 'LocalHost' => @opts['ServerHost'], 'LocalPort' => @opts['ServerPort'] )
378
+ # signal we are now running
379
+ @running = true
380
+ # start the servers main thread to pick up new clients
381
+ @server_thread = Rex::ThreadFactory.spawn("SOCKS4AProxyServer", false) do
382
+ while( @running ) do
383
+ begin
384
+ # accept the client connection
385
+ sock = @server.accept
386
+ # and fire off a new client instance to handle it
387
+ Client.new( self, sock ).start
388
+ rescue
389
+ wlog( "Socks4a.start - server_thread - #{$!}" )
390
+ end
391
+ end
392
+ end
393
+ rescue
394
+ wlog( "Socks4a.start - #{$!}" )
395
+ return false
396
+ end
397
+ return true
398
+ end
399
+
400
+ #
401
+ # Block while the server is running.
402
+ #
403
+ def join
404
+ @server_thread.join if @server_thread
405
+ end
406
+
407
+ #
408
+ # Stop the Socks4a server.
409
+ #
410
+ def stop
411
+ if( @running )
412
+ # signal we are no longer running
413
+ @running = false
414
+ # stop any clients we have (create a new client array as client.stop will delete from @clients)
415
+ clients = []
416
+ clients.concat( @clients )
417
+ clients.each do | client |
418
+ client.stop
419
+ end
420
+ # close the server socket
421
+ @server.close if @server
422
+ # if the server thread did not terminate gracefully, kill it.
423
+ @server_thread.kill if( @server_thread and @server_thread.alive? )
424
+ end
425
+ return !@running
426
+ end
427
+
428
+ def add_client( client )
429
+ @clients << client
430
+ end
431
+
432
+ def remove_client( client )
433
+ @clients.delete( client )
434
+ end
435
+
436
+ attr_reader :opts
437
+
438
+ end
439
+
440
+ end; end; end
441
+