在我以前的博客在介绍过OpenVAS釆用***测试原理,利用Scanner模块中的脚本引擎对目标进行安全检测。今天这篇文章重点讲述其扫描插件的工作原理,Openvas的Scanner的扫描性能依赖于同时进行扫描的并发进程数,不同的硬件环境上可设置的最有效并发扫描数各不相同,Openvas的扫描引擎设备可在保证系统稳定的前提下达到最佳的扫描性能,对于大型网络使用标准设备进行部署可大大降低安装和维护成本。
脚本引擎根据用户提交的配置与要求,首先对脚本进行加载与调度,按照顺序依次调用脚本并解析执行,实现扫描功能。

0.扫描流程

Openvas扫描过程分为两个阶段,首先是端口扫描,在该阶段openvas对扫描范围内所有目标判断是否在线,然后扫描端口,下面是探测阶段,在该阶段openvas需要确定目标操作系统类别和开发服务器和应用类别,最后再调用相应漏洞插件对其进行深度扫描,下面接下来交代漏洞插件之前大家要具备NASL的关键知识点。
OpenVAS漏洞扫描插件工作原理浅析
图1 扫描流程

1.什么是NASL脚本

NASL脚本语言是起初针对网络安全扫描工具Nessus开发的,该脚本语言具有方便快捷,灵活性强,安全性高的特点,便于用户根据新出现的漏洞特性,写出有针对性的检测脚本。
NASL(Nessus Attack Scripting Language)脚本具有其特定的格式要求,其脚本内容可分析两个部分,第一个部分是脚本的注册信息,包含脚本名称、CVE-ID、漏洞描述信息、脚本类型,依赖的脚本或端口等信息。第二部分是针对相应漏洞的检测代码,此部分是脚本内容的核心,包含添加引用的库,脚本初始化,脚本执行及检测返回信息等操作。
NASL脚本书写格式大致如下所示。

if(description)
{
/*注册信息:包含脚本名称、CVE-ID、漏洞描述信息、脚本类型,依赖的脚本或端口等*/
Script-name
CVE-ID;
exit(0)
}
/*脚本代码*/

NASL脚本语言功能强大,用于设计安全检测脚本足以。该脚本语言的语法类似于C语言,但是比C要简单许多,在使用NASL脚本语言时,不必考虑对象的类型,内存的分配与释放,变量声明等问题,只要认真设计漏洞的检测方法即可。由于漏洞扫描需在网络环境中进行,所以NASL语言提供了丰富的网络相关函数,包括套接字相关函数,用户可根据检测需要创建套接字,与目标主机进行通信;原始报文处理函数,用户可根据扫描需求构建检测报文,并对返回信息进行分析,提取重要内容;NASL语言还提供了一些工具参数来简化检测脚本的书写,例如对目标主机系统、端口等信息的提取函数。
NASL语言还提供了丰富的字符串处理函数。NASL语言允许使用=、<和>等操作符以及正则表达式对字符串进行模式匹配,并且提供多种实现模式匹配功能的函数。NASL语言包含字符串长度计算,内容复制,数据类型转换、大小写转换等功能函数,方便脚本书写。

2.插件功能举例****

在/var/lib/openvas/plugins/目录下,分析cross_site_scriping.nasl脚本,本文重点对该文件进行讲解,请大家在阅读之前准备好脚本。跨站脚本漏洞是Web应用的常见漏洞,下面将开始对cross_site_scriping.nasl脚本分析,总结此类漏洞检测过程。

 76  script_summary("Determine if the remote host is vulnerable to Cross Site Sc    ripting vulnerability");
 77  script_category(ACT_GATHER_INFO);
 78  script_family("Web Servers");

77行script_category(ACT_GATHER_INFO);设置脚本的类别,这些类别有:
 ACT_GATH (信息采集类脚本)
 ACT_ATTACK (尝试获取远程主机权限脚本)
 ACT_DENIAL(拒绝服务***脚本)
 ACT_SCANNER(端口扫描脚本)
