现在的位置: 首页 > 综合 > 正文

两个半连接扫描程序源代码

2012年01月08日 ⁄ 综合 ⁄ 共 13677字 ⁄ 字号 评论关闭

第一个:

//这是别人写的一个半连接的扫描
//

#include <winsock2.h>
#include <ws2tcpip.h>
#include "mstcpip.h"
#include <stdio.h>

#pragma comment(lib,"ws2_32.lib")

////////////////////////////////////////////////////////////////
//全局变量
////////////////////////////////////////////////////////////////

#define srcPort 88

char srcIP[20] = ;        //定义源地址 ----------->>>>>>>
char tgtIP[20] = ;        //定义目的地址 -------------->>>>>>>
int  portNow;            //定义正在扫描的端口

//标准端口列表
int ports[20] =;

typedef struct ip_hdr
{
    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地址
}IP_HEADER;

typedef struct tcp_hdr //定义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位紧急数据偏移量
}TCP_HEADER;

typedef struct tsd_hdr //定义TCP伪首部
{
    unsigned long saddr; //源地址
    unsigned long daddr; //目的地址
    char mbz;
    char ptcl; //协议类型
    unsigned short tcpl; //TCP长度
}PSD_HEADER;

////////////////////////////////////////////////////////////////
//函数原形
////////////////////////////////////////////////////////////////

int        send_packet();                //发送数据函数
int        recv_packet();                //监听数据函数
USHORT     checksum( USHORT *, int );    //计算检验和函数
void       check_port( char * );        //判断端口是否开放函数

//////////////////////////////////////////////////////////////// ------------------------------
//main函数
////////////////////////////////////////////////////////////////

int main( int argc , char *argv[] )
{
    int end;
    WSADATA                WSAData;
    DWORD                thread_ID = 1;
    char                FAR hostname[128] = ; //--------->>>>>>>>>>
    HANDLE                ThreadHandle[20];
    struct hostent        *phe;

    if( argc != 2 )//检查命令行参数是否正确
    {
        usage( argv[0] );
        exit( 0 );
    }

    if ( WSAStartup(MAKEWORD(2,2) ,  &WSAData) )
    {
        printf("WSAStartup Error.../n");
        exit(0);
    }

    strcpy(tgtIP,argv[1]);//得到目标主机的ip地址

    gethostname(hostname,128);//获取本机主机名

    phe = gethostbyname(hostname);//获取本机ip地址结构

    if(phe == NULL)
    {
        printf("Get LocalIP Error.../n");
    }

    strcpy(srcIP, inet_ntoa(*((struct in_addr *)phe->h_addr_list[0])));//得到本机ip地址

    //调试用,注释掉
    //printf("test/t%s/n",tgtIP);
    //printf("test/t%s/n",srcIP);

    //开启新线程,接受数据包,分析返回的信息
    HANDLE    RecvHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)recv_packet,NULL,0,&thread_ID);

    Sleep(500);//休息一下再启动发送数据包函数

    for(int tmp = 0; tmp < 20; tmp++)
    {
        ++thread_ID;

        //要扫描的端口
        portNow = ports[tmp];

        //开启新线程,发送数据包
        ThreadHandle[tmp] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)send_packet,NULL,0,&thread_ID);

        //防止生成线程过快,休息
        Sleep(100);
    }

    DWORD WaitThread = WaitForMultipleObjects( 20 , ThreadHandle , TRUE , INFINITE );
    if( WaitThread != WAIT_FAILED)
    {
        for( int n = 0 ; n < 20 ; n++ )
        {
            CloseHandle( ThreadHandle[n] );
        }
    }
    CloseHandle( RecvHandle );

    WSACleanup();
    scanf("%d",&end);
    return 0;
}

//---------------------------------------------------------------------功能函数

