C# 版 防止 DNS 污染,获取域名真实 IP 地址
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text; namespace TestDnsResolver
{
class Program
{
static void Main(string[] args)
{
GFWDnsResolver dnsResolver = GFWDnsResolver.Instance();
string domain = "www.google.com";
string ip = dnsResolver.GFWResolve(domain);
Console.WriteLine(ip + " " + domain);
Console.ReadKey();
}
} public class GFWDnsResolver
{
private static GFWDnsResolver resolver = null; private static string DNS_SERVER = "8.8.8.8"; private Encoding coding = Encoding.UTF8; private bool debug = false;
private bool cache = false; private int maxTryTimes = ;
private int waitTimes = ; private Dictionary<string, string> dnsCache = new Dictionary<string, string>(); string[] blackList = {
"74.125.127.102", "74.125.155.102", "74.125.39.102", "74.125.39.113",
"209.85.229.138",
"128.121.126.139", "159.106.121.75", "169.132.13.103", "192.67.198.6",
"202.106.1.2", "202.181.7.85", "203.161.230.171", "203.98.7.65",
"207.12.88.98", "208.56.31.43", "209.145.54.50", "209.220.30.174",
"209.36.73.33", "211.94.66.147", "213.169.251.35", "216.221.188.182",
"216.234.179.13", "243.185.187.39", "37.61.54.158", "4.36.66.178",
"46.82.174.68", "59.24.3.173", "64.33.88.161", "64.33.99.47",
"64.66.163.251", "65.104.202.252", "65.160.219.113", "66.45.252.237",
"72.14.205.104", "72.14.205.99", "78.16.49.15", "8.7.198.45", "93.46.8.89"}; public static GFWDnsResolver Instance()
{
if (resolver == null)
{
resolver = new GFWDnsResolver();
}
return resolver;
} private GFWDnsResolver() { } private bool IsBadReply(string ip)
{
for (int i = ; i < blackList.Length; i++)
{
if (blackList[i].Equals(ip))
{
return true;
}
}
return false;
} public string GFWResolve(string domain)
{
IPAddress[] address = Dns.GetHostAddresses(domain);
string ip = address[].ToString();
if (!IsBadReply(ip))
{
return ip;
}
else if (cache && dnsCache.ContainsKey(domain))
{
return dnsCache[domain];
} for (int i = ; i < maxTryTimes; i++)
{
ip = Resolve(domain);
if (IsBadReply(ip) || ip == null)
{
continue;
}
else
{
if (cache)
{
dnsCache.Add(domain, ip);
}
return ip;
}
}
return string.Empty;
} private void HexDump(byte[] bytes)
{
Console.WriteLine(BytesToHex(bytes));
} private string BytesToHex(byte[] bytes)
{
StringBuilder sb = new StringBuilder();
for (int i = ; i < bytes.Length; i++)
{
sb.AppendFormat("{0:X2}", bytes[i]);
} string hex = sb.ToString();
return hex;
} private string Resolve(string domain)
{
byte[] recvData = new byte[];
byte[] data = BuildRequestData(domain);
string result = null;
if (debug)
{
Console.WriteLine(" =============== dns query request package dump: ================");
HexDump(data);
} IPEndPoint iep = new IPEndPoint(IPAddress.Parse(DNS_SERVER), );
Socket dataSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
dataSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, * );
dataSocket.SendTo(data, iep); byte[] respData = new byte[];
for (int i = ; i < waitTimes; i++)
{
try
{
int intReceived = dataSocket.Receive(respData);
byte[] dataReceive = new byte[intReceived];
Array.Copy(respData, dataReceive, intReceived); if (debug)
{
Console.WriteLine("============ dns query answer package dump");
HexDump(dataReceive);
} string ip = DecodeDnsResponse(dataReceive, domain);
if (IsBadReply(ip))
{
continue;
}
else
{
result = ip;
break;
}
}
catch (SocketException ex)
{
throw ex;
}
} dataSocket.Close();
return result;
} private byte[] BuildRequestData(string host)
{
// head + (host length +1) + eof sign + qtype + qclass
int size = + host.Length + + + ;
using (MemoryStream buff = new MemoryStream(size))
{
byte[] tmp = null; Random random = new Random();
byte[] seq = new byte[];
random.NextBytes(seq);
buff.Write(seq, , seq.Length); byte[] header = new byte[] { 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
buff.Write(header, , header.Length); string[] parts = host.Split('.');
for (int i = ; i < parts.Length; i++)
{
buff.WriteByte((byte)parts[i].Length); byte[] partsByte = coding.GetBytes(parts[i]);
buff.Write(partsByte, , partsByte.Length);
} tmp = new byte[] { 0x00 };
buff.Write(tmp, , tmp.Length); tmp = new byte[] { 0x00, 0x01, 0x00, 0x01 };
buff.Write(tmp, , tmp.Length); return buff.ToArray();
}
} private string DecodeDnsResponse(byte[] resp, string host)
{
using (MemoryStream stream = new MemoryStream(resp))
{
using (BinaryReader buffer = new BinaryReader(stream))
{
//parse the query answer count.
int pos = ;
stream.Position = pos;
ushort qncount = buffer.ReadUInt16(); //skip query answer field
pos = + + host.Length + + ;
stream.Position = pos;
for (int i = ; i < qncount; i++)
{
stream.Position = pos;
byte pointFlg = buffer.ReadByte();
if ((pointFlg & 0xc0) == 0xc0)
{
pos += ;
}
else
{
pos += + host.Length + ;
} stream.Position = pos;
ushort queryType = buffer.ReadUInt16(); if (debug)
{
Console.WriteLine("qncount:" + qncount + "pos:" + pos + "queryType:" + queryType);
} pos += ;
stream.Position = pos;
int dataLen = buffer.ReadByte();
pos += ; //A record
if (queryType == 0x0001)
{
if (debug)
{
Console.WriteLine("parse A record");
} string ip = string.Empty;
for (int j = ; j < dataLen; j++)
{
stream.Position = pos;
int v = buffer.ReadByte();
v = v > ? v : 0x0ff & v;
ip += v + (j == dataLen - ? "" : ".");
pos += ;
}
return ip;
}
else
{
pos += dataLen;
}
}
return string.Empty;
}
}
}
}
}
C# 版 防止 DNS 污染,获取域名真实 IP 地址的更多相关文章
- 获取客户端真实IP地址
Java-Web获取客户端真实IP: 发生的场景:服务器端接收客户端请求的时候,一般需要进行签名验证,客户端IP限定等情况,在进行客户端IP限定的时候,需要首先获取该真实的IP. 一般分为两种情况: ...
- Java中使用HttpRequest获取用户真实IP地址端口
import javax.servlet.http.HttpServletRequest; /** * 自定义访问对象工具类 * * 获取对象的IP地址等信息 * @author X-rapido * ...
- Java获取客户端真实IP地址
Java代码 import javax.servlet.http.HttpServletRequest; /** * 获取对象的IP地址等信息 */ public class IPUtil { /** ...
- Java 获取客户端真实IP地址
本文基于方法 HttpServletRequest.getHeader 和 HttpServletRequest.getRemoteAddr 介绍如何在服务器端获取客户端真实IP地址. 业务背景 服务 ...
- java如何获取访问真实IP地址?
java如何获取访问真实IP地址 解决方法: 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址,如果没有代理,则获取真实ip public static String getIp( ...
- 伪造IP及获取客户端真实IP地址
Fiddler支持自定义规则,可以实现对HTTP请求数据发送给Server前或HTTP应答数据发送给浏览器前进行修改.下面的例子将演示如何向所有HTTP请求数据中增加一个头.1)打开Fiddler,点 ...
- 绕过CDN获取服务器真实IP地址
相关视频链接:(https://blog.sechelper.com/20220914/penetration-testing-guide/cdn-bypass) CDN(Content Delive ...
- CDN下nginx获取用户真实IP地址
随着nginx的迅速崛起,越来越多公司将apache更换成nginx. 同时也越来越多人使用nginx作为负载均衡, 并且代理前面可能还加上了CDN加速,但是随之也遇到一个问题:nginx如何获取用户 ...
- LNAMP架构中后端Apache获取用户真实IP地址的2种方法(转)
一.Nginx反向代理配置: 1.虚拟主机配置 复制代码代码如下: location / { try_files $uri @apache;} location @apache {interna ...
随机推荐
- AndroidのActivity启动模式
Activity启动模式 .概念 Activity启动模式定义了Activity启动的规则,它决定着Activity的实例创建与重用与否 .属性 Activity的启 ...
- .Net的差评
.NET平台很棒.真的很棒.直到它不再那么棒.我为什么不再用.NET?简单来说,它限制了我们选择的能力(对我来说很重要),转移了我们的注意力,使得我们向内认知它的安全性,替代了帮助我们认知外面广阔世界 ...
- CKFinder根据用户设置权限,不同用户有自己的私有的、独立的文件夹
CKFinder 默认情况下多个用户共用同一个图片目录.所有上传的图片和Flash全部保存在同一个文件夹(默认为 userfiles)内. 现在想实现: 第1个需求:不同用户有自己的私 ...
- [转]在Excel中使用SQL语句实现精确查询
本文转自:http://blog.sina.com.cn/s/blog_5fc375650102e1g5.html 今天在微博上看到@数据分析精选 分享的一篇文章,是关于<在Excel中使用SQ ...
- 基于QTP的自己主动化測试框架介绍
继前面用了七章介绍了基于QTP的自己主动化測试框架,以下再用几个视频再补充一下. 视频一:基本框架特点介绍说明 .框架的特点从正反两面进行了分析以及主要思想 http://v. ...
- Spark Streaming源码解读之流数据不断接收和全生命周期彻底研究和思考
本节的主要内容: 一.数据接受架构和设计模式 二.接受数据的源码解读 Spark Streaming不断持续的接收数据,具有Receiver的Spark 应用程序的考虑. Receiver和Drive ...
- 浏览器兼容性问题解决方案之CSS,已在IE、FF、Chrome测试
当前主浏览器的核心是什么? 1) Trident:IE浏览器使用的内核,该内核程序在1997年的IE4中首次被采用,是微软在Mosaic代码的基础之上修改而来的,并沿用到目前的 IE7.Trident ...
- php抽象与接口的区别[转载]
来自:http://www.cnblogs.com/k5054/archive/2012/12/26/2834205.html 对于面向对象开发,抽象类与接口这两个东西是比较难理解的! 今天看了一整天 ...
- jQuery Recipies - 使用map来过滤对应的元素集
<table id="tblEmployee" class="normal_table"> <tr> <td>Employe ...
- java类与对象_成员变量和局部变量区别
成员变量和局部变量:1.成员变量:再类中定义,用来描述对象将要有什么.2.局部变量:在类的方法中定义,在方法中临时保存数据.区别:1.作用域不同: 局部:仅限于定义它的方法 成员:整个类中都是可见 ...