Category代表了脚本执行的优先级,不是随便扫描,这种优先级的设定符合常规扫描过程,我们在扫描初期需要对目标主机的端口信息,系统信息,服务信息进行收集,根据这些已知信息合理的进行后续测试,这种测试也是按照由弱到强的顺序执行,为什么呢?如果首先就进行最强的漏洞扫描,相当于进行最危险的测试,一旦目标主机存在相应漏洞,立即系统就会崩溃,整个测试就无法全面进行。

NASL脚本的结构与参数在后面内容将会进行详细介绍,此处先对脚本中category参数进行简单描述,category在脚本调度的过程中具有非常重要的作用,category代表了脚本执行的优先级,通过宏对各类category值的优先级进行定义,NASL脚本按照下表中category优先级由高到低执行,相同优先级按照脚本id顺序执行。

这种优先级的设定符合一般扫描过程的逻辑,我们在扫描初期,需要对目标网络的端口信息、系统信息、服务信息等进行收集,根据这些已知信息,合理进行后续的测试,而且再测试过程中也要按照由弱到强的顺序执行,如果首先进行高危测试,且目标系统存在相应漏洞,则会导致系统崩溃,测试无法继续进行。NASL脚本在完成加载调度的过程中,需要经过三次处理,每次处理都定义了符合要求的链表结构对脚本及相关信息进行保存。

32 include("revisions-lib.inc");
33 tag_summary = "The remote web server seems to be vulnerable to a Cross Site Scripting
32行 include(“revisions-lib.inc”) 添加引用的类库。

63 script_id(10815);
64 script_version("$Revision: 41 $");
65 script_tag(name:"last_modification", value:"$Date: 2013-11-04 20:00:12 +010 0 (Mon, 04 Nov 2013) $");
63行 script_id(10815); 添加 openvas ID。
但有些脚本会同时出现script_cve_id(“CVE-2010-2963”、”CVE-2010-3067”)这代表添加CVE ID,CVE(Common Vulnerabilities and Exposure)这类例子大家可以参看deb_2126_1.nasl脚本(部分代码如下),如果该漏洞有CVE编号,可以再这个字段给出。
OpenVAS漏洞扫描插件工作原理浅析
同样在freebsd_php5-gd.nasl脚本里还出现了script_bugtraq_id(33002),我们可以把CVE看作是一个词典,它提供了许多的交叉引用,现在大量公司都宣布他们的安全产品或数据库都和CVE相兼容,也就是能够利用CVE中漏洞名称同其它CVE兼容的产品进行交叉引用,通过CVE中为每个漏洞分配一个唯一的名称,在其它使用了这个名称的工具、网站、数据库以及服务中检索到相关信息,同时自身关于该漏洞的信息也能够被检索到。所以在网络安全评估时,利用CVE可以找出修补漏洞的措施,CVE可以提供很好的指导。大家如果要具体查询这些ID信息可以用grep命令
grep –ir “script_bugtraq_id” /var/lib/openvas/plugins/
OpenVAS漏洞扫描插件工作原理浅析![]
78 script_family("Web Servers");
79 script_copyrigcript_summary("Determine if the remote host is vulnerable to Cross Site Sc ripting vulnerability");
78行 script_family("Web Servers");设置脚本所属的族(family)。
NASL对此没有明确规定,插件作者可以自己定义脚本所属的族,在Openvas中所使用的族有包括以下内容:

  • Debian Local Security Checks
  • Fedora Local Security Checks
  • Mandrake Local Security Checks
  • HP-UX Local Security Checks
  • Ubuntu Local Security Checks
  • CentOS Local Security Checks
  • Windows : Microsoft Bulletins
  • FreeBSD Local Security Checks
  • Red Hat Local Security Checks
  • Solaris Local Security Checks
  • CentOS Local Security Checks
  • Web application abuses
  • FreeBSD Local Security Checks
  • Buffer overflow
  • Firewalls
  • Web Servers
  • RPC
  • General
  • CISCO
  • Databases
  • Useless services
  • Default Accounts
  • Nmap NSE net
  • Gain a shell remotely
  • Malware
  • Port scanners
  • IT-Grundschutz
  • SMTP problems
  • Gentoo Local Security Checks
  • SuSE Local Security Checks
  • FTP
  • Denial of Service
  • Windows
  • Service detection
    实际上这些族就是主要的***种类。
    下面继续看79行内容:
    79行 script_copyright("Copyright (C) 2001 SecuriTeam, modified by Chris Sullo and Andrew Hintz");
    设置脚本的版权信息
    80行 script_dependendes("find_service.nasl", "httpver.nasl");
    第80行脚本说明脚本依赖关系,如果要让cross_site_scriping.nasl正常运行,必须依赖find_service.nasl"、"httpver.nasl"这两个脚本。
    80  77  script_category(ACT_GATHER_INFO);
    81  78  script_family("Web Servers");t("Copyright (C) 2001 SecuriTeam, modified     by Chris Sullo and Andrew Hintz");
    82  script_dependencies("find_service.nasl", "httpver.nasl");
    83  script_require_ports("Services/www", 80);
    84  if (revcomp(a: OPENVAS_VERSION, b: "6.0+beta5") >= 0) {
    85    script_tag(name : "summary" , value : tag_summary);
    86  }
    87  exit(0);
    88 }
    89 
    90 #
    91 # The script code starts here
    92 #
    93 
    94 include("http_func.inc");
    95 include("http_keepalive.inc");
    81行script_require_ports("Services/www", 80);

    表明执行此脚本所需的目标服务器的端口信息;
    95行 port = get_http_port(default:80);获取服务器端口
    123行if(get_port_state(port))判断端口是否打开
    134行req = http_get(item:url, port:port);发送带有***性的请求

