利用Java快速搭建一个DNSLog平台
字数 802 2025-08-11 08:36:09
Java搭建DNSLog平台详细教程
一、DNSLog平台概述
DNSLog平台主要用于渗透测试过程中的盲打回显场景,当公有DNSLog平台不可用时,搭建私有平台尤为重要。本教程将详细介绍如何使用Java快速搭建一个无需MySQL和Redis的轻量级DNSLog平台。
二、环境准备
1. 硬件与网络要求
- 云服务器一台(示例IP:88.88.88.88)
- 可解析的域名一个(示例:abc.com)
2. 软件要求
- Java 8运行环境
- Xshell(可选,用于远程连接)
- Xftp(可选,用于文件传输)
三、域名配置
1. 主域名解析
记录类型: A
主机记录: abc.com
记录值: 88.88.88.88
2. DNS服务域名绑定
记录类型: A
主机记录: dns.abc.com
记录值: 88.88.88.88
3. NS记录配置
记录类型: NS
主机记录: p5.abc.com
记录值: dns.abc.com
注意:子域名命名无限制,关键是指向正确的DNS服务器
四、服务器环境配置
1. 安装JDK 1.8
# 检查现有Java版本
java -version
# 更新软件包
yum update
# 查看可用Java安装包
yum -y list java*
# 安装JDK 1.8
yum -y install java-1.8.0-openjdk*
2. 部署应用
- 创建web目录
- 上传jar包(下载地址:https://web-1259107904.cos.ap-guangzhou.myqcloud.com/web-0.0.1-SNAPSHOT.jar)
3. 运行程序
# 停止53端口占用服务
sudo systemctl stop systemd-resolved
# 后台运行jar包
nohup java -jar web-0.0.1-SNAPSHOT.jar > root.log 2>&1 &
# 测试DNS解析
ping p5.abc.com
# 访问Web界面查看结果
http://abc.com
4. 停止服务
# 查找Java进程
ps -ef|grep java
# 终止进程
kill -9 [进程ID]
五、技术原理详解
1. 核心原理
DNSLog平台通过监听53端口,解析DNS请求数据包,记录请求信息并作出响应。
2. 关键代码实现
53端口监听
private void Listener(int port) throws SocketException {
log.info("UDPListener Start> port:"+port);
while (true) {
byte[] buffer = new byte[maxUdpDataSize];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
try {
socket.receive(packet);
buffer = packet.getData();
Message message = new Message(buffer);
Record record = message.getQuestion();
String name = record.getName().toString();
InetAddress address = packet.getAddress();
String ip = address.getHostAddress();
int targetPort = packet.getPort();
if(!ip.equals("127.0.0.1") && !ip.isEmpty() && ip!=null){
DNSLogRecorder.setDNSLog(ip, name.substring(0,name.length()-1).toLowerCase());
}
answer(message, address, targetPort);
log.info("receive new UDPMessage> ip:"+ip+" port:"+targetPort+" name:"+name);
} catch (IOException e) {
log.error(e.getMessage());
}
}
}
数据记录
public static void setDNSLog(String ip, String domain) {
UDPInfo udpInfo = new UDPInfo();
Long time = System.currentTimeMillis();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date = formatter.format(time);
udpInfo.setIp(ip);
udpInfo.setDomain(domain);
udpInfo.setDate(date);
if(list.size()>=10){
list.remove(9);
}
list.add(0, udpInfo);
}
DNS响应
private static void answer(Message message, InetAddress sourceAddress, int sourcePort) throws IOException {
Record record = message.getQuestion();
String addressIP = "127.0.0.1";
InetAddress answerIpAddr = Address.getByAddress(addressIP);
answerIpAddr.getCanonicalHostName();
Message answerMessage = message.clone();
Record answer = new ARecord(record.getName(), record.getDClass(), 64, answerIpAddr);
answerMessage.addRecord(answer, Section.ANSWER);
byte[] buff = answerMessage.toWire();
DatagramPacket response = new DatagramPacket(buff, buff.length, sourceAddress, sourcePort);
socket.send(response);
log.info("answer>Address:"+sourceAddress.getAddress().toString()+",HostAddress:"+answerIpAddr.getHostAddress()+",HostName:"+answerIpAddr.getHostName());
}
数据查询接口
@ResponseBody
@RequestMapping("/queryDNSLog")
public String queryDNSLog(){
List<UDPInfo> udpInfos = DNSLogRecorder.getDNSLog();
String json = null;
if (!udpInfos.isEmpty()){
resultMessage.setCode("200");
resultMessage.setMessage("success!");
resultMessage.setData(udpInfos);
} else {
resultMessage.setCode("400");
resultMessage.setMessage("data is null!");
log.info("data is null");
}
json = JSON.toJSONString(resultMessage);
return json;
}
六、使用说明
- 访问Web界面:
http://[你的域名] - 使用任意子域名进行DNS查询(如:
ping p5.abc.com) - 在Web界面查看记录的DNS查询信息
七、注意事项
- 确保53端口未被占用
- 域名解析需要时间,可能需要等待DNS生效
- 平台默认只保留最近的10条记录
- 生产环境应考虑增加安全措施
八、扩展建议
- 增加用户认证功能
- 实现记录持久化存储
- 添加更多查询过滤条件
- 支持自定义子域名生成
通过本教程,您可以快速搭建一个轻量级的DNSLog平台,满足渗透测试中的盲打回显需求。