Vulsをキックして脆弱性の差分をSlackにポストさせるPythonスクリプト
Pocket

脆弱性検知にVulsを使っているのだが、現時点ではまだ差分検知の機能が実装されておらず、cronなどでまわして新しい脆弱性が見つかったらその脆弱性だけをSlackにポストさせるようにするにはVuls単体だとまだできない状態。
で、そろそろ実装されると思っているのだが、その間の繋ぎとしてPythonでスクリプトを書いてやることにした。間に合わせなのであまり綺麗には書いてない状態。

(Rundeckでの実行可能版に書き換え。)

Sponsored Links

●vuls_run.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from os.path import join, relpath
import os,sys,subprocess,glob
import ConfigParser
import difflib
import slackweb
inifile = ConfigParser.SafeConfigParser()
inifile.read('/home/vuls/.auth_info')
# 変数
GO_CVE_BIN = '/home/vuls/go/bin/go-cve-dictionary'
VULS_BIN  = '/home/vuls/go/bin/vuls'
VULS_HOME = '/home/vuls/'
VULS_LOG  = VULS_HOME + '/results'
VULS_LOG_DIRDORMAT = '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9]'
SLACK_WEBHOOK=inifile.get('slack', 'WEBHOOK_URL')
SLACK_CHANNEL='#channel'
SLACK_USER='User'
# 【関数】脆弱性情報のアップデート
def LibUpdate(option,period):
update_command = GO_CVE_BIN + ' ' + option + ' -' + period + ' ' + '-dbpath ' + VULS_HOME + '/cve.sqlite3'
update_out = subprocess.call(update_command.strip().split(' '))
if update_out <> 0:
print 'Error Update "' + update_command + '".'
# 【関数】Slack Post
def SlackPost(ScanHost,txt):
slack=slackweb.Slack(url=SLACK_WEBHOOK)
attachments=[]
attachment={'title': ScanHost,'text': txt,"color": "#FF00FF",}
attachments.append(attachment)
slack.notify(channel=SLACK_CHANNEL, username=SLACK_USER, icon_emoji=":vuls:", attachments=attachments)
# 脆弱性ライブラリのアップデート
LibUpdate("fetchnvd","last2y")
LibUpdate("fetchjvn","last2y")
# スキャン対象サーバリストの取得
FNULL = open(os.devnull, 'w')
GETLIST_COMMAND = 'awk -F[].[] "/\[servers\./{printf \$3 \\" \\"}" ' + VULS_HOME + '/config.toml'
GETLIST = subprocess.check_output(GETLIST_COMMAND,shell=True)
# スキャンの実施
SCAN_COMMAND = VULS_BIN + ' scan -lang=ja -report-text -cve-dictionary-dbpath=' + VULS_HOME + '/cve.sqlite3 -config=' + VULS_HOME + '/config.toml -results-dir=' + VULS_LOG + ' ' + GETLIST
subprocess.call(SCAN_COMMAND,shell=True)
# 差分確認
dirs = glob.glob(VULS_LOG + '/' + VULS_LOG_DIRDORMAT)
sort_dirs = sorted(dirs,key=str.lower,reverse=True)
files = [relpath(x, sort_dirs[0]) for x in glob.glob(join(sort_dirs[0], '*'))]
for check_file in files:
if check_file == 'all.txt':
continue
# 対象ログの確認
before_log = sort_dirs[1] + '/' + check_file
now_log = sort_dirs[0] + '/' + check_file
if os.path.exists(before_log) == False:
delta = ''.join(x[0:] for x in open(now_log, 'r') if x.startswith('CVE-') and len(x.split('\t'))>2)
else:
line=difflib.ndiff(open(before_log, 'r').readlines(), open(now_log, 'r').readlines())
delta = ''.join(x[2:] for x in line if x.startswith('+ CVE-') and len(x.split('\t'))>2)
check_file.split('.')[0]
if len(delta) == 0:
continue
else:
ScanHost = check_file.split('.')[0]
SlackPost(ScanHost,delta)

 

認証情報の記述ファイル

●.authinfo

[slack]
WEBHOOK_URL = https://hooks.slack.com/services/TXXXX....

 

とりあえずこんな感じで。
ちゃんと機能として差分検知が実装されたら置き換えよう。

なお、Slackには以下のような感じで出力される。

20161201_001

 

Pocket

Written by blacknon

インフラ系のSE。一時期はプログラマ。 仮想化とオープンソースに興味あり。一日中寝てたい今日このごろ。 スペインとかで働きたいなぁ…(シエスタがあるので)

Leave a Comment

メールアドレスが公開されることはありません。

*