Can you guess it?
猜字符串游戏,了解一下几个函数的机制:
hash_equals ( string $known_string , string $user_string ) : bool
比较两个字符串,无论它们是否相等,本函数的时间消耗是恒定的。本函数可以用在需要防止时序攻击的字符串比较场景中, 例如,可以用在比较 crypt() 密码哈希值的场景。
random_bytes(int $length)
生成适合于加密使用的任意长度的加密随机字节字符串,例如在生成salt、密钥或初始化向量时,一般配合bin2hex()函数使用。
bin2hex()
把ASCII字符串转换为十六进制值
我们可以看一下hash_equals()内部实现机制
<?php
if(!function_exists('hash_equals')) {
function hash_equals($a, $b) {
if(!is_string($a) || !is_string($b)) {
return false;
}
$len = strlen($a);
if($len !== strlen($b)) {
return false;
}
$status = 0;
for($i = 0; $i<$len; $i++) {
$status |= ord($a[$i]) ^ ord($b[$i]);
}
return $status === 0;
}
}
基本上可以说整个流程是很安全的,所以突破口又回到了前面的文件包含。
<?php
include 'config.php'; // FLAG is defined in config.php
if (preg_match('/config\.php\/*$/i', $_SERVER['PHP_SELF'])) {
exit("I don't know what you are thinking, but I won't let you read it :)");
}
if (isset($_GET['source'])) {
highlight_file(basename($_SERVER['PHP_SELF']));
exit();
}
记录一下三个$_SERVER的区别:
网址:https://www.shawroot.cc/php/index.php/test/foo?username=root$_SERVER[‘PHP_SELF’] 得到:/php/index.php/test/foo $_SERVER[‘SCRIPT_NAME’] 得到:/php/index.php $_SERVER[‘REQUEST_URI’] 得到:/php/index.php/test/foo?username=root
漏洞点:
$_SERVER['PHP_SELF']
提交index.php/config.php时,经过basename过滤后只剩下config.php,需要绕过的只有正则,basename只能转换ASCII码内的字符,通过超过ASCII码范围的字符进行绕过。/index.php/config.php/%dd?source
Last modified 8mo ago