• 注意:nasl脚本主要是对的描述,只是说明的的步骤。

136     req = http_get(item:url, port:port);
137     r   = http_keepalive_send_recv(port:port, data:req, bodyonly: TRUE);
135行 r= http_keepalive_send_recv(port:port, data:req, bodyonly: TRUE); //接收响应
165行 set_Kb_item(name:string("www/", port, "/generic_xss"), value:TRUE);
165 set_kb_item(name:string("www/", port, "/generic_xss"), value:TRUE);

查看知识库中是否已存在此漏洞信息,知识库中保存了各类扫描所需相关信息,例如:
 主机存活信息(Host/dead)
 主机提供服务的信息(ftp/no_mkdir)
 端口扫描信息(services/ftp)
 测试登录信息(SMB/login SMB/password)
在脚本测试过程中,如果收集到有用的信息,将通过set_Kb_item()这个函数,在知识库中增加相应条目;当需要对知识库中的相关信息进行调用时,则利用get_Kb_item()函数进行读取。

3.NASL常用函数介绍

 open_sock_tcp()、open_sock_udp(),分别用于打开一个TCP或者UDP套接字。
 close(), 关闭一个端口。
 forge_ip_packet(), 函数构造一个新的IP报文。
 forge_tcp_packet() , 构造TCP报文。
 set_tcp_elements(), 可修改TCP报文的内容。
 forge_udp_packet(), 构造UDP报文。
 send_packet(), 函数发送报文。
 pcap_next() , 函数将从使用的最后一个接口读取一个报文。
 this_host(), 获取运行脚本的主机IP地址,没有参数。
 get_host_name() , 获取当前被测试主机的主机名,没有参数。
 get_host_ip() , 获取当前被测试主机的IP地址,没有参数。
 get_host_open_port() ,获取远程主机打开的第一个端口号,没有参数。
 get_port_stat(<portnum>),获取端口的状态。
除此之外还有大量的正则表达式函数这里就不一一举例。

4.OpenVAS脚本加载过程分析

