介绍:
自己懒得搭建靶场了,靶场地址是 GitHub - CHYbeta/Code-Audit-Challenges: Code-Audit-Challenges为了方便在公网练习,可以随地访问,本文所有的题目均来源于网站HSCSEC-Code Audit
1、习题一
题目内容如下:
1wMDEyY2U2YTY0M2NgMTEyZDQyMjAzNWczYjZgMWI4NTt3YWxmY=
<?php error_reporting(0);
require __DIR__.'/lib.php'; echo base64_encode(hex2bin(strrev(bin2hex($flag)))), '<hr>'; highlight_file(__FILE__);
查看题目,发现是对$flag 参数进行了一系列加密,得到字符1wMDEyY2U2YTY0M2NgMTEyZDQyMjAzNWczYjZgMWI4NTt3YWxmY= 因此,如果要还原成flag 就必须对加密的字符串,一一解密。即 base64_decode() -> bin2hex()->strrev()->hex2bin()
因此,撰写代码如下:
<?php
$s = "1wMDEyY2U2YTY0M2NgMTEyZDQyMjAzNWczYjZgMWI4NTt3YWxmY=";
echo(hex2bin(strrev(bin2hex(base64_decode($s)))))
?>
放在php 代码运行平台运行得到flag
在线运行PHP
flag{582a0f2c7e302244b110cc461f5cb100}
2、习题二
题目内容如下
<?php
error_reporting(0);
require __DIR__.'/lib.php';
if(isset($_GET['time'])){ if(!is_numeric($_GET['time'])){ echo 'The time must be number.'; }else if($_GET['time'] < 60 * 60 * 24 * 30 * 2){ echo 'This time is too short.'; }else if($_GET['time'] > 60 * 60 * 24 * 30 * 3){ echo 'This time is too long.'; }else{ sleep((int)$_GET['time']); echo $flag; } echo '<hr>';
}
highlight_file(__FILE__);
分析代码后,发现,只有当传入参数time的值必须为数字,而且值的大小必须介于在60 * 60 * 24 * 30 * 2=5,184,000 和60 * 60 * 24 * 30 * 3=7,776,000之间,才能拿到flag,比如说6000000 但是这样就直接sleep 的三个月,恰好科学计数法 6000000= 6e6满足数据要求,而且只需要sleep 6秒即可,因此构造payload 如下
?time=6e6
得到flag{yhngdasdaaljlj}
3、习题三
题目内容如下:
但是只是显示了这一个英文字母,查看一下源码,发现有一个index.txt
访问一下index.txt,发现了代码
<?php
error_reporting(0);
echo "<!--index.txt-->";
require __DIR__.'/lib.php';
if(!$_GET['id'])
{ header('Location: index.php?id=1'); exit();
}
$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.'))
{ echo 'Hahahahahaha'; return ;
}
$data = @file_get_contents($a,'r');
if($data=="1112 is a nice lab!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{ echo $flag;
}
else
{ print "work harder!harder!harder!";
}
?>
分析代码,首先初始化会跳转 index.php?id=1 然后 得到三个参数 id,a, b, 如果a的值包含有. 就输出Hahahahahaha,然后不含. 就得到内容定义参数为data 。
如果data的值是1112 is a nice lab! 并且id==0 b 的值的长度大于5 ,eregi("111".substr($b,0,1),"1114") 用111拼接完b的值的第一个字母后的值在1114中 ,要么b的首个字符为4要么为空,并且b的第一个字母的值不能是4 那么只能为空,然后输出flag
解法
1、对于id 的值来说,是一个数字,有$id==0,这里利用弱类型比较可以传字符也可以用0e去绕过,为了使id==0可以给id一个字符 比如 id=abc
2、对于b来说,如果b的第一个字符拼接完111后满足正则 1114 ,并且b的首个字符不能为4 ,因此可以用%00截断,因为 %00的长度为 1 所以b=%0012345 满足长度大于5
eregi 函数在较旧版本的PHP中用于执行不区分大小写的正则表达式匹配。
3、对于a来说,可以使用$a可以使用伪协议php://input也可以用data类型url$a=php://input
#然后POST一个内容为1112 is a nice lab!的body ,也可以使用 $a=data:,1112 is a nice lab! #data类型url
$a 使用data类型url 构造如下
?id=abc&a=data:,1112 is a nice lab!&b=%0012345
flag{dsayandahckasda}
使用伪协议php://input
?id=abc&a=php:%2f%2finput&b=%250012345
flag{dsayandahckasda}