LINEで送る
Pocket

お待ちかねの!!!!

Vulschatworkにも通知できるように開発しましたぁあああ!!!!(これは熱い)
今までメール,slack,hipchat,strideでしたが、やはりchatwork導入している
企業さん結構多いので、この際作ったらバズりそうと予想してました。(ちなみにMANABIYAでも告知はしてました)

個人的にGo勉強していますが、慣れということでVulsからチャレンジも兼ねて作ってみました!


■chatwork.go

// ChatWorkWriter定義。Writeメソッドを定義して、vuls report -to-chatworkを実行時に標準出力に加えてchatworkにもoutputするプログラム
package report
import (
"fmt"
"net/http"
"net/url"
"strconv"
"strings"
"github.com/future-architect/vuls/config"
"github.com/future-architect/vuls/models"
)
// ChatWorkWriter send report to ChatWork
type ChatWorkWriter struct{}
func (w ChatWorkWriter) Write(rs models.ScanResult) (err error) {
// tomlをパースしてconfig.Conf.ChatWorkに設定値が入りからの取得
conf := config.Conf.ChatWork
for _, r := range rs {
// api call OS名や詳細を取得
serverInfo := fmt.Sprintf("%s", r.ServerInfo())
if err = ChatWorkpostMessage(conf.Room, conf.ApiToken, serverInfo); err != nil {
return err
}
// メッセージ組み立て処理してCVEの値をループしている
for _, vinfo := range r.ScannedCves {
maxCvss := vinfo.MaxCvssScore()
severity := strings.ToUpper(maxCvss.Value.Severity)
if severity == "" {
severity = "?"
}
// chatworkへ通知するメッセージ生成
message := fmt.Sprintf(`%s[info][title]"https://nvd.nist.gov/vuln/detail/%s" %s %s[/title]%s[/info]`,
serverInfo,
vinfo.CveID,
strconv.FormatFloat(maxCvss.Value.Score, 'f', 1, 64),
severity,
vinfo.Summaries(config.Conf.Lang, r.Family)[0].Value)
if err = ChatWorkpostMessage(conf.Room, conf.ApiToken, message); err != nil {
return err
}
}
return nil
}
func ChatWorkpostMessage(room, token, message string) error {
// chatwork api url生成 token埋め込み
uri := fmt.Sprintf("https://api.chatwork.com/v2/rooms/%s/messages=%s", room, token)
// payload生成
payload := url.Values{
"body": {message},
}
// chatworkにpayloadを添えてPOST
reqs, err := http.NewRequest("POST", uri, strings.NewReader(payload.Encode()))
// chatwork api リクエストヘッダー追記
reqs.Header.Add("X-ChatWorkToken", token)
reqs.Header.Add("Content-Type", "application/x-www-form-urlencoded")
if err != nil {
return err
}
client := &http.Client{}
// HTTP Requestを投げている
resp, err := client.Do(reqs)
if err != nil {
return err
}
// http body readerをclose
defer resp.Body.Close()
return nil
}

view raw
chatwork.go
hosted with ❤ by GitHub

// add program
HipChat HipChatConf
// config追加
+ ChatWork ChatWorkConf
ToHipChat bool
+ ToChatWork bool
if hipchaterrs := c.HipChat.Validate(); 0 < len(hipchaterrs) {
errs = append(errs, hipchaterrs)
}
// -to-chatworkオプションを付けたのに設定がない場合のエラー処理
+ if chatworkerrs := c.ChatWork.Validate(); 0 < len(chatworkerrs) {
+ errs = append(errs, chatworkerrs)
+ }
// tomlのchatwork configを受け取る構造体
+ // ChatWorkConf is ChatWork config
+ type ChatWorkConf struct {
ApiToken string `json:"ApiToken"`
Room string `json:"Room"`
}
// configのvalidate処理
+ // Validate validates configuration
+ func (c *ChatWorkConf) Validate() (errs []error) {
+ if !Conf.ToChatWork {
+ return
+ }
+ if len(c.Room) == 0 {
+ + errs = append(errs, fmt.Errorf("chatworkcaht.room must not be empty"))
+ +}
+ if len(c.ApiToken) == 0 {
+ errs = append(errs, fmt.Errorf("chatworkcaht.ApiToken must not be empty"))
+ }
+ _, err := valid.ValidateStruct(c)
+ if err != nil {
+ errs = append(errs, err)
+ }
+ return
+}

view raw
config.go
hosted with ❤ by GitHub

// chatworkに通知するroomとapiTokenを指定
[chatwork]
room = "xxxxxxxxxx"
apiToken = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
[servers]
[servers.localhost]
host = "localhost"
port = "local"
// chatworkにreportするように追記
# vuls report -format-short-text -format-json -to-chatwork -cvss-over=7 -lang=ja

view raw
config.toml
hosted with ❤ by GitHub

// add program
toHipChat bool
// toChatWorkオプションの変数追加
+ toChatWork bool
[tohipchat]
// vuls report –helpを実行したときに表示されるusageに-to-chatworkオプションがある旨を追記
+ [tochatwork]
// コマンドラインオプションを受け取り、上記で定義したto-chatworkにbooleanの値を插入
f.BoolVar(&p.toHipChat, "to-hipchat", false, "Send report via hipchat")
+ f.BoolVar(&p.toChatWork, "to-chatwork", false, "Send report via chatwork")
c.Conf.ToHipChat = p.toHipChat
+ c.Conf.ToChatWork = p.toChatWork
// ChatWorkWriter構造体を作って、Writeメソッドをcall
if p.toHipChat {
reports = append(reports, report.HipChatWriter{})
}
+ if p.toChatWork {
+ reports = append(reports, report.ChatWorkWriter{})
+ }

view raw
report.go
hosted with ❤ by GitHub

Conf.HipChat = conf.HipChat
+ Conf.ChatWork = conf.ChatWork

view raw
tomlloader.go
hosted with ❤ by GitHub

とりあえずhipchatとほぼコードが同じなので、
@warugaki_k_kである、かずみんのコードを参考にしてみました。
上記のgistに補足いろいろと書いたので、Vulsのコードがどうなっているのか理解できるかと!


■ChatWork support #634

https://github.com/future-architect/vuls/pull/634

4つほど修正。

ちょんまげさんからmessageの部分でfmt.Sprintf使うと
分かりやすいとのことで修正しました。(こんなにキレイになるんですね)

・fmt.Sprintf

https://golang.org/pkg/fmt/#Sprintf

Goの静的型付けにおいてstringと他の型をstring型として一緒に扱うことができる関数ですね。

・Before

・After


■で、どんな感じよ

とまあ、初めはめちゃくちゃカオスでしたが….

このように見やすく!!!

chatworkはhtmlタグが使えないためリンクは挫折しました。。(対応してないぽい)
slackのようにスレッド形式ならもっと分かりやすく通知できましたが、
chatworkにはなんせそんなものがないので。。。
毎回ホスト名&OS情報を出してこの脆弱性どこのホストだよ!とならないようにしてみました。


■まとめ

今までVulsRepoのコントリビュータでしたが、
ついに本家のコントリビュータになれて嬉しい!!!!
Goも早く慣れていきたいので、この調子で今後もコントリビュート頑張りやす!!
※サポートしてくれた かずみんとその他Goできる友人サンクス!
そしてちょんまげさんもお忙しいところありがとうございました!)

LINEで送る
Pocket

カテゴリー: GoVuls

adachin

1989年生まれのLancers SRE。 ホスティングから大規模なアドテクなどのインフラエンジニアとして携わり、AnsibleやTerraformでのインフラコード化を推進。副業では数社サーバー保守、未経験によるエンジニアのメンターなども実施している。また、「脆弱性スキャナVuls」のOSS活動もしており、自称エバンジェリスト/技術広報/テクニカルサポート/コントリビュータでもある。現在はサービスの信頼性向上、可用性、レイテンシ、パフォーマンス、モニタリング、緊急対応、インフラコード化、リファクタリング、セキュリティ強化、新技術の検証、Docker開発環境の提供、AWSでのインフラ構築、グループ会社のインフラをECS/Fargateへ移行、CakePHP4での管理画面作成、メンター、分析基盤の運用を担当している。

0件のコメント

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください