Analyzis of DNS TXT Records
At the Internet Storm Center, we already mentioned so many times that the domain name system is a goldmine for threat hunting or OSINT. A particular type of DNS record is the TXT record (or text record). It's is a type of resource record used to provide the ability to associate free text with a host or other name. TXT records usually contain:
- any free text related to the domain like contact information
- technical data that can’t be stored in other records (SPF and DMARK records)
- validation records
- suspicious data (what did you expect?)
- encoded packets or files (DNS tunnelling of exfiltration of data)
- <put any relevant data>
Keep in mind that TXT records are publicly available and should never contain sensitive data. They can be requested by any tool that interacts with DNS servers like dig:
$ dig sans.edu txt ; <<>> DiG 9.10.6 <<>> sans.edu txt ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11178 ;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 4, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;sans.edu. IN TXT ;; ANSWER SECTION: sans.edu. 7200 IN TXT "MS=ms72131568" sans.edu. 7200 IN TXT "v=spf1 mx ip4:72.55.140.81 ip4:66.35.59.0/24 ip4:66.35.60.0/24 ip4:204.51.94.0/24" " ip4:160.109.234.213 include:stspg-customer.com" " include:cust-spf.exacttarget.com include:spf.clearslide.com" " include:amazonses.com include:spf.protection.outlook.com include:_spf.salesforce.com ~all" sans.edu. 7200 IN TXT "JI6UZuSsLXHEjD7PIBR1rWcPOqRkKRV2VwWAdhXZnLfbjhmfHHOwjMPizS78hfcgbTtjG1TaPTcdVqzgvUbyaw==" ;; AUTHORITY SECTION: sans.edu. 171976 IN NS dns21a.sans.org. sans.edu. 171976 IN NS dns21b.sans.org. sans.edu. 171976 IN NS dns31b.sans.org. sans.edu. 171976 IN NS dns31a.sans.org. ;; Query time: 131 msec ;; SERVER: 192.168.254.8#53(192.168.254.8) ;; WHEN: Tue Jul 16 14:18:20 CEST 2019 ;; MSG SIZE rcvd: 550
The RFC1464[1] discuss TXT records. They must contain printable characters so many TXT records contain Base64-encoded data (see the above example). But what can we find in TXT records? I extracted a long list of domain names from different DNS servers logs and malicious domains lists. Then I queried TXT records for each of them. Results have been loaded into a Splunk instance to search for some juicy stuff. What did I find?
Note: the set of collected domain names is directly related to the business/activity of the organizations' log sources. I tried to mix different sources but they do not cover the full Internet.
Across 300K+ TXT records, 186K were related to SPF filters[2]. What are the top email providers?
- Microsoft (Outlook.com) (9.9%)
- Google (7.8%)
- OVH (1.5%)
More than 3K domains have the following filter: "v=spf1 -all” which means basically “no hosts are authorized to send emails for those domains”.
Only 389(!) domains had a DKIM TXT record ("v=DKIM1; k=rsa; p=…”)
Another common usage of TXT records is to provide control to prove that you own a specific domain. That’s why many providers ask to create a validation record. The top-20 validation record types are:
google-site-verification facebook-domain-verification _globalsign-domain-verification adobe-idp-site-verification atlassian-domain-verification globalsign-domain-verification ciscocidomainverification status-page-domain-verification zoho-verification keybase-site-verification protonmail-verification have-i-been-pwned-verification dropbox-domain-verification workplace-domain-verification brave-ledger-verification webexdomainverification. citrix-verification-code adobe-sign-verification detectify-verification logmein-verification-code sophos-domain-verification
34K domains had an Office365 record “MS=msXXXXXXXX”
Domains using CloudFlare have a TXT record like “ca3-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" (5K+ records)
What about some suspicious/malicious activity?
I found 5 occurrences of:
window.location.replace(\"hxxp://www[.]28955bfg36abp[.]maintenirfa[.]icu/50968.html\”);
Some SQL injection attempts:
';alert(String.fromCharCode(88,83,83))//';alert(String.fromCharCode(88,83,83))//\""; alert(String.fromCharCode(88,83,83))//\
Injections:
'\"">><marquee><img src=x onerror=confirm(1)></marquee>\""></plaintext></,><plaintext/onmouseover=prompt(1)> <script>prompt(1)</script>@gmail.com<isindex formaction=javascript:alert(/XSS/) type=submit>'-->\""></script><script>alert(document.cookie)</script>\"">"" ""<img/id=\""confirm(1)\""/alt=\""/\""src=\""/\""onerror=eval(id)>'\""><img src=\""hxxp://www[.]shellypalmer[.]com/wp-content/images/2015/07/hacked-compressor.jpg\”">
Finally, I had a look at Base64-encoded strings. I extracted all TXT record in a flat file and used Didier's base64dump tool (only 16+ bytes data strings)
$ base64dump.py -n 16 txt-records.csv
18K strings have been decoded with mainly unknown data. If you restrict the min size of decoded data, you can find other types of records:
$ base64dump.py -n 128 1563290719_434556 | grep Salted__ 433: 172 U2FsdGVkX18ImyXI Salted__.?%?'|j bf4a8022560a0eaa5410421803f3f36a 4836: 172 U2FsdGVkX18UR6BW Salted__.G?V?~?+ 1b6cb31ff37707a5234411b0d2946d92 5020: 128 U2FsdGVkX18LDhF1 Salted__...u??&{ be5a0c41bd9113f59d105fe52b0d600b 10480: 172 U2FsdGVkX18Gx+Qk Salted__.??$??.? 8f3c2fb8cb65bf83deb319040cfa0431 10858: 172 U2FsdGVkX19uUZCc Salted__nQ??E?Q? d1518d4dd745cf21549881477e1f0663 10859: 172 U2FsdGVkX18swQke Salted__,?..?.?j d59604b22066693a2fe1020a9230cee2 10860: 172 U2FsdGVkX18kqxHK Salted__$?.?? ? ad198d777d6535e735e011a1962da767 10863: 172 U2FsdGVkX182vS1/ Salted__6?-/.?? 79b98e60256204b1496672bf534d798f 11111: 192 U2FsdGVkX19gXMHT Salted__`\??.R?* 9e3c2eb4248b8a9f19669b95733f6b42 11112: 172 U2FsdGVkX19eP/Xr Salted__^???+?? 62fec6ab31abf469714ed644f874dfe5 11989: 192 U2FsdGVkX19Lx8yU Salted__K??f?P9 bae75f0621aac882fe0d6437148eb6e2 12188: 172 U2FsdGVkX18fgi6U Salted__.?.??=?. d2f075147f0ecfd6dbd5decb5ab539a8 12189: 172 U2FsdGVkX1/bj0+w Salted__?O??J?- 57c4fab20a1d00ae6ab9421adb14db7d 12236: 128 U2FsdGVkX19eQQU7 Salted__^A.;?..? fe5ddee71702e557f2223b5dbf638521 12283: 172 U2FsdGVkX18oCMgi Salted__(.?"W??? 2340a1f6293d5094fbb1bfc7b0477ea9 12284: 172 U2FsdGVkX19TxBC7 Salted__S?.??Q7. 7023090b4b45d80468d73ccf1fd76f75 12292: 192 U2FsdGVkX19LqH/h Salted__K??h.?? f64d90db45cab9227c593fe99ee19ae6 12363: 152 U2FsdGVkX19AaKCa Salted__@h??.U0/ a9f3b2548d3a5571b75510c392ceea70 12573: 172 U2FsdGVkX19vmD8m Salted__o??&??./ 94b8e7d4c933bd1fc6c3dd381fea9b95 15550: 128 U2FsdGVkX18YmIhE Salted__.??D?}?7 61421ac7e9463408085cf67ee525c2a0 15551: 152 U2FsdGVkX18N9H+R Salted__.?????o 0eda0cc8c4d2667032ce27d0a389f2a9 16629: 152 U2FsdGVkX194reUj Salted__x??#?J? c098589181b03e2a78f34ef3e08c7b09
The prefix "Salted__" means this either is the output of an "openssl enc" command or something like this.
As you can see, they are plenty of interesting data that can be found in TXT records. I also found an interesting blog article[3] with a set of regex to search for data in TXT records. You should keep in an eye on them.
I'm considering a permanent script to collect them on the fly from my Bro instance and build some kind of "passivetxt" service.
[1] https://www.rfc-editor.org/rfc/rfc1464.txt
[2] https://en.wikipedia.org/wiki/Sender_Policy_Framework
[3] https://www.tide-project.nl/blog/ccr2019/
Xavier Mertens (@xme)
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key
Reverse-Engineering Malware: Malware Analysis Tools and Techniques | Frankfurt | Dec 9th - Dec 14th 2024 |
Comments
So, 389 domains had a misconfigured DKIM key.
You would never find a valid DKIM key at the root level.
Those using them would choose the selector under the _domainkey subdomain. A common pattern that Office365 uses would be s1._domainkey.domain.com or s2._domainkey.domain.com.
Anonymous
Jul 17th 2019
5 years ago
Dom McIntyre De Vitto
Anonymous
Jul 18th 2019
5 years ago
dmarc records usually point to dmarcian like service companies rather than to the domain itself.
caa records can also tell you a lot
Anonymous
Jul 18th 2019
5 years ago
Gmail has all three things as pass...
The key for it to work is the formatting, it has to be the right what I would call set of single and double quotes for it to stick right I guess..
Anonymous
Jul 19th 2019
5 years ago