//发送数据包的函数
int send_packet()
{
    SOCKET             sendSocket;
    BOOL               flag;
    int                timeout;
    SOCKADDR_IN        sin;
    IP_HEADER          ipHeader;
    TCP_HEADER         tcpHeader;
    PSD_HEADER         psdHeader;
    char               szSendBuf[60] = {0}; //发送包的缓冲区
    int                ret;
    unsigned long      source_ip;
    unsigned long      target_ip;

    //建立原生数据socket
    if((sendSocket = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
    {
        printf("Socket Setup Error.../n");
        return 0;
    }

    //设置自己填充数据包
    if(setsockopt(sendSocket, IPPROTO_IP, IP_HDRINCL, (char *)&flag, sizeof(flag)) == SOCKET_ERROR)
    {
        printf("Setsockopt IP_HDRINCL Error.../n");
        return 0;
    }

    //设置超时时间
    timeout = 1000;
    if(setsockopt(sendSocket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) == SOCKET_ERROR)
    {
        printf("Setsockopt SO_SNDTIMEO Error.../n");
        return 0;
    }

    target_ip = inet_addr(tgtIP);
    source_ip = inet_addr(srcIP);

    sin.sin_family = AF_INET;
    sin.sin_port = htons(portNow);
    sin.sin_addr.S_un.S_addr = target_ip;

    //填充IP首部
    ipHeader.h_verlen = (4<<4 | sizeof(ipHeader)/sizeof(unsigned long));
    ipHeader.total_len = htons(sizeof(ipHeader)+sizeof(tcpHeader));
    ipHeader.ident = 1;
    ipHeader.frag_and_flags = 0x40;
    ipHeader.ttl = 128;
    ipHeader.proto = IPPROTO_TCP;
    ipHeader.checksum = 0;
    ipHeader.sourceIP = source_ip;//源IP
    ipHeader.destIP = target_ip;//目的IP

    //填充TCP首部
    tcpHeader.th_dport = htons(portNow);//目的端口
    tcpHeader.th_sport = htons(srcPort); //源端口
    tcpHeader.th_seq = 0x12345678;
    tcpHeader.th_ack = 0;
    tcpHeader.th_lenres = (sizeof(tcpHeader)/4<<4|0);
    tcpHeader.th_flag = 2;//syn标志位。0,2,4,8,16,32->FIN,SYN,RST,PSH,ACK,URG(推测,哈哈)
    tcpHeader.th_win = htons(512);
    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));

    //计算TCP校验和
    memcpy(szSendBuf, &psdHeader, sizeof(psdHeader));
    memcpy(szSendBuf + sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader));

    tcpHeader.th_sum = checksum((USHORT *)szSendBuf, sizeof(psdHeader) + sizeof(tcpHeader));

    //计算IP检验和
    memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));
    memcpy(szSendBuf + sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));
    memset(szSendBuf + sizeof(ipHeader) + sizeof(tcpHeader), 0, 4);
    ipHeader.checksum = checksum((USHORT *)szSendBuf, sizeof(ipHeader) + sizeof(tcpHeader));

    memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));
    memcpy(szSendBuf + sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));

    //发送数据包
    ret = sendto(sendSocket, szSendBuf, sizeof(ipHeader) + sizeof(tcpHeader), 0, (struct sockaddr*)&sin, sizeof(sin));

    if(ret == SOCKET_ERROR)
    {
        printf("Send Packet Error.../n");
        return 0;
    }
    else return 1;
}

//SINFFER函数
int recv_packet()
{
    SOCKET          sock;
    SOCKADDR_IN     sniff;
    char            recvBuffer[65000] = {0};//缓冲区存放捕获的数据

    //建立socket监听数据包
    sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP);

    sniff.sin_family = AF_INET;
    sniff.sin_port = htons(0);
    sniff.sin_addr.s_addr = inet_addr(srcIP);

    //绑定到本地随机端口
    bind(sock,(PSOCKADDR)&sniff,sizeof(sniff));

    //设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包
    //copy来的
    DWORD dwBufferLen[10] ;
    DWORD dwBufferInLen = 1 ;
    DWORD dwBytesReturned = 0 ;
    WSAIoctl(sock,SIO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),&dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL);

    while(1)
    {
        memset(recvBuffer , 0 , sizeof(recvBuffer) );

        //开始捕获数据包
        int bytesRecived = recv(sock,recvBuffer,sizeof(recvBuffer),0);
        if(bytesRecived <= 0)
        {
            break;
        }
        check_port(recvBuffer); //调用解包函数
    }
    return 1;
}

