新手村Day 1

at 发布于 4 天前 18 次阅读


php弱类型

== 在进行比较的时候,会先判断两种字符串的类型是否相等,再比较

=== 在进行比较的时候,会先将字符串类型转化成相同,再比较

哈希(Md5)绕过

登录验证V1

$a != $b
Md5 ($a) == md5 ($b)

这是一道登录验证的题目,观察可以发现他要求我们输入字符串a与字符串b,并且要求,字符串a与b的Md5值弱相等,可以联想到0e开头的字符串进行==比较时会被解析为科学计数法,也就是说0e1234566 == 0e121

登录验证V2

$a != $b
Md5 ($a) === md5 ($b)

V2版本将弱相等改为了强相等,可以联想到arry与awww这样数组(在php中用?a[]=1&b[]=2,[]表示后面的是数组)在进行md5运算时输出均为NULL

登录验证V3

(string)$a != (string)$b
Md5 ($a) === md5 ($b)

这题强制要求输入的字符串不相等,但是最后的md5相等,进行MD5 碰撞,找到两个不同的数据块经过 MD5 算法计算后,产生的 128 位哈希值相同即可

变量覆盖

用传参的值替换原有变量的值

<?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);

//level 1
if (isset($_GET['num'])){
    $num = $_GET['num'];
    if(intval($num) < 2020 && intval($num + 1) > 2021){
        echo "我不经意间看了看我的劳力士,不是想看时间,只是想不经意间,让你知道我过得比你好。</br>";
    }else{
        die("金钱解决不了穷人的本质问题");
    }
}else{
    die("去非洲吧");
}

//level 2
if (isset($_GET['md5'])){
    $md5=$_GET['md5'];
    if ($md5==md5($md5))
        echo "想到这个CTFer拿到flag后,感激涕零,跑去东湖岸,找一家餐厅,把厨师叫出去,自己炒两个拿手小菜,倒一杯敌装白酒,致富有道,别学小黑";
    else
        die("我赶紧喝完我的酒肉朋友,他打了个电话,把他一家安排到了非洲");
}else{
    die("去非洲吧");
}

//get flag
if (isset($_GET['get_flag'])){
    $get_flag = $_GET['get_flag'];
    if(!strstr($get_flag," ")){

看题目要求,num在取整前要求< 2020,num先+1再取整要求> 2021,这显然矛盾

在php5里,intval对于2e4这样的数字处理后结果是2,2e4+1再取intval则是20001满足条件,level2中md5有两层含义,一层是md5变量,一层是取md5变换

因此我只要找到一个a在进行一次md5变换后与原先弱相等即可

首先就想到0e形式的数字0e215962017 -> md5值: 0e291242476940776845150308577824

最后一关直接输入get_flag即可拿到flag

构造请求:?num=2e4&md5=0e215962017&get_flag=1

随机数问题

无需暴破还原mt_rand()种子

def main(_R000, _R227, offset):
    # Both were >> 1, so the leftmost byte is unknown
    _R000 <<= 1
    _R227 <<= 1

    for R000_0 in range(2):
        for R227_0 in range(2):
            R000 = _R000 | R000_0
            R227 = _R227 | R227_0
            S000 = undo_php_mt_rand(R000)
            S227 = undo_php_mt_rand(R227)
            seed = undo_php_mt_reload(S000, S227, offset)
            if seed:
                print(seed)

只要给定间隔226个值的两个mt_rand()输出结果,我们就有可能计算出原始种子,无需暴力破解,因此也能计算出之前或者之后的mt_rand()输出值,成功解密PRNG

此作者没有提供个人介绍。
最后更新于 2025-10-01