HrPapers|Nmap渗透测试指南
红日安全成员 -- yumu
<font color=#FF0000> Nmap脚本引擎(NSE)</font>革新了Nmap的功能。它是在2007年的谷歌夏令营期间推出,虽然第一个脚本是针对服务和主机检测,时至今天,已经存在有14个类别涵盖广泛的任务,从网络发现到检测和利用安全漏洞。既然我们深知NSE的强大,那我们肯定要好好利用它,那么这篇文章我将引导大家走入NSE脚本的世界,时不我待,赶紧跟我一起行动吧。
01.先行体验
root@kali:~# nmap -sV -sC scanme.nmap.org
上一个命令运行带有操作<font color=#00ffff> 系统检测 (-O)</font>的SYN扫描,即<font color=#00ffff> 服务检测(-sV)</font>,最重要的是NSE在(-sC)上。 -sC选项启用NSE并在默认类别中运行任何脚本。 这组脚本被默认为是安全的,它不会执行任何可能会干扰在该服务上运行的服务的目标主机的操作。 但是,某些脚本执行可能引发的操作入侵检测系统(IDS)和入侵防护系统(IPS)中的警报。
02.深入了解
<font color=#FF0000>脚本分类</font>
首先我们得了解脚本的分类信息,这样我们才能更好地把我们自定义的脚本进行归类利用。
脚本类别 | 描述 |
---|---|
auth | 与用户认证相关的NSE脚本 |
broadcast | 使用广播收集网络信息 |
brute | 暴力破解 |
default | 默认,执行脚本(-sC) |
discovery | 与主机和服务发现相关的脚本 |
dos | 与拒绝服务攻击有关的脚本 |
exploit | 用于利用安全漏洞的脚本 |
external | 此类别适用于第三方服务的脚本 |
fuzzer | NSE脚本专注于模糊测试 |
intrusive | 入侵脚本 |
malware | 与恶意软件检测相关的脚本类别 |
safe | 在所有情况下默认为是安全的脚本 |
vuln | 与检测和利用安全漏洞相关的脚本 |
version | 高级系统脚本 |
<font color=#FF0000>NSE脚本选择</font>
Nmap使用<font color=#00ffff> --script</font>选项进行脚本的选择。 这个选项后面可以是一个脚本名称,NSE类别,NSE文件的路径,包含脚本的文件夹,甚至表达式。使用<font color=#00ffff> --script</font>通过脚本名称或类别进行选择脚本。Nmap选项会按名称执行脚本。 执行时用逗号分隔几个脚本:
直接加脚本名称
nmap --script http-title <target>
nmap -p80 --script http-huawei-hg5xx-vuln <target>
nmap --script http-title,http-methods <target>
以下屏幕截图显示了http-huawei-hg5xx-vuln脚本的输出。 此脚本利用华为设备中的远程漏洞进行检索,检索的信息包括PPPoE凭证和无线网络安全配置:
要选择整个类别,只需使用类别的名称(请参阅脚本作为参数。 例如,要运行漏洞类别,
使用以下命令:
nmap --script exploit <target>
您也可以用逗号分隔它们来运行多个类别:
nmap --script discovery,intrusive <target>
-sC选项仅仅是--script默认选项的别名。
按文件名或文件夹选择
要执行NSE脚本文件,请使用以下命令:
nmap --script /path/to/script.nse <target>
与类别类似,可以通过分离路径来执行多个脚本
用逗号分隔:
nmap --script /path/to/script.nse,/another/path/script2.nse <target>
要执行文件夹中包含的所有脚本,只需要传递文件夹名称
举个栗子:
nmap --script/path/to/folder/ <target>
nmap --script /custom-nse-scripts/ scanme.nmap.org
<font color=#FF0000>高级脚本选择与表达式</font>
表达式用于描述一组脚本。
我们可以利用脚本选择表达式的场景:
•举个栗子:(未利用表达式将匹配任何脚本)
使用不属于exploit类别的脚本:
#nmap -sV --script "not exploit" <target>
•或和运算符允许我们构造更复杂的表达式。
以下表达式将匹配不在intrusive,或者dos,或者exploit类别中的任何脚本。
#nmap --script "not(intrusive or dos or exploit)" -sV <target>
•如果我们想要执行broadcast和discovery中的所有类别脚本。
我们使用:
#nmap --script "broadcast and discovery" < target>
•甚至可以使用通配符*:
#nmap --script "snmp- *" <target>
•当然,我们可以结合使用通配符和表达式。例如:
让我们运行名称以http-开头的所有脚本,但排除
http-slowloris,http-brute,http-form-fuzzer和http-enum脚本:
#nmap --script "http-* and not(http-slowloris or http-brute or
http-enum or http-form-fuzzer)" <target>
下一个命令将执行以http开头的但不在exploit类别中的所有脚本:
#nmap --script“http- * not(exploit)”<target>
<font color=#FF0000>NSE脚本参数</font>
--script-args 选项用于在NSE脚本中设置参数。
还是举个栗子,设置http-title脚本的参数useragent,
使用这个表达式:
nmap -sV --script http-title --script-args http.useragent =“Mozilla 1337“<target></target>
当然有时你也可以在忽略脚本名称设置参数(以下两条表达意思是一致的):
nmap -p80 --script http-trace --script-args path <target></target>
nmap -p80 --script http-trace --script-args http-trace.path <target></target>
如果你使用共享参数名称的脚本,就必须避免参数冲突。例如下面中的uri参数,公用的时候要是需要进行额外的设置时就必须加上完整的脚本名称,避免参数之间的冲突。
$ nmap --script http-majordomo2-dir-traversal,http-axis2-dir-traversal
--script-args http-axis2-dir-traversal.uri = /axis2/,uri =/majordomo/ <target>
$ nmap --script http-majordomo2-dir-traversal,http-axis2-dir-traversal
--script-args uri = /axis2/,http-majordomo2-dir-traversal.uri = /majordomo/ <target>
03.万事具备
<font color=#FF0000>语言准备</font>
编写NSE脚本我们需要有lua编程语言的基础,可以回去自己学习一下。我这里简单列出编写脚本之前必须了解的一些语法。其他的就自己回去学习吧。转载于菜鸟教程:http://www.runoob.com/lua/lua-tutorial.html
Lua 特性
- 轻量级: 它用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可以很方便的嵌入别的程序里。
- 可扩展: Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。
- 其它特性
- 支持面向过程(procedure-oriented)编程和函数式编程(functional programming);
- 自动内存管理;只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象;
- 语言内置模式匹配;闭包(closure);函数也可以看做一个值;提供多线程(协同进程,并非操作系统所支持的线程)支持;
- 通过闭包和table可以很方便地支持面向对象编程所需要的一些关键机制,比如数据抽象,虚函数,继承和重载等
-- 单行注释
--[[
多行注释
多行注释
--]]
标示符
Lua 标示符用于定义一个变量,函数获取其他用户定义的项。标示符以一个字母 A 到 Z 或 a 到 z 或下划线 _ 开头后加上0个或多个字母,下划线,数字(0到9)。
最好不要使用下划线加大写字母的标示符,因为Lua的保留字也是这样的。
Lua 不允许使用特殊字符如 @, $, 和 % 来定义标示符。 Lua 是一个区分大小写的编程语言。因此在 Lua 中 Runoob 与 runoob 是两个不同的标示符。以下列出了一些正确的标示符:
mohd zara abc move_name a_123
myname50 _temp j a23b9 retVal
关键词
以下列出了 Lua 的保留关键字。保留关键字不能作为常量或变量或其他用户自定义标示符:
and break do else
elseif end false for
function if in local
nil not or repeat
return then true until
while
一般约定,以下划线开头连接一串大写字母的名字(比如 _VERSION)被保留用于 Lua 内部全局变量
Lua 数据类型
Lua是动态类型语言,变量不要类型定义,只需要为变量赋值。 值可以存储在变量中,作为参数传递或结果返回。
Lua中有8个基本类型分别为:nil、boolean、number、string、userdata、function、thread和table。
数据类型 描述
nil 这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)。
boolean 包含两个值:false和true。
number 表示双精度类型的实浮点数
string 字符串由一对双引号或单引号来表示
function 由 C 或 Lua 编写的函数
userdata 表示任意存储在变量中的C数据结构
thread 表示执行的独立线路,用于执行协同程序
table Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字或者是字符串。在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。
nil(空)
nil 类型表示一种没有任何有效值,它只有一个值 -- nil,例如打印一个没有赋值的变量,便会输出一个 nil 值:
Lua 变量
变量在使用前,必须在代码中进行声明,即创建该变量。
编译程序执行代码之前编译器需要知道如何给语句变量开辟存储区,用于存储变量的值。
Lua 变量有三种类型:全局变量、局部变量、表中的域。
Lua 中的变量全是全局变量,那怕是语句块或是函数里,除非用 local 显式声明为局部变量。