Baby PHP - hacklu CTF 2018

一道代码审计的题目,先贴出来源码

<?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 = "2";$a="‮b";//;1=b

if($$a !== $k1){
    die("lel no\n");
}
echo "Good Job ;)";
// TODO
// echo $flag;
?>

逐行审计一下代码
在这里插入图片描述
首先要以GET方式传入变量msg,否则会直接退出当前脚本并显示当前的页面的源码
在这里插入图片描述
file_get_contents是用来将文件的内容读入到一个字符串中的首选方法,当其解析的字符串为php://input伪协议时,会保存我们以POST方式传入的Hello Challenge即可完成验证。
联想到今年校赛使用的data协议,我们也可以将msg赋值为data://text/plain,Hello Challenge,同样也可以完成验证。
在这里插入图片描述
此处需要我们传入的$k1不等于1337但intval($k1)需要等于1337,intval函数起到的作用是返回变量的整数值
在这里插入图片描述
我们可以看到当传入的值为字符串时会截取字母前的数字,我们只要依葫芦画瓢传入k1的值1337e10
在这里插入图片描述
接着传入的$k2的长度需要是42,然后就是题目最坑的一点了我们都知道正则匹配的结尾符号是$,但此题的结尾符号为,就导致了不知道该怎么进行绕过的情况,采用数组绕过的话无法通过字符串长度的限制,原本以为此题要求变量k2从头至尾经过正则匹配都要是数字然后is_numeric判断不为数字,一时想不到解决办法。看到了此题的坑点之后直接使用payload:000000000000000000000000000000000001337%EF%BC%84,最后的%EF%BC%84的url编码。之后我们就可以对变量$cc重新赋值。
在这里插入图片描述

首先是

substr($cc, $bb) === sha1($cc)

先使用substr截取修改过后$cc的前$bb位需要等于$ccsha1值,我们可以传入数组使这两种函数的返回值均为NULL进行绕过。接着我们就可以使用变量覆盖,将k1的值覆盖为2即可读取flag。
在这里插入图片描述

发布了46 篇原创文章 · 获赞 17 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/stepone4ward/article/details/95801022