{
	"id": "48492109-69e0-4302-8bf7-31786edacfd5",
	"created_at": "2026-04-06T00:11:11.534947Z",
	"updated_at": "2026-04-10T13:12:03.239345Z",
	"deleted_at": null,
	"sha1_hash": "69f6b1f622a318cfbea8ae39d4a0a32e499ba3cc",
	"title": "SensePost | Waiting for goDoH",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 762628,
	"plain_text": "SensePost | Waiting for goDoH\r\nArchived: 2026-04-05 22:01:55 UTC\r\nor DNS exfiltration over DNS over HTTPS (DoH) with godoh\r\n“Exfiltration Over Alternate Protocol” techniques such as using the Domain Name System as a covert\r\ncommunication channel for data exfiltration is not a new concept. We’ve used the technique for many years at\r\nSensePost, including Haroon \u0026 Marco’s 2007 BH/DC talk on Squeeza. In the present age this is a well understood\r\ntopic, at least amongst Infosec folks, with a large number of resources, available, online that aim to enlighten\r\nthose that may not be  familiar with the concept. There are also  practical techniques for detecting DNS Tunnelling\r\non your network.\r\nUsing DNS as a covert communication channel has many benefits when considering the monitoring capabilities of\r\na target. By utilising a protocol that underpins technologies such as email and web browsing, one may not\r\nimmediately expect DNS to be used for anything other than, well, DNS. Alas, it is possible to use a completely\r\nlegitimate protocol for two-way communication in and out of a network, abusing a possibly overlooked\r\nmonitoring opportunity (if not a necessity). This technique does not come without cost to the attacker though.\r\nDNS covert communication is one of the slowest methods of the several options an attacker may have. Especially\r\nwhen compared to malware that make use of HTTP/S to communicate.\r\nMany organisations have also managed to adjust their architectures and monitoring to defend against this two\r\ndecade old idea, since malware and attackers alike have taken advantage of it. Using split horizon DNS,\r\nmonitoring the size and rate of requests as well as analysing the labels in a lookup all provide opportunities to\r\ndetect and prevent successful tunnelling. From an attackers perspective, this increases complexity when trying to\r\nstay under the radar while still having a reliable channel back into the network. By tweaking the behaviour of the\r\nDNS-channel such as the length of a hostname’s labels and the rate of requests detection can be bypassed but this\r\nwill almost always come with a speed trade off. Simply not allowing recursive name lookups to the outside world\r\nwould obviously also prevent the attack, but at the cost of some usability. Thankfully for defenders, monitoring\r\nDNS is relatively simple in that you only need to focus on DNS at a protocol level, and probably only from the\r\nfew caching forwarders you allow to make recursive, outbound lookups to the world.\r\nUntil now. Fast forward a few years from the original DNS tunnelling discussions, and we are presented with a\r\nnew RFC that describes a protocol called DNS-over-HTTPS, or DoH. Meet RFC8484. Basically, it is possible to\r\nhave a full RFC1035 compliant DNS conversation, over HTTPS. Think of it as a JSON API to make DNS\r\nlookups. A simple HTTP GET request and a predictable JSON response format, all via a provider such as Google.\r\nRight there is where attacker  spidey senses should have tingled. Using legitimate and more often than not, trusted\r\ndomains such as google.com to “front” your traffic to a C2 has been a thing for a while. Domain Fronting has seen\r\na decent enough uptake where it has been used for censorship circumvention as well as in some malware\r\ncampaigns. The present struggles of domain fronting aside, by abusing DNS over HTTPS we can once again\r\nachieve the same level of evasion, albeit at a much slower rate but using a trusted domain.\r\nhttps://sensepost.com/blog/2018/waiting-for-godoh/\r\nPage 1 of 6\n\nI built a quick proof of concept called “godoh” with the purpose of demonstrating DoH as an exfiltration channel,\r\nbut also to give defenders some tooling to test with so that monitoring and detections for this technique can be\r\nbuilt. I figured this DoH exfiltration technique was a neat idea, but literally while writing this post I have since\r\ndiscovered other existing mentions of this technique. And yesterday at the recent ATT\u0026CK conference,\r\n@dtmsecurity also released some tooling for red teamers to make use of this exact same idea in the popular\r\nadversary simulation toolkit, Cobalt Strike. Nonetheless, allow me to take you through my thought process and\r\nfinally give you some tooling to play with this on your own networks.\r\nImagine you are on a network that has relatively good DNS monitoring. They are capable of detecting its use as an\r\nexfiltration channel (or don’t allow external zones to resolve via DNS in the first place). They also have a fancy\r\nLayer7 proxy/firewall that does URL content classification and strictly blocks based on that. The google.com\r\ndomain is whitelisted for whatever reason, and therefore https://dns.google.com/ probably isn’t blocked.\r\nA simple piece of malware making use of DNS tunnelling may typically have code running on a computer that\r\nperiodically polls for commands to run, and responds with the output of those commands encoded as a series of A\r\nrecord lookups to an attacker controlled domain that are reconstructed server-side.\r\nExample traffic flow for traditional C2 using DNS.\r\nI ported the exact same protocol idea to simply use a DNS over HTTPS provider for exactly the same lookups.\r\nThe lookups themselves did not change (and don’t need to, we are still talking valid DNS remember), but merely\r\nthe transport used to ask DNS questions and parse an answer.\r\nhttps://sensepost.com/blog/2018/waiting-for-godoh/\r\nPage 2 of 6\n\nModified traffic flow, fronting DNS lookups using a provider such as Google.\r\nConsider this architecture and the monitoring implications for a moment. Now, one can no longer rely on the fact\r\nthat DNS is a very specific protocol that could be sinkholed and controlled on a network, but instead, we know\r\nhave the added complexity of an HTTPS connection, to an often trusted domain such as google.com, proxying\r\nthese DNS requests in and out of a network. Once a request is made to a DoH provider such as\r\nhttps://dns.google.com/, they in turn use traditional DNS to resolve a name and respond with an answer to the\r\nDoH client. But it’s not just Google, there are many DoH providers available today, and one can quickly see this is\r\na harder problem to solve all of a sudden.\r\nSince  godoh  is written in Golang, a single executable for most platforms can be built that contains both the\r\nserver-side and client-side code needed. Just like traditional DNS tunnelling, you would need to configure a\r\ndomain (or subdomain) to have its name server point to your c2 server and run the godoh c2  command from\r\nthere. The c2  command starts a DNS server specifically geared towards understanding how to have\r\nconversations with agents using DNS. On the client side, the godoh agent  command is run to connect to a c2\r\nusing any of the DoH providers supported by godoh. It is here where the agent and a DoH provider have\r\nconversations that are finally translated into questions for the c2 DNS server to answer. Simple, yet effective.\r\nIn practice, the server-side component for godoh  looks like this:\r\nhttps://sensepost.com/blog/2018/waiting-for-godoh/\r\nPage 3 of 6\n\ngodoh server-side C2 interactions example.\r\nIn the screenshot above, a new agent connected to the C2 and the command ls -lah /tmp/pwnd  was issued to be\r\nexecuted by the agent. Once completed, the agent sent the output back to the C2 (in the form of a series of DNS A\r\nrecord lookups) where the server finally decrypted the payload and presented the output to the screen. On the\r\nagent side, the invocation and execution of the command looked as follows:\r\ngodoh agent interaction\r\nAs you can see, the agent started to poll for new commands (every three seconds as indicated by the -t  flag) via\r\nDNS TXT record lookups. Once a command was received, it was decrypted and executed on the host. Once done,\r\nthe output was sent back to the C2 server via DNS A record lookups for a total of 5 requests for the complete\r\nconversation. What is interesting to note here is that the client knows if the server successfully received a packet\r\n(and could decrypt and validate a crc32 checksum) based on the IP address in the response data. A response\r\nof  1.1.1.1  indicates a successful receipt and decryption of data.\r\nIt is also possible to download files with godoh . Keep in mind that this is still DNS, which is limited in packet\r\nsize, so downloading large files take lots of requests, which directly translate into lots of time.\r\nhttps://sensepost.com/blog/2018/waiting-for-godoh/\r\nPage 4 of 6\n\ngodoh file download example.\r\nBy simply issuing the download /tmp/pwnd  command, the agent read the contents of the target file and sent it\r\nback to the C2.\r\ngodoh agent file download\r\nFrom the agents perspective, downloading a file simply means reading its contents and sending it back to the C2\r\nwith DNS A record lookups all using DoH.\r\ngodoh Windows client executing the whoami /groups command and returning the output to the C2.\r\nWhat you should have noticed in the screenshots for the agent output by now is the contents of the labels fields.\r\nThese are the full hostnames for the specially crafted protocol that would have been appended to the target domain\r\nto form DNS lookups. If you are interested in the details, this code comment attempts to shed some light on the\r\nmeanings of the labels themselves. The server-side component interpreting data can be found here. In short, the\r\nprotocol works as follows:\r\nOnce started, make a DNS TXT record lookup to the target domain in the form of\r\nagentidentifier.targetdomain .\r\nOnce the server receives the lookup, if it is the first time seeing this agent identifier the C2 would record\r\nthe existence of this new identifier as a potential target to interact with.\r\nIf there are no commands to be executed, just respond with the default “no commands” response. This loop\r\nrepeats itself infinitely.\r\nhttps://sensepost.com/blog/2018/waiting-for-godoh/\r\nPage 5 of 6\n\nIf there are commands to be executed, encode, compress and encrypt the command and send it along\r\nwithin the TXT lookup response.\r\nThe agent then parses the TXT record response and decrypts, decompresses and decodes the command\r\nto execute it.\r\nWhen complete, the output goes through a process of encoding and encryption, and finally translation ,\r\nwhere the encrypted data is translated into chunks to be sent as DNS A record lookups.\r\nServer side, a control flag is read to understand if an incoming request starts a new stream, is part of a\r\npending stream or is the end of a stream and decides based on that what the next step should be.\r\nOnce a DNS lookup stream is complete, the protocol type is checked (as in, is this simply command output\r\nto be echoed to screen or a file download where the contents should be saved to file) and the appropriate\r\naction is taken.\r\nWhen looking at this traffic using an HTTP proxy, this conversation looks something like this:\r\ngodoh C2 communications example viewed in a HTTP proxy.\r\nIf you are keen to play with this in your own environment then you can get godoh\r\nhere: https://github.com/sensepost/goDoH. Prebuilt binaries are available, but keep in mind that they are built\r\nusing a publicly known encryption key available in the source code. Ideally, you should build your own versions\r\nwith a unique key, easily generated with make key  before make .\r\nSource: https://sensepost.com/blog/2018/waiting-for-godoh/\r\nhttps://sensepost.com/blog/2018/waiting-for-godoh/\r\nPage 6 of 6",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://sensepost.com/blog/2018/waiting-for-godoh/"
	],
	"report_names": [
		"waiting-for-godoh"
	],
	"threat_actors": [],
	"ts_created_at": 1775434271,
	"ts_updated_at": 1775826723,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/69f6b1f622a318cfbea8ae39d4a0a32e499ba3cc.pdf",
		"text": "https://archive.orkl.eu/69f6b1f622a318cfbea8ae39d4a0a32e499ba3cc.txt",
		"img": "https://archive.orkl.eu/69f6b1f622a318cfbea8ae39d4a0a32e499ba3cc.jpg"
	}
}