Baby PHP - hacklu CTF 2018

本文围绕一道代码审计题目展开,先给出源码并逐行审计。介绍了以GET方式传变量的要求,以及利用php://input伪协议、data协议完成验证的方法。还分析了intval函数、字符串长度限制、正则匹配结尾符号等坑点,给出绕过办法,最后通过变量覆盖读取flag。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

<?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。
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值