-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
282 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Trojan-Killer | ||
|
||
这个 POC 是为了 **狠 狠 打 脸** 某些认为 TLS in TLS 检测不存在或成本很高的人。 | ||
|
||
该程序在 `127.0.0.1:12345` 接收 TLS 流量,并用 **非 常 廉 价** 的方式检测出其中的 Trojan 代理。 | ||
|
||
1. 设置浏览器的 HTTP 代理至 `127.0.0.1:12345`,观察该程序的输出。 | ||
2. 设置 Trojan 链式 HTTP 代理至 `127.0.0.1:12345`,观察该程序的输出。 | ||
|
||
我们的测试结果如下: | ||
|
||
1. 对于浏览器的 HTTPS 流量,**几乎没有阳性结果**。 | ||
2. 对于 Trojan 的 TLS in TLS 流量,**Trojan 字样直接刷屏**。 | ||
|
||
这与我们多次收到的 Trojan 被封、XTLS Vision 存活的反馈相符(它们均可选 Golang 指纹)。 | ||
|
||
值得一提的是,根据我们的观察,目前 REALITY 的“白名单域名”会被豁免于这样的检测。 | ||
|
||
## License | ||
|
||
[GNU AFFERO GENERAL PUBLIC LICENSE](https://github.com/XTLS/Trojan-killer/blob/main/LICENSE) | ||
|
||
## Compilation | ||
|
||
```bash | ||
go build -trimpath -ldflags "-s -w -buildid=" . | ||
``` | ||
|
||
## Stargazers over time | ||
|
||
[![Stargazers over time](https://starchart.cc/XTLS/Trojan-killer.svg)](https://starchart.cc/XTLS/Trojan-killer) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
-----BEGIN CERTIFICATE----- | ||
MIIDVTCCAj2gAwIBAgIQAOACeeTO8xa8MX71sctjcTANBgkqhkiG9w0BAQsFADAW | ||
MRQwEgYDVQQDDAtleGFtcGxlLmNvbTAeFw0yMzA1MTMwMzEwMTJaFw0zMzA1MTAw | ||
MzEwMTJaMBYxFDASBgNVBAMMC2V4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEF | ||
AAOCAQ8AMIIBCgKCAQEAkiCjDSVLws/LaMVCgPPBDHrpzDqmfXiq3+CzIE7Vpipl | ||
byAx16L0tRCQxYDuq/eKOQ1IrVPS9+v+XaT+17og/iWYK2lN/T7oXw8uDH+xqyTU | ||
/OM2oKsHxbgqlY3eN64UA0XLl5POZitnMb9RbRyAsmEUeZKrd4GvJrYnj3qFheod | ||
FO/r37QLEMUjwwlhCzhQ3XHdE+2cCIrtFUBKbqsbDWm4Gdrt+BIFHG6Gn/+PSRSh | ||
/bt39uK8I9SMMwlXB3qWo1AcuasoTXYn6cunjJqmYnvtGf4XSTTMcRAQAWlZBAQn | ||
ABcCpsnWE1emHmtyD557EVltoytUuI9MVCcTkCJ1pwIDAQABo4GeMIGbMB0GA1Ud | ||
DgQWBBTUF0I2kmmFXQJQvOvtaJpip59CEzAOBgNVHQ8BAf8EBAMCBLAwDAYDVR0T | ||
AQH/BAIwADA7BgNVHSUENDAyBggrBgEFBQcDAgYIKwYBBQUHAwEGCCsGAQUFBwMD | ||
BggrBgEFBQcDBAYIKwYBBQUHAwgwHwYDVR0jBBgwFoAU1BdCNpJphV0CULzr7Wia | ||
YqefQhMwDQYJKoZIhvcNAQELBQADggEBAHsNfIoIofaz6zsFfoh+yUzy7qIEYP5j | ||
gaF9t6YY4gsJDcYkOhnQErG4cocOWHSC18MPxsxYXsgLQFixNqCzg7L9nhFGhpxr | ||
vvqRD+j5HrjYKLUCJ+IxjJfJckD6WkINVUTO18HL0hbpIQclpHIJzSi8iMX7+uVY | ||
/yXRnLeK8mJnyA5iblPQPqFnECdXKfdVX4w9JPRk/8pB6VokzsM/hclbbSJzGvzq | ||
duuXweojyHx/MWka5BYb57xDb/8krS+G55U35JnXylhp88PScZl9V64j1vQcx/3I | ||
lm160qduqHAVllOMBzNNgcFyPItzYNYmXYXn0OuUDfTZORnhBiKxAnM= | ||
-----END CERTIFICATE----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
-----BEGIN PRIVATE KEY----- | ||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCSIKMNJUvCz8to | ||
xUKA88EMeunMOqZ9eKrf4LMgTtWmKmVvIDHXovS1EJDFgO6r94o5DUitU9L36/5d | ||
pP7XuiD+JZgraU39PuhfDy4Mf7GrJNT84zagqwfFuCqVjd43rhQDRcuXk85mK2cx | ||
v1FtHICyYRR5kqt3ga8mtiePeoWF6h0U7+vftAsQxSPDCWELOFDdcd0T7ZwIiu0V | ||
QEpuqxsNabgZ2u34EgUcboaf/49JFKH9u3f24rwj1IwzCVcHepajUBy5qyhNdifp | ||
y6eMmqZie+0Z/hdJNMxxEBABaVkEBCcAFwKmydYTV6Yea3IPnnsRWW2jK1S4j0xU | ||
JxOQInWnAgMBAAECggEABQ3RQIh5sP3e2yYiFrOs3vGhWcmYLd7D34ULV6K3tkzh | ||
FTwtJ811s+LOybCb5fa5y8oEfs+CDHEXwHAPIFxKUn/vs2YA/IageCkzk9sWxK88 | ||
GUMChgFkU2z7NruhY+ucEEDpubmy+cr71rdMlFQtX1NcPJgwtgFrkrsvbcGfEfKT | ||
xmSyEE+kK2nzvMzt1GbivABcOkV9mz0EJnaZdHmf8a6n0cAMr7jeCPlyaojDkfR3 | ||
sGvTjvVlf5lchJmcAz1UQEmMxMhjkRka2eMt0ZHnCKuRvC6ILR0Nn+bX0AjH9MnY | ||
8WHJbN89G7KZjUUO/zHIHKRsEjvKB6+45ocjxA+TgQKBgQD6Nq1Qzv6Feh44Ij70 | ||
To4DzIVrtFQswQM+zd2UIDuOpmONj+00BQCrl5Wd9z+rWaJO0yORFEo2McwGocGm | ||
BaZvTC4w4L/FgKKu58yXViT5TZNtzJgGJvbS6oNSFWbxn5n8Vnc6tNqeJv317ngw | ||
WxNII93tkMWkzVARlXA5KoqZxQKBgQCVgb7wouNlnrHbzn6IS34gKnmrNAkvWQDS | ||
oSB2aTGb/cU+XuAMf2QgFl/BDn0+SEoVLJsRCVb3OdeRPhDO4NlUyTm+2/N6bNNT | ||
7SLvwG4UGDpyYT8GLk0GhNcqK8qv8vf5zvaBBNVlEbqtMLWizltj5XDg5r4NflMK | ||
dASZSE2EewKBgHax01vfJcxJ1uYIENcyIJpavfwOylOEqDZ10CQBel88PUOdQAgK | ||
S3wa54XNEW4GkkFUVa3v8xhsXP3UZBmO2po3iD31j+NwFzxjh6FO4zFEhKh0grWA | ||
bFw3lV4t+uyqKpESr3Kw8nhNxPGSU3+U5Lu3EAMvRyLbpp0AyADGVoOFAoGASlk2 | ||
aham/O8ZRdT/qanZNAfLb6817hzVwukr6pbPe+KMR0MJKk3jre1SewBImkN6y+Ld | ||
znAVlmZmZC04UJkSmw5isB5Ti4s44KCp4g6Q719JGX5wyBMYbOh809TpO+yZEtqw | ||
TWLo+BUD/4KcoTT7z8bXBpDY7H7orucZLlz9Z6cCgYAh6Q/qJVAzz0rbL+La3dV3 | ||
E95VophRXw9XgWVO41nJGvSTnuuH7e7+CgKxqvuNK8vCDyt5EDXxEk28DjCI7s1+ | ||
7AGX9/oKRncOLZo8DFsnI8fMiFTna45hDar3bS6jZ9OV6Yhz4cZqr20fSYOAqwdu | ||
DNqkspXj0DChZLLxGoUPhQ== | ||
-----END PRIVATE KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
{ | ||
"log": { | ||
"loglevel": "warning" | ||
}, | ||
"inbounds": [ | ||
{ | ||
"listen": "127.0.0.1", | ||
"port": 11111, | ||
"protocol": "http" | ||
} | ||
], | ||
"outbounds": [ | ||
{ | ||
"protocol": "trojan", | ||
"settings": { | ||
"servers": [ | ||
{ | ||
"address": "127.0.0.1", | ||
"port": 22222, | ||
"password": "password" | ||
} | ||
] | ||
}, | ||
"streamSettings": { | ||
"network": "tcp", | ||
"security": "tls", | ||
"tlsSettings": { | ||
"serverName": "example.com", | ||
"allowInsecure": true | ||
}, | ||
"sockopt": { | ||
"dialerProxy": "http" | ||
} | ||
} | ||
}, | ||
{ | ||
"tag": "http", | ||
"protocol": "http", | ||
"settings": { | ||
"servers": [ | ||
{ | ||
"address": "127.0.0.1", | ||
"port": 12345 | ||
} | ||
] | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
{ | ||
"log": { | ||
"loglevel": "warning" | ||
}, | ||
"inbounds": [ | ||
{ | ||
"listen": "127.0.0.1", | ||
"port": 22222, | ||
"protocol": "trojan", | ||
"settings": { | ||
"clients": [ | ||
{ | ||
"password": "password" | ||
} | ||
] | ||
}, | ||
"streamSettings": { | ||
"network": "tcp", | ||
"security": "tls", | ||
"tlsSettings": { | ||
"certificates": [ | ||
{ | ||
"certificateFile": "example.com.cer", | ||
"keyFile": "example.com.key" | ||
} | ||
] | ||
} | ||
} | ||
} | ||
], | ||
"outbounds": [ | ||
{ | ||
"protocol": "freedom" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module github.com/xtls/trojan-killer | ||
|
||
go 1.20 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"bytes" | ||
"fmt" | ||
"io" | ||
"net" | ||
"net/http" | ||
"strings" | ||
"sync" | ||
"time" | ||
) | ||
|
||
func main() { | ||
fmt.Printf("Trojan-killer v1.0.0 started\n") | ||
l, _ := net.Listen("tcp4", "127.0.0.1:12345") | ||
fmt.Printf("Listening on %v\n\n", l.Addr()) | ||
for { | ||
c, _ := l.Accept() | ||
go Handle(c) | ||
} | ||
} | ||
|
||
var CCS = []byte{20, 3, 3, 0, 1, 1} | ||
|
||
func Handle(c net.Conn) { | ||
req, err := http.ReadRequest(bufio.NewReader(c)) | ||
if err != nil { | ||
return | ||
} | ||
state := "accepted" | ||
if !strings.EqualFold(req.Method, "CONNECT") { | ||
state = "rejected" | ||
} | ||
fmt.Printf("%v from %v %v %v\n", time.Now().Format(time.DateTime), c.RemoteAddr(), state, req.URL.Host) | ||
if state == "rejected" { | ||
return | ||
} | ||
|
||
conn, err := net.Dial("tcp", req.URL.Host) | ||
if err != nil { | ||
return | ||
} | ||
c.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n")) | ||
|
||
var mutex sync.Mutex | ||
|
||
uploading := false | ||
upCount := 0 | ||
|
||
downloading := false | ||
downCount := 0 | ||
|
||
go func() { | ||
buf := make([]byte, 8192) | ||
for { | ||
n, err := c.Read(buf) | ||
if err != nil { | ||
return | ||
} | ||
mutex.Lock() | ||
if upCount == 0 && n >= 6 && bytes.Equal(buf[:6], CCS) { | ||
uploading = true | ||
} | ||
if uploading { | ||
upCount += n | ||
} | ||
if downloading { | ||
downloading = false | ||
//fmt.Printf("%v\tupCount %v\tdownCount %v\n", req.URL.Host, upCount, downCount) | ||
if upCount >= 650 && upCount <= 750 && | ||
((downCount >= 170 && downCount <= 180) || (downCount >= 3000 && downCount <= 7500)) { | ||
fmt.Printf("%v is Trojan\n", req.URL.Host) | ||
} | ||
} | ||
mutex.Unlock() | ||
_, err = conn.Write(buf[:n]) | ||
if err != nil { | ||
return | ||
} | ||
if !downloading && downCount != 0 { | ||
go io.CopyBuffer(conn, c, buf) | ||
return | ||
} | ||
} | ||
}() | ||
|
||
go func() { | ||
buf := make([]byte, 8192) | ||
for { | ||
n, err := conn.Read(buf) | ||
if err != nil { | ||
return | ||
} | ||
mutex.Lock() | ||
if uploading { | ||
uploading = false | ||
downloading = true | ||
} | ||
if downloading { | ||
downCount += n | ||
} | ||
mutex.Unlock() | ||
_, err = c.Write(buf[:n]) | ||
if err != nil { | ||
return | ||
} | ||
if !downloading && downCount != 0 { | ||
go io.CopyBuffer(c, conn, buf) | ||
return | ||
} | ||
} | ||
}() | ||
} |