見出し画像

プログラミングのリスキリングも兼ねて、脆弱性スキャンの自動化を構築するためのネタ・アイディアのたたき台

脆弱性に関する思いついたアイディアや実装したい機能を、片っ端から作ってみた。
最近、プログラミングしていないので、コーディング技術を最低限レベルで維持するために、備忘録として記録してみました。

社内ネットワークに接続しているLinux-PCへの公開鍵のばらまき

#!/bin/bash

# IPアドレス一覧ファイルのパス
ip_list_file="<your_ip_list_file_path>"

# id_rsa.pubのパス
pub_key_file="<your_pub_key_file_path>"

# SSH接続用のIDとPasswordを入力
read -p "Enter SSH ID: " ssh_id
read -p "Enter SSH Password: " -s ssh_password

# 失敗したIPアドレスを記録するテキストのパス
failed_ip_list_file="<your_failed_ip_list_file_path>"

# IPアドレス一覧ファイルから各IPアドレスを読み込み
while read line
do
  ip=$line
  echo "Connecting to $ip..."

  # SSHログインしてid_rsa.pubを配置
  if sshpass -p $ssh_password ssh $ssh_id@$ip "mkdir -p ~/.ssh; chmod 700 ~/.ssh; cat >> ~/.ssh/authorized_keys" < $pub_key_file; then
    echo "Done."
  else
    echo "Failed."
    echo $ip >> $failed_ip_list_file
  fi
done < $ip_list_file

# 失敗したIPアドレスがある場合は通知
if [ -s $failed_ip_list_file ]; then
  echo "Failed IP addresses are recorded in $failed_ip_list_file."
else
  echo "Successfully completed."
fi

接続先のIDとPasswardは一時的に統一してもらい、本シェルが完了次第、元に戻す必要がある。
SSHログインが成功したら、"id_rsa.pub"を/your_home/.ssh/配下に格納する
SSHログインが失敗したら、IPアドレス一覧のテキストを出力

SBOMがある前提で、OSSとバージョンの情報を取得して、NVD、CVE、JVNのサイトから脆弱性をチェック

#!/bin/bash

