前言
专栏名为【代码小审计】,面向CTFer和代码审计新手。基于代码小片段进行讲解,包含但不限于php等语言。此次题目来自:Code-Audit-Challenges: php/challenge-2
Challenge<?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 '
';
}
?>
Solution>>> 60 * 60 * 24 * 30 * 2
5184000
>>> 60 * 60 * 24 * 30 * 3
7776000
>>> hex(5184000)
'0x4f1a00'
>>> hex(7776000)
'0x76a700'
要是传入普通的数字比如 5184001 ,固然能过掉前两个if判断,但sleep函数就要让你等到天荒地老了。
我们通过GET或者POST传入的参数,是作为字符串保存的。is_numeric()支持普通数字型字符串、科学记数法型字符串、部分支持十六进制0x型字符串。而强制类型转换int,不能正确转换的类型有十六进制型字符串、科学计数法型字符串(部分)。
测试代码:<?php
show_source(__FILE__);
$temp = $_GET['temp'];
echo (int)$temp;
?>
当传入参数为 ?temp=0x76a701 之类的十六进制型字符串,当传入参数如?temp=0e11之类的科学计数法型字符串,会输出0。当传入参数如?temp=4e11之类的科学计数法型字符串,会输出4
所以最后的payload如下:payload:?time=0x76a701
payload2:?time=0e11
小结
此题难度较小,主要考察了以下几个知识点:php弱类型
is_numeric()的特性
进制转换
若有其他想法/做法,欢迎各位留言评论,或在github开issue一起讨论。