CBC字节翻转攻击

主页,writeup,ctf,web,嘤嘤嘤,完结 2018-05-06

CBC字节翻转攻击

参考文章

http://www.freebuf.com/articles/system/163756.html

CBC翻转攻击方法的精髓在于:

通过损坏密文字节来改变明文字节。(注:借助CBC内部的模式)借由此可以绕过过滤器,或者改变用户权限提升至管理员,又或者改变应用程序预期明文以尽猥琐之事。

整个加密的过程简单说来就是:

  1. 首先将明文分组(常见的以16字节为一组),位数不足的使用特殊字符填充。
  2. 生成一个随机的初始化向量(IV)和一个密钥。
  3. 将IV和第一组明文异或。
  4. 用密钥对3中xor后产生的密文加密。
  5. 用4中产生的密文对第二组明文进行xor操作。
  6. 用密钥对5中产生的密文加密。
  7. 重复4-7,到最后一组明文。
  8. 将IV和加密后的密文拼接在一起,得到最终的密文。

解密的过程其实只要理解了加密,反过来看解密过程就也很简单了,同样的,前一块密文参与下一块密文的还原。

  1. 从密文中提取出IV,然后将密文分组。
  2. 使用密钥对第一组的密文解密,然后和IV进行xor得到明文。
  3. 使用密钥对第二组密文解密,然后和2中的密文xor得到明文。
  4. 重复2-3,直到最后一组密文。

具体加密解密过程这里不过多叙述,请参考开始提到的文章.

首先得到一个登陆界面,随意输入登陆,提示需要admin才能看到flag.

username=zdmin&password=12345

登陆之后得到第一次的cookie

iv=uL86lH%2BXnh%2BUBpm6ZdAzeg%3D%3D
cipher=VnxHhOF%2Fxnne4kBWpJWw8uRj2oW6qRdShJRFbwsLRkuwTDxwI%2BzTD8OC9b1%2F8TWv9F%2FuicGOxNJn3SWqOGLewQ%3D%3D

编写脚本将cipher替换

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import base64
import requests
import urllib
iv_raw='uL86lH%2BXnh%2BUBpm6ZdAzeg%3D%3D'  #这里填写第一次返回的iv值
cipher_raw='VnxHhOF%2Fxnne4kBWpJWw8uRj2oW6qRdShJRFbwsLRkuwTDxwI%2BzTD8OC9b1%2F8TWv9F%2FuicGOxNJn3SWqOGLewQ%3D%3D'  #这里填写第一次返回的cipher值

#print "iv_raw:  " + iv_raw
#print "cipher_raw:  " + cipher_raw

cipher = base64.b64decode(urllib.unquote(cipher_raw))
#s:2:{s:8:"username";s:5:"zdmin";s:8:"password";s:5:"12345"}
#s:2:{s:8:"userna
#me";s:5:"zdmin";
#s:8:"password";s
#:3:"12345";}
xor_cipher = cipher[0:9] +  chr(ord(cipher[9]) ^ ord('z') ^ ord('a')) + cipher[10:]  #请根据你的输入自行更改,原理看上面的介绍
xor_cipher=urllib.quote(base64.b64encode(xor_cipher))
print "cipher:" + xor_cipher

将得到的翻转之后的cipher上传

这里注意要将提交的数据删除,不然将造成重新获得cookie,触发不了现象.

得到网站返回

base64_decode('CgyrbtJF60ZGs6qgRn6AhW1lIjtzOjU6ImFkbWluIjtzOjg6InBhc3N3b3JkIjtzOjU6IjEyMzQ1Ijt9') can't unserialize

再次编写脚本
将无法反序列化的字符串赋给cipher

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import base64
import requests
import urllib

cipher = 'CgyrbtJF60ZGs6qgRn6AhW1lIjtzOjU6ImFkbWluIjtzOjg6InBhc3N3b3JkIjtzOjU6IjEyMzQ1Ijt9'#填写提交后所得的无法反序列化密文
iv = 'uL86lH%2BXnh%2BUBpm6ZdAzeg%3D%3D'#一开始提交的iv
#cipher = urllib.unquote(cipher)
cipher = base64.b64decode(cipher)
iv = base64.b64decode(urllib.unquote(iv))
newIv = ''
right = 'a:2:{s:8:"userna'#被损坏前正确的明文
for i in range(16):
    newIv += chr(ord(right[i])^ord(iv[i])^ord(cipher[i])) #这一步相当于把原来iv中不匹配的部分修改过来
print urllib.quote(base64.b64encode(newIv))

最后将得到的newiv赋给iv,cipher依然是翻转之后得到的.
上传得到flag.


本文由 saltyfishyu 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

还不快抢沙发

添加新评论