原始套接字伪造A的IP地址给B发送TCP数据包(类似三次握手第一步)
楼主在校生,在做一个项目,改良版的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 = { 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;
}
学习了,谢谢楼主。
页:
[1]