This commit is contained in:
xvzc 2021-12-30 02:08:30 +09:00
parent d94a94de55
commit 83de169fcc
10 changed files with 283 additions and 14 deletions

View File

@ -1,12 +1,22 @@
package main package main
import ( import (
"fmt" "flag"
"os"
"github.com/itworksnow/SpoofDPI/hello" "github.com/xvzc/SpoofDPI/proxy"
) )
func main() { func main() {
fmt.Print("hello") src := flag.String("src", "localhost:8080", "source-ip:source-port")
hello.SayHello() dns := flag.String("dns", "8.8.8.8", "DNS server")
debug := flag.Bool("debug", false, "true | false")
mtu := flag.Int("mtu", 100, "int")
err := proxy.InitConfig(*src, *dns, *mtu, *debug)
if err != nil {
os.Exit(1)
}
proxy.Start()
} }

BIN
cmd/spoof-dpi/spoof-dpi Executable file

Binary file not shown.

4
go.mod
View File

@ -1,3 +1,5 @@
module SpoofDPI module github.com/xvzc/SpoofDPI
go 1.17 go 1.17
require github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6

2
go.sum Normal file
View File

@ -0,0 +1,2 @@
github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6 h1:4NNbNM2Iq/k57qEu7WfL67UrbPq1uFWxW4qODCohi+0=
github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6/go.mod h1:J29hk+f9lJrblVIfiJOtTFk+OblBawmib4uz/VdKzlg=

View File

@ -1,9 +0,0 @@
package hello
import (
"fmt"
)
func SayHello() {
fmt.Print("from module hello: Hello")
}

69
proxy/config.go Normal file
View File

@ -0,0 +1,69 @@
package proxy
import (
"errors"
"log"
"strings"
"fmt"
"sync"
)
type Config struct {
SrcIp string
SrcPort string
DNS string
MTU int
Debug bool
}
var config *Config
var once sync.Once
var err error
func tokenizeAddress(srcAddress string) (string, string, error) {
tokens := strings.Split(srcAddress, ":")
if len(tokens) < 2 {
return "", "", errors.New("Error while parsing source address: invalid format.")
}
ip := tokens[0]
port := tokens[1]
return ip, port, nil
}
func InitConfig(srcAddress string, dns string, mtu int, debug bool) error {
err = nil
once.Do(func() {
ip, port, err := tokenizeAddress(srcAddress)
if err != nil {
log.Fatal(err)
return
}
config = &Config{
SrcIp : ip,
SrcPort : port,
DNS : dns,
MTU : mtu,
Debug : debug,
}
})
log.Println("source ip : " + config.SrcIp)
log.Println("source port : " + config.SrcPort)
log.Println("dns : " + config.DNS)
log.Println("mtu : " + fmt.Sprint(config.MTU))
if config.Debug {
log.Println("debug : true")
} else {
log.Println("debug : false")
}
return err
}
func getConfig() (*Config) {
return config
}

45
proxy/http.go Normal file
View File

@ -0,0 +1,45 @@
package proxy
import (
"fmt"
"log"
"net"
"github.com/xvzc/SpoofDPI/util"
)
func HandleHttp(clientConn net.Conn, ip string, message []byte) {
remoteConn, err := net.Dial("tcp", ip+":80") // create connection to server
if err != nil {
log.Fatal(err)
return
}
defer remoteConn.Close()
_, write_err := remoteConn.Write(message)
if write_err != nil {
log.Fatal("failed:", write_err)
return
}
defer remoteConn.(*net.TCPConn).CloseWrite()
buf, err := util.ReadMessage(remoteConn)
if err != nil {
log.Fatal("failed:", err)
return
}
fmt.Println()
log.Println()
fmt.Println("##### Response from the server: ")
fmt.Println(string(buf))
// Write to client
_, write_err = clientConn.Write(buf)
if write_err != nil {
log.Fatal("failed:", write_err)
return
}
defer clientConn.(*net.TCPConn).CloseWrite()
}

58
proxy/proxy.go Normal file
View File

@ -0,0 +1,58 @@
package proxy
import (
"log"
"fmt"
"net"
"os"
"github.com/xvzc/SpoofDPI/util"
)
func Start() {
listener, err := net.Listen("tcp", ":" + config.SrcPort)
if err != nil {
log.Fatal("Error creating listener: ", err)
os.Exit(1)
}
log.Println("Created a listener")
for {
clientConn, err := listener.Accept()
if err != nil {
log.Fatal("Error accepting connection: ", err)
continue
}
log.Println("Accepted a new connection.", clientConn.RemoteAddr())
go func() {
defer clientConn.Close()
message , err := util.ReadMessage(clientConn)
if err != nil {
return
}
fmt.Println()
log.Println()
fmt.Println("##### Request from client : ")
fmt.Println(string(message))
domain := util.ExtractDomain(&message)
ip, err := util.DnsLookupOverHttps(getConfig().DNS, domain) // Dns lookup over https
if err != nil {
return
}
log.Println("ip: "+ ip)
if util.ExtractMethod(&message) == "CONNECT" {
fmt.Println("got a HTTPS Request")
}else {
HandleHttp(clientConn, ip, message)
}
}()
}
}

BIN
spoof-dpi Executable file

Binary file not shown.

92
util/util.go Normal file
View File

@ -0,0 +1,92 @@
package util
import (
"net"
"log"
"io"
"strings"
"github.com/babolivier/go-doh-client"
)
func ReadMessage(conn net.Conn)([]byte, error) {
buf := make([]byte, 0, 4096) // big buffer
tmp := make([]byte, 1024) // using small tmo buffer for demonstrating
for {
n, err := conn.Read(tmp)
if err != nil {
if err != io.EOF {
log.Fatal("ReadRequest error:", err)
}
return nil, err
}
buf = append(buf, tmp[:n]...)
if n < 1024 {
break
}
}
return buf, nil
}
func ExtractDomain(message *[]byte) (string) {
i := 0
for ; i < len(*message); i++ {
if (*message)[i] == '\n' {
i++
break;
}
}
for ; i < len(*message); i++ {
if (*message)[i] == ' ' {
i++
break;
}
}
j := i
for ; j < len(*message); j++ {
if (*message)[j] == '\n' {
break;
}
}
domain := strings.Split(string((*message)[i:j]), ":")[0]
return strings.TrimSpace(domain)
}
func DnsLookupOverHttps(dns string, domain string)(string, error) {
// Perform a A lookup on example.com
resolver := doh.Resolver{
Host: dns, // Change this with your favourite DoH-compliant resolver.
Class: doh.IN,
}
log.Println(domain)
a, _, err := resolver.LookupA(domain)
if err != nil {
log.Fatal("Error looking up dns. ", err)
return "", err
}
ip := a[0].IP4
return ip, nil
}
func ExtractMethod(message *[]byte) (string) {
i := 0
for ; i < len(*message); i++ {
if (*message)[i] == ' ' {
break;
}
}
method := strings.TrimSpace(string((*message)[:i]))
log.Println(method)
return strings.ToUpper(method)
}