返回文章列表

Bash 系統組態驗證工具

本文介紹 validateconfig.sh,一個使用 Bash 編寫的系統組態驗證工具,它能檢查檔案存在性、檔案雜湊值、使用者和群組等組態,並提供程式碼解析、主程式邏輯說明以及擴充套件功能的建議,例如檢查檔案許可權、網路埠和程式狀態等,以提升系統組態驗證效率和安全性。

資安 系統管理

在系統管理和資安領域中,驗證系統組態的正確性至關重要。validateconfig.sh 是一款以 Bash 語言開發的工具,能有效檢查系統組態是否符合預期。它支援多種檢查方式,涵蓋檔案存在性、檔案 SHA-1 雜湊值、使用者及群組是否存在、Windows 登入檔鍵值等。核心功能包含讀取預先定義的組態規範,逐行解析命令與引數,並根據命令型別呼叫對應的驗證函式。主要的驗證函式包含 vfilevhashvuservgroupvreg,分別用於檢查檔案存在性、檔案雜湊值、使用者、群組和 Windows 登入檔。透過反轉檢查結果的引數設計,可以彈性地檢查組態是否存在或不存在。主程式邏輯會逐行讀取組態規範,並根據命令型別呼叫對應的函式執行驗證。若驗證結果與預期不符,則會輸出錯誤訊息,方便管理員快速定位問題。

使用 Bash 驗證系統組態的工具:validateconfig.sh

在網路安全領域,驗證系統組態是一項重要的任務。validateconfig.sh 是一個使用 Bash 編寫的工具,能夠根據特定的組態規範檢查系統的組態狀態。本篇文章將探討該工具的實作原理、功能特點以及如何擴充套件其功能。

工具概述

validateconfig.sh 工具的主要功能是驗證指定的組態是否存在於系統中。它支援多種組態檢查方式,包括檔案存在性檢查、檔案雜湊值檢查、Windows 登入檔檢查、使用者和群組檢查等。

程式碼解析

1. 主要函式

function errexit ()
{
    echo "invalid syntax at line $ln"
    echo "usage: [!]file|hash|reg|[!]user|[!]group [args]"
    exit 2
} 

errexit 函式用於輸出錯誤訊息並離開程式。當輸入的組態規範不正確時,會呼叫此函式。

2. 檔案存在性檢查

function vfile ()
{
    local isThere=0
    [[ -e $2 ]] && isThere=1
    (( $1 )) && let isThere=1-$isThere
    return $isThere
}

vfile 函式檢查指設定檔案是否存在。第一個引數用於指示是否需要反轉檢查結果(即檢查檔案是否不存在)。

3. 使用者和群組檢查

function vuser ()
{
    local isUser
    $UCMD $2 &>/dev/null
    isUser=$?
    if (( $1 ))
    then
        let isUser=1-$isUser
    fi
    return $isUser
}

function vgroup ()
{
    local isGroup
    id $2 &>/dev/null
    isGroup=$?
    if (( $1 ))
    then
        let isGroup=1-$isGroup
    fi
    return $isGroup
}

vuservgroup 函式分別用於檢查指定的使用者和群組是否存在。這些函式會根據第一個引數的值決定是否反轉檢查結果。

4. 檔案雜湊值檢查

function vhash ()
{
    local res=0
    local X=$(sha1sum $2)
    if [[ ${X%% *} == $1 ]]
    then
        res=1
    fi
    return $res
}

vhash 函式計算指設定檔案的 SHA-1 雜湊值,並與提供的雜湊值進行比較。

5. Windows 登入檔檢查

