Iscc 2025_基本功
打开题目
告诉我们关键点是输入正确的“用户代理”身份标识与英雄名称,很容易联想到是不是修改User-Agent。
我们直接在当前页面修改一下试试,发现直接跳转到Process.php页面,并且显示黑客入侵无处不在!!!在这里输入信息是没用的!!!
回到首页面随便输入点东西,发现也是跳转到这个页面。并且通过尝试发现题目给的EBaLeiKeDun,EBaLeiKeDun,ShengLingShiZheLeiKeDun都用不了。又想起关键点是身份标识和英雄名称,这里的身份标识有可能是后面的堡垒卫士、超频战士之类的
那尝试在UA处写上BaoLeiWeiShiLeiKeDunbao(堡垒卫士雷克顿)
但是发现还是没用
再仔细查看题目信息,注意到一个小细节,心想这位是“计算机行业”的专家,给出的英雄里只有高级工程师跟计算机有点关系。
那尝试在UA写入GaoJiGongChengShiFoYeGe
得到一个新的php文件,访问它,发现得到了一段源码
<?php
show_source(__FILE__);
include('E8sP4g7UvT.php');
$a=$_GET['huigui_jibengong.1'];
$b=$_GET['huigui_jibengong.2'];
$c=$_GET['huigui_jibengong.3'];
$jiben = is_numeric($a) and preg_match('/^[a-z0-9]+$/',$b);
if($jiben==1)
{
if(intval($b) == 'jibengong')
{
if(strpos($b, "0")==0)
{
echo '基本功不够扎实啊!';
echo '<br>';
echo '还得再练!';
}
else
{
$$c = $a;
parse_str($b,$huiguiflag);
if($huiguiflag[$jibengong]==md5($c))
{
echo $flag;
}
else{
echo '基本功不够扎实啊!';
echo '<br>';
echo '还得再练!';
}
}
}
else
{
echo '基本功不够扎实啊!';
echo '<br>';
echo '还得再练!';
}
}
else
{
echo '基本功不够扎实啊!';
echo '<br>';
echo '还得再练!';
}
?> 基本功不够扎实啊!
还得再练!
代码审计以后,得知需要满足下面条件才能输出flag
- $jiben==1
- 也就是满足条件is_numeric(a) and preg_match(’/^[a-z0-9]+/’,$b);
- 就是a必须是数字,并且b要以小写字母或数字开头
- intval($b) == ‘jibengong’
$b
经过intval()
转换后必须等于字符串'jibengong'
- strpos($b, “0”)!=0
- 必须确保
$b
的第一个字符不是0
- 必须确保
- 解析
$b
为数组$huiguiflag
, 验证$huiguiflag[$jibengong]
是否等于md5($c)
首先要解决的是在PHP中变量里的.和空格会被解析成_,所以变量就会变成huigui_jibengong_1从而无法传参。
在网上查阅资料得知,在php版本小于8的时候如果参数中出现中括号[
,中括号会被转换成下划线_
,但是会出现转换错误导致接下来如果该参数名中还有非法字符
并不会继续转换成下划线_
,也就是说如果中括号[
出现在前面,那么中括号[
还是会被转换成下划线_
,但是因为出错导致接下来的非法字符并不会被转换成下划线_
。
也就是传入的变量写成huigui[jibengong.1就能被正常解析成huigui_jibengong.1
然后便是构造payload绕过各种判断
huigui[jibengong.1=1就好了因为没有什么条件约束。
但是对于huigui[jibengong.2,首先可以通过开头写一个换行符使正则表达式失效绕过,然后要满足strpos($b, “0”)!=0 这里第一个字符我们直接写了换行符所以不是0直接绕过了,然后要满足intval($b) == ‘jibengong’,因为字符串在与整数条件判断时是0,所以只要b经过intval以后是0就可,但是第一个字符是换行符intval识别到后也会将$b视为0,所以0=0满足条件。
然后$b会被解析成数组$huiguiflag,取其中的$jibengong处索引的值与$c的md5值进行判断。而注意到前面$$c = $a;所以我们让huigui[jibengong.3=jibengong其实就是变成$jibengong = 1。就变成取数组$huiguiflag[1]的值与$c也就是’jibengong’的md5值进行判断是否相等。这里便可以通过传参的时候0=…….&1=………,这样huigui[jibengong.2就会自动变成含有两个元素的数组,然后让1=e559dcee72d03a13110efe9b6355b30d(jibengong的md5值)即可
综上所述huigui[jibengong.2的payload就是
huigui[jibengong.2=%0A0=0%261=e559dcee72d03a13110efe9b6355b30d
%26是&的url编码,%0A是换行符。
首先通过%0A绕过正则表达式,然后,然后第一个字符是%0A,绕过了strpos($b, "0")==0和intval($b) == 'jibengong',然后0=0&1=这是让huigui[jibengong.2变成有两个元素的数组,然后1=e559dcee72d03a13110efe9b6355b30d,这是使得满足$huiguiflag[$jibengong]==md5($c)
从而输出flag
所以最终的payload是
?huigui[jibengong.1=1&huigui[jibengong.2=%0A0=0%261=e559dcee72d03a13110efe9b6355b30d&huigui[jibengong.3=jibengong
说些什么吧!