|
3驿站币
本帖最后由 00011011 于 2017-3-6 10:42 编辑
楼主在校生,在做一个项目,改良版的nmap扫描器中的idle扫描。
下面的代码实现的功能是:原始套接字伪造A的IP地址给B发送TCP数据包(类似三次握手第一步)
下面代码中setsockopt这个函数一直报错,请各位指正,参考书是刘文涛的《网络安全编程技术与实例》、李瑞民的《网络扫描技术揭秘》以及诸位大佬的相关代码额。。。。。
- #include "stdafx.h"
- #include <WinSock2.h>
- #pragma warning(disable:4996)
- #include <stdio.h>
- #include <string.h>
- #include <WS2tcpip.h>
- #include "mstcpip.h"
- #include <time.h>
- #pragma comment(lib,"ws2_32.lib")
- #define MAXSIZE 1024
- char *CHAR_SOURCE_IP = "10.251.93.11"; //所伪造的IP地址
- char *CHAR_TARGET_IP = "10.252.245.38"; //目标的IP地址
- //重定义IP数据包头部
- typedef struct ip_header
- {
- unsigned char h_verlen; //版本号+头长度--------------1组
- unsigned char tos; //分区服务(默认为0)--------1组
- unsigned short total_len; //首部及数据总长度-----------2组
- unsigned short ident; //分片标识-------------------2组
- unsigned short frag_and_flags; //分片设置3bit---------------3/4组
- unsigned char ttl; //生存周期(跳数限制)-------1组
- unsigned char proto; //携带的协议-----------------1组
- unsigned short checksum; //首部校验和-----------------2组
- unsigned int sourceIP; //源IP地址-------------------4组
- unsigned int destIP; //目的IP地址-----------------4组
- };
- //重定义TCP数据包首部
- typedef struct tcp_header
- {
- USHORT th_sport; //16位源端口
- USHORT th_dport; //16位目的端口
- unsigned int th_seq; //32位序列号seq
- 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位紧急数据偏移量
- };
- //定义TCP伪首部
- typedef struct psd_tcp_header
- {
- unsigned long saddr; //源地址
- unsigned long daddr; //目的地址
- char mbz; char ptcl; //协议类型
- unsigned short tcpl; //TCP长度
- };
- //计算首部校验和的函数
- unsigned short checksum(unsigned short * buffer, int size)
- {
- unsigned long cksum = 0;
- unsigned short answer = 0;
- while (size > 1)
- {
- cksum += *buffer++;
- size -= sizeof(USHORT);
- }
- if (size == 1)
- {
- *(char *)&answer = *(char *)buffer;
- cksum += answer;
- }
- while (cksum >> 16)
- cksum = (cksum >> 16) + (cksum & 0xffff);
- return (USHORT)(~cksum);
- };
- int attacker2target(int port)
- {
- SOCKET sendsocket;
- SOCKADDR_IN addr_in;
- WSADATA wsa;
- ip_header IP_HEADER;
- tcp_header TCP_HEADER;
- psd_tcp_header PSD_TCP_HEADER;
- int SOURCE_PORT = 80;
- char szSendBuf[MAXSIZE] = { 0 };
- unsigned long desip = inet_addr(CHAR_TARGET_IP);
- if (WSAStartup(MAKEWORD(2, 2), &wsa) == SOCKET_ERROR)
- {
- printf("error !\n%d\n", GetLastError());
- return false;
- }
- srand((unsigned)time(NULL)); //随机种子生成,留出时间
- if ((sendsocket = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
- {
- printf("WSASocket failed with error !\n%d\n", GetLastError());
- return false;
- }
-
- bool bOpt = true;
- if (setsockopt(sendsocket, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt, sizeof(bOpt)) == SOCKET_ERROR )
- {
- printf("setsocketopt error !\n %d \n", WSAGetLastError());
- return false;
- }
- int nTimeOver = 1000;
- if (setsockopt(sendsocket, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeOver, sizeof(nTimeOver)) == SOCKET_ERROR)
- {
- printf("setsockopt failed with error %d\n\n", WSAGetLastError());
- return false;
- }
- addr_in.sin_family = AF_INET;
- addr_in.sin_port = htons(port);
- addr_in.sin_addr.S_un.S_addr = inet_addr(CHAR_TARGET_IP);
- //填充IP报头
- IP_HEADER.h_verlen = (4 << 4 | sizeof(IP_HEADER) / sizeof(unsigned long));
- // IP_HEADER.tos=0;
- IP_HEADER.total_len = htons(sizeof(IP_HEADER) + sizeof(TCP_HEADER));
- IP_HEADER.ident = 1;
- IP_HEADER.frag_and_flags = 0;
- IP_HEADER.ttl = 128;
- IP_HEADER.proto = IPPROTO_TCP;
- IP_HEADER.checksum = 0;
- IP_HEADER.sourceIP = inet_addr("localhost");
- IP_HEADER.destIP = desip;
- //填充TCP报头
- TCP_HEADER.th_dport = htons(port);
- TCP_HEADER.th_sport = htons(SOURCE_PORT); //源端口号
- TCP_HEADER.th_seq = htonl(0x12345678);
- TCP_HEADER.th_ack = 0;
- TCP_HEADER.th_lenres = (sizeof(TCP_HEADER) / 4 << 4 | 0);
- TCP_HEADER.th_flag = 2; //标志位探测,2是SYN
- TCP_HEADER.th_win = htons(512);
- TCP_HEADER.th_urp = 0;
- TCP_HEADER.th_sum = 0;
- PSD_TCP_HEADER.saddr = IP_HEADER.sourceIP;
- PSD_TCP_HEADER.daddr = IP_HEADER.destIP;
- PSD_TCP_HEADER.mbz = 0;
- PSD_TCP_HEADER.ptcl = IPPROTO_TCP;
- PSD_TCP_HEADER.tcpl = htons(sizeof(TCP_HEADER));
- memcpy(szSendBuf, &PSD_TCP_HEADER, sizeof(PSD_TCP_HEADER));
- memcpy(szSendBuf + sizeof(PSD_TCP_HEADER), &TCP_HEADER, sizeof(TCP_HEADER));
- TCP_HEADER.th_sum = checksum((unsigned short*)szSendBuf, sizeof(PSD_TCP_HEADER) + sizeof(TCP_HEADER));
- memcpy(szSendBuf, &IP_HEADER, sizeof(IP_HEADER));
- memcpy(szSendBuf + sizeof(IP_HEADER), &TCP_HEADER, sizeof(TCP_HEADER));
- memset(szSendBuf + sizeof(IP_HEADER) + sizeof(TCP_HEADER), 0, 4);
- IP_HEADER.checksum = checksum((unsigned short*)szSendBuf, sizeof(IP_HEADER) + sizeof(TCP_HEADER));
- memcpy(szSendBuf, &IP_HEADER, sizeof(IP_HEADER));
- int rect = sendto(sendsocket, szSendBuf, sizeof(IP_HEADER) + sizeof(TCP_HEADER), 0,
- (struct sockaddr*) &addr_in, sizeof(addr_in));
- if (rect == SOCKET_ERROR)
- {
- printf("send error!:%d\n", WSAGetLastError());
- return false;
- }
- else
- printf("send ok!\n");
- closesocket(sendsocket);
- WSACleanup();
- return rect;
- }
- int main()
- {
- int port;
- printf("please enput port number=\n");
- scanf("%d", &port);
- attacker2target(port);
- return 0;
- }
复制代码 |
上一篇: 一个关于WinPCAP和TCP的问题下一篇: 一个简单的C语言题求大神解答
|