php代码审计——初次尝试

来源:互联网 发布:js 修改class 属性值 编辑:程序博客网 时间:2024/06/15 22:23

首次尝试PHP代码审计,不够完善,敬请指教。

原题如下:

<?php
show_source(__FILE__);
$flag = "xxxx";
if(isset($_GET['time'])){ 
        if(!is_numeric($_GET['time'])){ 
                echo 'The time must be number.'; 
        }else if($_GET['time'] < 60 * 60 * 24 * 30 * 2){ 
                        echo 'This time is too short.'; 
        }else if($_GET['time'] > 60 * 60 * 24 * 30 * 3){ 
                        echo 'This time is too long.'; 
        }else{ 
                sleep((int)$_GET['time']); 
                echo $flag; 
        } 
                echo '<hr>'; 
}
?>

解题:

1、相关知识:PHP弱类型、is_numeric()函数等。

2、分析:题中先使用is_numeric()判断time是数字还是数字字符串,然后判断是否在60*60*24*30*2~60*60*24*30*3之间,最后对time参数有一个sleep()延时函数,函数用了一个int类型的强制类型转换。要绕过的是时间大小的限制,因此通过计算得到限制的时间范围最小是5184000秒,转换成16进制就是0x4F1A00,于是传参time=0x4F1A00,通过了四次判断,GET获取值类型为字符串,最后sleep函数中进行类型转换的时候0x4F1A00,遇到字母就停止转换,变成了0,于是不能继续sleep,最后输出结果。

3、问题:is_numeric()中强制类型转换成int,不能正确转换的类型有十六进制型和部分科学计数法型字符串。

4、测试:

<?php
show_source(__FILE__);
$temp = $_POST['temp'];
echo (int)$temp;
?>

当传入参数为 0x6F1A00之类的十六进制型字符串和0e10之类的科学计数法型字符串时,会输出0;当传入参数6e10之类的科学计数法型字符串时,会输出6。

5、Payload:
(1)?time=0x6F1A00--十六进制

(2)?time=0e10--科学计数法

(3)?time=6e10--科学计数法