企業(yè)網(wǎng)絡(luò)安全漏洞掃描
網(wǎng)絡(luò)安全漏洞掃描的工作原理
安全漏洞掃描技能是一類重要的網(wǎng)絡(luò)安全技能。安全漏洞掃描技能與防火墻、侵略檢測(cè)體系互相配合,能夠有效提高網(wǎng)絡(luò)的安全性。經(jīng)過對(duì)網(wǎng)絡(luò)的掃描,網(wǎng)絡(luò)管理員能夠了解網(wǎng)絡(luò)的安全裝備和運(yùn)轉(zhuǎn)的應(yīng)用效勞,及時(shí)發(fā)現(xiàn)安全漏洞,客觀評(píng)估網(wǎng)絡(luò)危險(xiǎn)等級(jí)。網(wǎng)絡(luò)管理員能夠根據(jù)掃描的成果更正網(wǎng)絡(luò)安全漏洞和體系中的錯(cuò)誤裝備,在黑客進(jìn)犯前進(jìn)行防范。假如說防火墻和網(wǎng)絡(luò)監(jiān)控體系是被迫的防護(hù)手法,那么安全漏洞掃描就是一種自動(dòng)的前范辦法,能夠有效避免黑客進(jìn)犯行為,做到防患于未然。
網(wǎng)絡(luò)安全漏洞掃描技能是計(jì)算機(jī)安全掃描技能的主要分類之一。網(wǎng)絡(luò)安全漏洞掃描技能主要針對(duì)體系中設(shè)置的不合適軟弱的口令,以及針對(duì)其他同安全規(guī)矩沖突的方針進(jìn)行檢查等。
網(wǎng)絡(luò)安全漏洞掃描技能是一種根據(jù) Internet 遠(yuǎn)程檢測(cè)方針網(wǎng)絡(luò)或本地主機(jī)安全性軟缺點(diǎn)的技能。
經(jīng)過網(wǎng)絡(luò)安全漏洞掃描,體系管理員能夠發(fā)現(xiàn)所維護(hù)的 Web 效勞器的各種TCP/IP 端口的分配、開放的效勞、 Web 效勞軟件版別和這些效勞及軟件呈現(xiàn)在 Internet上的安全漏洞。網(wǎng)絡(luò)安全漏洞掃描技能也是采用活躍的、非破壞性的辦法來檢驗(yàn)體系是否有或許被進(jìn)犯崩潰。其利用了一系列的腳本模仿對(duì)體系進(jìn)行進(jìn)犯的行為,并對(duì)成果進(jìn)行剖析。這種技能通常被用來進(jìn)行模仿進(jìn)犯實(shí)驗(yàn)和安全審計(jì)。
注:網(wǎng)絡(luò)安全漏洞掃描技能與防火墻、安全監(jiān)控體系互相配合就能夠?yàn)榫W(wǎng)絡(luò)供給很高的安全性。
一次完整的網(wǎng)絡(luò)安全漏洞掃描分為三個(gè)階段:
第一階段:發(fā)現(xiàn)方針主機(jī)或網(wǎng)絡(luò)。
第二階段:發(fā)現(xiàn)方針后進(jìn)一步搜集方針信息,包含操作體系類型、運(yùn)轉(zhuǎn)的效勞以及效勞軟件的版別等。假如方針是一個(gè)網(wǎng)絡(luò),還能夠進(jìn)一步發(fā)現(xiàn)該網(wǎng)絡(luò)的拓?fù)浣Y(jié)構(gòu)、路由設(shè)備以及各主機(jī)的信息。
第三階段:根據(jù)搜集到的信息判別或者進(jìn)一步測(cè)試體系是否存在安全漏洞。
網(wǎng)絡(luò)安全漏洞掃描技能包含有 PING 掃射(Ping sweep)、操作體系探測(cè) (Operating system identification)、怎么探測(cè)拜訪操控規(guī)矩 (firewalking)、端口掃描 (Port scan)以及漏洞掃描 (vulnerability scan)等。這些技能在網(wǎng)絡(luò)安全漏洞掃描的三個(gè)階段中各有體現(xiàn)。
PING 掃描用于網(wǎng)絡(luò)安全漏洞掃描的第一階段,能夠協(xié)助咱們辨認(rèn)體系是否處于活動(dòng)狀況。
操作體系探測(cè)、怎么探測(cè)拜訪操控規(guī)矩和端口掃描用于網(wǎng)絡(luò)安全漏洞掃描的第二階段,其中操作體系探測(cè)顧名思義就是對(duì)方針主機(jī)運(yùn)轉(zhuǎn)的操作體系進(jìn)行辨認(rèn);怎么探測(cè)拜訪操控規(guī)矩用于獲取被防火墻維護(hù)的遠(yuǎn)端網(wǎng)絡(luò)的材料;而端口掃描是經(jīng)過與方針體系的 TCP/IP 端口銜接,并檢查該體系處于監(jiān)聽或運(yùn)轉(zhuǎn)狀況的效勞。
網(wǎng)絡(luò)安全漏洞掃描第三階段采用的漏洞掃描通常是在端口掃描的基礎(chǔ)上,對(duì)得到的信息進(jìn)行相關(guān)處理,進(jìn)而檢測(cè)出方針體系存在的安全漏洞。
網(wǎng)絡(luò)安全漏洞掃描技能的兩大核心技能就是端口掃描技能和漏洞掃描技能,這兩種技能廣泛運(yùn)用于當(dāng)前較老練的網(wǎng)絡(luò)掃描器中,如聞名的 Nmap 和 Nessus 就是利用了這兩種技能。
企業(yè)的安全工程師在業(yè)務(wù)上線前或?qū)舅匈Y產(chǎn)進(jìn)行周期性地例行掃描,可以在被攻擊者發(fā)現(xiàn)可利用的漏洞之前發(fā)現(xiàn)并修復(fù),將可能帶來的損害減少到最低,對(duì)企業(yè)信息安全來說有積極主動(dòng)、防患于未然的作用。外部黑客前需要踩點(diǎn),在得知域名及IP等有限的信息逐步進(jìn)行嘗試、還需要繞過ACL、IDS、WAF等防御措施。企業(yè)內(nèi)部掃描可以直接拿到所有服務(wù)器的資產(chǎn)列表、所有Web的域名及在每個(gè)IDC部署掃描服務(wù)器,所以內(nèi)部掃描更加方便、更全面。即便是這種信息不對(duì)稱的情況下,外部的黑客或白帽子總有辦法找到漏洞,所以各大互聯(lián)網(wǎng)公司紛紛都建立了自己的應(yīng)急響應(yīng)中心(俗稱SRC),并給報(bào)漏洞的白帽子發(fā)豐厚的獎(jiǎng)勵(lì)。(注:當(dāng)下的SRC已經(jīng)不只獎(jiǎng)勵(lì)漏洞,同時(shí)還獎(jiǎng)勵(lì)舉報(bào)的危害線索)可以說內(nèi)部掃描可以發(fā)現(xiàn)99%以上的漏洞,剩余的則需要建立應(yīng)急響應(yīng)中心借助廣大白帽子的力量(眾測(cè),類似眾籌的一種形式)一起消滅掉,比如接收外部白帽子提供的漏洞和威脅情報(bào)信息并進(jìn)行獎(jiǎng)勵(lì)。
一、漏洞掃描的種類
1、按漏洞類型分類
●ACL掃描
●系統(tǒng)及應(yīng)用服務(wù)漏洞掃描
(1)ACL掃描
ACL掃描是用來按一定的周期監(jiān)視公司服務(wù)器及網(wǎng)絡(luò)的ACL的,比如無需對(duì)外開放的端口或IP是否暴露在了公網(wǎng)中。ACL掃描器的作用如下:
1)安全部門可以根據(jù)掃描報(bào)告督促網(wǎng)絡(luò)管理員和系統(tǒng)管理員關(guān)閉暴露在公網(wǎng)中的高危服務(wù),避免重要的服務(wù)因放在公網(wǎng)中被入侵的風(fēng)險(xiǎn)。
2)等某些應(yīng)用或某些版本的應(yīng)用發(fā)現(xiàn)新時(shí),安全部門可以快速?gòu)闹胁榈酱嬖诘姆?wù)及版本,直接報(bào)到業(yè)務(wù)部門去修復(fù)。
ACL掃描的周期至少為一天一次,對(duì)于不同規(guī)模服務(wù)器的企業(yè)可以采用以下的方式:
1)對(duì)于數(shù)量較少的公司,可以直接用掃描,并將掃描出來的IP、端口、應(yīng)用服務(wù)名、應(yīng)用版本、時(shí)間等信息存放到中。
2)對(duì)于數(shù)量很多的公司,可以用Masscan掃描出所有的端口信息,然后再用去識(shí)別端口的協(xié)議及應(yīng)用程序版本信息,可以根據(jù)實(shí)際情況部署掃描的數(shù)量、形成分布式的架構(gòu),加快掃描速度。
(2)弱口令掃描
管理員因疏忽大意或安全意識(shí)薄弱給網(wǎng)絡(luò)設(shè)備、或應(yīng)用使用了默認(rèn)的和簡(jiǎn)單的口令,這種的設(shè)備掛在公網(wǎng)上后很快就被或蠕蟲掃描到并快速。常見的掃描器如Nessus、x-scan、h-scan、Hydra都具備掃描的功能,其中hydra支持的服務(wù)列表如下:
asterisk cisco cisco-enable cvs ftp ftps http[s]-{head|get}http[s]-{get|post}-form http-proxy http-proxy-urlenum
icq imap[s]irc ldap2[s]ldap3[-{cram|digest}md5][s]mssql mysql(v4)nntp oracle-listener oracle-sid pcanywhere
pcnfs pop3[s]postgres rdp redis rexec rlogin rsh s7-300 sip smb smtp[s]smtp-enum snmp
socks5 ssh sshkey svn teamspeak telnet[s]vmauthd vnc xmpp
以下為一個(gè)Python調(diào)用hydra掃描SSH的腳本,掃描結(jié)束后會(huì)將結(jié)果寫到一個(gè)文本文件中:
import os
import re
import glob
import datetime
# import subprocess
import torndb
from bs4 import BeautifulSoup
# honeypot white db
db_info = dict(
hostname='127.0.0.1',
database='honeypot',
username='xxxxx',
password='xxxxxx
)
# Nmap scan class
# ------------------------------------------------------------------------------
class NmapScaner(object):
def __init__(self, ip_list, exclude_file):
self.dir = '/data1/ssh_scan'
self.ip_list = "%s/%s" % (self.dir, ip_list)
self.exclude_file = exclude_file
self.report = "%s/report_%s.xml" % (self.dir, str(datetime.datetime.now)[:10])
self.ssh_list = "%s/report_%s.ssh" % (self.dir, str(datetime.datetime.now)[:10])
self.cmd = '/usr/bin/nmap -iL %s --excludefile %s -p 22,8022 -oX %s -n --open -vv' % (
self.ip_list, self.exclude_file, self.report
)
self.hosts = []
def start(self):
print self.cmd
os.system(self.cmd)
# p = subprocess.Popen(self.cmd, shell=True)
# p.wait
def result(self):
print "report: ", self.report, type(self.report)
p1 = r'<address addr="(.+?)" addrtype=".*"></address>'
r1 = re.compile(p1)
p2 = r'<port portid="(.+?)" protocol=".*">'
r2 = re.compile(p2)
soup = BeautifulSoup(open(self.report).read)
results = soup.find_all("host")
for item in results:
host = dict
host["ports"] = list
ret_ip = r1.findall(str(item.address))
if ret_ip:
ip = ret_ip[0]
host["ip"] = ip
for port in item.ports:
ret_port = r2.findall(str(port))
if ret_port:
host["ports"].append(ret_port[0])
self.hosts.append(host)
# print hosts
f = open(self.ssh_list, "w")
for item in self.hosts:
ports = item.get('ports')
ip = item.get('ip')
if ip in CONST_HONEYPOT:
continue
for port in ports:
f.write('%s:%sn' % (ip, port))
return self.ssh_list
# Crack ssh passwd
# ------------------------------------------------------------------------------
class CrackSSH(object):
def __init__(self, ssh_filename):
self.ssh_file = ssh_filename
self.dir = '/data1/ssh_scan'
self.dir1 = '/data1/ssh_scan/scan_ssh'
self.hydra = '/usr/local/bin/hydra'
def prepare(self):
cmd = 'rm -f %s/x*' % self.dir1
print cmd
os.system(cmd)
cmd = "/usr/bin/killall -9 hydra"
os.system(cmd)
# ret = subprocess.call(cmd, shell=True)
# print ret
os.environ = '/data1/ssh_scan'
cmd = 'cd %s;/usr/bin/split -l 2000 %s' % (self.dir1, self.ssh_file)
# print cmd
# ret = subprocess.call(cmd, shell=True)
# print ret
os.system(cmd)
os.environ = None
def scan(self):
search = r'%s/x*' % self.dir1
# print search, type(search)
iplist = glob.glob(search)
# print iplist
for ip in iplist:
cmd = '%s -vV -L %s/user.txt -P %s/password.txt -M %s ssh -o
%s.log -t 4 -w 10 -e nsr >> %s.log &' %
(self.hydra, self.dir, self.dir, ip, ip, self.ssh_file)
# print cmd
os.system(cmd)
# Honeypot white list
# ------------------------------------------------------------------------------
class HoneyWhite(object):
def __init__(self):
self.db = torndb.Connection(
host=db_info.get('hostname'), database=db_info.get('database'),
user=db_info.get('username'), password=db_info.get('password')
)
self.whiteList = []
def result(self):
sql = "select * from honeypotip"
ret = self.db.query(sql)
for item in ret:
self.whiteList.append(item.get('ip').strip)
return self.whiteList
# Main Function
# ------------------------------------------------------------------------------
if __name__ == '__main__':
# get honeypot white list
honey_white = HoneyWhite
CONST_HONEYPOT = honey_white.result
print "Honeypot white listn", CONST_HONEYPOT
start_time = datetime.datetime.now
ip_list_file = 'ip_list_test.txt'
exclude_file = "exclude_file.txt"
h_exclude_file = open(exclude_file, "w")
for ip in CONST_HONEYPOT:
h_exclude_file.write("%sn" % ip)
h_exclude_file.close
nmap_scanner = NmapScaner(ip_list_file, exclude_file)
nmap_scanner.start
ssh_file = nmap_scanner.result
end_time = datetime.datetime.now
use_time = (end_time - start_time).seconds / 60.0
print "Start Time:%s, End Time:%s, Cost %s minutes" % (start_time, end_time, use_time)
# start to crack ssh weak password
crack_ssh = CrackSSH(ssh_file)
crack_ssh.prepare
crack_ssh.scan
(3)系統(tǒng)及應(yīng)用服務(wù)漏洞掃描
常見的系統(tǒng)及應(yīng)用服務(wù)掃描器有Nessus及開源的openVAS,當(dāng)數(shù)量巨大時(shí),需要部署多臺(tái)Nessus以集群模式進(jìn)行掃描。
實(shí)踐方法如下:
1)用程序調(diào)用Nessus的接口,將Nessus的掃描做成周期性任務(wù),每天對(duì)全部進(jìn)行一次安全掃描,并將掃描結(jié)果入庫(kù),按級(jí)別進(jìn)行分級(jí)。
2)程序自動(dòng)建立工單并提交到業(yè)務(wù)部門進(jìn)行修復(fù),修復(fù)好后再轉(zhuǎn)到安全部門確認(rèn),形成一個(gè)良性的閉環(huán)(如果您所在的公司沒有工單系統(tǒng),則至少需要建立一個(gè)漏洞管理系統(tǒng)代替)。
Nessus官方提供的REST API接口的GitHub地址為:https://github.com/tenable/nessrest。
(4)Web漏洞掃描
業(yè)內(nèi)常用的Web掃描工具列表如下:
● Acunetix Web Vulnerability Scanner(AWVS)
● IBM Rational AppScan
● sqlmap
● w3af
● arachni
● Zed Attack Proxy
以上幾款掃描器中,前2款是商業(yè)軟件,后幾款是免費(fèi)開源的。
實(shí)踐方法如下:
網(wǎng)站較少的公司。安全工程師手工用掃描器進(jìn)行Web掃描即可,但至少要使用2款以上掃描器進(jìn)行交叉確認(rèn),避免因某款掃描器漏報(bào)導(dǎo)致漏洞沒掃到而被外界黑客利用的情況發(fā)生。一般建議AWVS必用,再配合zap或arachni進(jìn)行確認(rèn)。
網(wǎng)站較多的公司。大中型的互聯(lián)網(wǎng)公司有成千上萬個(gè)大大小小的網(wǎng)站,安全工程師人肉利用掃描工具進(jìn)行掃描已經(jīng)不現(xiàn)實(shí)了,需要自研掃描工具,實(shí)現(xiàn)自動(dòng)化、批量化的漏洞掃描。常見的一個(gè)自動(dòng)化Web掃描器的架構(gòu)圖1所示。
圖1 自動(dòng)化Web安全檢測(cè)平臺(tái)
2、按掃描器行為分類
根據(jù)掃描器是否主動(dòng)發(fā)包的行為,可將掃描器分為以下幾種:
1)主動(dòng)掃描
2)半被動(dòng)掃描器
3)全被動(dòng)掃描器
(1)主動(dòng)掃描
常規(guī)的掃描器都是主動(dòng)發(fā)包,然后根據(jù)返回的包判斷目標(biāo)設(shè)備是否存在。對(duì)于掃描器來說,是先將URL爬出來,然后再在該URL中各個(gè)可以輸入?yún)?shù)的地方測(cè)試注入、等負(fù)載。常用的AWVS、、Nessus等都是主動(dòng)掃描器。
(2)半被動(dòng)掃描
其實(shí)該類掃描器還是屬于主動(dòng)掃描器,區(qū)別是URL的獲取途徑不是爬蟲,而是以下幾種方式。
1)通過Access log獲取URL
例如將用戶或QA訪問站點(diǎn)的Access log去重后進(jìn)行掃描。
2)通過流量鏡像的方式獲取URL
通過旁路鏡像得到全流量URL,去重后進(jìn)行掃描。對(duì)于比較大規(guī)模的Web資源掃描,可以通過Storm流式計(jì)算平臺(tái)將來自分光的全流量URL庫(kù)rewrite替換,去重歸一,驗(yàn)證真實(shí)性后作為掃描器的輸入源,由消息隊(duì)列推送至分布式掃描器中。以下為一個(gè)利用WAF log、爬蟲結(jié)果及流量鏡像中的URL作為輸入源的掃描器的架構(gòu)如圖2所示。
圖2 URL庫(kù)作為掃描器輸入源
3)HTTP代理式的掃描器
這種方式常被QA或滲透測(cè)試人員使用,在瀏覽器設(shè)置一個(gè)代理,然后去訪問網(wǎng)站的頁面,每訪問一個(gè)URL就會(huì)被放到后臺(tái)去掃描,基本的框架代碼如下:
class ProxyHandler(tornado.web.RequestHandler):
SUPPORTED_METHODS = ['GET', 'POST', 'CONNECT']
@tornado.web.asynchronous
def get(self):
url_info = dict(
method=
self.request.method,
url=self.request.uri
)
self.request_info = None
def handle_response
(response):
if (response.error and not
isinstance(response.error, tornado.httpclient.HTTPError)):
self.set_status(500)
self.write('Internal server error:n' + str(response.error))
else:
self.set_status(response.code)
for header in ('Date', 'Cache-Control', 'Server','Content-Type', 'Location'):
v = response.headers.get(header)
if v:
self.set_header(header, v)
v = response.headers.get_list('Set-Cookie')
if v:
for i in v:
self.add_header('Set-Cookie', i)
if response.body:
self.write(response.body)
# Insert http request and response into mongodb
if self.application.scan:
url = url_info.get('url')
url_filter = UrlFilter(url)
if url_filter.filter:
http_info = HttpInfo(url_info, self.request_info, response)
values = http_info.get_info
mongodb = Mongodb(db_info)
mongodb.insert(values)
self.finish
body = self.request.body
self.request_info = self.request
if not body:
body = None
try:
fetch_request(
self.request.uri, handle_response,
method=
self.request.method, body=body,
headers=self.request.headers, follow_redirects=False,
allow_nonstandard_methods=True)
except tornado.httpclient.HTTPError as e:
if hasattr(e, 'response') and e.response:
handle_response(e.response)
else:
self.set_status(500)
self.write('Internal server error:n' + str(e))
self.finish
完整的demo代碼請(qǐng)參考:https://github.com/netxfly/passive_scan。
4)vpn式的掃描器
與前一種類似,不過該種掃描需要播入一個(gè)特定的VPN中,在VPN中會(huì)設(shè)置一個(gè)透明代理,將80和443端口的數(shù)據(jù)轉(zhuǎn)發(fā)到透明代理中,之后測(cè)試者每訪問一個(gè)URL也會(huì)放到后臺(tái)去掃描,以下的golang代碼就實(shí)現(xiàn)了一個(gè)透明代理:
package main
import (
"flag"
"fmt"
"github.com/netxfly/Transparent-Proxy-Scanner/hyperfox/proxy"
"github.com/netxfly/Transparent-Proxy-Scanner/hyperfox/tools/capture"
"strings"
// "github.com/netxfly/Transparent-Proxy-Scanner/hyperfox/tools/logger"
"github.com/toolkits/slice"
"log"
"net/http"
"net/url"
"os"
"time"
"upper.io/db"
"upper.io/db/mongo"
)
const version = "0.9"
const (
defaultAddress = `0.0.0.0`
defaultPort = uint(3129)
defaultSSLPort = uint(3128)
)
const (
Host = "127.0.0.1"
Port = "27017"
User = "xsec"
Password = "x@xsec.io"
Database = "passive_scan"
)
var settings = mongo.ConnectionURL{
Address: db.Host(Host), // MongoDB hostname.
Database: Database, // Database name.
User: User, // Optional user name.
Password: Password, // Optional user password.
}
var (
flagAddress = flag.String("l", defaultAddress, "Bind address.")
flagPort = flag.Uint("p", defaultPort, "Port to bind to, default is 3129")
flagSSLPort = flag.Uint("s", defaultSSLPort, "Port to bind to (SSL mode),
default is 3128.")
flagSSLCertFile = flag.String("c", "", "Path to root CA certificate.")
flagSSLKeyFile = flag.String("k", "", "Path to root CA key.")
)
var (
sess db.Database
col db.Collection
)
var (
static_resource []string = []string{"js", "css", "jpg", "gif", "png", "exe",
"zip", "rar", "ico",
"gz", "7z", "tgz", "bmp", "pdf", "avi", "mp3", "mp4", "htm", "html", "shtml"}
)
// dbsetup sets up the database.
func dbsetup error {
var err error
// Attemping to establish a connection to the database.
sess, err = db.Open(mongo.Adapter, settings)
fmt.Println(sess)
if err != nil {
log.Fatalf("db.Open: %qn", err)
}
// Pointing to the "http_info" table.
col, err = sess.Collection("http_info")
return nil
}
// filter function
func filter(content_type string, raw_url string) bool {
ret := false
if strings.Contains(content_type, "text/plain") || strings.Contains
(content_type, "application/x-gzip") {
url_parsed, _ := url.Parse(raw_url)
path := url_parsed.Path
t := strings.Split(path[1:], ".")
suffix := t[len(t)-1]
if !slice.ContainsString(static_resource, suffix) {
ret = true
}
}
return ret
}
// Parses flags and initializes Hyperfox tool.
func main {
var err error
var sslEnabled bool
// Parsing command line flags.
flag.Parse
// Opening database.
if err = dbsetup; err != nil {
log.Fatalf("db: %q", err)
}
// Remember to close the database session.
defer sess.Close
// Is SSL enabled?
if *flagSSLPort > 0 && *flagSSLCertFile != "" {
sslEnabled = true
}
// User requested SSL mode.
if sslEnabled {
if *flagSSLCertFile == "" {
flag.Usage
log.Fatal(ErrMissingSSLCert)
}
if *flagSSLKeyFile == "" {
flag.Usage
log.Fatal(ErrMissingSSLKey)
}
os.Setenv(proxy.EnvSSLCert, *flagSSLCertFile)
os.Setenv(proxy.EnvSSLKey, *flagSSLKeyFile)
}
// Creatig proxy.
p := proxy.NewProxy
// Attaching logger.
// p.AddLogger(logger.Stdout{})
// Attaching capture tool.
res := make(chan capture.Response, 256)
p.AddBodyWriteCloser(capture.New(res))
// Saving captured data with a goroutine.
go func {
for {
select {
case r := <-res:
if filter(r.ContentType, r.URL) {
// fmt.Println(r.Method, r.URL, r.ContentType)
if _, err := col.Append(r); err != nil {
log.Printf(ErrDatabaseError.Error, err)
}
}
}
}
}
cerr := make(chan error)
// Starting proxy servers.
go func {
if err := p.Start(fmt.Sprintf("%s:%d", *flagAddress, *flagPort)); err != nil {
cerr <- err
}
}
if sslEnabled {
go func {
if err := p.StartTLS(fmt.Sprintf("%s:%d", *flagAddress, *flagSSLPort)); err != nil {
cerr <- err
}
}
}
err = <-cerr
log.Fatalf(ErrBindFailed.Error, err)
}
完整的實(shí)現(xiàn)代碼請(qǐng)參考GitHub
(3)全被動(dòng)掃描
部署方式上類似于,不主動(dòng)爬URL,而是對(duì)B/S & C/S雙向交互的數(shù)據(jù)流進(jìn)行掃描以期發(fā)現(xiàn),全被動(dòng)掃描的特點(diǎn)如下:
1)不需要聯(lián)網(wǎng),不會(huì)主動(dòng)爬取URL,不會(huì)主動(dòng)發(fā)出任何數(shù)據(jù)包。
2)更關(guān)注漏洞感知,而不是入侵行為。
何時(shí)需要被動(dòng)掃描?在日常的安全管理中,經(jīng)常有一些業(yè)務(wù)部門會(huì)引發(fā)安全管理之痛,例如:
● 業(yè)務(wù)部門沒有經(jīng)過安全部門的安全掃描和評(píng)估就擅自上線,結(jié)果上線的服務(wù)器或站點(diǎn)被入侵了。
● 業(yè)務(wù)上線時(shí)確實(shí)經(jīng)過安全掃描和評(píng)審環(huán)節(jié),當(dāng)時(shí)證明是安全的,但在業(yè)務(wù)運(yùn)營(yíng)的過程中,經(jīng)過幾次更新,把安全漏洞更新到生產(chǎn)環(huán)境中了。
● 部分業(yè)務(wù)因人員更換或離職變成了無人管理的業(yè)務(wù),也有可能資產(chǎn)不在公司的資產(chǎn)列表中,因長(zhǎng)期無人維護(hù)被攻擊者鉆了空子。
有了被動(dòng)式掃描器后,可以對(duì)這些處于灰色地帶的資產(chǎn)進(jìn)行防護(hù)。
二、如何應(yīng)對(duì)大規(guī)模的資產(chǎn)掃描
近年來和很火,不少?gòu)S商的安全部門也紛紛引入了及分布式運(yùn)算,比如安全日志分析、通過反爬蟲、用流量鏡像中的URL進(jìn)行掃描、分布式掃描器等。普通的掃描方式在數(shù)萬或幾十萬臺(tái)的環(huán)境下會(huì)遇到以下問題:
1)單臺(tái)或數(shù)臺(tái)掃描器仍不足以覆蓋海量IDC,完成全網(wǎng)掃描需要很多資源。
2)大量的并發(fā)掃描占用網(wǎng)絡(luò)帶寬,高峰時(shí)影響用戶體驗(yàn),執(zhí)行深度檢測(cè)可能會(huì)使應(yīng)用或服務(wù)直接宕掉。
3)大量的誤報(bào)以及中低風(fēng)險(xiǎn)漏洞會(huì)使人工解讀和后續(xù)整理難上加難。
因此海量IDC規(guī)模下漏洞掃描需要尋求高效的方式,總體思路是減少工作量,有幾個(gè)方法:
1)簡(jiǎn)化漏洞評(píng)估鏈,減少需要掃描的任務(wù)。
2)減少漏洞掃描的網(wǎng)絡(luò)開銷和被檢查者的性能損耗。
3)減少漏洞掃描的種類。
4)減少手工確認(rèn)的工作量。
在實(shí)踐中,需要從以下幾方面進(jìn)行優(yōu)化:
1)不做全網(wǎng)的掃描,先做端口掃描,這樣做的前提是訪問控制和縱深防御做到位,利用ACL大幅減少攻擊面,把需要掃描的端口減少到22、80、443等,開的端口少了,全網(wǎng)全協(xié)議掃描就縮減為全網(wǎng)幾個(gè)關(guān)鍵應(yīng)用的掃描。
2)做好高危端口監(jiān)控,防止“計(jì)劃外”應(yīng)用的濫用,這樣漏洞掃描這件事就瘦身為端口監(jiān)控加關(guān)鍵應(yīng)用掃描。
3)在系統(tǒng)和應(yīng)用掃描上,不完全依賴于網(wǎng)絡(luò)掃描器,可同時(shí)借助于本機(jī)agent掃描,類似心臟滴血的與其從網(wǎng)絡(luò)上去獲取掃,不如在本地獲取OpenSSL的版本更簡(jiǎn)單。OS本地的agent除了可以掃系統(tǒng)型,還可以掃本地配置型,相對(duì)來說本地獲取的信息比網(wǎng)絡(luò)獲取更準(zhǔn)確,但代價(jià)是會(huì)消耗資源,所以這塊需要盡可能地減少性能損耗。
除了極個(gè)別大公司,對(duì)于絕大多數(shù)企業(yè)而言,自研掃描器比商業(yè)產(chǎn)品或成熟的開源產(chǎn)品掃描能力更強(qiáng)的可能性是不高的,但是單機(jī)掃描又嚴(yán)重影響效率,所以對(duì)于業(yè)務(wù)有一定規(guī)模但安全團(tuán)隊(duì)又沒能力自制掃描器的公司,可以考慮將現(xiàn)有的掃描器改成分布式的,如下所示:
● 對(duì)于Web掃描,可以通過任務(wù)隊(duì)列的方式將掃描任務(wù)發(fā)給awvs、arachni、w3af等掃描器,改成分布式掃描器。
● 對(duì)于及網(wǎng)絡(luò)掃描,可以多部署幾臺(tái)Nessus掃描器,并配置為集群模式,調(diào)用API進(jìn)行大規(guī)模掃描。
三、結(jié)語
在愈演愈烈的現(xiàn)代,光有基于靜態(tài)規(guī)則和帶fuzz功能的掃描還是會(huì)有許多覆蓋不到,安全部門需要采取基于數(shù)據(jù)的掃描,比如結(jié)合等。其次需要建立中心,讓廣大也參與到的挖掘與發(fā)現(xiàn)中,盡可能多地把暴露在外面的消滅掉。
大型公司在安全實(shí)踐上可能采取一些精簡(jiǎn)手段,只做某些事情,前提是他們已經(jīng)做了另外一些看不見的防御措施,在某處精簡(jiǎn)必然是因?yàn)樵谄渌胤较鳒p了攻擊面,并且有多層次的防御機(jī)制做互補(bǔ),也就是說他們的方案往往是針對(duì)自身特點(diǎn)的,不是一個(gè)完全意義上的通用方案,如果我們的安全建設(shè)尚未到達(dá)那個(gè)階段,直接和安全走在前沿的大型公司看齊,采用人家“高大上”的安全解決方案時(shí),很有可能會(huì)發(fā)生刻舟求劍的笑話,需要實(shí)事求是,根據(jù)實(shí)際情況逐步地建設(shè)所在機(jī)構(gòu)的安全體系。