macronut / phantomsocks

A cross-platform proxy client/server for Linux/Windows/macOS

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

一点疑问,伪造的 SNI 域名后缀也是随机字符,这会不会显得比较奇怪?~

opened this issue · comments

我在用 Wireshark 观察数据包的时候,发现:

伪造的域名是完全按照真实域名长度及格式(点的位置)生成的随机字符。
域名前缀及子域名随机倒是没什么,但是我发现域名后缀也是随机的,随机到的域名后缀都是不存在的:

.com 变成了:.nc1 .6xi .dy-

我感觉这会显得比较奇怪,这可能会成为特征?(机器虽然不知道,但是如果以后使用该原理工具的人多了,总会被注意到的),因此用同样长度的真实域名后缀会不会更好些?(内置一些 2 个 3 个 4 个字符的后缀随机选个)
还是说这样做是有什么深层的意义我没想到么。。。

这只是我粗浅的理解,有什么错误的地方希望指正~

昨天晚上突然想到一个作者之所以没有这么做的可能原因。
那就是对于一些较短的域名,可能会出现随机到真实的域名,例如:
访问 a.com ,因为域名前面就一个字符,因此如果按照我前面说的(使用真实域名后缀)会导致随机生成的域名如下:

b.org
c.net
1.xyz

而这些短域名都是真实存在的,甚至正在用,如果碰巧某个域名被墙了或被当地运营商屏蔽了,那么就会导致错误。
虽然总体概率不是很高,但能避免还是避免的好~

当然这个问题也可以通过添加足够数量的域名后缀来缓解(域名列表)。


虽然上面说的方式有些缺陷,但是我同时又想到了优化方案,于是早上起来后就立即开始折腾了~

以下代码修改都在 phantomtcp/tcp.go 文件中,共有 3 处,代码都一样

首先对连词符 - 特殊处理,从随机范围中移除(常量 domainBytes),只有域名中存在 - 时才会在相同位置保留连词符。

其实更好的做法是将 - 限定在中间范围内,因为按照域名规则,连词符不能在域名首尾出现,但是我嫌麻烦懒得搞。
或者也可以直接舍弃,把 - 也随机成任意一个字母/数字也行。

然后新添加一个随机范围常量 domainBytesSuffix,只包含 26 个字母,用作域名后缀的随机(毕竟没有存在数字的域名后缀)。

const domainBytes = "abcdefghijklmnopqrstuvwxyz0123456789"
const domainBytesSuffix = "abcdefghijklmnopqrstuvwxyz"

接着就是写相关代码了,我不懂 Go 语言,但我会一点其他语言,基本逻辑我是明白的,因此今天早上临时抱佛脚,边搜边写,虽然最终实现了我的要求,但代码可能并不够好,因此欢迎指正

min_dot := offset + length
max_dot := offset
// 新增变量,用来存储域名最后一个 '.' 的位置
index_dot := bytes.LastIndex(fakepayload[max_dot:min_dot], []byte("."))
// 这个循环是将域名拆分成一个个字符处理(当然这个是原本就有的,我只是解释下)
for i := offset; i < offset+length; i++ {
	if fakepayload[i] == '.' {
	    // 如果当前循环到 '.' 且还是最后一个 '.' 那么说明后续的字符就是域名后缀了
	    if i-offset == index_dot {
		index_dot = 0
	    }
	if i < min_dot {
		min_dot = i
	}
	if i > max_dot {
		max_dot = i
	}
	// 如果当前循环到的字符是连词符 - 那么不随机,保留下来(也可以直接舍弃这段,这样的话 ` - ` 就会被随机成任意一个字母/数字)
	} else if fakepayload[i] == '-' {
		continue
	// 如果域名变量等于 0 那么说明已经循环到域名的后缀范围了,此时改用另一个随机范围常量(即只有 26 个字母)
	} else if index_dot == 0 {
		fakepayload[i] = domainBytesSuffix[rand.Intn(len(domainBytesSuffix))]
	} else {
		fakepayload[i] = domainBytes[rand.Intn(len(domainBytes))]
	}
}

修改后,域名的后缀就会只局限于 26 个字母了。

# 以前
abc.com -> r1u.dy-
a-b.com -> tkc.l1k
# 现在
abc.com -> r1u.dyg
a-b.com -> t-c.lkj

虽然依然有随机到真实域名后缀的可能,但毕竟很短且被墙的域名很少(1~2 个长度的域名,超过 3 个的话概率就太低了,主要是随机出来的太难看,可能都没人注册),因此正巧碰到真实域名且被墙的概率相比我一开始说的方案要明显低很多。

There is no need to do this at the moment, but if we need to in the future we can add a specified domain name and fill in the excess with random characters.