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

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

Sponsored Links

●vuls_run.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from os.path import join, relpath
import os,subprocess,glob
import difflib
import sys
import slackweb


# 変数
VULS_BIN  = '/home/vuls/go/bin/vuls'
VULS_HOME = '/opt/script/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]'
GOCVE_BIN = '/home/vuls/go/bin/go-cve-dictionary'
SLACK_WEBHOOK='https://hooks.slack.com/services/XXXXXX/XXXXXXX/XXXXXXXXXXXXXXX'
SLACK_CHANNEL='#vuls'
SLACK_USER='Vuls'
FNULL = open(os.devnull, 'w')


# 【関数】脆弱性情報のアップデート
def LibUpdate(option,period):
    update_command = GOCVE_BIN + ' ' + option + ' -' +period
    update_out = subprocess.call(update_command.strip().split(' '),stdout=FNULL,stderr=FNULL)
    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")


# スキャンの実施
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
scan_out = subprocess.call(scan_command.strip().split(' '),stdout=FNULL,stderr=FNULL)


# 差分確認
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)

 

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

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

20161201_001

 

Pocket

Written by blacknon

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

Leave a Comment

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