首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

NDIS 修改数据包,拦截URL解决方法

2011-12-31 
NDIS 修改数据包,拦截URL想实现:本机输入www.baidu.com 拦截后显示,This page is restricted by xiaoc!下

NDIS 修改数据包,拦截URL
想实现:本机输入www.baidu.com 拦截后显示,This page is restricted by xiaoc!


下面这个函数就是在MPSend 和 MPSendOnePacket 调用后修改数据包的。
修改完后就会调用NdisSend发送,运行结果是输入www.baidu.com 后无法找到该页
不知道错在哪里?还有如何知道效验值check的正确性?

C/C++ code
void FilterHttpRequest(PUCHAR p){        __u32 u32temp;    __u16 u16temp;    struct psdhdr ph;    /* pseudo header declaration */        //////////////////////////SENDING BLOCK PAGE TO CLIENT//////////////////////////    // Use the first 40 bytes of m_pBlockBuffer for future TCP control packet transmission.    char* pBlockBuffer;    struct iphdr*    respIpHdr;    struct tcphdr*    respTcpHdr;        char* pTcpData;    unsigned int   dsize;    //DbgBreakPoint();    respIpHdr        = (struct iphdr*)(p + sizeof(struct ethhdr));    respTcpHdr        = ((struct tcphdr*)((char*)respIpHdr + sizeof (struct iphdr)));    pTcpData = (char*)respIpHdr + sizeof(struct iphdr) + sizeof(struct tcphdr);        NdisAllocateMemoryWithTag(&pBlockBuffer, 512, TAG);    NdisZeroMemory(pBlockBuffer, 512);    sprintf(pBlockBuffer,        "%s",        "<html>"        "<head>"        "<title>HTTPFilter block page</title></head><body><TABLE height=\"100%\" width=\"100%\">"        "<TR>"        "<TD align=\"center\"><h1>This page is restricted by xiaoc!</h1>"        "</TD>"        "</TR>"        "</TABLE>"        "</body>"        "</html>\n\n\n"        );    dsize = Xc_strlen(pBlockBuffer, '\0');    NdisZeroMemory(pBlockBuffer, 512);    sprintf(pBlockBuffer,        "HTTP/1.1 200 OK\r\n"        "Content-Type: Text/HTML\r\n"        "Connection: close\r\n"        "Content-Lenght: %d"                "\r\n\r\n"        "%s",        dsize,        "<html>"        "<head>"        "<title>HTTPFilter block page</title></head><body><TABLE height=\"100%\" width=\"100%\">"        "<TR>"        "<TD align=\"center\"><h1>This page is restricted by xiaoc!</h1>"        "</TD>"        "</TR>"        "</TABLE>"        "</body>"        "</html>\n\n\n"        );    dsize = Xc_strlen(pBlockBuffer, '\0');    DbgPrint("[xiaoc httpfiter] block info : %s", pBlockBuffer);    NdisZeroMemory(pTcpData, XC_ntohs(respIpHdr->tot_len) - sizeof(struct iphdr) - sizeof(struct tcphdr));    NdisMoveMemory(pTcpData, pBlockBuffer, dsize);    DbgPrint("[xiaoc httpfilter] FilterHttpRequest debug 1");    respIpHdr->check = 0;    u32temp = respIpHdr->daddr;    respIpHdr->daddr = respIpHdr->saddr;    respIpHdr->saddr = u32temp;    respIpHdr->tot_len = XC_htons(sizeof (struct iphdr) + sizeof (struct tcphdr) + dsize);    respIpHdr->id = XC_htons((__u16)2);        respIpHdr->frag_off = 0;    respIpHdr->protocol = 0x06;    respIpHdr->check =         CalcIPSum((__u16*) respIpHdr, sizeof(struct iphdr));    u32temp = respTcpHdr->ack_seq;    respTcpHdr->ack_seq = XC_htonl (XC_htonl (respTcpHdr->seq) + dsize);    respTcpHdr->seq = u32temp;    u16temp = respTcpHdr->source;    respTcpHdr->source = respTcpHdr->dest;    respTcpHdr->dest = u16temp;    respTcpHdr->ack = 1;    respTcpHdr->fin = 1;    //SET_TCP_OFFSET(respTcpHdr, 0x5);    //SET_TCP_X2(respTcpHdr, 0x0);    respTcpHdr->urg = 0;    ph.sourceip = respIpHdr->saddr;    ph.destip    = respIpHdr->daddr;    ph.mbz = 0;    ph.ptcl = 0x06;    ph.plen = XC_htons((__u16)(sizeof (struct tcphdr) + dsize));    respTcpHdr->check = 0;    respTcpHdr->check =         CalcTCPSum((__u16 *)&ph,         (__u16 *)respTcpHdr,        sizeof(struct tcphdr) + dsize);    if( pBlockBuffer )    {        NdisFreeMemory(pBlockBuffer, 512, 0);    }} 



[解决办法]
无法找到该页:TCP的SYN/ACK包没有收到。是不是根据IP过滤的?
[解决办法]
用抓包工具等查看一下你过滤的数据包等是否正确
[解决办法]
Dns完成后,client发syn包连接,server回复的syn/ack/psh应该不满足你的过滤条件;不过client再ack/psh就被滤了,三次握手没完成。
如果简单地根据IP/PORT滤包,TCP连不上,过滤可以实现,你自己的html内容也就不能被上层收到。
你的条件是目的端口=HTTP,这个时候过滤会把HTTP请求替换,这个有点问题。
感觉你想做的是TCP欺骗,要允许TCP连接上,但是要伪造服务器返回的内容。这样的话,你要自己写类似TCP控制块的东西,记录要欺骗的连接,并修改内容,要注意!sequence number需要伪造不能错!
简单一点,判断是HTTP请求指定站点,记录TCP控制块;一旦该连接建立,就冒充服务器生成一个包(包含HTTP头和HTML),然后断开TCP,释放控制块。也够烦的。

[解决办法]
处理的时候把原来的包放过去,如果需要过滤再多发一个你的修改包,这样TCP应该能连接上。
[解决办法]
重定向到本地不是那么容易的

热点排行