Skip to content

Commit

Permalink
v1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
RPRX committed May 13, 2023
1 parent 5517925 commit 02c3683
Show file tree
Hide file tree
Showing 7 changed files with 282 additions and 0 deletions.
31 changes: 31 additions & 0 deletions README.md
@@ -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)
20 changes: 20 additions & 0 deletions example/example.com.cer
@@ -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-----
28 changes: 28 additions & 0 deletions example/example.com.key
@@ -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-----
49 changes: 49 additions & 0 deletions example/trojanClient.json
@@ -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
}
]
}
}
]
}
36 changes: 36 additions & 0 deletions example/trojanServer.json
@@ -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"
}
]
}
3 changes: 3 additions & 0 deletions go.mod
@@ -0,0 +1,3 @@
module github.com/xtls/trojan-killer

go 1.20
115 changes: 115 additions & 0 deletions main.go
@@ -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
}
}
}()
}

0 comments on commit 02c3683

Please sign in to comment.