前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WEB中常见的几类密码学攻击方式

WEB中常见的几类密码学攻击方式

作者头像
ConsT27
发布2022-02-11 15:24:42
1K0
发布2022-02-11 15:24:42
举报
文章被收录于专栏:ConsT27的笔记ConsT27的笔记

参考: https://www.freebuf.com/articles/database/151167.html https://www.jianshu.com/p/7f171477a603

因为是涉及密码学的东西,所以看的我头大,记录一下吧。

Padding oracle attack 与CBC翻转字节攻击

异或(XOR)

何为异或? 异或是一种运算方法,简要概括就是同假异真

代码语言:javascript
复制
true xor true = false; true xor false = true;

在二进制中:
011 xor 110 = 101; 二进制数每位数分别进行xor运算
上面算式的运算步骤是这样的 0 xor 1 = 1;1 xor 1 = 0;1 xor 0=1
然后把运算结果写在一起就是101了

在更高的进制中:
以十进制为例: 65 xor 42 = 107; 原理就是把十进制数字先变为二进制数进行异或,再将异或得到的二进制数结果变为十进制数

在字符中:
对字符进行异或运算其实就是对字符的ascii码进行异或计算,计算得到的结果视作新的一个ascii码再将其转换为字符。

xor还有一个性质,就是 已知 a xor b = c 那么 b xor c =a; a xor c = b.即满足异或运算里只需知道任意两个数就能得到另一个数。

CBC模式

CBC是一种加密模型,采用的是分组链接模式。把明文分为一组一组进行加密

Padding oracle attack详细解析
Padding oracle attack详细解析

上图是CBC加密流程。最开始一个特别分组IV去和第一段密文XOR,得到的结果被密钥加密,加密得到该组的密文,同时这个密文会充当最开始的特别分组IV的作用去参与下一组的加密,以此类推。

CBC的每一个分组的加密结果都可以影响到下一个分组的加密结果, 使原本独立的分组密码加密过程形成迭代 , 这可以强化加密算法的”敏感性”,即实现所谓的”雪崩效应”,在香浓理论中这就是”扰乱原则” 。

CBC只是一种模式,它经常把aes或des作为加密使用的算法。 DES分组长度是八字节而AES分组长度是十六字节 。

接下来是CBC解密

Padding oracle attack详细解析
Padding oracle attack详细解析

顺序依旧是从左到右,第一组密文被KEY解密后与IV xor得到第一组明文,同时第一组密文参与下一组的解密充当IV作用。

PKCS #5

竟然CBC模式涉及到分组,那么就会出现最后一组字节没有被占满的情况。 比如原本一个分组是8字节,我们有15个字节的明文需要被加密,此时最后一个分组就不会被占满(还差一个字节占满),那么这个时候要怎么办呢?

这时候就需要对最后一个分组进行填充,将其填充满。 对于采用des算法加密的内容,填充规则是PKC #5,而AES是 PKC #7. 这两者唯一区别是 PKCS #5填充是八字节分组而PKCS #7是十六字节 ,还记得上面我们说过的 DES分组长度是八字节而AES分组长度是十六字节 吗?就是这个分组字节数影响了填充方式。

那么具体是怎么填充的呢,我们以PKC #5为例

Padding oracle attack详细解析
Padding oracle attack详细解析

当最后一组还剩n个字节未被填充时,就会填充n个 0xn字符上去. 上图是PKCS #5,其实PKCS #7和PKCS #5原理是一样的,不过是分组字节数大了点罢了(0~16)

Padding oracle attack

上面只是铺垫,建议学懂了再来看这个攻击方式。不然会非常头大。

Padding oracle attack 攻击场景举例

首先我们假设一个场景,从而引出这个攻击。

假设我们有一个任意文件包含场景

代码语言:javascript
复制
url?file=/etc/passwd

黑客们看见了就会很轻而易举的去包含想要的文件。管理者发现了这个问题,对file参数采用了CBC加密,即当提交请求时,file参数的值是被加密的,然后服务器用算法解密得到其想包含的文件,然后返回给客户端。

代码语言:javascript
复制
url?file=e28b2e3c972edab8 其中前8位数是IV,后八位数是密文。(这里是我瞎写的密文= =,你只需要理解到这里是一个CBC加密后的密文就行了)

那么如何去实现我们的任意文件包含呢? padding oracle attack 出现了。

攻击原理

假设我们向刚刚那个任意文件包含的提交了一段密文。服务器就会尝试解密,就会出现三种结果。

1.密文不能正常解密,这种原因是在于最后一组的填充字节出现了错误 2.密文能正常解密但解密出来的文件路径不存在 3.密文能正常解密且能成功包含