//解包函数
void check_port(char *buffer)
{
    IP_HEADER        *ipHeader;//IP_HEADER型指针
    TCP_HEADER       *tcpHeader;//TCP_HEADER型指针

    ipHeader = (IP_HEADER *)buffer;
    tcpHeader = (TCP_HEADER *) (buffer+sizeof(IP_HEADER));

    if(ipHeader->sourceIP != inet_addr(tgtIP))
    {
        return;
    }

    for(int tmp=0;tmp<20;tmp++)
    {
        //SYN+ACK -> 2+16=18(也是推测,哈哈)
        if(tcpHeader->th_flag == 18 && tcpHeader->th_sport == htons(ports[tmp]))
        {
            printf("[Found]/t%s/tport/t%d/tOpen/n",tgtIP,ports[tmp]);
        }
    }
}

//--------------------------------------------------------
//计算检验和函数,完全抄别人的
USHORT checksum(USHORT *buffer, int size)
{
    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);
}

第二个:

//半打开扫描源程序(for WIN2K)
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include "mstcpip.h"
#pragma comment(lib,"ws2_32")

#define DEFAULT_DEST_PORT 5
#define DEST_HOST "www.hrbust.edu.cn"
#define SEQ 0x28376839

typedef struct _iphdr
{
unsigned char h_lenver; //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地址
}IP_HEADER;

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位紧急数据偏移量
}TCP_HEADER;

struct //定义TCP伪首部
{
unsigned long saddr; //源地址
unsigned long daddr; //目的地址
char mbz;
char ptcl; //协议类型
unsigned short tcpl; //TCP长度
}psd_header;

SOCKET sockRaw = INVALID_SOCKET,
sockListen = INVALID_SOCKET;
struct sockaddr_in dest;

//SOCK错误处理程序
void CheckSockError(int iErrorCode, char *pErrorMsg)
{
if(iErrorCode==SOCKET_ERROR) 
{
printf("%s Error:%d/n", pErrorMsg, GetLastError());
closesocket(sockRaw);
ExitProcess(-1);
}

}

