zoukankan      html  css  js  c++  java
  • bugku login4

    (前排提示:这次思路写的极不清晰,可能只有我自己看的懂,打个预防针QAQ)

    首先看题:

    扫描,拿到了 .index.php.swp 

    这个文件是可以复原的。

     

     

     上面的是重要的源码。审计之后发现这是CBC加密。

     题目也给了提示,CBC字节翻转攻击。那就好说很多了,百度呗!

    首先 CBC 是什么? 

    电码本模式(Electronic Codebook Book,简称ECB:是一种基础的加密方式,密文被分割成分组长度相等的块(不足补齐),然后单独一个个加密,一个个输出组成密文。

    密码分组链接模式(Cipher Block Chaining,简称CBC:是一种循环模式,前一个分组的密文和当前分组的明文异或操作后再加密,这样做的目的是增强破解难度。

    计算器模式(Counter,简称CTR):计算器模式不常见,在CTR模式中, 有一个自增的算子,这个算子用密钥加密之后的输出和明文异或的结果得到密文,相当于一次一密。这种加密方式简单快速,安全可靠,而且可以并行加密,但是在计算器不能维持很长的情况下,密钥只能使用一次。

    密码反馈模式(Cipher FeedBack,简称CFB):实际上是一种反馈模式,目的也是增强破解的难度。

    输出反馈模式(Output FeedBack,简称OFB:实际上是一种反馈模式,目的也是增强破解的难度。

    简单的来说CBC就是分组呗。CBC采用十六个字节为一组的加密方式。

    加密过程

    Plaintext:待加密的数据

    IV:用于随机化加密的比特块,保证即使对相同明文多次加密,也可以得到不同的密文。

    Key:被一些如AES的对称加密算法使用

    Ciphertext:加密后的数据

     解密过程

     看的懂吗?反正我看了好久才看懂!我就在这里把自己的思路理一下吧!

    加密:

    A:第n组的待加密数据

    B:第n-1组的加密后的数据

    C:第n组的加密后的数据

    A^B的数据经过私有秘钥key加密后得到C,重复这个过程。(第一组有些不一样,但是思路是一样的)

    解密:

    A:第n组的加密后的数据

    B:第n-1组加密后的数据

    C:第n组解密后的数据

    A经过私有秘钥key解密后与C进行异或操作,最终得到C。

    看完之后应该还是很迷吧(都怪我太菜,讲解不好,那也没办法了,给个链接吧)

    https://blog.csdn.net/csu_vc/article/details/79619309 

    (感谢大佬)

    然后就是CBC字节翻转攻击了。(CBC字节翻转攻击只能用于解密阶段)

    重点:在密文中改变的字节只会影响在下一明文中具有相同偏移量的字节

    所以字节翻转攻击就是在利用n-1轮的数据来影响n轮明文的数据。

    当我们的一个值C是由A和B异或得到
    C = A XOR B
    那么
    A XOR B XOR C很明显是=0的
    当我们知道B和C之后,想要得到A的值也很容易
    A = B XOR C
    因此,A XOR B XOR C等于0。有了这个公式,我们可以在XOR运算的末尾处设置我们自己的值,即可改变。

    我们构造的用户名admia账号序列化后为
    a:2:{s:8:"username";s:5:"admia";s:8:"password";s:3:"123";}

    我们的目标是将k改成n,因此第一件事就是把明文分成16个字节的块:

    Block1: a:2:{s:8:"userna

    Block2: me";s:5:"admia";

    Block3: s:8:"password";s

    Block4: :3:"123";}

    所以我们要翻转的是第二组的“a”翻转为“n”,所以我们要改变第一组的密文从而达到攻击的效果

    我们可以看到我们的目标字符位于块2,偏移量为13,这就意味着我们要改变块一中偏移量为13的字符

    第二块明文偏移量为13的字符(C) = 第一块密文偏移量为13的字符(A) ^ decrypt(第二块密文的偏移量为13的字符)(B)

    即 C = A ^ B,这里我们知道C和A,因此B = A ^ C

    假设我们修改A为A2,使得 A2 = A ^ C ^ D(我们想要的字符,这里指‘n’)

    那么C = A2 ^ B = A ^ C ^ D ^ A ^ C = 0 ^ D  = D,即

    $enc[13] = chr(ord($enc[13]) ^ ord("a") ^ ord ("n"))

    然后写脚本就完事了

     

     把cookie中的数据复制一下(注意看源码哦,每一次的iv都是不同的)

    还有把post发送的数据给删掉哦,要不然iv会一直重置的。。。

    先把cipher和iv给扔进脚本里,获得

     把下面这行数据写进 cipher 里,继续go一下。(注意:bp有一个很恶心的缺点,+ / = 都要转成url编码,否则会出现编码错误的)

     说无法解码?原来是这样

    因为我们修改了第一块的密文,如果我们继续用原来的iv去解密第一块密文,

    那么肯定是不成功的,是无法反序列化的,

    因此我们需要修改iv,使其解密第一块得到的是a:2:{s:8:"userna

    那么如何修改iv呢

    第一块错误明文 = decrypt(第一块原密文) ^ ord_iv

    那么  decrypt(第一块原密文) = 第一块错误明文 ^ ord_iv

    第一块正确明文 = decrypt(第一块原密文) ^ new_iv

    那么  new_iv = decrypt(第一块原密文) ^ 第一块正确明文 =  第一块错误明文 ^ ord_iv ^ 第一块正确明文

    (我的脚本中只用把无法解码的字符串换一下就行了)

     给上我写的垃圾脚本。

    <?php
    
    $a = array('username'=>'admia','password'=>'21354');
    echo serialize($a),"<br/>";                    //a:2:{s:8:"username";s:5:"admia";s:8:"password";s:6:"dawawd";}
    
    $old_iv = base64_decode('8TvnQRCNnQRxlTuE/YddSg==');                                      // 明文 admia  
    $cipher = 'R6EhHmZbmAQRcx3iHTDADBy1sgXnZOaIRZVZ7MA+DO7zcafXEEUPx0JoNe4l52ROEn7YFQYoA/AiLR8347MQOQ==';      
    
    $enc = base64_decode($cipher);
    
    $enc[13] = chr(ord($enc[13]) ^ ord('a') ^ ord('n'));                   //把第一组的第13位给转变了
    $enc = base64_encode($enc);
    echo $enc,"<br/>";
    
    $right = 'a:2:{s:8:"userna';
    $enc = base64_decode('XgB4zuCXhYaAkeVJwKfphG1lIjtzOjU6ImFkbWluIjtzOjg6InBhc3N3b3JkIjtzOjU6IjIxMzQ1Ijt9');   //无法反序列化的字符串
    $new_iv = '';
    for( $i = 0 ; $i < 16 ; $i++ )
    {
        $new_iv = $new_iv.chr(ord($enc[$i]) ^ ord($right[$i]) ^ ord($old_iv[$i]));
        
    }
    echo base64_encode($new_iv);
     
    ?>

    最后,想说一些话:

    bugku的web区最后一道题,从8月一直到11月,整整三个月,终于结束了。犹记得当初刚进web,连post和get是什么都一知半解,

    不断地在题目中摸爬滚打,我不敢说我现在有多么强,但是,我可以说,我比四个月前强太多了,这几个月也结识了好多志同道合的朋友,

    cytnb,fjlnb,qlnb,yjznb

    虽然每天都在自闭中度过,但是,

    好开心的说。

    也许这就是CTF的魅力吧,也许这就是web的魅力吧。

    bugku结束了,但是我的web才刚刚开始。

    (好尬啊啊啊啊啊!!但是好开心。)

  • 相关阅读:
    命令行编译运行java工程(转)
    JAVA配置环境变量的意义(转)
    在Linux环境下搭建Tomcat+mysql+jdk环境(转)
    java环境变量
    varchar(8000) nvarchar(4000) varchar(max) nvarchar(max) 区别
    HTTP与HTTPS握手的那些事(转载)
    ELK研究-部署搭建运用
    主机规划与磁盘分区
    占位符问题 python pymysql
    django 数据迁移的问题 sqlite3 --> mysql
  • 原文地址:https://www.cnblogs.com/cioi/p/11788320.html
Copyright © 2011-2022 走看看