function vreg ()
{
    local res=0
    local keypath=$1
    local value=$2
    local expected=$3
    local REGVAL=$(query $keypath //v $value)
    if [[ $REGVAL == $expected ]]
    then
        res=1
    fi
    return $res
}

vreg 函式檢查 Windows 登入檔中指定鍵值對的值是否符合預期。

主程式邏輯

主程式邏輯涉及讀取組態規範並根據規範呼叫相應的檢查函式。以下是主程式碼片段:

while read cmd args
do
    let ln++
    donot=0
    if [[ ${cmd:0:1} == '!' ]]
    then
        donot=1
        basecmd=${cmd#\!}
    fi
    case "$basecmd" in
        file)
            OK=1
            vfile $donot "$args"
            res=$?
            ;;
        # 其他 case 陳述式...
        *) errexit
            ;;
    esac
    if (( res != OK ))
    then
        echo "FAIL: [$ln] $cmd $args"
    fi
done

程式碼解析:

  • 逐行讀取組態規範:使用 while read cmd args 迴圈逐行讀取輸入的組態規範,每行包含一個命令和其引數。
  • 處理命令字首:檢查命令是否以 ! 開頭,若是,則設定 donot 為 1,並移除 ! 以取得基礎命令名稱。
  • 命令分派:使用 case 陳述式根據基礎命令名稱呼叫相應的檢查函式(如 vfilevhash 等)。
  • 結果檢查:檢查函式的傳回結果,若結果與預期不符,則輸出失敗訊息。

在未來的網路安全工作中,持續擴充套件和改進 validateconfig.sh 工具將有助於提高系統組態驗證的效率和準確性。同時,結合其他安全工具(如 YARA),可以進一步增強系統的安全監控能力。

工作坊

嘗試擴充套件 validateconfig.sh 的功能,新增以下特性:

  1. 檢查特設定檔案許可權是否存在。
  2. 檢查特定網路埠是否開啟或關閉。
  3. 檢查特定程式是否正在執行。
  4. 在輸入串流中支援註解,若讀取的行第一個字元是 hashtag,則丟棄該行(即無需處理)。

存取網路安全營運網站以取得更多資源和這些問題的答案。

檢查密碼是否已洩露

Have I Been Pwned 提供了一個 API 來查詢密碼是否已在資料洩露事件中被公開。為了安全起見,該服務不接受明文密碼,而是要求提供密碼的 SHA-1 雜湊值的前五個字元。

使用 API 查詢密碼

首先,需要將密碼轉換為 SHA-1 雜湊值。例如,密碼 password 的 SHA-1 雜湊值是 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8。然後,取前五個字元 5baa6 並將其附加到 API URL 後面:https://api.pwnedpasswords.com/range/5baa6

處理查詢結果

Have I Been Pwned 的 API 會傳回所有以 5baa6 開頭的雜湊值列表。然後,在本地搜尋完整的雜湊值 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8(或其後 35 個字元)是否在列表中。如果找到,則表示密碼已洩露。

結果範例

1CC93AEF7B58A1B631CB55BF3A3A3750285:3
1D2DA4053E34E76F6576ED1DA63134B5E2A:2
1D72CD07550416C216D8AD296BF5C0AE8E0:10
1E2AAA439972480CEC7F16C795BBB429372:1
1E3687A61BFCE35F69B7408158101C8E414:1
1E4C9B93F3F0682250B6CF8331B7EE68FD8:3533661

每行後面的數字表示使用該密碼的帳戶數量。

自動化檢查密碼的指令碼

下面是一個 bash 指令碼 checkpass.sh,用於自動檢查密碼是否已洩露。

checkpass.sh 程式碼

#!/bin/bash -

if (( "$#" == 0 ))
then
  printf 'Enter your password: '
  read -s passin
else
  passin="$1"
  echo
fi

passin=$(echo -n "$passin" | sha1sum)
passin=${passin:0:40}
firstFive=${passin:0:5}
ending=${passin:6}