如果你需要开发插件对于,需要了解的一个重点问题是,当启动OpenVAS时,由openvassd进程加载所有的脚本(/var/lib/openvas/plugins/下的*.nasl脚本),存储为argiist结构(数量可变的参数列表指针);根据客户端传递的配置信息,选取需要的脚本,加载为scheduler_plugin结构;最后根据选取脚本的category将脚本分组,组织脚本的执行顺序,保存到plugins_scheduler-struct结构。
OpenVAS关于脚本管理设计的非常合理,初始的加载脚本是保存的argiist链表内容,供后面进步一选取脚本及组织脚本执行顺序时调用,可有效减少内存的使用,提高工作效率。在脚本引擎的工作中,将脚本执行收集到的信息保存在知识库中,可有效避免重复扫描,减少不必要的资源浪费,提高工作效率。知识库中条目结构定义如下:

Struct kb_item
{
char name; /*知识库中条目名称*/
char type; / 条目的类型 int 或 string /
union
{
char *v_str;
int v_int;
} V; /*知识库中条目的值*/
struct kb item next; /指针指向下一条目 */
};

知识库中保存的信息包含各类扫描信息例如:
 主机存活信息(Host/dead)。
 主机提供的服务信息(ftp/no_mkdir)。
 端口扫描信息(Services/ftp)。
 测试登录信息(SMB/login; SMB/password)。
 用户检测时进行的系统设置信息。
在脚本执行过程中,如果收集到有用信息,将通过set_kb_item()函数,在知识库中增加相应条目;如果需要对知识库中的相关信息进行调用,则使用get_kb_item()函数进行读取操作。
脚本在执行时如果有依赖的系统环境、端口状态等信息,会到知识库中查询,并根据查询结果做出合理的操作。例如:某脚本的执行需要目标主机的80端口打开,通过知识库查询,发现目标的80端口是关闭的,那么此脚本的执行将放弃,且该脚本对应线程关闭;如果发现目标的80端口处于开启状态,那么该脚本将顺利执行,对目标进行检测。通过对知识库中信息的查询判断,可有效提高脚本执行的效率,一些无意义的扫描将被过滤。

5.插件同步过程

在OSSIM命令行中输入命令“openvas-nvt-sync”,以下为显示为输出结果。

[i] This script synchronizes an NVT collection with the 'OpenVAS NVT Feed'.

[i] The 'OpenVAS NVT Feed' is provided by 'The OpenVAS Project'.

[i] Online information about this feed: 'http://www.openvas.org/openvas-nvt-feed.html'.

[i] NVT dir: /var/lib/openvas/plugins

[i] Will use rsync

[i] Using rsync: /usr/bin/rsync

[i] Configured NVT rsync feed: rsync://feed.openvas.org:/nvt-feed

OpenVAS feed server - http://www.openvas.org/

This service is hosted by Intevation GmbH - http://intevation.de/

All transactions are logged.

Please report synchronization problems to openvas-feed@intevation.de.

If you have any other questions, please use the OpenVAS mailing lists

or the OpenVAS IRC chat. See http://www.openvas.org/ for details.

receiving incremental file list

deleting gb_openssl_38562.nasl.asc

deleting gb_openssl_38562.nasl

./

