目录
写在开头
方法一:nmap扫描
方法二:非nmap环境的主机发现——ping命令
方法三:netcat实现端口扫描
方法四:伪设备实现端口扫描
总结与思考
信息搜集是渗透测试的第一步,而主机发现和端口扫描则是信息搜集的关键步骤。后续的渗透测试都是基于开始搜集侦察的信息。这一步一定要保证把信息搜集完整齐全,否则一旦后续渗透过程出现了思路不畅,就会返工完全重做,非常浪费时间。哪怕是扫描不到有效的信息,也要及时记录,至少证明此处我已经扫描过了,不需要重复返工。同时在大型的渗透测试项目时,可能是整个团队在进行渗透,及时记录更有助于团队成员的信息共享。而在进行常规打靶时的主机发现于端口扫描是有一些套路的,这里做一个简要的总结。
本文涉及nmap、ping命令、nc.traditional、伪设备连接四种方法进行主机发现/端口扫描,还涉及到许多bash脚本的编写。本篇博客是我看了红队笔记大佬的视频后总结实践归纳的笔记,其原视频见:
「红队笔记」主机发现和端口扫描的基本原理和工具选择_哔哩哔哩_bilibili
另外本人技术有限,如果博客中有错误或读者有其他简要,欢迎指正。
nmap是进行主机发现和端口扫描最为常见的工具,其中自带的一些脚本也可以帮助我们干很多事情 ,包括漏洞扫描等等。nmap在kali中是自带的,使用起来非常方便。但由于nmap这个工具过于出名,其流量特征早已被分析透彻,因此使用nmap进行扫描是很容易暴露痕迹的,容易被蓝队发现。在常规的打靶自学中,nmap还是非常常规的工具,我们应该熟悉其常规的参数和原理。nmap的参数使用帮助可使用nmap --help查看:
nmap --help
其中的参数有很多,我这里截图只有其中一部分。--help的帮助信息是非常关键的,细小的参数差异可能实现很多不同的功能。使用nmap扫描需要sudo,本篇博客就用root进行演示,省略sudo了,大家切勿效仿。莫慌,常见的参数只有几个,且听我慢慢道来。
1.主机发现:对整个网段进行扫描。如果靶机和攻击机在同一个网段,我们可以扫描自己的网段确定靶机的ip,命令如下:
nmap -sn 192.168.200.0/24
-sn是使用ping扫描的参数,早期的nmap版本使用-sP封装了ping,现已弃用。后接待扫描的网段,这里我攻击机和靶机都在同一网段,可使用ip a命令查看自己的网段。
可发现靶机的ip是192.168.200.144。网段中有很多主机,如何判断靶机一定是144呢?其实这源于对网段的熟悉,1,2,254这些ip都是对应一些网关,131是我kali攻击机的ip,因此可以确定144是靶机ip。在实际的渗透中,要想保证扫描准确,可以在靶机上线前后各进行一次扫描,对比上线的ip即可确定靶机的ip。
2.全端口扫描:确定靶机ip后,扫描靶机ip的全端口(1-65535),探测开放的端口,命令如下:
nmap --min-rate 10000 -p- 192.168.200.144
这里--min-rate 10000的意思是让nmap以不小于每秒10000次的速率进行扫描。10000这个数字是权衡的结果,数字过大,则扫描速度过快,有可能会有端口遗漏;数字过小,则扫描速度过慢,浪费时间。实际情况中建议扫描两次,保证没有端口遗漏。-p是要扫描的端口,-p-则表示进行全端口扫描(1-65535)。如上图,本次扫描出了许多tcp端口。
3.UDP扫描:查看有没有开放的UDP端口,UDP端口暴露的攻击面虽然较小,但我们也不要遗漏信息。
nmap -sU --min-rate 10000 -p- 192.168.200.144
如上图,开放的udp端口有111,5353,32768
4.服务版本探测:这一步通常基于第二步开放端口的探测结果,进一步扫描每个端口对应的服务版本和操作系统,得到更具体的信息。命令如下:
nmap -sT -sV -O -p22,25,80,110,111,139,143,445,901,3306 192.168.200.144
参数中-sT表示进行TCP扫描,-sV扫描服务版本,-O扫描操作系统,-p后面接第二步确定的开放端口,表示探测这些端口的服务版本。
5.漏洞脚本扫描:nmap中自带了一些内置脚本,其中就用漏洞脚本vuln,vuln是vulnerbility漏洞脆弱点的简写,命令如下:
nmap --script=vuln -p22,25,80,110,111,139,143,445,901,3306 192.168.200.144
--script=vuln表示使用自带的漏洞扫描脚本进行扫描,-p后接开放的端口,表示探测这些端口的漏洞。这一步扫描的时间较长,可能需要几分钟时间。nmap的漏洞扫描结果可以给我们一个渗透测试的大致思路,即哪里的漏洞较多,我们可以从哪个端口入手进行渗透。
我的这个靶机漏洞比较多,主要发生在80端口,其中的漏洞涉及Dos,sql注入,csrf,敏感信息等。通常情况nmap的漏洞扫描不会有太多结果,仅仅是一个辅助。
实际情况中,可能我们无法使用nmap进行主机发现(不想暴露流量特征/nmap被ban/环境中没有nmap且无法联网等情况) ,此时可以使用ping命令进行扫描。有关ping命令的参数帮助可用ping --help查看
参数有很多,最常见的是-c表示收到多少个应答后停止,-W设置超时时间等。如果不指定参数,window会默认发送4个icmp报文,而linux则会一直发送icmp报文,直到我们手动ctrl+c停止。对192.168.200.144进行ping探测,收到两个响应后停止,设置操作时间为1s,如下图,没有丢包。
ping -c 2 -W 1 192.168.200.144
有了这个基础,我们就可以用写一个bash脚本,对网段中的一些的ip进行遍历,并依次ping每个ip,查看回显,从而进行主机探测。我们这里写一个脚本,对192.168.200.141~192.168.200.145范围内的ip进行ping扫描,设置对每个ip收到1个响应即停止,超时时间为0.1秒,bash脚本如下:
for i in {141..145}; do ping 192.168.200.$i -c 1 -W 0.1; done
可以很明显的看到只有144这个ip有回显,显示64 bytes from 192.168.200.144,其他ip都没有反应,因此在141-145的范围内,存活的ip是144。如果主机存活(ping成功看到回显),回显中会有'from'字符,我们把from作为grep过滤的关键词,就可以更方便的看到ping成功的ip,bash脚本如下,此处对192.168.200.0/24整个网段进行ping探测:
for i in {1..254}; do ping -c 1 -W 0.1 192.168.200.$i|grep from;done
可以很方便的看到这个网段范围内存活的一些主机
利用nc进行端口扫描,不过要实现端口扫描用的是旧版的nc,而kali中默认安装的新版的nc,因此要使用nc.traditional,可以先用nc.traditional -h查看参数帮助:
比如以扫描20-120的端口开放情况为例,命令如下:
nc.traditional -vv -z 192.168.200.144 20-120
-vv
: 这是命令的选项之一,表示进行详细的输出(verbose)。通过使用该选项,命令将提供更多关于扫描进程的信息。
-z
: 这也是命令的选项之一,表示进行端口扫描。它会尝试建立到指定IP地址和端口的连接,但不发送任何实际的数据。
结果包含了20-120每个端口的开放情况,少部分是open,大部分是Connection redused。我们可以使用字符串open过滤,但发现单纯的使用|grep open无法实现过滤,这是显示标准错误和标准输出类型不统一的问题,我们需要加上2>&1实现类型的统一才可。
如果不添加2>&1
,标准错误(stderr)的输出将不会被重定向到标准输出(stdout),而是直接显示在终端上。这意味着通过管道操作符|
将无法捕获和处理错误输出。
在端口扫描过程中,如果存在连接错误或其他错误消息,它们将显示在终端上,而不会通过管道传递给下一个命令(grep)进行过滤和处理。这样就无法对错误消息进行筛选,只能看到所有的输出信息,包括成功连接的端口和连接错误的端口。
因此,如果不添加2>&1
,就无法将错误消息与正常输出一起处理,可能会导致输出信息的混乱,并且无法方便地区分哪些端口连接成功,哪些连接失败。添加2>&1
可以将错误消息与正常输出合并,使得可以对整个输出进行统一的处理。完整命令如下:
nc.traditional -vv -z 192.168.200.144 20-120 2>&1| grep open
当然,我们也可以反向过滤,过滤出不含refused的内容,添加命令|grep -v refused即可。-v
选项表示显示不匹配模式的行。命令如下:
nc.traditional -vv -z 192.168.200.144 20-120 2>&1| grep -v refused
伪设备,即/dev/tcp/ ,此处需要bash环境,而kali中的默认shell环境是zsh,可以用如下命令看到:
我们需要输入bash字符调整为bash的shell环境,若对20~120号端口进行扫描,bash脚本如下:
for i in {20..120}; do (echo < /dev/tcp/192.168.200.144/$i) &>/dev/null && printf "\n[+] The open port is : %d\n" "$i" || printf ".";done
这个脚本的作用是遍历指定的端口范围,尝试与目标IP地址的每个端口建立TCP连接。如果连接成功,则显示一个带有开放端口号的消息,如果连接失败,则显示一个点号.表示关闭端口,同时表示程序正在运行。这样可以快速扫描目标主机的端口,识别哪些端口是开放的。
for循环会依次遍历端口号,循环体中使用/dev/tcp特殊文件(伪设备)来进行基于TCP的端口连接测试。192.168.200.144
是要扫描的目标IP地址,$i
表示当前循环的端口号。
(echo < /dev/tcp/192.168.200.144/$i) &>/dev/null
:这一部分尝试与指定的IP地址和端口建立TCP连接。echo
命令通过输入重定向将内容发送到特殊文件/dev/tcp/IP/PORT
,这会尝试与给定的IP地址和端口进行连接。&>/dev/null
将连接过程中的任何输出(包括标准输出和标准错误)都重定向到/dev/null,意味着将其丢弃而不显示。
&& printf "\n[+] The open port is : %d\n" "$i"
:如果连接成功,即端口开放,就会执行这个语句,即逻辑与仅当&&之前的命令成功执行才会继续执行&&后面的命令,使用printf
命令打印出一个带有开放端口号的消息。
|| printf "."
:如果连接失败,即端口关闭,就会执行这个语句。它使用printf
命令打印一个点号作为标记表示端口关闭。同时不断的输出.也会表示程序正在运行,让我们方便确定程序一直在运行,而没有卡死。(如果遍历1-65535,时间会很长,通常情况大部分端口都是关闭的,如果没有输出,我们难以判断是不是脚本卡死了)
这里插叙一下,如果遍历所有端口1-65535,时间会很长,通常情况大部分端口都是关闭的,会输出很多点. 如果我们想终止程序,需要用ctrl + z,然后再kill -9 %1终止上一条命令:
本文总结了有关主机发现和端口扫描的常规方法思路。包括使用nmap工具和使用ping命令进行主机发现、使用nc.traditional进行端口扫描、使用伪设备进行端口扫描。本文涉及了许多bash脚本的for循环命令、有关输出重定向>&符号的使用、逻辑运算符&&和||的使用等,希望读者慢慢消化。
在进行常规的打靶训练时,nmap工具足够强大,也很方便。但我们不能单纯依赖工具,还是要会自己编写脚本,以适应更多nmap不方便使用的情况。
总结完毕,如果读者觉得有用,恳请多多点赞收藏关注。有关问题也可以在评论区提出,我一定知无不言。后续我还会继续学习渗透测试相关的知识,并写博客进行总结。希望读者多多支持。