works on linux tun!

This commit is contained in:
lyc8503
2023-01-18 13:47:19 +08:00
parent 6f5b390b61
commit b856ef3cd3
4 changed files with 56 additions and 54 deletions

View File

@@ -4,6 +4,7 @@ Still working in progress.
Complete:
- [x] Protocol reverse engineering
- [x] Web login reverse engineering
- [x] **now Works on Linux TUN**
To-do:
- [x] Get Session ID & IP

1
go.mod
View File

@@ -7,6 +7,7 @@ require github.com/refraction-networking/utls v1.2.0
require (
github.com/andybalholm/brotli v1.0.4 // indirect
github.com/klauspost/compress v1.15.12 // indirect
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8
golang.org/x/crypto v0.1.0 // indirect
golang.org/x/sys v0.1.0 // indirect
)

2
go.sum
View File

@@ -4,6 +4,8 @@ github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kE
github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
github.com/refraction-networking/utls v1.2.0 h1:U5f8wkij2NVinfLuJdFP3gCMwIHs+EzvhxmYdXgiapo=
github.com/refraction-networking/utls v1.2.0/go.mod h1:NPq+cVqzH7D1BeOkmOcb5O/8iVewAsiVt2x1/eO0hgQ=
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 h1:TG/diQgUe0pntT/2D9tmUCz4VNwm9MfrtPr0SU2qSX8=
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E=
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=

View File

@@ -2,16 +2,13 @@ package main
import (
"crypto/rand"
"encoding/binary"
"encoding/hex"
"io"
"log"
"net"
"os"
"strings"
"time"
tls "github.com/refraction-networking/utls"
"github.com/songgao/water"
)
func dumpHex(buf []byte) {
@@ -46,7 +43,7 @@ func tlsConn(server string) (*tls.UConn, error) {
return conn, nil
}
func recvListen(conn *tls.UConn, token *[48]byte, ip *[4]byte) {
func recvListen(conn *tls.UConn, token *[48]byte, ip *[4]byte, targetDev *water.Interface) {
// RECV STREAM START
message := []byte{0x06, 0x00, 0x00, 0x00}
message = append(message, token[:]...)
@@ -72,23 +69,31 @@ func recvListen(conn *tls.UConn, token *[48]byte, ip *[4]byte) {
for true {
n, err = conn.Read(reply)
if err != nil {
log.Fatal(err)
continue
}
log.Printf("recv: read %d bytes", n)
dumpHex(reply[:n])
if strings.Contains(string(reply[:n]), "abcdefghijklmnopqrstuvwabcdefghi") {
panic(">>> PING REPLY RECEIVED TEST PASSED <<<")
n, err = targetDev.Write(reply[:n])
if err != nil {
log.Fatal(err)
}
time.Sleep(time.Second)
// if strings.Contains(string(reply[:n]), "abcdefghijklmnopqrstuvwabcdefghi") {
// panic(">>> PING REPLY RECEIVED TEST PASSED <<<")
// }
// time.Sleep(time.Second)
}
}
func send() {
}
func AskIp(conn *tls.UConn, token *[48]byte) []byte {
// ASK IP PACKET
func QueryIp(conn *tls.UConn, token *[48]byte) []byte {
// QUERY IP PACKET
message := []byte{0x00, 0x00, 0x00, 0x00}
message = append(message, token[:]...)
message = append(message, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff}...)
@@ -98,16 +103,16 @@ func AskIp(conn *tls.UConn, token *[48]byte) []byte {
panic(err)
}
log.Printf("ask ip: wrote %d bytes", n)
log.Printf("query ip: wrote %d bytes", n)
dumpHex(message[:n])
reply := make([]byte, 0x40)
n, err = conn.Read(reply)
log.Printf("ask ip: read %d bytes", n)
log.Printf("query ip: read %d bytes", n)
dumpHex(reply[:n])
if reply[0] != 0x00 {
panic("unexpected ask ip reply.")
panic("unexpected query ip reply.")
}
return reply[4:8]
@@ -117,17 +122,27 @@ func main() {
server := "vpn.nju.edu.cn:443"
token := WebLogin()
// ask IP
// query IP
conn, err := tlsConn(server)
if err != nil {
panic(err)
}
defer conn.Close()
ip := AskIp(conn, (*[48]byte)(token))
log.Printf("IP: %q", ip)
ip := QueryIp(conn, (*[48]byte)(token))
log.Printf("IP: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3])
ip[0], ip[1], ip[2], ip[3] = ip[3], ip[2], ip[1], ip[0] // reverse the ip slice for future use
// TUN dev
log.Printf("Initializing TUN device...")
ifce, err := water.New(water.Config{
DeviceType: water.TUN,
})
if err != nil {
panic(err)
}
// send conn
conn, err = tlsConn(server)
if err != nil {
@@ -135,7 +150,7 @@ func main() {
}
defer conn.Close()
go recvListen(conn, (*[48]byte)(token), (*[4]byte)(ip))
go recvListen(conn, (*[48]byte)(token), (*[4]byte)(ip), ifce)
// tlsConn for sending data
conn, err = tlsConn(server)
@@ -169,21 +184,25 @@ func main() {
panic("unexpected send handshake reply.")
}
for true {
tmp := []byte("\x45\x00\x00\x3c\x0e\x83\x00\x00\x80\x01\x00\x00" + string([]byte{ip[3], ip[2], ip[1], ip[0]}) + "\xac\x1a\x2c\x51")
checksum := CheckSum(tmp)
binary.BigEndian.PutUint16(tmp[10:12], checksum)
message = make([]byte, 2000)
for {
n, err := ifce.Read(message)
if err != nil {
log.Fatal(err)
continue
}
message2 := string(tmp) +
"\x08\x00\x49\x27\x00\x01\x04\x34\x61\x62\x63\x64" +
"\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74" +
"\x75\x76\x77\x61\x62\x63\x64\x65\x66\x67\x68\x69"
if message[0] == 0x60 {
continue
}
n, err = conn.Write(message[:n])
if err != nil {
panic(err)
}
n, err = io.WriteString(conn, message2)
log.Printf("send: wrote %d bytes", n)
dumpHex([]byte(message2[:n]))
time.Sleep(time.Second)
dumpHex([]byte(message[:n]))
}
// // HANDSHAKE?
@@ -193,24 +212,3 @@ func main() {
// // message = message + "\x03\x00\x00\x00" + token + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
}
func CheckSum(data []byte) uint16 {
var (
sum uint32
length int = len(data)
index int
)
for length > 1 {
sum += uint32(data[index])<<8 + uint32(data[index+1])
index += 2
length -= 2
}
if length > 0 {
sum += uint32(data[index])
}
sum += (sum >> 16)
return uint16(^sum)
}