邪恶八进制信息安全团队技术讨论组's Archiver

冰血封情 2004-9-25 04:49

[转载]一个syn扫描程序源代码

文章作者:云舒 [PST]

[code]//---------------------------------------------------------------------------
//Filename:ss.c
//Author:yunshu
//Write:2004-04-02
//Thanks Wineggdrop
//Modify:2004-09-08
//---------------------------------------------------------------------------

#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     usage( char * );//显示帮助函数
void     check_port( char * );//判断端口是否开放函数


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

int main( int argc , char *argv[] )
{
   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();
   return 0;
}

//计算检验和函数,完全抄别人的
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);
}

void usage(char *prog)
{
   printf("===========================================\n");
   printf("Used To Scan Remote Host&#39;s Ports\n");
   printf("OurTeam:[url]http://www.ph4nt0m.net[/url]\n");
   printf("Usage:%s TargetIP\n",prog);
   printf("===========================================\n");
   exit(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] = ;
   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;
}

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

   //建立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(TRUE)
   {
      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]);
      }
   }
}[/code]

icephonix 2005-6-8 18:33

这个代码到底是用说明编译的,我用VC++6.0编译,有一堆的错误!

EvilOctal 2005-6-8 22:08

[quote][b]下面是引用icephonix于06-08-2005 18:33发表的:[/b]
这个代码到底是用说明编译的,我用VC++6.0编译,有一堆的错误![/quote]
我用VC6编译通过 一开始有错误:
[quote]--------------------Configuration: Cpp1 - Win32 Debug--------------------
Compiling...
Cpp1.cpp
C:\Documents and Settings\Administrator\My Documents\Cpp1.cpp(22) : error C2059: syntax error : &#39;;&#39;
C:\Documents and Settings\Administrator\My Documents\Cpp1.cpp(23) : error C2059: syntax error : &#39;;&#39;
C:\Documents and Settings\Administrator\My Documents\Cpp1.cpp(27) : error C2059: syntax error : &#39;;&#39;
C:\Documents and Settings\Administrator\My Documents\Cpp1.cpp(84) : error C2059: syntax error : &#39;;&#39;
C:\Documents and Settings\Administrator\My Documents\Cpp1.cpp(190) : error C2059: syntax error : &#39;;&#39;
C:\Documents and Settings\Administrator\My Documents\Cpp1.cpp(283) : error C2059: syntax error : &#39;;&#39;
Error executing cl.exe.

Cpp1.obj - 6 error(s), 0 warning(s)[/quote]
但是这些并不是真正的错误 自己看看就知道了

icephonix 2005-6-10 19:16

我在办公室的机器上的错误和你一样,在宿舍的机器上有四十多个错误!不过办公室编译出来的还是用不起来,总是数据包发送错误!

dahubaobao 2005-6-11 01:53

VC 6.0中是没有mstcpip.h的  自己添加吧  另外我编译好了一个  见附件

[code]
//  Copyright (C) Microsoft Corporation, 1996-1999
#if _MSC_VER > 1000
#pragma once
#endif

/* Argument structure for SIO_KEEPALIVE_VALS */

struct tcp_keepalive {
   u_long  onoff;
   u_long  keepalivetime;
   u_long  keepaliveinterval;
};

// New WSAIoctl Options

#define SIO_RCVALL        _WSAIOW(IOC_VENDOR,1)
#define SIO_RCVALL_MCAST    _WSAIOW(IOC_VENDOR,2)
#define SIO_RCVALL_IGMPMCAST  _WSAIOW(IOC_VENDOR,3)
#define SIO_KEEPALIVE_VALS   _WSAIOW(IOC_VENDOR,4)
#define SIO_ABSORB_RTRALERT  _WSAIOW(IOC_VENDOR,5)
#define SIO_UCAST_IF       _WSAIOW(IOC_VENDOR,6)
#define SIO_LIMIT_BROADCASTS  _WSAIOW(IOC_VENDOR,7)
#define SIO_INDEX_BIND      _WSAIOW(IOC_VENDOR,8)
#define SIO_INDEX_MCASTIF    _WSAIOW(IOC_VENDOR,9)
#define SIO_INDEX_ADD_MCAST  _WSAIOW(IOC_VENDOR,10)
#define SIO_INDEX_DEL_MCAST  _WSAIOW(IOC_VENDOR,11)
[/code]

icephonix 2005-6-12 15:46

我也编译出来了,运行后,结果和你的一样是Send Packet Error...
Send Packet Error...
Send Packet Error...
Send Packet Error...
Send Packet Error...
Send Packet Error...
Send Packet Error...
Send Packet Error...
Send Packet Error...
Send Packet Error...
Send Packet Error...
Send Packet Error...
Send Packet Error...
Send Packet Error...
Send Packet Error...
Send Packet Error...
Send Packet Error...

云舒 2005-8-26 12:54

我写这个的时候用的是dev-cpp,win2000系统。
不好意思,那时侯写代码还不知道写上编译环境,现在比较规范了,也开始使用vc编译了。
这个我用的时候是可以的,是不是你们的电脑不能发送raw数据包?

kiki 2005-9-14 00:11

确实是有一些问题,,在一些机器上可以运行,,有一部分却又发生send error!!
是不是权限的问题呢?

恶魔的影子 2005-10-25 22:39

我在vc.net中编译通过.
在debug环境下运行一切正常:
D:\vc\synscan\Debug>synscan.exe 192.168.10.3
[Found] 192.168.10.3   port   135    Open
[Found] 192.168.10.3   port   139    Open
[Found] 192.168.10.3   port   445    Open
[Found] 192.168.10.3   port   80    Open
[Found] 192.168.10.3   port   443    Open
可在release环境下虽然编译通过,
程序也可以发包.就是没什么提示.不知道怎么回事?!

云舒 2005-10-28 14:44

汗,这么多奇怪的问题啊
我写完这个代码就没管了,你们空了就看看吧,找到原因也告诉我,忙死了,我。

云舒 2005-11-3 11:25

前几天晚上在虚拟机上面看了下
我用dev-c++编译的,修改了点代码,主要就是输出错误比较详细。
Win2003+sp1不能运行,估计xp+sp2可能也不行,其他的系统应该没问题。
空了再看看nmap,它在Win2003+sp1下是可以的,不过似乎是利用的winpcap库。

云舒 2005-12-16 13:20

汗,我爱搞破坏
还记得吗,灰色的时候。。。。。。。曾经的灰色。。。

页: [1]
© 1999-2008 EvilOctal Security Team