CBC翻转字节攻击

CBC翻转字节攻击

CBC加密过程(密文分组链接模式
在这里插入图片描述
异或后加密
在这里插入图片描述

攻击点为IV或者加密后的某段密文

改第一组明文的信息,需要更改IV

$A = Plaintext[0] = 'h' ;
$B = IV[0] =  可控;
$C = Decrypt(Ciphertext)[0] = ?;

//所以我们需要伪造一个新的IV向量,使得$C ^ New_IV = 我们需要的明文
//因为有 
$C ^ Old_IV = Source_str
//所以
$C = Old_IV ^ Source_str
//并且我们还需要
$C ^ New_IV = Target_str
//即
$C = New_IV ^ Target_str
//所以
Old_IV ^ Source_str = New_IV ^ Target_str
//所以
New_IV = Old_IV ^ Source_str ^ Target_str

已知异或之后的第N-1组密文(Decrypt之后的密文),我们就可以通过字节翻转改变第N组明文

下面假设我们要更改第3组明文

$Old_pt[1]为第2组明文,$Old_ct[1]为第2组密文,$Old_ct[2]为第3组密文

$Plaintext = [
  'comment1=wowsuch',
  '%20CBC;userdata=',
  '*admin=true;come',
  'nt2=%20suchsafe%',
  '20very%20encrypt',
  'wowww'
];//我们要使$Plaintext[2]中的*变成;
//密文全部已知并可控
$Old_pt[1] = Plaintext[1] = '%20CBC;userdata=';
$Old_ct[1] = Decrypt(Ciphertext)[1] = 已知 并且我们攻击的点在这;
$Old_ct[2] = Decrypt(Ciphertext)[2] = 已知;

//所以我们需要伪造一个新的第2组密文,使得$Old_ct[2] ^ $New_ct[1] = 我们需要的明文$New_pt[2]
//因为有 
$Old_ct[1] ^ $Old_ct[2] = $Old_pt[2];
//所以
$Old_ct[2] = $Old_ct[1] ^ $Old_pt[2];
//并且还已知
$New_ct[1] ^ $Old_ct[2] = $New_pt[2];
//即
$Old_ct[2] = $New_ct[1] ^ $New_pt[2];
//所以
$Old_ct[1] ^ $Old_pt[2] = $New_ct[1] ^ $New_pt[2];
//所以
$New_ct[1] = $Old_ct[1] ^ $Old_pt[2] ^ $New_pt[2];

https://resources.infosecinstitute.com/cbc-byte-flipping-attack-101-approach/#

https://www.jianshu.com/p/7f171477a603

bugku login4

http://123.206.31.85:49168/
flag格式:SKCTF{xxxxxxxxxxxxxxxx}
hint:CBC字节翻转攻击

有备份文件
在这里插入图片描述

恢复

<?php
define("SECRET_KEY", file_get_contents('/root/key'));
define("METHOD", "aes-128-cbc");
session_start();

function get_random_iv(){
    $random_iv='';
    for($i=0;$i<16;$i++){
        $random_iv.=chr(rand(1,255));
    }
    return $random_iv;
}

function login($info){
    $iv = get_random_iv();//随机iv,加密的post提交的username和password的结果—>cipher
    $plain = serialize($info);
    $cipher = openssl_encrypt($plain, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv);
    $_SESSION['username'] = $info['username'];
    setcookie("iv", base64_encode($iv));//设置cookie
    setcookie("cipher", base64_encode($cipher));
}

function check_login(){
    if(isset($_COOKIE['cipher']) && isset($_COOKIE['iv'])){//如果cookie中有cipher和iv
        $cipher = base64_decode($_COOKIE['cipher']);
        $iv = base64_decode($_COOKIE["iv"]);
        //进行CBC模式的AES解密,并对解密结果进行反序列化,设置session中的username为反序列化后数组中的username的值
        if($plain = openssl_decrypt($cipher, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv)){
            $info = unserialize($plain) or die("<p>base64_decode('".base64_encode($plain)."') can't unserialize</p>");
            $_SESSION['username'] = $info['username'];
        }else{
            die("ERROR!");
        }
    }
}

function show_homepage(){
    if ($_SESSION["username"]==='admin'){//username=admin->flag
        echo '<p>Hello admin</p>';
        echo '<p>Flag is $flag</p>';
    }else{
        echo '<p>hello '.$_SESSION['username'].'</p>';
        echo '<p>Only admin can see flag</p>';
    }
    echo '<p><a href="loginout.php">Log out</a></p>';
}

if(isset($_POST['username']) && isset($_POST['password'])){//post username!=admin
    $username = (string)$_POST['username'];
    $password = (string)$_POST['password'];
    if($username === 'admin'){
        exit('<p>admin are not allowed to login</p>');
    }else{
        $info = array('username'=>$username,'password'=>$password);
        login($info);
        show_homepage();
    }
}else{
    if(isset($_SESSION["username"])){
        check_login();
        show_homepage();
    }else{
        echo '<body class="login-body">
                <div id="wrapper">
                    <div class="user-icon"></div>
                    <div class="pass-icon"></div>
                    <form name="login-form" class="login-form" action="" method="post">
                        <div class="header">
                        <h1>Login Form</h1>
                        <span>Fill out the form below to login to my super awesome imaginary control panel.</span>
                        </div>
                        <div class="content">
                        <input name="username" type="text" class="input username" value="Username" onfocus="this.value=\'\'" />
                        <input name="password" type="password" class="input password" value="Password" onfocus="this.value=\'\'" />
                        </div>
                        <div class="footer">
                        <input type="submit" name="submit" value="Login" class="button" />
                        </div>
                    </form>
                </div>
            </body>';
    }
}
?>

提交cookie->base64解密->AES(CBC)解密->反序列化->得到username、password

禁止直接提交用户名为admin进行登陆,但是返回flag的条件又是session中用户名要是admin。所以需要构造类似"xdmin"形式的用户名,之后通过修改iv和cipher,通过CBC翻转攻击将字符x还原成"admin"

a:2:{s:8:"username";s:5:"ddmin";s:8:"password";s:3:"123";}
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

iv的值是随机变化的,即使同一个用户名,多次发送POST数据,也会改变iv,所以提交一次POST后就一次完成,否则就从头再来

序列化内容分组,16个一组

a:2:{s:8:"userna
me";s:5:"ddmin";
s:8:"password";s
:3:"123";}

我们想要改的d->a在第二组的9位(从0开始),那我们要改第一组的第9位。

<?php
$enc=base64_decode("wcj5C0sDD3hBduHkKhFN%2FlYyWtwSUtTbMvCNLIzQESHlZQALF%2F1M5lMIU3atTVIznl%2F1U8whHODSSBFL5EGOZQ%3D%3D");
$enc[9] = chr(ord($enc[9]) ^ ord("d") ^ ord ("a"));
echo base64_encode($enc);
?>

wcj5C0sDD3hBc%2bHkKhFN%2FlYyWtwSUtTbMvCNLIzQESHlZQALF%2F1M5lMIU3atTVIznl%2F1U8whHODSSBFL5EGOZQ%3D%3D

+ / = 要url编码(%2b、%2F、%3D

(enc只要%2F之前的其实就够
在这里插入图片描述

<?php
$enc=base64_decode("ABLICF5SX1TTIjjSWuVo821lIjtzOjU6ImFkbWluIjtzOjg6InBhc3N3b3JkIjtzOjM6IjEyMyI7fQ==");
$iv=base64_decode("fnPzpI/TgpGT2Y8THFilug==");
$cleartext = 'a:2:{s:8:"userna';
$newiv = '';
for ($i=0;$i<16;$i++){
    $newiv=$newiv.chr(ord($iv[$i]) ^ ord($enc[$i]) ^ ord ($cleartext[$i]));
}
echo base64_encode($newiv);
?>

H1sJlqry5/162cKyI8+jKA==
在这里插入图片描述

https://blog.csdn.net/zpy1998zpy/article/details/80684485

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值