iscc2018线上赛开始两周多了,学到了很多,写几篇文章总结一下遇到的知识点,做一个归纳,方便以后查找。

web300-----CBC字节翻转攻击

cbc是AES加密的cbc模式 即密码分组链模式:

先将铭文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,在于密钥进行加密。

直接看图理解一下加解密原理:

明文以16个字节为一组进行分组,给出初始化向量iv于明文进行异或然后利用密钥key在进行加密得到密文a,密文a就相当于下一段明文的初始化向量,以此类推。

解密时,同样将密文分组,每组密文先利用密钥解密在与“iv”异或得到明文,过程类似加密。

我们的攻击发生在解密的时候,即我们可以控制解密时所生成的明文。

根据解密方式我们可以知道,A=ciphertext(N-1),B=plaintext(N),C为第N块待异或且经过解密的字符,C'为我们经过翻转要得到的明文。

所以我们可以打得到关系:

A = B ^ C

C = A ^ B

A ^ B ^ C = 0

A ^ B ^ C ^ C' = C'

根据关系式可以得到 A' = A ^ C ^ C'

所以说我们只需要修改前一组密文所对应的本组明文相同位置的字符,即可得到想要的明文。

下面贴上源代码以便理解:

<?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();
$plain = serialize($info);
$cipher = openssl_encrypt($plain, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv);
$_SESSION['username'] = $info['username'];
setcookie("iv", base64_encode($iv));
setcookie("cipher", base64_encode($cipher));
} function check_login(){
if(isset($_COOKIE['cipher']) && isset($_COOKIE['iv'])){
$cipher = base64_decode($_COOKIE['cipher']);
$iv = base64_decode($_COOKIE["iv"]);
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'){
echo $flag;
}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'])){
$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>';
}
}
?>

阅读源代码,我们可以知道,只有admin用户才能读取flag,但是admin用户又不允许登录。虽然相互矛盾,由于题目用到了aes的cbc模式加密,所以我们可以利用cbc字节翻转攻击来得到我们想要的明文。我们来看一下流程:

以账号 admiN 密码 123456登录

