CTF Web安全

Web hash长度扩展攻击

Posted on 2020-01-02,5 min read

md5算法

1:
将消息分组。长度为512位(512/8=64字节)
2:
加密字符串的长度%512=448,不够则对分组进行字符填充
当需要进行消息摘要的明文%512!=448,那么就需要补位,补一个80,然后无限补0.直到字符串%512=448
PS:补位是必须进行的操作。长度刚好位448.也得补位。补64字节
3:
存储原消息长度

总结下格式:明文+80+00补全=56字节+8字节的消息长度
第一个方框中。是我们的明文test(16进制),占了4字节
中间的是补位:在后面加上一个80.然后0000一直补位到56字节
最后一个方框。是我们的消息长度。test长度为4字节。4*8=32位,16进制为0x20,小端显示
0x00000020=0x20000000
0x12345678=0x78563412

4.
计算消息摘要,当准备工作做好后。就开始加密运算。
这步就不说了。密码学tnl
hash长度扩展攻击

<?php
$SECRET="xxxxx";        //len($SECERT)=6;
$auth = "test";
if (isset($_COOKIE["auth"])) {
    $hsh = $_COOKIE["hsh"];
    if ($hsh !== md5($SECRET . $_COOKIE["auth"])) {
        die("F4ck_U!");
    }
} else {
    setcookie("auth", $auth);
    setcookie("hsh", md5($SECRET . $auth));
    die("F4ck_U!");
}
die("this is flag{fdajkfjdkjakfjk`}");
?>
这题的要求是md5(SECERT.SECERT._COOKIES['auth'])==$_COOKIES['hsh']
也就是说。我们传入hsh要和(auth和secert拼接然后MD5加密)的值一样
auth和hsh都是我们可控的。但是secert不知道。只知道长度为6

进入web

找到test对应的hash:5a2e54ee57e5b7273b9a8fed78c1ebd8
这时候,使用kali下的一个工具hashpump。

Input Signature: 5a2e54ee57e5b7273b9a8fed78c1ebd8
#已知的hash
Input Data: test
#已知的用户名
Input Key Length: 6
#密钥长度
Input Data to Add: 123
#要在密文后添加的字符串,这题随便添加。没要求
e2e5d57bd08006da01fcf36b1fa69ea2
#生成的md5字符串。
test\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x00\x00\x00\x00\x00\x00\x00123
#生成的hash字符


hsh=e2e5d57bd08006da01fcf36b1fa69ea2
auth=test%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00P%00%00%00%00%00%00%00123
提交得到flag

WhaleCTF: 哈希入侵
web主页。。条件都很清楚了。
密钥长度=4
role(用户名)=admin
hash=c7813629f22b6a7d28a08041db3e80a9
扩展字符串=joychou

要注意的是。生成的字符串。要将\x替换为%

jarvisoj:flag在管理员手里
hsh和role。然后要成为管理员。估计就是admin

扫描了下。有index.php~

        <?php 
            $auth = false;
            $role = "guest";
            $salt = 
            if (isset($_COOKIE["role"])) {
                $role = unserialize($_COOKIE["role"]);
                $hsh = $_COOKIE["hsh"];
                if ($role==="admin" && $hsh === md5($salt.strrev($_COOKIE["role"]))) {
                    $auth = true;
                } else {
                    $auth = false;
                }
            } else {
                $s = serialize($role);
                setcookie('role',$s);
                $hsh = md5($salt.strrev($s));
                setcookie('hsh',$hsh);
            }
            if ($auth) {
                echo "<h3>Welcome Admin. Your flag is 
            } else {
                echo "<h3>Only Admin can see the flag!!</h3>";
            }
        ?>

爆破脚本:

import hashpumpy
import requests
import urllib
for i in range(0,13):
    m=hashpumpy.hashpump('3a4727d57463f122833d9e732f94e4e0',';\"tseug\":5:s',';\"nimda\":5:s',i)
    hsh=m[0]
    role=urllib.quote(urllib.unquote(m[1])[::-1])
    cookie='role='+role+'; hsh='+hsh
    headers={
    'cookie': cookie,
    }
    print(headers)
    url='http://web.jarvisoj.com:32778/'
    r=requests.get(url=url,headers=headers)
    print(r.text)

首先我们不知道密钥长度。只能爆破。
由于源程序是MD5=($salt+反转字符串)
那么我们也要传入反转的字符串。来解密。模拟程序输入
然后用python的hashpumpy模块来爆破。
第一个参数是MD5。第二个参数是反转的用户名。
第三个参数是要添加的数据。第四个参数是密钥长度。
然后。需要将\x00URL编码成%00,然后再反转。这次是为了模拟程序输出
总结一句话。源程序加密的时候反转字符串。我们解密的时候也要反转字符串(放入hashpump的参数)
程序输出的时候反转字符串。我们输入的时候也要反转字符串(得到的参数反转)

下一篇: Mysql REGEXP正则注入→