CBC字节翻转攻击
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字节翻转攻击的更多相关文章
- Padding Oracle 和 CBC字节翻转攻击学习
以前一直没时间来好好研究下这两种攻击方式,虽然都是很老的点了= =! 0x01:Padding oracle CBC加密模式为分组加密,初始时有初始向量,密钥,以及明文,明文与初始向量异或以后得到中间 ...
- CBC 字节反转攻击
一.CBC 简介 现代密码体制 现代密码中的加密体制一般分为对称加密体制(Symmetric Key Encryption)和非对称加密体制(Asymmetric Key Encryption).对称 ...
- 实验吧之【简单的登录题(】CBC字节反转攻击)
开始刷ctf题吧 慢慢来. 实验吧---简单的登录题 题目地址:http://ctf5.shiyanbar.com/web/jiandan/index.php 随便提交一个id,看到后台set了两个 ...
- 关于AES-CBC模式字节翻转攻击(python3)
# coding:utf-8 from Crypto.Cipher import AES import base64 def encrypt(iv, plaintext): if len(plaint ...
- session安全&&CBC字符反转攻击&&hash拓展攻击
session安全 p神写的: 在传统PHP开发中,$_SESSION变量的内容默认会被保存在服务端的一个文件中,通过一个叫"PHPSESSID"的Cookie来区分用户.这类se ...
- 于bugku中游荡意外得到关于CBC翻转攻击思路
个人简介:渣渣一枚,萌新一个,会划水,会喊六六今天在bugku遇到关于CBC翻转攻击的题目,总结了一下关于CBC翻转攻击的原理,以及关于这道题目的解题思路个人博客:https://www.cnblog ...
- CBC翻转攻击(实验吧_简单的登陆题)
题目链接 http://ctf5.shiyanbar.com/web/jiandan/index.php 有源码在test.php页面 分析代码过程 如果post id,将id转字符串,然后进入sql ...
- BUGKUctf-web-writeup
---恢复内容开始--- 找到了个ctf平台.里面的web挺多的.终于将web题目写的差不多了. Web 签到题 加群就可以了 Web2 直接F12就看到了 文件上传测试 Burp抓包 文件名改成 1 ...
- 百道CTF刷题记录(一)
简介 最近在刷CTF题,主攻Web,兼职Misc Shiyanbar 0x01 简单的登陆题 简单概括: 考点: %00截断正则 CBC字节翻转攻击 难度: 难 WP:https://blog.csd ...
随机推荐
- Python 到底是强类型语言,还是弱类型语言?
0.前言 我在上一篇文章中分析了 为什么 Python 没有 void 类型 的话题,在文章发布后,有读者跟我讨论起了另一个关于类型的问题,但是,我们很快就出现了重大分歧. 我们主要的分歧就在于:Py ...
- 喵的Unity游戏开发之路 - 游泳
原文: https://mp.weixin.qq.com/s/-ERFNB1GRZ6UAkHOhP9UQw 很多童鞋没有系统的Unity3D游戏开发基础,也不知道从何开始学.为此我们精选了一套国外优秀 ...
- composer源码简单分析(一)
composer分析(一) 本文内容 基于PSR-4规范的自动加载 请结合文档和下面的代码注释 spl_autoload_register php闭包Closure简单用法(大体使用情景: 生成回调提 ...
- Android开发之将Edittext输入弹出的软键盘设置搜索确定键。详细代码,已验证可用。
1,首先在布局中添加 android:imeOptions="actionSearch 2,然后java代码中设置代码: et_input_password.setOnEditorActio ...
- laya资源版本管理
layaair-cmd https://ldc.layabox.com/doc/?nav=zh-as-3-4-2 Laya的版本管理 https://blog.csdn.net/qq_43287088 ...
- node.js的安装及其相关环境变量的配置
笔者最近一直重置电脑,本来想换台mac,想了想还是加下配置吧. 于是慢慢的一直会去安装node 接下来进入教程环节 一.NodeJS下载 1.下载NodeJS安装包下载地址:NodeJS下载 2.开始 ...
- Java远程连接Linux服务器并执行命令及上传文件
最近再开发中遇到需要将文件上传到Linux服务器上,至此整理代码笔记. 此种连接方法中有考虑到并发问题,在进行创建FTP连接的时候将每一个连接对象存放至 ThreadLocal<Ftp> ...
- 当前PageOffice需要获取更高版本的授权才能正常运行。(Error:0x0005)
说明当前程序的是pagoeffice3说明当前程序的是pagoeffice3.0的程序,而序列号用的是2.0的序列号,或者说是当前程序是4.0的程序,而序列号用的是3.0的序列号.即当前用的是高版 ...
- 15_Web框架-mini frame
1.WSGI协议概述(Python Web Server Gateway Interface) 1.WSGI允许开发者将选择web框架和web服务器分开,可以混合匹配web服务器和web框架,选择一个 ...
- 干货 | 45张图庖丁解牛18种Queue,你知道几种?
在讲<21张图讲解集合的线程不安全>那一篇,我留了一个彩蛋,就是Queue(队列)还没有讲,这次我们重点来看看Java中的Queue家族,总共涉及到18种Queue.这篇恐怕是市面上最全最 ...