COPYING

 588 100%  574.22kB/s    0:00:00 (xfer#1, to-check=13347/13355)

COPYING.GPLv2

18002 100% 17.17MB/s 0:00:00 (xfer#2, to-check=13346/13355)
COPYING.files

1819904 100% 1.77MB/s 0:00:00 (xfer#3, to-check=13345/13355)
DDI_Directory_Scanner.nasl

32957 100% 32.74kB/s 0:00:00 (xfer#4, to-check=13342/13355)
DDI_Directory_Scanner.nasl.asc

 198 100%    0.20kB/s    0:00:00 (xfer#5, to-check=13341/13355)

... ...

同步数万个插件时间比较长,消耗资源不大,可以去喝杯咖啡啦。

6.插件更新过程

Tips:以下命令操作占用CPU资源比较多

#perl /usr/share/ossim/scripts/vulnmeter/updateplugins.pl migrate / 比较消耗CPU和磁盘I/O /

2018-09-07 07:27:33 Framework profile has been found...

2018-09-07 07:27:33 Deleting all tasks in 192.168.11.150 ...

2018-09-07 07:27:33 updateplugins: configured to not updateplugins

2018-09-07 07:27:33 updateplugins: configured to not repair DB

2018-09-07 07:27:33 BEGIN - DUMP PLUGINS

2018-09-07 07:29:01 FINISH - DUMP PLUGINS [ Process took 88 seconds ]

2018-09-07 07:29:01 BEGIN - IMPORT PLUGINS

2018-09-07 07:30:00 FINISH - IMPORT PLUGINS [ 40473 plugins - Process took 59 seconds ]

2018-09-07 07:30:00 BEGIN - UPDATE CATEGORIES

2018-09-07 07:30:00 FINISH - UPDATE CATEGORIES [ Process took 0 seconds ]

2018-09-07 07:30:00 BEGIN - UPDATE FAMILIES

2018-09-07 07:30:00 FINISH - UPDATE FAMILIES [ Process took 0 seconds ]

2018-09-07 07:30:00 BEGIN - UPDATE OPENVAS_PLUGINS

2018-09-07 07:30:03 FINISH - UPDATE OPENVAS_PLUGINS [ Process took 3 seconds ]

2018-09-07 07:30:03 BEGIN - UPDATE NESSUS_PREFERENCES

2018-09-07 07:30:03 show tables like "vuln_nessus_preferences_defaults"

2018-09-07 07:30:03 updateprefs: Getting plugin preferences

2018-09-07 07:30:05 FINISH - UPDATE NESSUS_PREFERENCES [ Process took 2 seconds ]

2018-09-07 07:30:06 Creating Deep profile...

2018-09-07 07:30:06 Filling categories...............

2018-09-07 07:30:06 Done

2018-09-07 07:30:06 Filling families.............................................................

2018-09-07 07:30:06 Done

2018-09-07 07:30:06 Filling plugins...

2018-09-07 07:30:13 Filling preferences in Alienvault DB...

2018-09-07 07:30:14 Done

2018-09-07 07:30:14 Deep profile inserted

2018-09-07 07:30:15 Creating Default profile...

2018-09-07 07:30:15 Filling categories...............

2018-09-07 07:30:15 Done

2018-09-07 07:30:15 Filling families.............................................................

2018-09-07 07:30:15 Done

2018-09-07 07:30:15 Filling plugins...

2018-09-07 07:30:23 Filling preferences in Alienvault DB...

2018-09-07 07:30:24 Done

2018-09-07 07:30:24 Default profile inserted

2018-09-07 07:30:24 Creating Ultimate profile...

2018-09-07 07:30:24 Filling categories...............

2018-09-07 07:30:24 Done

2018-09-07 07:30:24 Filling families.............................................................

2018-09-07 07:30:24 Done

2018-09-07 07:30:24 Filling plugins...

2018-09-07 07:30:32 Filling preferences in Alienvault DB...

2018-09-07 07:30:33 Done

2018-09-07 07:30:33 Ultimate profile inserted

2018-09-07 07:30:33 BEGIN - UPDATE PORT SCANNER

2018-09-07 07:30:35 FINISH - UPDATE PORT SCANNER [ Process took 2 seconds ]

Updating plugin_sid vulnerabilities scanner ids

plugins fetched

Updating...

Script id:94151, Name:IT-Grundschutz M4.288: Sichere Administration von VoIP-Endger?ten, Priority:0

Script id:703073, Name:Debian Security Advisory DSA 3073-1 (libgcrypt11 - security update), Priority:1

Script id:804624, Name:Adobe Reader Plugin Signature Bypass Vulnerability (Windows), Priority:2

Script id:868149, Name:Fedora Update for kernel FEDORA-2014-9959, Priority:5

Script id:95048, Name:IT-Grundschutz M5.145: Sicherer Einsatz von CUPS, Priority:0

Script id:842216, Name:Ubuntu Update for linux USN-2616-1, Priority:4

Script id:105036, Name:Open××× Detection, Priority:0

Script id:868005, Name:Fedora Update for audacious-plugins FEDORA-2014-8183, Priority:1

Script id:869350, Name:Fedora Update for springframework FEDORA-2018-6862, Priority:5

… …

Script id:105084, Name:Multiple ManageEngine Products Arbitrary File Upload Vulnerability, Priority:3

Script id:867751, Name:Fedora Update for python-keystoneclient FEDORA-2014-5555, Priority:3

Script id:882209, Name:CentOS Update for nss CESA-2018:1185 centos6, Priority:2

Script id:842209, Name:Ubuntu Update for libmodule-signature-perl USN-2607-1, Priority:5

大约经过一刻钟等待终于更新完成。注意,该过程需要一气呵成,中途不能强制退出。

7. 测试NASL脚本

将自己写的插件复制到openvas插件库目录:
/var/lib/openvas/plugins
加载插件:
openvassd
OpenVAS漏洞扫描插件工作原理浅析

8. 重建插件库

openvasmd –rebuild
注意:参数“rebuild”代表从一个正在运行的扫描器(openvassd)中重建数据库信息。

9.开始Openvas扫描

必要条件:首先必须由足够大的内存,其次升级补丁工作建议在系统刚架设完毕就做,然后升级Openvas插件。然后确保Sensor传感器是可用状态,Nmap进程运行正常。
• 注意,扫描前要确保服务器和客户机的时钟要保持一致。
操作步骤:
 定义扫描目标,可以是IP地址、网段地址;
 创建新任务,选择扫描目标、扫描方式;
 运行新创建的扫描任务;
 等待扫描结束,然后查看扫描报告。
OSSIM 平台下操作过程:
(1)选择Anaylysis→Vulnerabilities ,然后点击"New scan job"按钮,开始创建一个新的扫描任务;
(2)从上到下依次输入任务名称,例如“Server1”,选择关联引擎,如果是分布式系统就要选择相应的传感器,然后选择扫描方式选项包括立即执行,每天/每周执行,系统提供了非常详细的计划任务列表,图2所示。
OpenVAS漏洞扫描插件工作原理浅析
图 2 操作过程
建议不要扫描过多的主机(以本书第一章推荐的服务器配置为基准,建议每次扫描主机数量,以不超过30台,在系统/etc/openvas/openvassd.conf配置文件中,定义最大主机数为5台,每台主机同时检查插件数为10条),如图3所示。
OpenVAS漏洞扫描插件工作原理浅析
图3
(3)最后对任务进行扫描检测以确保以下要求:扫描检查结果包含目标IP和主机名,传感器是否启用,漏洞扫描库是否准备好,Nmap是否可用这几个参数,如图4~图5所示。
OpenVAS漏洞扫描插件工作原理浅析
图4
OpenVAS漏洞扫描插件工作原理浅析
图5
扫描前选取系统资源时,注意要从Assets资源池中选取,而不能手工输入IP地址的方式,否则会报错。
OSSIM 5以后的系统Web UI 发生较大变化,其Web漏洞扫描菜单路径为:Environment→ Vulnerabilities,如图6-7所示
OpenVAS漏洞扫描插件工作原理浅析
图6 选择扫描范围

OpenVAS漏洞扫描插件工作原理浅析
图7 选择传感器
无论哪个版本的OSSIM扫描时,都会消耗服务器的大量资源(内存)。通常情况下建议扫描机器不宜过多,以25台左右为宜,可根据机器配置情况做适量增减。在配置文件/etc/openvas/openvassd.conf中可以适当改变这个数值。
OpenVAS漏洞扫描插件工作原理浅析
图8 扫描过程中
如果大家在OpenVAS操作过程中遇到各种困惑,可以关注我的2019年最新作品《开源安全运维平台OSSIM疑难解析--入门篇》《开源安全运维平台OSSIM疑难解析--提高篇》,也可以加入OSSIM技术讨论群大家一起学习,共同进步。
OpenVAS漏洞扫描插件工作原理浅析