Smaug 2016-04-15 14:42 采纳率: 0%
浏览 2048

原始套接字实现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 0x28376839

USHORT 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("不来自目标IP\n");
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("%d\n", 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;
}


  • 写回答

1条回答 默认 最新

  • devmiao 2016-04-15 15:43
    关注
    评论

报告相同问题?

悬赏问题

  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能
  • ¥15 jmeter脚本回放有的是对的有的是错的
  • ¥15 r语言蛋白组学相关问题