问题描述
- 原始套接字实现SYN扫描,但用wireshark时始终没有发现发出去的包
-
#include
#include
#include
#include
#include
#include "WS2TCPIP.H"#pragma comment(lib,"Ws2_32.lib")
using namespace std;
//SOCKADDR_IN target, source;
//sockaddr_in target, source;
//int sock;typedef struct _iphdr
{
unsigned char h_verlen; //4位首部长度+4位IP版本号
unsigned char tos; //8位服务类型TOS
unsigned short total_len; //16位总长度(字节)
unsigned short ident; //16位标识
unsigned short frag_and_flags; //3位标志位
unsigned char ttl; //8位生存时间TTL
unsigned char proto; //8位协议(TCP、UDP或其他协议)
unsigned short checksum; //16位IP首部校验和
unsigned int sourceIP; //32位源IP地址
unsigned int destIP; //32位目的IP地址
}IPHEADER;//TCP伪首部的作用主要是进行校验和的计算
typedef struct psd_hdr //定义TCP伪首部
{
unsigned long saddr; //源地址
unsigned long daddr; //目的地址
char mbz;
char ptcl; //协议类型
unsigned short tcpl; //TCP长度
}PSDHEADER;typedef struct _tcphdr //定义TCP首部
{
USHORT th_sport; //16位源端口
USHORT th_dport; //16位目的端口
unsigned int th_seq; //32位序列号
unsigned int th_ack; //32位确认号
unsigned char th_lenres; //4位首部长度/6位保留字
unsigned char th_flag; //6位标志位
USHORT th_win; //16位窗口大小
USHORT th_sum; //16位校验和
USHORT th_urp; //16位紧急数据偏移量
}TCPHEADER;#define FINISH 100
#define RUN 200
#define SIO_WSAIOW(IOC_VENDOR,l)
#define SEQ 0x28376839USHORT CheckSum(USHORT buffer, int size) //CRC校验通用代码
{
unsigned long cksum = 0;
while (size > 1)
{
cksum += *buffer++;
size -= sizeof(USHORT);
}
if (size)
cksum += *(UCHAR)buffer;
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >> 16);
return (USHORT)(~cksum);
}//************************IP解包******************
/*
int DecodeIPHeader(char recvbuf, int bytes)
{
IPHEADER *iphdr;
TCPHEADER *tcphdr;
unsigned short iphdrlen;
iphdr = (IPHEADER *)recvbuf;
iphdrlen = sizeof(unsigned long) * (iphdr->h_verlen & 0xf);
iphdrlen = sizeof(IPHEADER);
tcphdr = (TCPHEADER)(recvbuf + iphdrlen);//是否来自目标IP
if (iphdr->sourceIP != target.sin_addr.s_addr) {
printf("不来自目标IPn");
return 0;
}//序列号是否正确
if (ntohl(tcphdr->th_ack) != (SEQ + 1)) {
printf("序列号错误n");
return 0;
}//RST/ACK - 无服务
if (tcphdr->th_flag == 20) {
printf("RST+ACK 无服务.n");
return 1;
}//SYN/ACK - 扫描到一个端口
if (tcphdr->th_flag == 18) {
printf("%dn", ntohs(tcphdr->th_sport));
return 2;
}
printf("未知n");
return 1;
}
*/////////////////////////////////////////////////////////////////////////
void SynScan(string uIP, u_short uPortBegin, u_short uPortEnd)
{
int datasize;
IPHEADER ipHeader;//IP包头
TCPHEADER tcpHeader;//TCP包头
PSDHEADER psdHeader;//伪TCP包头//**********************扫描顺序*********************** for (u_short port = uPortBegin;port<uPortEnd;port++) //端口顺序 { //SOCKET sock = INVALID_SOCKET; //SOCKET sock; int sock; SOCKADDR_IN target, source; WSADATA data; WORD w = MAKEWORD(2, 2); WSAStartup(w, &data); if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP)) == INVALID_SOCKET) { cout << "发送原始套接字Socket创建出错" << endl << GetLastError() << endl; return; } //**********************扫描顺序*********************** BOOL flag = true; if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag)) == SOCKET_ERROR) { cout << "套接字选项IP_HDRINCL出错!n" << endl; return; } //SIO_RCVALL函数是可以读取所有IP数据包的必要设置 DWORD dwBufferLen[10]; DWORD dwBufferInLen = 1; DWORD dwBytesReturned = 0; WSAIoctl(sock, _WSAIOW(IOC_VENDOR, 1), &dwBufferInLen, sizeof(dwBufferInLen), &dwBufferLen, sizeof(dwBufferLen), &dwBytesReturned, NULL, NULL); setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&flag, sizeof(flag)); source.sin_family = AF_INET; source.sin_port = htons(53638); source.sin_addr.s_addr = inet_addr("10.15.57.28");//本机IP地址 if (bind(sock, (PSOCKADDR)&source, sizeof(source)) == SOCKET_ERROR) cout << "绑定本地IP接收出错。" << endl; target.sin_family = AF_INET; target.sin_addr.s_addr = inet_addr(uIP.c_str()); //对方IP target.sin_port = htons(port); //对方端口 cout << uIP.c_str() << endl; //分别自己填充IP头、TCP头、伪IP头,并计算其中的校验和 char SendBuf[1024] = { 0 }; //设置IP包头 ipHeader.h_verlen = (4 << 4 | sizeof(ipHeader) / sizeof(unsigned long)); ipHeader.tos = 0; ipHeader.total_len = htons(sizeof(ipHeader) + sizeof(tcpHeader)); ipHeader.ident = 1; ipHeader.frag_and_flags = 0; ipHeader.ttl = 128; ipHeader.proto = IPPROTO_TCP; ipHeader.checksum = 0; ipHeader.sourceIP = source.sin_addr.s_addr; ipHeader.destIP = target.sin_addr.s_addr; //设置TCP头 tcpHeader.th_sport = source.sin_port; //本地端口 tcpHeader.th_dport = target.sin_port; //目标端口 tcpHeader.th_seq = htonl(SEQ); tcpHeader.th_ack = 0; tcpHeader.th_lenres = (sizeof(tcpHeader) / 4 << 4 | 0); tcpHeader.th_flag = 2; //2为SYN,1为FIN,16为ACK tcpHeader.th_win = htons(16384); tcpHeader.th_urp = 0; tcpHeader.th_sum = 0; //伪TCP头 psdHeader.saddr = ipHeader.sourceIP; psdHeader.daddr = ipHeader.destIP; psdHeader.mbz = 0; psdHeader.ptcl = IPPROTO_TCP; psdHeader.tcpl = htons(sizeof(tcpHeader)); //计算校验和 memcpy(SendBuf, &psdHeader, sizeof(psdHeader)); memcpy(SendBuf + sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader)); tcpHeader.th_sum = CheckSum((USHORT *)SendBuf, sizeof(psdHeader) + sizeof(tcpHeader)); memcpy(SendBuf, &ipHeader, sizeof(ipHeader)); memcpy(SendBuf + sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader)); memset(SendBuf + sizeof(ipHeader) + sizeof(tcpHeader), 0, 4); ipHeader.checksum = CheckSum((USHORT*)SendBuf, sizeof(ipHeader) + sizeof(tcpHeader)); //复制IP包+TCP包,进行发送 memcpy(SendBuf, &ipHeader, sizeof(ipHeader)); if ((sendto(sock, SendBuf, sizeof(ipHeader) + sizeof(tcpHeader), 0, (struct sockaddr *)&target, sizeof(struct sockaddr))) < 0) { cout << "sendto error" << endl << GetLastError() << endl; } int buflen = sizeof(target); memset(RecvBuf, 0, sizeof(RecvBuf)); cout << "端口 " << port << endl; shutdown(sock, 2); closesocket(sock); WSACleanup(); }
}
int main()
{
string ip = "10.15.57.1";
SynScan(ip, 1, 500);
system("pause");
return 0;
}
解决方案
http://bbs.csdn.net/topics/390659636