pwned=$(curl -s "https://api.pwnedpasswords.com/range/$firstFive" | tr -d '\r' | grep -i "$ending" )
passwordFound=${pwned##*:}

if [ "$passwordFound" == "" ]
then
  exit 1
else
  printf 'Password is Pwned %d Times!\n' "$passwordFound"
  exit 0
fi

程式碼解密:

  1. 檢查輸入密碼:指令碼首先檢查是否提供了密碼作為命令列引數。如果沒有,則提示使用者輸入密碼。
  2. 計算 SHA-1 雜湊值:使用 sha1sum 命令計算輸入密碼的 SHA-1 雜湊值。
  3. 提取雜湊值的前五個和後三十五個字元:將雜湊值的前五個字元儲存在 firstFive 中,將剩下的字元儲存在 ending 中。
  4. 查詢 Have I Been Pwned API:使用 curl 命令查詢 API,並傳入 firstFive
  5. 處理傳回結果:移除傳回結果中的 \r 字元,然後使用 grep 命令搜尋 ending 是否存在於結果中。
  6. 輸出結果:如果找到匹配的雜湊值,則輸出密碼被洩露的次數。

使用指令碼

執行指令碼時,可以直接傳入密碼或在提示時輸入:

$ ./checkpass.sh password
Password is Pwned 3533661 Times!

檢查電子郵件地址是否已洩露

檢查電子郵件地址是否已洩露相對簡單。Have I Been Pwned 提供了一個 API,可以查詢電子郵件地址是否出現在資料洩露事件中。

使用 API 查詢電子郵件地址

API URL 為 https://haveibeenpwned.com/api/v2/breachedaccount/,後面附加要查詢的電子郵件地址。

自動化檢查電子郵件地址的指令碼

下面是一個 bash 指令碼 checkemail.sh,用於自動檢查電子郵件地址是否已洩露。

checkemail.sh 程式碼

#!/bin/bash -

if (( "$#" == 0 ))
then
  printf 'Enter email address: '
  read emailin
else
  emailin="$1"
fi

pwned=$(curl -s "https://haveibeenpwned.com/api/v2/breachedaccount/$emailin")

if [ "$pwned" == "" ]
then
  exit 1
else
  echo 'Account pwned in the following breaches:'
  echo "$pwned" | grep -Po '"Name":".*?"' | cut -d':' -f2 | tr -d '\"'
  exit 0
fi

程式碼解密:

  1. 檢查輸入電子郵件地址:指令碼首先檢查是否提供了電子郵件地址作為命令列引數。如果沒有,則提示使用者輸入。
  2. 查詢 Have I Been Pwned API:使用 curl 命令查詢 API,並傳入電子郵件地址。
  3. 處理傳回結果:如果傳回結果不為空,則解析 JSON 結果,提取出洩露事件的名稱。
  4. 輸出結果:輸出電子郵件地址出現在哪些資料洩露事件中。

檢查電子郵件地址是否已洩露

在進行資安檢查時,檢查電子郵件地址是否已在資料洩露事件中被公開是一項重要任務。本篇文章將介紹如何使用bash指令碼結合Have I Been Pwned?(HIBP)API來檢查電子郵件地址的安全狀態。

指令碼實作:checkemail.sh

以下是一個基本的checkemail.sh指令碼,用於檢查輸入的電子郵件地址是否已在HIBP資料函式庫中被記錄:

#!/bin/bash
# checkemail.sh - 檢查電子郵件地址是否在Have I Been Pwned?資料函式庫中

if (( "$#" == 0 ))
then
    printf '輸入電子郵件地址: '
    read emailin
else
    emailin="$1"
fi

URL="https://haveibeenpwned.com/api/v2/breachedaccount/$emailin"
pwned=$(curl -s "$URL" | grep -Po '"Name":".*?"' )

if [ "$pwned" == "" ]
then
    exit 1
else
    echo '帳戶在以下資料洩露事件中被洩露:'
    pwned="${pwned//\"/}" # 移除所有引號
    pwned="${pwned//Name:/}" # 移除所有'Name:'
    echo "${pwned}"
    exit 0
fi

內容解密:

  1. 檢查輸入引數:指令碼首先檢查是否提供了命令列引數。如果沒有,則提示使用者輸入電子郵件地址。
  2. 建構API請求URL:使用提供的或輸入的電子郵件地址,建構HIBP API的請求URL。
  3. 傳送API請求並解析結果:使用curl傳送請求,並透過grep解析傳回的JSON結果,提取出與資料洩露事件相關的名字。
  4. 處理結果輸出:如果有資料洩露事件相關的結果,則輸出這些事件的名字;否則,指令碼以狀態碼1離開,表示未發現相關的資料洩露事件。

指令碼變體與最佳化

為了展示不同的實作方式,提供了另兩個指令碼變體:checkemailAlt.shcheckemail.1liner

checkemailAlt.sh

這個版本在執行curl命令時直接進行grep操作,以提高效率。它還使用了bash的變數替換功能來編輯結果,避免了呼叫額外的程式如cuttr

#!/bin/bash
# checkemailAlt.sh - 檢查電子郵件地址是否在Have I Been Pwned?資料函式庫中

if (( "$#" == 0 ))
then
    printf '輸入電子郵件地址: '
    read emailin
else
    emailin="$1"
fi

URL="https://haveibeenpwned.com/api/v2/breachedaccount/$emailin"
pwned=$(curl -s "$URL" | grep -Po '"Name":".*?"' )
if [ "$pwned" == "" ]
then
    exit 1
else
    echo '帳戶在以下資料洩露事件中被洩露:'
    pwned="${pwned//\"/}" 
    pwned="${pwned//Name:/}" 
    echo "${pwned}"
    exit 0
fi

內容解密:

  • 與前一版本類別似,但直接在curl後進行grep,然後使用變數替換簡化輸出結果。

checkemail.1liner

這個版本將所有操作壓縮到一行中,使用了較長的管道命令來處理結果。

#!/bin/bash
# checkemail.1liner - 檢查電子郵件地址是否在Have I Been Pwned?資料函式庫中(單行版本)

EMAILIN="$1"
if (( "$#" == 0 ))
then
    printf '輸入電子郵件地址: '
    read EMAILIN
fi

EMAILIN="https://haveibeenpwned.com/api/v2/breachedaccount/$EMAILIN"
echo '帳戶在以下資料洩露事件中被洩露:'
curl -s "$EMAILIN" | grep -Po '"Name":".*?"' | cut -d':' -f2 | tr -d '\"'

內容解密:

  • 使用單一變數EMAILIN來儲存URL和最終結果。
  • 管道命令用於處理curl傳回的結果,直接輸出處理後的資料洩露事件名稱。

批次處理電子郵件地址:emailbatch.sh

當需要檢查多個電子郵件地址時,可以使用emailbatch.sh指令碼,它從檔案中讀取電子郵件地址列表,並為每個地址呼叫checkemail.sh

#!/bin/bash -
# emailbatch.sh - 從檔案中讀取電子郵件地址並檢查是否在Have I Been Pwned?資料函式庫中

cat "$1" | tr -d '\r' | while read fileLine
do
    ./checkemail.sh "$fileLine" > /dev/null
    if (( "$?" == 0 ))
    then
        echo "$fileLine 已被洩露!"
    fi
    sleep 0.25
done

內容解密:

  1. 讀取檔案內容:指令碼讀取第一個命令列引數指定的檔案內容,並移除Windows風格的換行符。
  2. 逐行處理:對檔案的每一行(即每個電子郵件地址),呼叫checkemail.sh指令碼。
  3. 檢查結果並輸出:如果checkemail.sh傳回0,表示該電子郵件地址已被洩露,指令碼輸出相應資訊。
  4. 延遲執行:為了避免超過HIBP API的呼叫速率限制,指令碼在每次呼叫之間延遲0.25秒。

練習與擴充套件方向

  1. 擴充套件checkpass.sh:使其能夠接受SHA-1雜湊值作為命令列引數,用於檢查密碼是否已被洩露。
  2. 建立類別似emailbatch.sh的指令碼:用於批次檢查SHA-1雜湊值列表中的密碼是否已被洹露。
  3. 整合多個指令碼:將checkpass.sh、checkemail.sh和emailbatch.sh的功能整合到一個單一的指令碼中,以提供更全面的資安檢查工具。