新东西
审计源码发现采用AES加密
这是拿php写的AES加密页面,emmm,这个是密码学的东西
不愧是web🐕
由源码可知
AES密钥长度为128位,加密$iv和明问$data可控。
AES CBC的两种攻击手法:Padding Oracle和字节反转
这道题刚好考到这两点
Padding Oracle适合在我们可以知道iv,不清楚加密Key,能够区分解密成功与否的情况下,直接获得明文
而这题刚好可以判断解密是否成功
根据上述文章
在Padding Oracle Attack攻击中,攻击者输入的参数是IV+Cipher,我们要通过对IV的"穷举"来请求服务器端对我们指定的Cipher进行解密
因此我们需要知道密文,而那个加密函数刚好把密文显示出来了。
这个攻击类似布尔盲注
现在条件都满足
IV:6666666666666666
ly7auKVQCZWum/W/4osuPA==
既然是爆破初始化向量,我们需要知道iv是怎么构成的
先说说cbc解密是怎么解的
首先密文和key进行运算得到一个中间值,然后在通过中间值与IV值的异或,最后得到明文。
上述文章已经讲的很清楚了
由于这题如果解密失败会返False,因此我们只需通过枚举IV,然后得到中间值,然后再中间值和原来真正的IV抑或,即可得到明文。
因此需要通过padding值来判断中间值
我们可以知道padding的长度和middle是相等的
看了wp,不知道这个公式怎么来的,记一下
一道ctf题目
因此IV的构成不难猜了
首先IV肯定是16位的也就是0000000000000000
在进行爆破时
他需要还剩下爆破的位数+正在爆破的值,再加上最后的位数要运算后要保证和padding相等,因此iv[N-step+1:] ^ middle = padding 由此这最后一位就是middle和padding进行异或的结果
刚开始middle未知,因此middle要为空值,
如果解密成功那么middle[当前位置]= iv爆破成功的值 ^当前的位置
由此构遭exp
其实也就是抄别人的来分析
wp链接
import requests
import time
iv = "6666666666666666"
N = 16
middle =""
m =''
url ='http://7dbf58a1-ae85-4457-a828-0a131c8a1f17.node3.buuoj.cn/index.php?source=1&method=decrypt'
def xor(a,b):
return "".join([chr(ord(a[i]) ^ ord(b[i])) for i in range(0,len(a))])
for step in range(1,N+1):
padding = chr(step) * (step -1)
print("爆破的最后{}位".format(step))
for i in range(0,256):
print(i)
new_iv = chr(0)*(N-step)+chr(i)+xor(padding,middle)
data={
"iv":new_iv,
"data":'ly7auKVQCZWum/W/4osuPA=='
}
r = requests.post(url=url,data=data)
time.sleep(0.06)
if r.text != "False":
middle =xor(chr(i),chr(step)) +middle
print(middle)
break
得到FlagIsHere.php
然后就是cbc字节反转
要求’piapiapiapia’加密的密文,通过可控IV,解密成’weber’,就是要我们把IV给解出来
当遇到明文已经经过IV处理过,然后要你解出来是另一个明文时,就要用到CBC字节反转
由于是128长度,16位为一组
因此
两个明文后面都要补齐,填充模式是PK7模式填充,就是拿16减去最后一位的位数的十六进制来进行填充
比如:piapiapiapia\0x04\0x04\0x04\0x04
weber\0x0B\0x0B\0x0B\0x0B\0x0B\0x0B\0x0B\0x0B\0x0B\0x0B\0x0B
然后直接上脚本吧,多说无益,这个看脚本就能理解
方法就是将目标i明文和初始的IV异或后再和原来的明文进行异或。
注意在python3里,一定要传入byte类型,否则将会自动解码hex.
import base64
target = b'weber\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b'
orginal = b'piapiapiapia\x04\x04\x04\x04'
iv = base64.b64decode('ORqPXRzXrXqB3j+Yw7sVPQ==')
result = b''
for i in range(16):
result +=bytes([target[i] ^ iv[i] ^ orginal[i]])
print(base64.b64encode(result))
传过去得到一个网站
然后得到链接,buu做的,直接下载附件就彳亍
是一个java编译过的二进制文件,IDEA永远嘀神,直接拖进去
ascii码即可
byte[] var10000 = new byte[]{102, 108, 97, 103, 123, 119, 101, 54, 95, 52, 111, 103, 95, 49, 115, 95, 101, 52, 115, 121, 103, 48, 105, 110, 103, 125};
String flag="";
for(int j =0; j<var10000.length ;j++){
flag +=(char)var10000[j];
}
System.out.println(flag);
芜湖