题目将用户名密码传入数组并序列化得到a:2:{s:8:"username";s:5:"admiN";s:8:"password";s:5:"123456";

接下来进行aes加密,并将得到的cipher和iv进行base64编码放入cookie中(cookie对于攻击者来说可控,所以存在cbc字节翻转攻击)

明文加密时分组为:

a:2:{s:8:"userna
me";s:5:"admiN";
s:8:"password";s
:6:"123456";}  

因此我们只需要将"N"字节翻转为"n"即可得到flag。

根据我们得到的关系,已知只需修改前一组密文即可。

$newcipher[13]=chr(ord(13) ^ ord('N') ^ ord('n'))

这时我们就会得到

a:2:{s:8:"username";s:5:"admin";s:8:"password";s:5:"123456";

但是由于前一组密文被修改了 所以前一组的明文会出现乱码,因此接下来我们再生成新的iv将前一组明文改回a:2:{s:8:"userna 即可得到flag。

写了一个脚本(代码烂的不行  凑活看....)

#-*- coding:utf8 -*-
import base64
import urllib
# a:2:{s:8:"userna
# me";s:5:"admiN";
# s:8:"password";s
# :6:"123456";} def Module1():
ciphertext = raw_input("Please input the first round cipher:\n")
cipher = base64.b64decode(urllib.unquote(ciphertext))
new_cipher = cipher[:13] + chr(ord(cipher[13]) ^ ord('N') ^ ord('n')) + cipher[14:]
print urllib.unquote(base64.b64encode(new_cipher)) def Module2():
errorcipher = base64.b64decode(urllib.unquote(raw_input('Please input errorcipher: \n')))
ivtext = raw_input("Please input iv:\n")
iv = base64.b64decode(urllib.unquote(ivtext))
cleartext = 'a:2:{s:8:"userna'
newiv = ''
for i in range(16):
newiv += chr(ord(iv[i]) ^ ord(errorcipher[i]) ^ ord(cleartext[i]))
print urllib.unquote(base64.b64encode(newiv)) option = raw_input("Please input option [1 or 2]:")
if option == '1':
Module1()
elif option == '2':
Module2()
else:
pass

先登录网站

在地址栏处回车,抓包得到cipher和iv。

运行脚本 选择 1;

复制cipher值粘贴到脚本中 得到新的cipher。

用新的cipher替换数据包中的cipher

这个时候我们的admiN其实已经变成了admin了  接下来就是生成新的iv。(将报错的信息解码看一下)

重新抓包

将iv和cipher改为 新生成的iv和之前生成的cipher发包 得到flag。

理解的时候大费周章,记录的时候也还是有点难写的  有的地方不知道怎么说, 以此记录学习成果。

任重而道远。

CBC字节翻转攻击的更多相关文章

  1. Padding Oracle 和 CBC字节翻转攻击学习

    以前一直没时间来好好研究下这两种攻击方式,虽然都是很老的点了= =! 0x01:Padding oracle CBC加密模式为分组加密,初始时有初始向量,密钥,以及明文,明文与初始向量异或以后得到中间 ...

  2. CBC 字节反转攻击

    一.CBC 简介 现代密码体制 现代密码中的加密体制一般分为对称加密体制(Symmetric Key Encryption)和非对称加密体制(Asymmetric Key Encryption).对称 ...

  3. 实验吧之【简单的登录题(】CBC字节反转攻击)

    开始刷ctf题吧  慢慢来. 实验吧---简单的登录题 题目地址:http://ctf5.shiyanbar.com/web/jiandan/index.php 随便提交一个id,看到后台set了两个 ...

  4. 关于AES-CBC模式字节翻转攻击(python3)

    # coding:utf-8 from Crypto.Cipher import AES import base64 def encrypt(iv, plaintext): if len(plaint ...

  5. session安全&&CBC字符反转攻击&&hash拓展攻击

    session安全 p神写的: 在传统PHP开发中,$_SESSION变量的内容默认会被保存在服务端的一个文件中,通过一个叫"PHPSESSID"的Cookie来区分用户.这类se ...

  6. 于bugku中游荡意外得到关于CBC翻转攻击思路

    个人简介:渣渣一枚,萌新一个,会划水,会喊六六今天在bugku遇到关于CBC翻转攻击的题目,总结了一下关于CBC翻转攻击的原理,以及关于这道题目的解题思路个人博客:https://www.cnblog ...

  7. CBC翻转攻击(实验吧_简单的登陆题)

    题目链接 http://ctf5.shiyanbar.com/web/jiandan/index.php 有源码在test.php页面 分析代码过程 如果post id,将id转字符串,然后进入sql ...

  8. BUGKUctf-web-writeup

    ---恢复内容开始--- 找到了个ctf平台.里面的web挺多的.终于将web题目写的差不多了. Web 签到题 加群就可以了 Web2 直接F12就看到了 文件上传测试 Burp抓包 文件名改成 1 ...

  9. 百道CTF刷题记录(一)

    简介 最近在刷CTF题,主攻Web,兼职Misc Shiyanbar 0x01 简单的登陆题 简单概括: 考点: %00截断正则 CBC字节翻转攻击 难度: 难 WP:https://blog.csd ...

随机推荐

  1. openstack nova 虚机镜像后端提取

    参考链接:https://www.cnblogs.com/storymedia/p/4500186.html 1.nova 创建的虚机后端目录 其中的base是虚机基础镜像,创建虚机会根据这个基础镜像 ...

  2. 区块链入门到实战(26)之以太坊(Ethereum) – 挖矿

    以太坊(Ethereum)与其他公共区块链一样,使用工作量证明机制确保区块链网络正常运行. 矿工进行工作量证明计算,即挖矿,来选择区块,写入区块链,确认交易. 交易过程如下图所示: 从技术角度来看,以 ...

  3. 【翻译】.NET 5 Preview8发布

    [翻译].NET 5 Preview8发布 今天,.NET 5预览8发布了,对于.NET5.0的功能开发已经完成了,这必须要排除待处理的bug,预览8是最后一次预览版本.预计11月正式的.NET5.0 ...

  4. 通过Tomcat jpress连接不到数据库

    -- 实际数据库.用户名,密码,主机账号,端口号均正确 提示如下: 异常如下:------------------------------------------------------------- ...

  5. 模型层中QuerySet的学习

    创建对象 使用关键字参数实例化模型实例来创建一个对象,然后调用save()把它保存到数据库中 pub_obj = models.Publisher(title='奥利给出版社') pub_obj.sa ...

  6. Codeforces 1324E Sleeping Schedule DP

    题意 给你一个长度为\(n\)的数组\(a\)和3个数字\(h,l和r\).\(t\)初始为0,每次可以使\(t=(t+a_i) \% h\)或者\(t=(t+a_i-1)\%h\),如果这时\(t\ ...

  7. oracle数据库创建数据库实例-九五小庞

    oracle数据库创建数据库实例

  8. 当this碰到return会发生什么

    当this碰到return时 function fn(params) { this.user = 'fzy' return {} } var a = new fn console.log(a.user ...

  9. JVM学习第二天(垃圾回收器和内存分配策略)大章

    说道垃圾回收器大家应该都会有所了解,GC白,当然说道具体的可能就不是很清楚了,今天我们就来玩一玩; GC要做的事情: 第一步:确定堆中需要回收的对象; 第二步:什么时候回收; 第三步:怎样回收 为什么 ...

  10. 使用HttpUrlConnection访问www.163.com遇到503问题,用设置代理加以解决

    一次我使用如下程序连接到网易,意图获取其网站的html文本: try { String urlPath = "http://www.163.com/"; URL url = new ...