其中第1种情况和2.3种情况网页返回的内容肯定是不同的。 比如说第一种情况可能就直接返回500了,2.3可能就是302跳转啥啥的,通过这个网页返回的信息,我们就有了可乘之机。

我们先通过一个图感受一下第一组的解密流程

Padding oracle attack详细解析
Padding oracle attack详细解析

好的好的,感受了这个解密流程后,我们来说说攻击的事。 如果我们得到了 Intermediary Value(中间值),并且可以手动修改IV,那么我们岂不是可以构造任意Decrypted Value(明文)了? 所以padding oracle attack 的核心就是去获得中间值。 那么我们怎么去获取呢?

还记得刚刚提到的3种情况吗?我们可以通过修改IV,通过判断网页返回内容来判断中间值,具体做法如下:

我们先把IV全部设置为0x00,然后修改IV的最后一个数,当其与中间值XOR后的值为0x01则此时解密就会成功,若不是0x01解密就会失败,网页会返回不同的内容,以此来判断何时解密成功。然后把解密成功时的IV的最后一位数与0x01进行异或计算,即可得到中间值的最后一位

Padding oracle attack详细解析
Padding oracle attack详细解析

然后我们把IV最后一位数设置为能和中间值最后一位数异或后值为0x02的数,穷举IV倒数第二个数看看哪个数能和中间值倒数第二个数异或运算后值为0x02,然后我们就可得到中间值倒数第二个数,以此类推可以获得第一组的中间值(有点绕) 然后破解到了中间值我们再用最开始的IV(不是我们后面构造的IV)去和中间值异或就得到明文了 当然,你也可以再次构造IV,从而构造解密出来的字符(通过中间值与IV异或)

[NPUCTF2020]web🐕中的Padding oracle Attack

我们以这道题为切入点,详细看看如何实现攻击。 本题就是以下代码,我们要想方设法先拿到$flag

代码语言:javascript
复制
<?php 
error_reporting(0);
include('config.php');   # $key,$flag
define("METHOD", "aes-128-cbc");  //定义加密方式
define("SECRET_KEY", $key);    //定义密钥
define("IV","6666666666666666");    //定义初始向量 16个6
define("BR",'<br>');
if(!isset($_GET['source']))header('location:./index.php?source=1');


#var_dump($GLOBALS);   //听说你想看这个?
function aes_encrypt($iv,$data)
{
    echo "--------encrypt---------".BR;
    echo 'IV:'.$iv.BR;
    return base64_encode(openssl_encrypt($data, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv)).BR;
}
function aes_decrypt($iv,$data)
{
    return openssl_decrypt(base64_decode($data),METHOD,SECRET_KEY,OPENSSL_RAW_DATA,$iv) or die('False'); //只能返回1或false
}
if($_GET['method']=='encrypt')
{
    $iv = IV;
    $data = $flag;    
    echo aes_encrypt($iv,$data);
} else if($_GET['method']=="decrypt")
{
    $iv = @$_POST['iv'];
    $data = @$_POST['data'];
    echo aes_decrypt($iv,$data);
}
echo "我摊牌了,就是懒得写前端".BR;

if($_GET['source']==1)highlight_file(__FILE__);
?>

我们先拿到密文 ly7auKVQCZWum/W/4osuPA== 然后对其进行base64解密,发现其刚好是有16个字节,那么我们可以直接穷举IV得到中间值,然后凭此与初始IV(16个6)进行异或得到明文$flag.

话不多说,爆破中间值的脚本安排上。(借鉴了一个大佬的WP)

代码语言:javascript
复制
import requests
import base64
import time
Intermediary=""
url="http://de1650aa-2b24-40e0-bb51-736ff5d38269.node3.buuoj.cn//index.php?source=1&method=decrypt"
iv=""
hexs=""
IV="6666666666666666"
def xor(a,b):
    return "".join([chr(ord(a[i])^ord(b[i])) for i in range(len(a))])

for step in range(1,17):
    padding=chr(step)*(step-1)
    print("第%s轮"%step)
    for i in range(0,256):
        iv=chr(0)*(16-step)+chr(i)+xor(Intermediary,padding)
        post={
            "iv":iv,
            "data":"ly7auKVQCZWum/W/4osuPA=="
        }
        r=requests.post(url=url,data=post,proxies={"http":"http://127.0.0.1:8080"})
        time.sleep(0.1)
        print(r.text+"第%s轮i=%s "%(step,i))
        if "False" !=  r.text:
            Intermediary=xor(chr(i),chr(step))+Intermediary
            print(Intermediary)
            break
for k in range(len(Intermediary)):
    hexs="%"+str(ord(Intermediary[k]))+hexs