//计算检验和
USHORT checksum(USHORT *buffer, int size)
{
  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解包程序
bool DecodeIPHeader(char *buf, int bytes)
{
IP_HEADER *iphdr;
TCP_HEADER *tcphdr;
  unsigned short iphdrlen;

  iphdr = (IP_HEADER *)buf;
  iphdrlen = sizeof(unsigned long) * (iphdr->h_lenver & 0xf);
  tcphdr = (TCP_HEADER*)(buf + iphdrlen);

//是否来自目标IP
if(iphdr->sourceIP != dest.sin_addr.s_addr) return false;

//序列号是否正确
if((ntohl(tcphdr->th_ack) != (SEQ+1)) && (ntohl(tcphdr->th_ack) != SEQ)) return false;

//RST/ACK - 无服务
if(tcphdr->th_flag == 20)
{
printf("./n");
return true;
}

//SYN/ACK - 扫描到一个端口
if(tcphdr ->th_flag == 18)
{
printf("%d/n",ntohs(tcphdr->th_sport));
return true;
}

  return true;
}

//主函数
int main(int argc,char **argv)
{
int iErrorCode;
int datasize;
struct hostent *hp;
IP_HEADER ip_header;
TCP_HEADER tcp_header;
char SendBuf[128]={0};
char RecvBuf[65535]={0};

//初始化SOCKET
WSADATA wsaData;
iErrorCode = WSAStartup(MAKEWORD(2,2),&wsaData);
CheckSockError(iErrorCode, "WSAStartup()");
sockRaw = socket(AF_INET , SOCK_RAW , IPPROTO_IP);
CheckSockError(sockRaw, "socket()");
sockListen = socket(AF_INET , SOCK_RAW , IPPROTO_IP);
CheckSockError(sockListen, "socket");

//设置IP头操作选项
BOOL bOpt = true;
iErrorCode = setsockopt(sockRaw,IPPROTO_IP,IP_HDRINCL,(char *)&bOpt,sizeof(bOpt));
CheckSockError(iErrorCode, "setsockopt()");

//获得本地IP
SOCKADDR_IN sa;
unsigned char LocalName[256];

iErrorCode = gethostname((char*)LocalName,sizeof(LocalName)-1);
CheckSockError(iErrorCode, "gethostname()");
if((hp = gethostbyname((char*)LocalName)) == NULL)
{
CheckSockError(SOCKET_ERROR, "gethostbyname()");
}
memcpy(&sa.sin_addr.S_un.S_addr,hp->h_addr_list[0],hp->h_length);
sa.sin_family = AF_INET;
sa.sin_port = htons(7000);
iErrorCode = bind(sockListen, (PSOCKADDR)&sa, sizeof(sa));
CheckSockError(iErrorCode, "bind");

//设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包
DWORD dwBufferLen[10] ;
DWORD dwBufferInLen = 1 ;
DWORD dwBytesReturned = 0 ;
iErrorCode=WSAIoctl(sockListen, SIO_RCVALL,&dwBufferInLen, sizeof(dwBufferInLen),      
            &dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL );
CheckSockError(iErrorCode, "Ioctl");

//获得目标主机IP
memset(&dest,0,sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_port = htons(DEFAULT_DEST_PORT);
if((dest.sin_addr.s_addr = inet_addr(DEST_HOST)) == INADDR_NONE)
{
if((hp = gethostbyname(DEST_HOST)) != NULL)
{
memcpy(&(dest.sin_addr),hp->h_addr_list[0],hp->h_length);
dest.sin_family = hp->h_addrtype;
printf("dest.sin_addr = %s/n",inet_ntoa(dest.sin_addr));
}
else
{
CheckSockError(SOCKET_ERROR, "gethostbyname()");
}
}

//填充IP首部
ip_header.h_lenver=(4<<4 | sizeof(ip_header)/sizeof(unsigned long));
//高四位IP版本号,低四位首部长度
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…)
ip_header.checksum=0; //16位IP首部校验和
ip_header.sourceIP=sa.sin_addr.s_addr; //32位源IP地址
ip_header.destIP=dest.sin_addr.s_addr; //32位目的IP地址

//填充TCP首部
tcp_header.th_sport=htons(7000); //源端口号
tcp_header.th_dport=htons(DEFAULT_DEST_PORT); //目的端口号
tcp_header.th_seq=htonl(SEQ); //SYN序列号
tcp_header.th_ack=0; //ACK序列号置为0
tcp_header.th_lenres=(sizeof(TCP_HEADER)/4<<4|0); //TCP长度和保留位
tcp_header.th_flag=2; //SYN 标志
tcp_header.th_win=htons(16384); //窗口大小
tcp_header.th_urp=0; //偏移
tcp_header.th_sum=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));

//计算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));
memcpy(SendBuf+sizeof(ip_header),&tcp_header,sizeof(tcp_header));
memset(SendBuf+sizeof(ip_header)+sizeof(tcp_header),0,4);
datasize=sizeof(ip_header)+sizeof(tcp_header);
ip_header.checksum=checksum((USHORT *)SendBuf,datasize);

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

//发送TCP报文
iErrorCode=sendto(sockRaw,SendBuf,datasize,0,(struct sockaddr*) &dest,
sizeof(dest));
CheckSockError(iErrorCode, "sendto()");

//接收数据
DWORD timeout = 2000;
DWORD start = GetTickCount();
while(true)
{
//计时,2s超时
if((GetTickCount() - start) >= timeout) break;

memset(RecvBuf, 0, sizeof(RecvBuf));
iErrorCode = recv(sockListen, RecvBuf, sizeof(RecvBuf), 0);
CheckSockError(iErrorCode, "recv");

if(DecodeIPHeader(RecvBuf,iErrorCode)) break;
}

//退出前清理
if(sockRaw != INVALID_SOCKET) closesocket(sockRaw);
WSACleanup();
return 0;
}

抱歉!评论已关闭.