# NVD、CVE、JVNのサイトから脆弱性情報を取得する
get_vulnerability_info() {
  local oss=$1
  local version=$2

  # NVDサイトから脆弱性情報を取得
  local nvd_info=$(curl -s https://nvd.nist.gov/vuln/search/results?form_type=Advanced&cves=on&cpe_version=$oss:$version)

  # CVEサイトから脆弱性情報を取得
  local cve_info=$(curl -s https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=$oss+$version)

  # JVNサイトから脆弱性情報を取得
  local jvn_info=$(curl -s https://jvndb.jvn.jp/search/index.php?mode=_vulnerability_search_IA_VulnSearch&lang=ja&keyword=$oss+$version)

  # 脆弱性情報が存在するかどうか判定
  if [[ $nvd_info = *"No matching results"* && $cve_info = *"0 vulnerabilities"* && $jvn_info = *"該当する脆弱性情報は見つかりませんでした"* ]]; then
    echo "$oss $version is not vulnerable"
  else
    echo "$oss $version is vulnerable"
    # 脆弱性情報をテキストで保存
    echo "$oss $version is vulnerable" >> vulnerabilities.txt
  fi
}

# oss_version_list.txtからOSSとバージョン情報を取得
while read line; do
  oss=$(echo $line | awk '{print $1}')
  version=$(echo $line | awk '{print $2}')
  get_vulnerability_info $oss $version
done < oss_version_list.txt

dpkgからインストールされているパッケージを取得し、各パッケージの脆弱性をチェック

#!/bin/bash

URL="https://jvndb.jvn.jp/myjvn?feed=hnd&method=getVulnOverviewList&"
START="datePublicStartY=2015&"
RANGEP="rangeDatePublished=n&"
RANGEF="rangeDateFirstPublished=n&"
RES_TMP_FILE="res_tmp.txt"
CSV_FILE="result.csv"

check_vulnerability () {
    local pkg=$1
    curl -s "${URL}keyword=${pkg}&${START}${RANGEP}${RANGEF}" > $RES_TMP_FILE
    local html=$(grep -oE 'http(s?)://[0-9a-zA-Z?=#+_&:/.%-]+' $RES_TMP_FILE)
    if [ -z "$html" ]; then
        echo "${pkg}, 脆弱性報告なし"
    else
        # echo "${pkg}, 脆弱性あり (詳細確認してください), $html"
        # 各脆弱性情報のページから必要な情報を取得する
        # local info=$(curl -s $html | grep -E "jvn-info-title-.*\s*.*\s*.*\s*.*\s*.*\s*.*\s*.*\s*.*\s*.*" | awk -F ' ' '{printf("%s,%s,%s,%s\n", $3, $4, $8, $11)}')
        local info=$(curl -s $html | grep -E "jvn-info-title-.\s.\s.\s.\s.\s.\s.\s.\s.*" | awk -F ' ' '{printf("%s,%s,%s,%s\n", $3, $4, $8, $11)}')
        local info=$(curl -s $html | grep -E "jvn-info-title-.\s.\s.\s.\s.\s.\s.\s.\s.*" | awk -F ' ' '{printf("%s,%s,%s,%s\n", $3, $4, $8, $11)}
        local score=$(echo $info | awk -F ',' '{print $3}')
        local version=$(echo $info | awk -F ',' '{print $2}')
        echo "${pkg}, 脆弱性あり, Version: $version, CVSS: $score"
        # CVSSスコアが7.5以上であれば、CSVファイルに書き込む
        if awk -v score="$score" 'BEGIN {if (score >= 7.5) exit 0; exit 1}'; then
            echo $info | awk -F ',' '{printf("%s,%s,%s,%s\n", $1, $2, $3, $4)}' >> $CSV_FILE
        fi
    fi
}

# 結果を出力するCSVファイルを初期化する
echo "OSS名, Version, CVSS, CVE番号" > $CSV_FILE

# dpkgからインストールされているパッケージを取得し、各パッケージの脆弱性を確認する
dpkg -l | awk '$1 == "ii" {print $2}' | while read pkg; do
    check_vulnerability "$pkg"
done

ソースコード(C言語、C++)からOSSとversionOSSを取得し、NVDサイトを使用してCVSS 7.5以上の脆弱性をチェック

#!/bin/bash

# 出力するファイル名
OUTPUT_FILE=libraries.txt

# C言語とC++言語のソースコードの一覧を取得
SOURCES=$(find . -name "*.c" -or -name "*.cpp")

# 使用する外部ライブラリを抽出し、出力
for SOURCE in $SOURCES; do
  OBJS=$(nm $SOURCE 2>&1 | grep "U" | awk '{print $NF}')
  for OBJ in $OBJS; do
    if ! grep -q "^$OBJ," $OUTPUT_FILE; then
      echo -n "$OBJ," >> $OUTPUT_FILE
      ldd $(which $OBJ) | grep -oP "(?<=\ )[^ ]+(?=\ .so)" | awk '{print $1}' >> $OUTPUT_FILE
      # NVDから脆弱性情報を取得し、追記
      CVE=$(curl -s "https://nvd.nist.gov/vuln/search/results?form_type=Advanced&results_type=overview&query=$OBJ&search_type=all&cves=on" | grep -oP 'CVE-\d{4}-\d{4,7}' | head -n 1)
      CVSS=$(curl -s "https://nvd.nist.gov/vuln/detail/$CVE" | grep -oP '(?<=CVSS Score: )[^<]+' | head -n 1)
      SEVERITY=$(curl -s "https://nvd.nist.gov/vuln/detail/$CVE" | grep -oP '(?<=Severity:</strong> )[^<]+' | head -n 1)
      echo "$OBJ,$CVE,$CVSS,$SEVERITY" >> $OUTPUT_FILE
      echo "" >> $OUTPUT_FILE
    fi
  done
done

(nmコマンドで依存関係を調べているので)ソースコードはビルドされていることが条件
出力一例


$ cat libraries.txt
libc.so.6,glibc,CVE-2021-1049,6.8,High
libz.so.1,zlib,CVE-2018-12130,5.3,Moderate
...
...
...


この記事が気に入ったらサポートをしてみませんか?