print(hexs)
print(xor(Intermediary,IV))

爆出了中间值和$flag明文

QQ截图20210217152650
QQ截图20210217152650

这里有些疑惑,为啥中间值会是15位的… 发现$flag不是最终flag,至于接下来要做的东西,就是CBC字节翻转攻击了

CBC翻转字节攻击

在对CBC模式加密的数据进行解密时,若iv可控,则可以任意控制解密后的内容。 CBC翻转字节攻击不同于padding oracle attack,后者的核心是IV可控情况下获取中间值,从而可以获得明文或者任意控制密文解密后的数据。 而CBC翻转字节攻击的核心思想就不是获取中间值了,而是在IV可控的情况下,通过算法缺陷来直接控制密文解密后的数据。

现在假定有中间值A,明文B1,IV C1 那么就有

代码语言:javascript
复制
A^B1=c1

一点错误都没有对吧。 现在又假定有中间值A,我们想要解密出的明文B2和与之对应的IV C2 那么就有

代码语言:javascript
复制
A^B2=C2
结合以上两个式子,有
A=B1^C1=B2^C2
于是有
B2=B1^C1^C2
或C2=B1^B2^C1
若我们已知B1,C1,且C2可控,那么B2即可控
既满足刚刚我们说的,通过算法缺陷来直接控制密文解密后的数据。

这,就是CBC翻转字节攻击,没太懂没事,看例子就行了

[NPUCTF2020]web🐕中的CBC翻转字节攻击

跟进我们刚刚讲的,FlagIsHere.php,核心代码如下

代码语言:javascript
复制
X5uucFgPTVdCo9f3ZHGP8g==
<?php 
#error_reporting(0);
include('config.php');    //$fl4g
define("METHOD", "aes-128-cbc");
define("SECRET_KEY", "6666666");
session_start();

function get_iv(){    //生成随机初始向量IV
    $random_iv='';
    for($i=0;$i<16;$i++){
        $random_iv.=chr(rand(1,255));
    }
    return $random_iv;
}

$lalala = 'piapiapiapia';

if(!isset($_SESSION['Identity'])){
    $_SESSION['iv'] = get_iv();

    $_SESSION['Identity'] = base64_encode(openssl_encrypt($lalala, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $_SESSION['iv']));
}
echo base64_encode($_SESSION['iv'])."<br>";

if(isset($_POST['iv'])){
    $tmp_id = openssl_decrypt(base64_decode($_SESSION['Identity']), METHOD, SECRET_KEY, OPENSSL_RAW_DATA, base64_decode($_POST['iv']));
    echo $tmp_id."<br>";
    if($tmp_id ==='weber')die($fl4g);
}

highlight_file(__FILE__);
?>

此时我们已知初始IV,初始密文,且IV可控,那么CBC翻转字节攻击条件成立,可以攻击。

代码语言:javascript
复制
这里贴一个别人写的python2 CBC字节反转攻击脚本
自己拿python3写了半天都没写出很好的效果...
import base64
def bxor(b1, b2): # use xor for bytes
    parts = []
    for b1, b2 in zip(b1, b2):
        parts.append(bytes([b1 ^ b2]))
    return b''.join(parts)
iv = base64.b64decode("h34HL5RbMPw8oTaQ+P58nw==")
text = b"piapiapiapia\x04\x04\x04\x04"
result = b"weber\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
middle = bxor(iv,text)
iv = bxor(middle,result)
print(base64.b64encode(iv))

把跑出来的结果POST过去,就会得到下一步了..

Hash长度扩展攻击

1 byte=8 bit

hash算法

Merkle–Damgård构造

易受hash长度扩展攻击的算法有 SHA系列与MD系列,因为他们都是基于Merkle–Damgård构造。具体它是怎么结构,从下文的MD5算法可以感受到

MD5算法

分组

MD5算法里,会先设置好一个一个的分组,每个组的大小是512bit或者说是64bytes。

每个组都包含2个部分: 1.数据区,占56bytes来记录需要被加密的字符串数据,当数据无法填满数据区时,会进行”补位”操作(请看下文解释) 2.长度描述符区,用于记录“非补位”数据的大小,占8个byte,其值为该组数据区种非补位数据的bit大小的16进制值。 比如非补位数据是admin,其占5个byte,40个bit,40的十六进制是28,所以其值会是28。 然后这个值会以一种叫做小端存储的方式记录到长度描述符区。 (非补位数据指该组的非填充的数据,即真正需要被加密的字符串)

补位

很简单,若某个组的数据长度小于56byte,该组的数据区不会被占满,那么就会自动补位来使数据区被填满。

其规则是在数据后先添加一个80字节,然后再用00字节填充完整个数据区。

