求助!SYN扫描接收不到对方的回应

wangtingkui 2015-08-12 05:05:53
发送自定义包可以成功,但是接收不到对方的回应,用connect扫描可以正确扫描

代码如下:
//申请发送套接字
SOCKET sockRaw = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (sockRaw == INVALID_SOCKET)
{
setErrInfo("申请Row Socket失败",WSAGetLastError());
return FALSE;
}

//设置套接字选项
BOOL bOpt = true;
int iTimeOut = 1000;
setsockopt(sockRaw, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt, sizeof(bOpt));
setsockopt(sockRaw, SOL_SOCKET, SO_SNDTIMEO, (char *)&iTimeOut, sizeof(iTimeOut));
setsockopt(sockRaw, SOL_SOCKET, SO_RCVTIMEO, (char *)&iTimeOut, sizeof(iTimeOut));

//绑定本机接收IP
sockaddr_in myAddr;
memset(&myAddr, 0, sizeof(myAddr));
myAddr.sin_addr.S_un.S_addr = getLocalIP();
myAddr.sin_family = AF_INET;
myAddr.sin_port = htons(DEF_LISTEN_PORT);
if (SOCKET_ERROR == bind(sockRaw, (const sockaddr*)&myAddr, sizeof(myAddr)))
{
closesocket(sockRaw);
sockRaw = INVALID_SOCKET;
setErrInfo("绑定接收套接字失败", WSAGetLastError());
return FALSE;
}

//设置可以接受所有IP
DWORD dwInBuffer = 1;
char szBuffer[10] = {0};
DWORD dwBytesReturned = 0;
if (SOCKET_ERROR == WSAIoctl(sockRaw, SIO_RCVALL, &dwInBuffer, sizeof(dwInBuffer),
NULL, 0, &dwBytesReturned, NULL, NULL))
{
closesocket(sockRaw);
sockRaw = INVALID_SOCKET;
setErrInfo("WSAIoctl设置出错", WSAGetLastError());
return FALSE;
}

//设置目的地址
sockaddr_in dstAddr;
memset(&dstAddr, 0, sizeof(dstAddr));
dstAddr.sin_addr.S_un.S_addr = inet_addr(m_dstIP);
dstAddr.sin_family = AF_INET;

//封装并发送数据包
IP_HEADER ip_header;
TCP_HEADER tcp_header;
PSD_HEADER psd_header;

//填充IP首部
ip_header.h_lenver = (4 << 4 | sizeof(ip_header) / sizeof(unsigned long)); //高四位IP版本号,低四位首部长度
ip_header.tos = 0;
ip_header.total_len = htons(sizeof(IP_HEADER) + sizeof(TCP_HEADER)); //16位总长度(字节)
ip_header.ident = 1; //16位标识
ip_header.frag_and_flags = 0; //3位标志位
ip_header.ttl = 128; //8位生存时间TTL
ip_header.proto = IPPROTO_TCP; //8位协议(TCP,UDP…) //16位IP首部校验和
ip_header.sourceIP = myAddr.sin_addr.S_un.S_addr; //32位源IP地址
ip_header.destIP = dstAddr.sin_addr.S_un.S_addr; //32位目的IP地址

//填充TCP首部
tcp_header.th_sport = htons(DEF_LISTEN_PORT);
tcp_header.th_seq = htonl(SEQ); //源端口号
tcp_header.th_ack = 0; //ACK序列号置为0
tcp_header.th_lenres = (sizeof(TCP_HEADER) / 4 << 4 | 0); //TCP长度和保留位
tcp_header.th_flag = 2; //SYN 标志,1:FIN,16:ACK
tcp_header.th_win = htons(512);
tcp_header.th_urp = 0;

//填充TCP伪首部(用于计算校验和,并不真正发送)
psd_header.saddr = ip_header.sourceIP;
psd_header.daddr = ip_header.destIP;
psd_header.mbz = 0;
psd_header.ptcl = IPPROTO_TCP;
psd_header.tcpl = htons(sizeof(tcp_header));

//对每一个端口发送一个测试包
char sendBuf[128] = "";
for (DWORD port = m_dwPortBegin; port<= m_dwPortEnd; ++port)
{
//初始化头部检验和
ip_header.checksum = 0;
tcp_header.th_sum = 0;

//设置目的端口号
tcp_header.th_dport = htons(port);
dstAddr.sin_port = htons(port);

//计算TCP校验和,计算校验和时需要包括TCP pseudo header
memcpy(sendBuf, &psd_header, sizeof(psd_header));
memcpy(sendBuf + sizeof(psd_header), &tcp_header, sizeof(tcp_header));
tcp_header.th_sum = checksum((USHORT *)sendBuf, sizeof(psd_header) + sizeof(tcp_header));

//计算IP校验和
memcpy(sendBuf, &ip_header, sizeof(ip_header));
ip_header.checksum = checksum((USHORT *)sendBuf, sizeof(ip_header));

//填充发送缓冲区
memcpy(sendBuf, &ip_header, sizeof(ip_header));
memcpy(sendBuf + sizeof(ip_header), &tcp_header, sizeof(tcp_header));


//发送TCP报文
int iRet = sendto(sockRaw, sendBuf, sizeof(ip_header) + sizeof(tcp_header) ,0, (struct sockaddr*)&dstAddr, sizeof(dstAddr));
if (iRet == SOCKET_ERROR)
{
setErrInfo("发送出错", WSAGetLastError());
closesocket(sockRaw);
sockRaw = INVALID_SOCKET;
return FALSE;
}

//接收
int timeout = 2000;
DWORD startTime = GetTickCount();
int flag = 0;
char recvBuffer[65535] = "";
while (true)
{
if (GetTickCount() - startTime > timeout)
{
break;
}

int iRet = recv(sockRaw, recvBuffer, 65535, 0);
if (iRet != SOCKET_ERROR)
{
//解包
IP_HEADER *iphdr;
TCP_HEADER *tcphdr;
unsigned short iphdrlen;
iphdr = (IP_HEADER *)recvBuffer;
iphdrlen = sizeof(unsigned long) * (iphdr->h_lenver & 0xf);
tcphdr = (TCP_HEADER*)(recvBuffer + iphdrlen);

//是否来自目标IP
if (iphdr->sourceIP != dstAddr.sin_addr.S_un.S_addr)
continue;

//是否来自目标端口
if (ntohs(tcphdr->th_dport) != port)
continue;

//SYN/ACK - 扫描到一个端口
if (tcphdr->th_flag == 18)
{
setPortInfo(port, "listening...");
flag = 1;
break;
}
else
{
setPortInfo(port, "free...");
flag = 1;
break;
}
}
}

//长时间没有收到对方返回的包
if (flag == 0)
{
setPortInfo(port, "free...");
}
}
closesocket(sockRaw);
...全文
490 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
kinkon007 2016-02-22
  • 打赏
  • 举报
回复
把你发出的包抓下来分析一下
dibotiger 2015-09-12
  • 打赏
  • 举报
回复
如果CONNECT可以得到正确的结果. SYN包却得不到正确的响应, 只有一种可能, 你自己构造的数据报文内容有问题, 要么没有正确发出,要么被对方直接丢弃了.
wangtingkui 2015-08-12
  • 打赏
  • 举报
回复
引用 1 楼 oyljerry的回复:
是不是有防火墙过滤了你的SYN攻击
我没有开启防火墙啊
oyljerry 2015-08-12
  • 打赏
  • 举报
回复
是不是有防火墙过滤了你的SYN攻击

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