freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

PHP代码审计学习-常见漏洞函数-弱类型篇
luckinsven 2021-03-28 21:51:19 243770

前言

PHP是一种创建动态交互性站点的强有力的服务器端脚本语言,免费并且使用非常广泛。PHP环境目前的搭建也相当简单,可使用PhpStudy等工具一步到位。

本文主要除了除理论上去解释PHP常见函数的漏洞利用,更结合CTF题目,实战解释,有兴趣的朋友可以将源码Copy后复现,相信会收益更多。

众所周知,PHP一门弱类型的脚本语言,本文介绍的漏洞,均是是从类型转换缺陷、类型转换不严入手。

下一篇会从变量覆盖出发。

1.is_numeric类型缺陷转换

PHP提供了is_numeric函数,用来判断变量是否为数字。PHP弱类型语言的一个特性,当一个整型和一个其他类型行比较的时候,会先把其他类型intval数字化再比。

intval() 函数用于获取变量的整数值。

<?php
    error_reporting(0);  
    // 关闭错误报告
    $flag = 'flag{is_numeric_pass}';
    // 新建一个变量,值为:flag{is_numeric_pass}
    $a = $_GET['a'];
    // 新建一个变量a,以Get的形式赋值
    is_numeric($a)?die("Sorry...."):NULL;
    //通过 is_numeric函数,判断id是否为数字,如果为数字,则结束,输出sorry    
    if($a>2019){
    // 若a大于2019输出flag
        echo $flag;
    } 
?>
//解题思路,要求输入一个大于2019的数字才能获取flag,但是如果变量为数字就结束程序,陷入矛盾,
//利用PHP弱类型比较的特点,一个其他类型与整型比较时,会将其他类型自动取整型再比较,利用此特性绕过,即赋值a为10000abc,绕过

构造Payload:http://192.168.200.148/php_lab/lab1.php?a=10000a

image.png

2.Hash比较缺陷

<?php
    $md51 = md5('240610708');
    $a = @$_GET['a'];
    $md52 = @md5($a);
    if(isset($a)){
        if ($a != '240610708' && $md51 == $md52) {
            echo "flag{md5_pass}";
        } else {
            echo "false";
        }
    }
    
?>

该函数要求我们输入一个a,这个a不能是240610708,但是要求其MD5值是一致,同样陷入矛盾困局。

此时还是利用PHP弱类型缺陷

首先240610708的MD5值为:0e462097431906509019562988736854

这里是0e开头的,在进行等于比较的时候,PHP把它当作科学计数法,0的无论多少次方都是零。 所以这里利用弱类型的比较的缺陷来进行解题:如果md5的值是以0e开头的,那么就与其他的0e开头的Md5值是相等的。我们找到:s1885207154a,其MD5为:0e509367213418206700842008763514

构造Payload:http://192.168.200.148/php_lab/lab2.php?a=s1885207154a

image.png

3.switch判断绕过

本章节会涉及一点正则相关的知识,如果零基础的同学,可以通过下方链接学习。

https://www.runoob.com/regexp/regexp-syntax.html正则表达式学习

<?php
if(isset($_GET['a'])){
    $pattern = '/^(?=.*[0-9].*)(?=.*[a-zA-Z].*).{4,}$/';
    //^为开头,.*为匹配,要求字符串开头有数字,有字母,匹配不少于4次
    $a = $_GET['a'];
    //给a赋值
    if(preg_match($pattern,$a)===0){
        //如果不匹配正则表达式,输出格式错误
        echo "format error";
    }else{
        switch($a){
            //当a值等于4的时候,可以得到flag
            //解决思路,还是弱类型转换绕过,?a=4abc
            case 1:
                echo "error..";
                break;
            case 2:
                echo "error..";
                break;
            case 3:
                echo "error..";
                break;
            case 4:
                echo "flag{switch_pass}";
                break;
        }
    }
}
?>

我们将a赋值为 4abc,符合匹配要求,最后在判断的时候,因为4abc不是整型,会自动进行转换取整,故数值为4,得到flag。

构造Payload:http://192.168.200.148/php_lab/lab3.php?a=4abc

image.png

4.strcmp()字符串比较函数绕过

<?php
 error_reporting(0);
 //关闭错误提示
if (isset($_GET['a'])) {  
    //判断是否以get形式为a赋值
    if (strcmp($_GET['a'], $flag) == 0) 
        //比较a变量和flag的字符,再将结果与0【false】比较
        echo 'flag{strcmp_pass}'; 
    else  
        print 'you are failure';  
}
?>

int strcmp ( string $str1 , string $str2 ),函数介绍:如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果两者相等,返回 0。

但strcmp只会处理字符串参数,如果给个数组的话呢,就会返回NULL。而NULL==0是 bool(true),满足if判断的逻辑,就得到flag了

构造payload:http://192.168.200.148/php_lab/lab4.php?a[]=7

image.png

5.sha1()安全哈希散列函数比较绕过

<?php
error_reporting(0);
//关闭错误报告
if (isset($_GET['a']) and isset($_GET['b'])) 
    //判断a变量和b是否为空
{
    if ($_GET['a'] == $_GET['b'])
        //判断a和b是否相等
        echo '<p>a and b  can not be same!</p>';
    else if (sha1($_GET['a']) === sha1($_GET['b']))
        //判断a和b的sha1值是否相等,如果相等则输出flag
      echo 'flag{sha1_pass}';
    else
        echo '<p>You are failure.</p>';
}
else
    echo '<p>You are failure!</p>';
//题目要求a和b的sha1值相等,但是变量值不能相等,此处为突破点
?>

sha1()函数默认的传入参数类型是字符串型,那要是给它传入数组则会出现错误,使sha1()函数返回false,两个false也就符合条件输出flag了。

构造Payload:http://192.168.200.148/php_lab/lab5.php?a[]=6&b[]=7

image.png

作为一名渗透初学者,理解有限,如果您看到这里,非常感谢您的支持,欢迎提出宝贵意见,多多交流。

# 渗透测试 # 绕过 # php代码审计 # CTF知识 # 类型缺陷
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 luckinsven 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
渗透测试方法论
luckinsven LV.1
这家伙太懒了,还未填写个人描述!
  • 1 文章数
  • 1 关注者
文章目录