[转载]一个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'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] 这个代码到底是用说明编译的,我用VC++6.0编译,有一堆的错误! [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 : ';'
C:\Documents and Settings\Administrator\My Documents\Cpp1.cpp(23) : error C2059: syntax error : ';'
C:\Documents and Settings\Administrator\My Documents\Cpp1.cpp(27) : error C2059: syntax error : ';'
C:\Documents and Settings\Administrator\My Documents\Cpp1.cpp(84) : error C2059: syntax error : ';'
C:\Documents and Settings\Administrator\My Documents\Cpp1.cpp(190) : error C2059: syntax error : ';'
C:\Documents and Settings\Administrator\My Documents\Cpp1.cpp(283) : error C2059: syntax error : ';'
Error executing cl.exe.
Cpp1.obj - 6 error(s), 0 warning(s)[/quote]
但是这些并不是真正的错误 自己看看就知道了 我在办公室的机器上的错误和你一样,在宿舍的机器上有四十多个错误!不过办公室编译出来的还是用不起来,总是数据包发送错误! 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] 我也编译出来了,运行后,结果和你的一样是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... 我写这个的时候用的是dev-cpp,win2000系统。
不好意思,那时侯写代码还不知道写上编译环境,现在比较规范了,也开始使用vc编译了。
这个我用的时候是可以的,是不是你们的电脑不能发送raw数据包? 确实是有一些问题,,在一些机器上可以运行,,有一部分却又发生send error!!
是不是权限的问题呢? 我在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环境下虽然编译通过,
程序也可以发包.就是没什么提示.不知道怎么回事?! 汗,这么多奇怪的问题啊
我写完这个代码就没管了,你们空了就看看吧,找到原因也告诉我,忙死了,我。 前几天晚上在虚拟机上面看了下
我用dev-c++编译的,修改了点代码,主要就是输出错误比较详细。
Win2003+sp1不能运行,估计xp+sp2可能也不行,其他的系统应该没问题。
空了再看看nmap,它在Win2003+sp1下是可以的,不过似乎是利用的winpcap库。 汗,我爱搞破坏
还记得吗,灰色的时候。。。。。。。曾经的灰色。。。
页:
[1]