发新话题
打印

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

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

文章作者:云舒 [PST]
复制内容到剪贴板
代码:
//---------------------------------------------------------------------------
//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]);
      }
   }
}
qq310926是我唯一用号,除此之外有其他号码号自称邪八冰血封情,则非本人。

TOP

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

TOP

引用:
下面是引用icephonix于06-08-2005 18:33发表的:
这个代码到底是用说明编译的,我用VC++6.0编译,有一堆的错误!
我用VC6编译通过 一开始有错误:
引用:
--------------------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)
但是这些并不是真正的错误 自己看看就知道了
曾几何时,有人对我说:装B遭雷劈。我说:去你妈的。于是,这个人又对我说:如果再说脏话,上帝会惩罚你的。我说:我操上帝。结论:彪悍的人生不需要上帝。

TOP

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

TOP

VC 6.0中是没有mstcpip.h的  自己添加吧  另外我编译好了一个  见附件
复制内容到剪贴板
代码:
//  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)

附件

syn.rar (13 KB)

2005-6-11 01:53, 下载次数: 255

请加47809945   100%通过!每个月总有那么几天,您的网络会受到黑客的攻击--坐立不安,烦躁无力,使用虎虎开发的"月月舒"防火墙,超轻超薄,易于携带,提供由内到外的全方位保护,即使流量再大,也可以冲浪自如,再也不用担心侧漏啦。

TOP

我也编译出来了,运行后,结果和你的一样是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...

TOP

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

TOP

确实是有一些问题,,在一些机器上可以运行,,有一部分却又发生send error!!
是不是权限的问题呢?
源静则流清 本正则丰茂 内修则外理 形端则影直

TOP

我在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环境下虽然编译通过,
程序也可以发包.就是没什么提示.不知道怎么回事?!

TOP

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

TOP

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

TOP

汗,我爱搞破坏
还记得吗,灰色的时候。。。。。。。曾经的灰色。。。
http://www.icylife.net

TOP

发新话题