web2_故人 三五夜中新月色,二千里外故人心

web:

if(is_numeric($a) and strlen($a)<7 and $a!=0 and $a**2==0){
    $d = ($b==hash("md2", $b)) && ($c==hash("md2",hash("md2", $c)));
    if($d){
             highlight_file('hint.php');
             if(filter_var($url[1],FILTER_VALIDATE_URL)){
                $host=parse_url($url[1]);
                print_r($host); 
                if(preg_match('/ctfshow\.com$/',$host['host'])){
                    print_r(file_get_contents($url[1]));

我们只需要通过这三个if语句即可;

第一个if语句:
if(is_numeric($a) and strlen($a)<7 and $a!=0 and $a**2==0)

有一个判断它是否为数字的函数,这里提供两种绕过方法:

16进制绕过:

is_numeric() 会对「16进制」(0x开头)返回 true 。数值型和字符型都可以。

var\_dump(is\_numeric(0x7e));
var\_dump(is\_numeric('0x7e'));

上面的都会显示true;

科学计数法绕过:

is_numeric() 会对「科学计数法」(0e开头)返回 true 。数值型和字符型都可以。

并且,0e开头的值,强制转换成int类型后,都是1。


但是它的要求是a!=0但是a的平方等于0,直接逻辑错误。正常的数字是不可能满足的。看了一下XiLitter师傅的wp,这里有一个PHP的小知识:

在php语言运算中。小数点后超过161位做平方运算时会被截断,但是超过323位又会失效。
也就是说,小数点位数在这个范围内的,就会舍弃掉小数部分。

也就是当我们的小数点在161位至323位的时候,都会把小数点后面的视为0.

所以这一层的payload为:

?a=1e-200

采用科学计数法的同时,还让他为0的负200次。

第二个if语句:
$d = ($b==hash("md2", $b)) && ($c==hash("md2",hash("md2", $c)))

这里,他提示了md5的碰撞,如果我们直接去碰撞的话,几乎是不可能的

这是他给出了提示,所以我们只需要遍历即可,这里我们书写我们的PHP脚本:

前面要加上0e,所以这一层的payload为:

b=0e652024452&c=0e603448399

$m == hash("md2", $m)

为什么会为真,即 $d 的值为 1,而当直接计算哈希值时,哈希值与原始字符串并不相同

原因在于 PHP 的字符串比较机制和特定哈希值的特性。$m 和 $n 是以 "0e" 开头的字符串,它们看起来像科学记数法的数字表示(例如 "0e652024452" 看起来像是 0 * 10^652024452)。当 PHP 比较这些字符串时,它们被解释为数字 0。这种情况称为“松散比较”,在 PHP 中,字符串被解释为数字时,如果是 "0e..." 开头的字符串,就会被视为零。

因此,$m == hash("md2", $m) 的比较实际上是在比较两个零,这就解释了为什么结果为 1,即真。

第三个if语句:
if(filter_var($url[1],FILTER_VALIDATE_URL)){
                $host=parse_url($url[1]);
                print_r($host); 
                if(preg_match('/ctfshow\.com$/',$host['host']))

这里的漏洞在于filter_var这个函数,我们需要使用ssrf的来绕过。

这段代码的逻辑是在于,我要上传一个参数,这个参数必须满足是url的形式,并且需要他对返回的【host】部分是匹配的

/ctfshow\.com$/,之后才可以读取a的参数。

所以,我们需要绕过filter_var()的函数,payload为:

1://example.com

但是同时需要对他进行正则匹配:

1://ctfshow.com

这里还有一个提示,所以,我们直接使用目录遍历的方法·来读取这个,最终payload:

url=b://ctfshow.com/../../../../../../../../fl0g.txt

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值