前提
実行環境: CentOS6.X, ruby, slack-incoming-webhooks, backlog_kit
アラート通知先: slack
チケット登録先: backlog
今回はnginxの脆弱性情報をサンプルに取得してみます。
(参考)Vulsなんていうすばらしいツールがあるのをあとから知りました・・・
http://qiita.com/sadayuki-matsuno/items/0bb8bb1689425bb9a21c
脆弱性情報をどこから収集するか
IPAが提供している「MyJVN API」を利用します。LACさんが脆弱性情報を提供していると、どこかで聞いたような気がするので、提供される情報は信じていいとおもいます。
http://jvndb.jvn.jp/apis/
API経由で脆弱性情報を取得するには製品ID(productId)が必要になりますので、事前に調べておきましょう。以下のページのキーワードに「nginx」と入れて検索すると、レスポンスXMLが返ってきます。
<?xml version="1.0" encoding="UTF-8" ?>
<Result
version="3.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://jvndb.jvn.jp/myjvn/Results"
xmlns:mjres="http://jvndb.jvn.jp/myjvn/Results"
xmlns:status="http://jvndb.jvn.jp/myjvn/Status"
xsi:schemaLocation="http://jvndb.jvn.jp/myjvn/Results http://jvndb.jvn.jp/schema/results_3.2.xsd">
<VendorInfo xml:lang="ja">
<Vendor vname="Igor Sysoev" cpe="cpe:/:igor_sysoev" vid="551">
<Product pname="nginx" cpe="cpe:/a:nginx:nginx" pid="2221"/>
<Product pname="nginx" cpe="cpe:/a:igor_sysoev:nginx" pid="2221"/>
</Vendor>
</VendorInfo>
<status:Status version="3.2" method="getProductList" lang="ja" retCd="0" retMax="10000" errCd="" errMsg="" totalRes="2" totalResRet="2" firstRes="1" keyword="nginx" xsl="0" startItem="1"/>
</Result>
Productのpid=productIdとなりますので控えておきます。今回は2221です。
脆弱性情報をいつ収集するか
最新の情報が漏れなければいいとおもうので、毎日午前3時に前日に発表された脆弱性を収集することにします。
slack通知の準備
「Team Settings」を開き「Configure Apps」を選択します。
「Custom Integrations」から「Incoming WebHooks」を選択します。
Nameに任意のチャネル名を入れて、「Create Channel」を選択
backlog登録の準備
メモを記入して「登録」選択
APIキーが発行されますのでメモしておきます。
次に、「課題」から、「高度な検索」を選択します。
種別「バグ」を選択した状態でURLをコピーしてください。
https://hoge.backlog.jp/find/SECURITY_CHECK?condition.projectId=XXXXXX&condition.issueTypeId=YYYYYY&condition.componentId=&condition.versionId=&condition.fixedVersionId=&condition.statusId=1&・・・
このようなURLが取得できますので、hoge(space_id)とprojectId=XXXXXXとissueTypeId=YYYYYYをメモしておきます。
rubyの環境を準備する
# バージョン確認
$ ruby -v
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]
# インストール
$ gem install slack-incoming-webhooks
$ gem install backlog_kit
$ gem install nokogiri
チェックスクリプト作成
# -*- coding: utf-8 -*-
require 'rubygems'
require 'kconv'
require 'nokogiri'
require 'open-uri'
require 'mysql2'
require 'mechanize'
require "date"
require 'slack/incoming/webhooks'
require 'backlog_kit'
# 脆弱性を取得する日(昨日)
checkdate=Date.today - 1
#slack webhook
slack = Slack::Incoming::Webhooks.new "https://hooks.slack.com/services/XXXXXXXX/XXXXXXXX/XXXXXXXXXXXXXXXXXXXX"
#backlog api
projectid = XXXXXX
issueypeid = YYYYYY
priorutyid = 1
client = BacklogKit::Client.new(
space_id: 'hoge',
api_key: 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ'
)
#MyJVNのXMLを解析するためのクローラー
agent = Mechanize.new
agent.user_agent_alias = 'Mac Safari'
# Nginxの脆弱性を取得するためのURL
# productId=2221でnginxを指定
url="http://jvndb.jvn.jp/myjvn?rangeDateFirstPublished=n&dateFirstPublishedStartM=#{checkdate.mon}&dateFirstPublishedEndM=#{checkdate.mon}&productId=2221&dateFirstPublishedStartY=#{checkdate.year}&dateFirstPublishedEndY=#{checkdate.year}&dateFirstPublishedStartD=#{checkdate.day}&dateFirstPublishedEndD=#{checkdate.day}&rangeDatePublic=n&method=getVulnOverviewList&rangeDatePublished=n&lang=ja"
page = agent.get(url)
baseHTML = Nokogiri::HTML(page.body)
baseHTML.css("item").each do |item|
title=item.css("title").text
link=item.attr('rdf:about')
opend_at=item.css("issued").text.gsub("+09:00","").gsub("T"," ")
#slackにアラート通知
attachments = [{
title: "#{title}",
title_link: "#{link}",
text: "公開日時:#{opend_at}",
color: "#7CD197"
}]
slack.post "nginx脆弱性情報", attachments: attachments
#backlogチケット登録
params = {
"projectId" => projectid,
"issueTypeId" => issueypeid,
"priorityId" => priorutyid,
"summary"=> "#{title}",
"description"=> "#{link}\n公開日時:#{opend_at}"
}
client.create_issue("security issue", params)
end
実行してみる
$ ruby securityCheck.rb
うまく動いたら、cronに登録して自動化