HECTF2020题解之ezphp

9 篇文章 0 订阅

HECTF2020题解之ezphp

一 题目的来源

这道题的前身来源于NCTF2019的一道题名为“easyphp”,在HECTF中并没有完全复刻上述的题目,只是对其中的两个考点进行了参考,这篇文章也将对这其中的两个考点进行讲述。本文在在行文过程中同样参考了NCTF2019的官方wp,链接会放在文章最后。

二 题目描述

<?php 
error_reporting(0);
highlight_file(__file__);
include('flag.php'); 
$string_1 = $_GET['str1']; 
$string_2 = $_GET['str2']; 

if($_GET['param1']!==$_GET['param2']&&md5($_GET['param1'])===md5($_GET['param2'])){

        if(is_numeric($string_1)){ 
            $md5_1 = md5($string_1); 
            $md5_2 = md5($string_2); 
            if($md5_1 != $md5_2){ 
                $a = strtr($md5_1, 'cxhp', '0123'); 
                $b = strtr($md5_2, 'cxhp', '0123'); 
                if($a == $b){
                    echo $flag;
                }
                else {
                    die('you are close');
                }
            }  
            else {
               die("md5 is wrong"); 
            }
            } 
        else {
        die('str1 not number'); 
        }
    }
else {
    die('you are wrong!');
}
?> 

考点一,md5校验漏洞

PHP在进行哈希值的相关比较的时候,如果字符串以0e作为开头的话,PHP会忽略后面的字符,并将其解释成0,所以两个不同的字符串经过md5加密后所得到的字符串是0e开头的话,PHP会将其判断成相等字符串。
还有一种情况就是经典的数组方案了,如果往md5()中传入数组参数的话,函数会返回null,所以当两个传入字符均是数组的话,那么就会出现null=null的情况,两者被判定为相等。
下面是一些经过md5加密之后开头是0e的例子:

	QNKCDZO
    240610708//经典永流传
    s878926199a
    s155964671a
    s214587387a
    s214587387a

考点二,php弱类型

截取题中的两行来看:

if($md5_1 != $md5_2){ 
                $a = strtr($md5_1, 'cxhp', '0123'); 
                $b = strtr($md5_2, 'cxhp', '0123'); 

显然,题目想让我们将两个字符串md5加密过后,使其不相等,等到将两个字符串中的“c”,“x”,“h”,“p”相应的替换成“0”,“1”,“2”,“3”之后再使其相等。从常识中我们知道md5加密过后的字符串是不会存在“x”,“h”,“p”这三种字符的。
所以,目标就转向了“c”与“0”的置换当中。从上面的分析过程我们我们可以得出一个结论,我们要找的一个关键的字符串它的开头应该是ce这样的话,程序的执行才能进入if中,至于另外一个字符串,咱们只需挑选一个开头是0e的字符串即可。

最后,求字符串脚本

import hashlib

def makemd5(s):
    return hashlib.md5(s.encode('utf-8')).hexdigest()

s = '0123456789c'

for i in range(10000000000):
    md5 = makemd5(str(i))
    if md5[0:2] == 'ce':
        if all(map(lambda x: x in s, md5[2:])):
            print(str(i)+"   "+md5)
            break

运行脚本过后,我们会得到一个字符串“9427417”其加密过后是“ce156443c7c7c4c63366466c25317636”满足条件。随即构造payload:?param1=s878926199a&param2=s155964671a&str1=9427417&str2=240610708
[1]: http://meta.math.stackexchange.com/questions/5020/mathjax-basic-tutorial-and-quick-reference
[2]: https://mermaidjs.github.io/
[3]: https://mermaidjs.github.io/
[4]: http://adrai.github.io/flowchart.js/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值