Linux Capabilities 入門教程:概念篇
原文連結:Linux Capabilities 入門教程:概念篇
Linux 是一種安全的作業系統,它把所有的系統許可權都賦予了一個單一的 root 使用者,只給普通使用者保留有限的許可權。root 使用者擁有超級管理員許可權,可以安裝軟體、允許某些服務、管理使用者等。
作為普通使用者,如果想執行某些只有管理員才有許可權的操作,以前只有兩種辦法:一是通過 sudo
提升許可權,如果使用者很多,配置管理和許可權控制會很麻煩;二是通過 SUID(Set User ID on execution)來實現,它可以讓普通使用者允許一個 owner
為 root 的可執行檔案時具有 root 的許可權。
SUID
的概念比較晦澀難懂,舉個例子就明白了,以常用的 passwd
命令為例,修改使用者密碼是需要 root 許可權的,但普通使用者卻可以通過這個命令來修改密碼,這就是因為 /bin/passwd
被設定了 SUID
標識,所以普通使用者執行 passwd 命令時,程序的 owner 就是 passwd 的所有者,也就是 root 使用者。
SUID
雖然可以解決問題,但卻帶來了安全隱患。當執行設定了 SUID
的命令時,通常只是需要很小一部分的特權,但是 SUID
給了它 root 具有的全部許可權。這些可執行檔案是黑客的主要目標,如果他們發現了其中的漏洞,就很容易利用它來進行安全攻擊。簡而言之,SUID
為了對 root 許可權進行更細粒度的控制,實現按需授權,Linux 引入了另一種機制叫 capabilities
。
1. Linux capabilities 是什麼?
Capabilities
機制是在 Linux 核心 2.2
之後引入的,原理很簡單,就是將之前與超級使用者 root(UID=0)關聯的特權細分為不同的功能組,Capabilites 作為執行緒(Linux 並不真正區分程序和執行緒)的屬性存在,每個功能組都可以獨立啟用和禁用。其本質上就是將核心呼叫分門別類,具有相似功能的核心呼叫被分到同一組中。
這樣一來,許可權檢查的過程就變成了:在執行特權操作時,如果執行緒的有效身份不是 root,就去檢查其是否具有該特權操作所對應的 capabilities,並以此為依據,決定是否可以執行特權操作。
Capabilities 可以在程序執行時賦予,也可以直接從父程序繼承。所以理論上如果給 nginx 可執行檔案賦予了 CAP_NET_BIND_SERVICE
capabilities,那麼它就能以普通使用者執行並監聽在 80 埠上。
capability 名稱 | 描述 |
---|---|
CAP_AUDIT_CONTROL | 啟用和禁用核心審計;改變審計過濾規則;檢索審計狀態和過濾規則 |
CAP_AUDIT_READ | 允許通過 multicast netlink 套接字讀取審計日誌 |
CAP_AUDIT_WRITE | 將記錄寫入核心審計日誌 |
CAP_BLOCK_SUSPEND | 使用可以阻止系統掛起的特性 |
CAP_CHOWN | 修改檔案所有者的許可權 |
CAP_DAC_OVERRIDE | 忽略檔案的 DAC 訪問限制 |
CAP_DAC_READ_SEARCH | 忽略檔案讀及目錄搜尋的 DAC 訪問限制 |
CAP_FOWNER | 忽略檔案屬主 ID 必須和程序使用者 ID 相匹配的限制 |
CAP_FSETID | 允許設定檔案的 setuid 位 |
CAP_IPC_LOCK | 允許鎖定共享記憶體片段 |
CAP_IPC_OWNER | 忽略 IPC 所有權檢查 |
CAP_KILL | 允許對不屬於自己的程序傳送訊號 |
CAP_LEASE | 允許修改檔案鎖的 FL_LEASE 標誌 |
CAP_LINUX_IMMUTABLE | 允許修改檔案的 IMMUTABLE 和 APPEND 屬性標誌 |
CAP_MAC_ADMIN | 允許 MAC 配置或狀態更改 |
CAP_MAC_OVERRIDE | 忽略檔案的 DAC 訪問限制 |
CAP_MKNOD | 允許使用 mknod() 系統呼叫 |
CAP_NET_ADMIN | 允許執行網路管理任務 |
CAP_NET_BIND_SERVICE | 允許繫結到小於 1024 的埠 |
CAP_NET_BROADCAST | 允許網路廣播和多播訪問 |
CAP_NET_RAW | 允許使用原始套接字 |
CAP_SETGID | 允許改變程序的 GID |
CAP_SETFCAP | 允許為檔案設定任意的 capabilities |
CAP_SETPCAP | 參考 capabilities man page |
CAP_SETUID | 允許改變程序的 UID |
CAP_SYS_ADMIN | 允許執行系統管理任務,如載入或解除安裝檔案系統、設定磁碟配額等 |
CAP_SYS_BOOT | 允許重新啟動系統 |
CAP_SYS_CHROOT | 允許使用 chroot() 系統呼叫 |
CAP_SYS_MODULE | 允許插入和刪除核心模組 |
CAP_SYS_NICE | 允許提升優先順序及設定其他程序的優先順序 |
CAP_SYS_PACCT | 允許執行程序的 BSD 式審計 |
CAP_SYS_PTRACE | 允許跟蹤任何程序 |
CAP_SYS_RAWIO | 允許直接訪問 /devport、/dev/mem、/dev/kmem 及原始塊裝置 |
CAP_SYS_RESOURCE | 忽略資源限制 |
CAP_SYS_TIME | 允許改變系統時鐘 |
CAP_SYS_TTY_CONFIG | 允許配置 TTY 裝置 |
CAP_SYSLOG | 允許使用 syslog() 系統呼叫 |
CAP_WAKE_ALARM | 允許觸發一些能喚醒系統的東西(比如 CLOCK_BOOTTIME_ALARM 計時器) |
2. capabilities 的賦予和繼承
Linux capabilities 分為程序 capabilities 和檔案 capabilities。對於程序來說,capabilities 是細分到執行緒的,即每個執行緒可以有自己的capabilities。對於檔案來說,capabilities 儲存在檔案的擴充套件屬性中。
下面分別介紹執行緒(程序)的 capabilities 和檔案的 capabilities。
執行緒的 capabilities
每一個執行緒,具有 5 個 capabilities 集合,每一個集合使用 64
位掩碼來表示,顯示為 16
進位制格式。這 5 個 capabilities 集合分別是:
- Permitted
- Effective
- Inheritable
- Bounding
- Ambient
每個集合中都包含零個或多個 capabilities。這5個集合的具體含義如下:
Permitted
定義了執行緒能夠使用的 capabilities 的上限。它並不使能執行緒的 capabilities,而是作為一個規定。也就是說,執行緒可以通過系統呼叫 capset()
來從 Effective
或 Inheritable
集合中新增或刪除 capability,前提是新增或刪除的 capability 必須包含在 Permitted
集合中(其中 Bounding 集合也會有影響,具體參考下文)。 如果某個執行緒想向 Inheritable
集合中新增或刪除 capability,首先它的 Effective
集合中得包含 CAP_SETPCAP
這個 capabiliy。
Effective
核心檢查執行緒是否可以進行特權操作時,檢查的物件便是 Effective
集合。如之前所說,Permitted
集合定義了上限,執行緒可以刪除 Effective 集合中的某 capability,隨後在需要時,再從 Permitted 集合中恢復該 capability,以此達到臨時禁用 capability 的功能。
Inheritable
當執行exec()
系統呼叫時,能夠被新的可執行檔案繼承的 capabilities,被包含在 Inheritable
集合中。這裡需要說明一下,包含在該集合中的 capabilities 並不會自動繼承給新的可執行檔案,即不會新增到新執行緒的 Effective
集合中,它只會影響新執行緒的 Permitted
集合。
Bounding
Bounding
集合是 Inheritable
集合的超集,如果某個 capability 不在 Bounding
集合中,即使它在 Permitted
集合中,該執行緒也不能將該 capability 新增到它的 Inheritable
集合中。
Bounding 集合的 capabilities 在執行 fork()
系統呼叫時會傳遞給子程序的 Bounding 集合,並且在執行 execve
系統呼叫後保持不變。
- 當執行緒執行時,不能向 Bounding 集合中新增 capabilities。
- 一旦某個 capability 被從 Bounding 集合中刪除,便不能再添加回來。
- 將某個 capability 從 Bounding 集合中刪除後,如果之前
Inherited
集合包含該 capability,將繼續保留。但如果後續從Inheritable
集合中刪除了該 capability,便不能再添加回來。
Ambient
Linux 4.3
核心新增了一個 capabilities 集合叫 Ambient
,用來彌補 Inheritable
的不足。Ambient
具有如下特性:
Permitted
和Inheritable
未設定的 capabilities,Ambient
也不能設定。- 當
Permitted
和Inheritable
關閉某許可權(比如CAP_SYS_BOOT
)後,Ambient
也隨之關閉對應許可權。這樣就確保了降低許可權後子程序也會降低許可權。 - 非特權使用者如果在
Permitted
集合中有一個 capability,那麼可以新增到Ambient
集合中,這樣它的子程序便可以在Ambient
、Permitted
和Effective
集合中獲取這個 capability。現在不知道為什麼也沒關係,後面會通過具體的公式來告訴你。
Ambient
的好處顯而易見,舉個例子,如果你將 CAP_NET_ADMIN
新增到當前程序的 Ambient
集合中,它便可以通過 fork()
和 execve()
呼叫 shell 指令碼來執行網路管理任務,因為 CAP_NET_ADMIN
會自動繼承下去。
檔案的 capabilities
檔案的 capabilities 被儲存在檔案的擴充套件屬性中。如果想修改這些屬性,需要具有 CAP_SETFCAP
的 capability。檔案與執行緒的 capabilities 共同決定了通過 execve()
執行該檔案後的執行緒的 capabilities。
檔案的 capabilities 功能,需要檔案系統的支援。如果檔案系統使用了 nouuid
選項進行掛載,那麼檔案的 capabilities 將會被忽略。
類似於執行緒的 capabilities,檔案的 capabilities 包含了 3 個集合:
- Permitted
- Inheritable
- Effective
這3個集合的具體含義如下:
Permitted
這個集合中包含的 capabilities,在檔案被執行時,會與執行緒的 Bounding 集合計算交集,然後新增到執行緒的 Permitted
集合中。
Inheritable
這個集合與執行緒的 Inheritable
集合的交集,會被新增到執行完 execve()
後的執行緒的 Permitted
集合中。
Effective
這不是一個集合,僅僅是一個標誌位。如果設定開啟,那麼在執行完 execve()
後,執行緒 Permitted
集合中的 capabilities 會自動新增到它的 Effective
集合中。對於一些舊的可執行檔案,由於其不會呼叫 capabilities 相關函式設定自身的 Effective
集合,所以可以將可執行檔案的 Effective bit 開啟,從而可以將 Permitted
集合中的 capabilities 自動新增到 Effective
集合中。
詳情請參考 Linux capabilities 的 man page。
3. 執行 execve() 後 capabilities 的變化
上面介紹了執行緒和檔案的 capabilities,你們可能會覺得有些抽象難懂。下面通過具體的計算公式,來說明執行 execve()
後 capabilities 是如何被確定的。
我們用 P
代表執行 execve()
前執行緒的 capabilities,P'
代表執行 execve()
後執行緒的 capabilities,F
代表可執行檔案的 capabilities。那麼:
P'(ambient) = (file is privileged) ? 0 : P(ambient)
P'(permitted) = (P(inheritable) & F(inheritable)) | (F(permitted) & P(bounding))) | P'(ambient)
P'(effective) = F(effective) ? P'(permitted) : P'(ambient)
P'(inheritable) = P(inheritable) [i.e., unchanged]
P'(bounding) = P(bounding) [i.e., unchanged]
我們一條一條來解釋:
如果使用者是 root 使用者,那麼執行
execve()
後執行緒的Ambient
集合是空集;如果是普通使用者,那麼執行execve()
後執行緒的Ambient
集合將會繼承執行execve()
前執行緒的Ambient
集合。- 執行
execve()
前執行緒的Inheritable
集合與可執行檔案的Inheritable
集合取交集,會被新增到執行execve()
後執行緒的Permitted
集合;可執行檔案的 capability bounding 集合與可執行檔案的Permitted
集合取交集,也會被新增到執行execve()
後執行緒的Permitted
集合;同時執行execve()
後執行緒的Ambient
集合中的 capabilities 會被自動新增到該執行緒的Permitted
集合中。 - 如果可執行檔案開啟了 Effective 標誌位,那麼在執行完
execve()
後,執行緒Permitted
集合中的 capabilities 會自動新增到它的Effective
集合中。 執行
execve()
前執行緒的Inheritable
集合會繼承給執行execve()
後執行緒的Inheritable
集合。
這裡有幾點需要著重強調:
上面的公式是針對系統呼叫
execve()
的,如果是fork()
,那麼子執行緒的 capabilities 資訊完全複製父程序的 capabilities 資訊。可執行檔案的
Inheritable
集合與執行緒的Inheritable
集合並沒有什麼關係,可執行檔案Inheritable
集合中的 capabilities 不會被新增到執行execve()
後執行緒的Inheritable
集合中。如果想讓新執行緒的Inheritable
集合包含某個 capability,只能通過capset()
將該 capability 新增到當前執行緒的Inheritable
集合中(因為 P'(inheritable) = P(inheritable))。如果想讓當前執行緒
Inheritable
集合中的 capabilities 傳遞給新的可執行檔案,該檔案的Inheritable
集合中也必須包含這些 capabilities(因為 P'(permitted) = (P(inheritable) & F(inheritable))|...)。將當前執行緒的 capabilities 傳遞給新的可執行檔案時,僅僅只是傳遞給新執行緒的
Permitted
集合。如果想讓其生效,新執行緒必須通過capset()
將 capabilities 新增到Effective
集合中。或者開啟新的可執行檔案的 Effective 標誌位(因為 P'(effective) = F(effective) ? P'(permitted) : P'(ambient))。在沒有
Ambient
集合之前,如果某個指令碼不能呼叫capset()
,但想讓指令碼中的執行緒都能獲得該指令碼的Permitted
集合中的 capabilities,只能將Permitted
集合中的 capabilities 新增到Inheritable
集合中(P'(permitted) = P(inheritable) & F(inheritable)|...),同時開啟 Effective 標誌位(P'(effective) = F(effective) ? P'(permitted) : P'(ambient))。有 有Ambient
集合之後,事情就變得簡單多了,後續的文章會詳細解釋。如果某個 UID 非零(普通使用者)的執行緒執行了
execve()
,那麼Permitted
和Effective
集合中的 capabilities 都會被清空。從 root 使用者切換到普通使用者,那麼
Permitted
和Effective
集合中的 capabilities 都會被清空,除非設定了 SECBIT_KEEP_CAPS 或者更寬泛的 SECBIT_NO_SETUID_FIXUP。
關於上述計算公式的邏輯流程圖如下所示(不包括 Ambient
集合):
4. 簡單示例
下面我們用一個例子來演示上述公式的計算邏輯,以 ping
檔案為例。如果我們將 CAP_NET_RAW
capability新增到 ping 檔案的 Permitted
集合中(F(Permitted)),它就會新增到執行後的執行緒的 Permitted
集合中(P'(Permitted))。由於 ping 檔案具有 capabilities 意識,即能夠呼叫 capset()
和 capget()
,它在執行時會呼叫 capset()
將 CAP_NET_RAW
capability 新增到執行緒的 Effective
集合中。
換句話說,如果可執行檔案不具有 capabilities 意識,我們就必須要開啟 Effective 標誌位(F(Effective)),這樣就會將該 capability 自動新增到執行緒的 Effective
集合中。具有capabilities 意識的可執行檔案更安全,因為它會限制執行緒使用該 capability 的時間。
我們也可以將 capabilities 新增到檔案的 Inheritable
集合中,檔案的 Inheritable
集合會與當前執行緒的 Inheritable
集合取交集,然後新增到新執行緒的 Permitted
集合中。這樣就可以控制可執行檔案的執行環境。
看起來很有道理,但有一個問題:如果可執行檔案的有效使用者是普通使用者,且沒有 Inheritable
集合,即 F(inheritable) = 0
,那麼 P(inheritable)
將會被忽略(P(inheritable) & F(inheritable))。由於絕大多數可執行檔案都是這種情況,因此 Inheritable
集合的可用性受到了限制。我們無法讓指令碼中的執行緒自動繼承該指令碼檔案中的 capabilities,除非讓指令碼具有 capabilities 意識。
要想改變這種狀況,可以使用 Ambient
集合。Ambient
集合會自動從父執行緒中繼承,同時會自動新增到當前執行緒的 Permitted
集合中。舉個例子,在一個 Bash 環境中(例如某個正在執行的指令碼),該環境所在的執行緒的 Ambient
集合中包含 CAP_NET_RAW
capability,那麼在該環境中執行 ping 檔案可以正常工作,即使該檔案是普通檔案(沒有任何 capabilities,也沒有設定 SUID)。
5. 終極案例
最後拿 docker 舉例,如果你使用普通使用者來啟動官方的 nginx 容器,會出現以下錯誤:
bind() to 0.0.0.0:80 failed (13: Permission denied)
因為 nginx 程序的 Effective
集合中不包含 CAP_NET_BIND_SERVICE
capability,且不具有 capabilities 意識(普通使用者),所以啟動失敗。要想啟動成功,至少需要將該 capability 新增到 nginx 檔案的 Inheritable
集合中,同時開啟 Effective 標誌位,並且在 Kubernetes Pod 的部署清單中的 securityContext --> capabilities 欄位下面新增 NET_BIND_SERVICE
(這個 capability 會被新增到 nginx 程序的 Bounding
集合中),最後還要將 capability 新增到 nginx 檔案的 Permitted
集合中。如此一來就大功告成了,參考公式:P'(permitted) = ...|(F(permitted) & P(bounding)))|...
和 P'(effective) = F(effective) ? P'(permitted) : P'(ambient)
。
如果容器開啟了 securityContext/allowPrivilegeEscalation
,上述設定仍然可以生效。如果 nginx 檔案具有 capabilities 意識,那麼只需要將 CAP_NET_BIND_SERVICE
capability 新增到它的 Inheritable
集合中就可以正常工作了。
當然了,除了上述使用檔案擴充套件屬性的方法外,還可以使用 Ambient
集合來讓非 root 容器程序正常工作,但 Kubernetes 目前還不支援這個屬性,具體參考 Kubernetes 專案的 issue。
雖然 Kubernetes 官方不支援,但我們可以自己來實現,具體實現方式可以關注我後續的文章。
6. 參考資料
- Linux Capabilities: Why They Exist and How They Work
- Understanding Capabilities in Linux
- Linux Capabilities in a nutshell
- Linux的capabilities機制
微信公眾號
掃一掃下面的二維碼關注微信公眾號,在公眾號中回覆◉加群◉即可加入我們的雲原生交流群,和孫巨集亮、張館長、陽明等大佬一起探討雲原生技術
相關推薦
Linux Capabilities 入門教程:概念篇
原文連結:Linux Capabilities 入門教程:概念篇 Linux 是一種安全的作業系統,它把所有的系統許可權都賦予了一個單一的 root 使用者,只給普通使用者保留有限的許可權。root 使用者擁有超級管理員許可權,可以安裝軟體、允許某些服務、管理使用者等。 作為普通使用者,如果想執行某些只有
Linux Capabilities 入門教程:基礎實戰篇
該系列文章總共分為三篇: Linux Capabilities 入門教程:概念篇 Linux Capabilities 入門教程:基礎實戰篇 待續... 上篇文章介紹了 Linux capabilities 的誕生背景和基本原理,本文將會通過具體的示例來展示如何檢視和設定檔案的 capabilities。
Linux Capabilities 入門教程:進階實戰篇
> 原文連結:[https://fuckcloudnative.io/posts/linux-capabilities-in-practice-2/](https://fuckcloudnative.io/posts/linux-capabilities-in-practice-2/) 該系列文章總共分為三
Systemd入門教程:命令篇(轉)
apache 完整 start -o 一是 analyze sudo one iso 作者: 阮一峰 日期: 2016年3月 7日 Systemd 是 Linux 系統工具,用來啟動守護進程,已成為大多數發行版的標準配置。 本文介紹它的基本用法,分
Systemd入門教程:實戰篇(轉)
現在 重啟 penssh span 日誌 才會 查看 筆記本 dep 作者: 阮一峰 日期: 2016年3月 8日 上一篇文章,我介紹了 Systemd 的主要命令,今天介紹如何使用它完成一些基本的任務。 一、開機啟動 對於那些支持 Systemd 的軟
CentOS_7 Systemd 入門教程:實戰篇
一、開機啟動 對於那些支援 Systemd 的軟體,安裝的時候,會自動在/usr/lib/systemd/system目錄新增一個配置檔案。 如果你想讓該軟體開機啟動,就執行下面的命令(以httpd.service為例)。 $ sudo systemctl enable
Systemd 入門教程:命令篇 systemctl
一、系統管理 Systemd 並不是一個命令,而是一組命令,涉及到系統管理的方方面面。 1.1 systemctl systemctl是 Systemd 的主命令,用於管理系統。 # 重啟系統 $ sudo systemctl reboot # 關
Linux Cgroup 入門教程:cpuset
這是 Cgroup 系列的第四篇,往期回顧: + [Linux Cgroup 入門教程:基本概念](https://fuckcloudnative.io/posts/understanding-cgroups-part-1-basics/) + [Linux Cgroup 入門教程:CPU](https:/
Linux入門教程:檔案許可權、使用者、使用者組
單個檔名或目錄名長度不超過255字元;檔案或目錄的絕對路徑長度不超過4096字元。 一、檔案所有者與使用者組 一個檔案有很多屬性,包括檔案型別、檔案許可權、檔案隱藏許可權、檔案所有者、使用者組、檔案大小、建立日期、修改日期、訪問日期等。 1.檔案型別 (1)d:目錄;find / -type d 查詢;
Flex 布局教程:語法篇
https stat token flow tutorial ble 布局 fault contain 作者: 阮一峰 日期: 2015年7月10日 網頁布局(layout)是 CSS 的一個重點應用。 布局的傳統解決方案,基於盒狀模型,依賴 display 屬性
Flex 布局教程:語法篇 作者: 阮一峰
num 完全 tutorials eight 項目 default size webkit http 網頁布局(layout)是 CSS 的一個重點應用。 布局的傳統解決方案,基於盒狀模型,依賴 display 屬性 + position屬性 + float屬性。它對於那
Linux快速入門教程-進程管理ipcs命令學習
Linux Linux入門 Linux運維 Linux命令 使用Linux系統必備的技能之一就是Linux進程管理,系統運行的過程正是無數進程在運行的過程。這些進程的運行需要占用系統的內存等資源,做好系統進程的管理,對於我們合理分配、使用系統資源有非常大的意義。今天我們來看進程管理命令中的ip
Ehcache入門經典:第二篇ehcache.xml的參數
new evict 正在 關閉 讀數 memory intervals 忽略 mes 繼續第一篇 diskStorepath:指定在硬盤上存儲對象的路徑path屬性可以配置的目錄有: user.home(用戶的家目錄) user.dir(用戶當前的工作目錄)
ubuntu快速入門教程:初次見面
切換 優化 第三方軟件 技術分享 計算 shu 做的 基本 移動設備 1 什麽是ubuntu? Ubuntu(友幫拓、優般圖、烏班圖)是一個以桌面應用為主的開源GNU/Linux操作系統,Ubuntu 是基於Debian GNU/Linux,支持x86、amd64(即x6
HTML5入門教程 :Cookie會話跟蹤技術~
會話跟蹤 嵌入 網絡 影響 自動 img 更改 txt文件 發送 1. Cookie會話跟蹤技術介紹 會話跟蹤是Web程序中常用的技術,用來跟蹤用戶的整個會話。常用的會話跟蹤技術是Cookie與Session。Cookie通過在客戶端記錄信息確定用戶身份,可以在客戶端保存臨
Flex 布局教程:語法篇(摘抄,學習中)
有關 之前 表示 技術 play under line -c 內容 網頁布局(layout)是CSS的一個重點應用。 布局的傳統解決方案,基於盒狀模型,依賴 display屬性 + position屬性 + float屬性。它對於那些特殊布局非常不方便,比如,垂直居中就不
HTML5前端入門教程:簡析正則表達式
分開 mail 出現 字符串匹配 很多 字符串操作 一個 來看 條件 很多人對正則表達式的印象都是用來做表單驗證的,這其實是不大準確的。正則表達式目前在很多軟件中都得到了廣泛的應用,包括Linux,Unix等操作系統,VB,Java,PHP等開發環境中,以及很多應用軟件都能
HTML5前端入門教程:Ajax 異步請求技術
結合 adding 情況下 編寫 安全 ont format loaded ruby AJAX的全稱是Asynchronous JavaScript and XML(異步的 JavaScript 和 XML)。 ?ajax不是新的編程語言,而是一種使用現有標準的新方法
Linux pwn入門教程——格式化字符串漏洞
發現 都是 檢查 循環 我們 編譯 bbs 阻止 可見 本文作者:Tangerine@SAINTSEC 原文來自:https://bbs.ichunqiu.com/thread-42943-1-1.html 0×00 printf函數中的漏洞printf函數族是一個在C編程
hadoop快速入門教程:hadoop安裝包下載與監控參數說明
分布式 height tex region 集群 RoCE 發行版 store serve 前階段用了差不多兩周的時間把DKhadoop的運行環境搭建以及安裝的各個操作都介紹了一遍。關於DKhadoop安裝包下載也只是順帶說了一下,但好像大快搜索的服務器在更新,新的下載頁面