在系統管理和資安領域中,驗證系統組態的正確性至關重要。validateconfig.sh 是一款以 Bash 語言開發的工具,能有效檢查系統組態是否符合預期。它支援多種檢查方式,涵蓋檔案存在性、檔案 SHA-1 雜湊值、使用者及群組是否存在、Windows 登入檔鍵值等。核心功能包含讀取預先定義的組態規範,逐行解析命令與引數,並根據命令型別呼叫對應的驗證函式。主要的驗證函式包含 vfile、vhash、vuser、vgroup 和 vreg,分別用於檢查檔案存在性、檔案雜湊值、使用者、群組和 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
}
vuser 和 vgroup 函式分別用於檢查指定的使用者和群組是否存在。這些函式會根據第一個引數的值決定是否反轉檢查結果。
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陳述式根據基礎命令名稱呼叫相應的檢查函式(如vfile、vhash等)。 - 結果檢查:檢查函式的傳回結果,若結果與預期不符,則輸出失敗訊息。
在未來的網路安全工作中,持續擴充套件和改進 validateconfig.sh 工具將有助於提高系統組態驗證的效率和準確性。同時,結合其他安全工具(如 YARA),可以進一步增強系統的安全監控能力。
工作坊
嘗試擴充套件 validateconfig.sh 的功能,新增以下特性:
- 檢查特設定檔案許可權是否存在。
- 檢查特定網路埠是否開啟或關閉。
- 檢查特定程式是否正在執行。
- 在輸入串流中支援註解,若讀取的行第一個字元是 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
程式碼解密:
- 檢查輸入密碼:指令碼首先檢查是否提供了密碼作為命令列引數。如果沒有,則提示使用者輸入密碼。
- 計算 SHA-1 雜湊值:使用
sha1sum命令計算輸入密碼的 SHA-1 雜湊值。 - 提取雜湊值的前五個和後三十五個字元:將雜湊值的前五個字元儲存在
firstFive中,將剩下的字元儲存在ending中。 - 查詢 Have I Been Pwned API:使用
curl命令查詢 API,並傳入firstFive。 - 處理傳回結果:移除傳回結果中的
\r字元,然後使用grep命令搜尋ending是否存在於結果中。 - 輸出結果:如果找到匹配的雜湊值,則輸出密碼被洩露的次數。
使用指令碼
執行指令碼時,可以直接傳入密碼或在提示時輸入:
$ ./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
程式碼解密:
- 檢查輸入電子郵件地址:指令碼首先檢查是否提供了電子郵件地址作為命令列引數。如果沒有,則提示使用者輸入。
- 查詢 Have I Been Pwned API:使用
curl命令查詢 API,並傳入電子郵件地址。 - 處理傳回結果:如果傳回結果不為空,則解析 JSON 結果,提取出洩露事件的名稱。
- 輸出結果:輸出電子郵件地址出現在哪些資料洩露事件中。
檢查電子郵件地址是否已洩露
在進行資安檢查時,檢查電子郵件地址是否已在資料洩露事件中被公開是一項重要任務。本篇文章將介紹如何使用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
內容解密:
- 檢查輸入引數:指令碼首先檢查是否提供了命令列引數。如果沒有,則提示使用者輸入電子郵件地址。
- 建構API請求URL:使用提供的或輸入的電子郵件地址,建構HIBP API的請求URL。
- 傳送API請求並解析結果:使用
curl傳送請求,並透過grep解析傳回的JSON結果,提取出與資料洩露事件相關的名字。 - 處理結果輸出:如果有資料洩露事件相關的結果,則輸出這些事件的名字;否則,指令碼以狀態碼1離開,表示未發現相關的資料洩露事件。
指令碼變體與最佳化
為了展示不同的實作方式,提供了另兩個指令碼變體:checkemailAlt.sh和checkemail.1liner。
checkemailAlt.sh
這個版本在執行curl命令時直接進行grep操作,以提高效率。它還使用了bash的變數替換功能來編輯結果,避免了呼叫額外的程式如cut和tr。
#!/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
內容解密:
- 讀取檔案內容:指令碼讀取第一個命令列引數指定的檔案內容,並移除Windows風格的換行符。
- 逐行處理:對檔案的每一行(即每個電子郵件地址),呼叫
checkemail.sh指令碼。 - 檢查結果並輸出:如果
checkemail.sh傳回0,表示該電子郵件地址已被洩露,指令碼輸出相應資訊。 - 延遲執行:為了避免超過HIBP API的呼叫速率限制,指令碼在每次呼叫之間延遲0.25秒。
練習與擴充套件方向
- 擴充套件checkpass.sh:使其能夠接受SHA-1雜湊值作為命令列引數,用於檢查密碼是否已被洩露。
- 建立類別似emailbatch.sh的指令碼:用於批次檢查SHA-1雜湊值列表中的密碼是否已被洹露。
- 整合多個指令碼:將checkpass.sh、checkemail.sh和emailbatch.sh的功能整合到一個單一的指令碼中,以提供更全面的資安檢查工具。