分组与补位小结

再更进一步的了解MD5算法前,需要更加深刻地理解一下分组与补位,不然稍后的理解会非常困难。

QQ截图20210217152432
QQ截图20210217152432
加密流程

这里放张自己画的加密流程的图

QQ截图20210217152445
QQ截图20210217152445

字符串先分组,然后第一组与初始链进行复杂数学运算得到链1. 注意,这里的初始链是固定的,每个MD5运算的初始链都是固定的,其值就是图中所记录的。也就是说,无论对什么数据进行MD5加密,其初始链都是

0x67452301 0xefcdab89 0x98badcfe 0x10325476

ok。第一组数据与初始链进行复杂运算得到链1,然后链1与第二组数据进行复杂运算得到链2,如此往复,直到倒数第二条链与最后一组数据进行复杂运算得到最后一条链(链final)

然后链final进行高低位转换就得到最终hash,那么什么是高低位转换?

如果final链是

  1. A=0x20f4847a
  2. B=0x42e6abf8
  3. C=0xf9097423
  4. D=0x51a8dad4

那么其hash便是 7a84f420f8abe642237409f9d4daa851

hash长度扩展攻击

基础知识掌握了,就开始了解这个重头戏了。

以一道题为切入点(改了一下实验吧的一道题)

代码语言:javascript
复制
Your cookies don't match up! STOP HACKING THIS SITE. <?php
include "flag.php";
//$secret="XXXXXXXXXXXXXXX"; This secret is 15 characters long for security!
$username="admin";
$password = $_POST["password"];
if($_POST["getmein"] === md5($secret . urldecode($username . $password))){
    if(is_numeric(strpos($password,"abc"))){
    echo "Congratulations! You are a registered user.\n";
    die ("The flag is ". $flag);
    }
}else{
    echo("Your cookies don't match up! STOP HACKING THIS SITE.");
}
highlight_file(__FILE__);
echo(md5($secret . urldecode($username . "admin")));
?> 93a5e7bea9c040065617b1a62ffc3d72

从中我们可以得知secret长度是15,md5($sercet.”adminadmin”)=93a5e7bea9c040065617b1a62ffc3d72

题目的意思很明显,我们需要传两个参数getmein和password使得

getmein=md5($secret.”admin”.password),且password包含abc字符

那么这就是hash长度扩展攻击经典的使用典例,即: 知道salt长度(这里secret变量的长度) 知道一组被加密字符串长度小于56的样本( md5($sercet.”adminadmin”) 的值) 即可知道某个值与salt一起被MD5加密后的hash

那这种攻击是如何实现的呢? 首先我们知道了一组样本,即等于我们知道了该样本的final链(高低位变换)。 同时我们知道了salt长度,即等于我们可以构造出该分组。 那么如果我们又构造出一个新的分组,同时其上一个组是已知样本,那么与新分组进行复杂运算的就是已知样本的final链。 已知样本的final链,新分组的待加密字符串,即可通过复杂运算,高低位变换获得最终hash。 故新分组待加密字符串的hash值是可以预测的。 这,就是hash长度扩展攻击的原理。 可能还是云里雾里的,那就看如何解题吧。

因为已知salt长度,那么可以预测一下样本的分组的情况 因为salt+adminadmin的长度是25,那么其bit就是200,转换为16进制就是c8. 那么假设salt字符全为x(仅仅是个假设而已,别想太多了),该分组的情况

QQ截图20210217152508
QQ截图20210217152508

那么我们可以传参 password=admin%80%00*30abc 其中abc以前的字符会在被MD5运算的时候分配到前一个组,然后通过运算获得链1,这个链1就是我们已知样本的final链了。 然后我们就可以预知,这个final链与abc进行复杂运算,高低位变换得到的hash了。然后再把这个hash赋值给openmein,这个题就做出来了。

好的,大致原理就是这样了。 这时候可以自行写脚本来找到某明文对应的MD5密文,或者使用工具:hashpump.

![

](https://const27blog.oss-cn-beijing.aliyuncs.com/img/QQ截图20210217152515.png)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-06-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Padding oracle attack 与CBC翻转字节攻击
    • 异或(XOR)
      • CBC模式
        • PKCS #5
          • Padding oracle attack
            • Padding oracle attack 攻击场景举例
            • 攻击原理
          • [NPUCTF2020]web🐕中的Padding oracle Attack
            • CBC翻转字节攻击
              • [NPUCTF2020]web🐕中的CBC翻转字节攻击
              • Hash长度扩展攻击
                • hash算法
                  • Merkle–Damgård构造
                  • MD5算法
                • hash长度扩展攻击
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档