CryptoXORCRYPTO中的XOR问题
AiY0uXOR是CTFer在做题中常见的问题,本文分享一下我在做题过程中遇到的经典问题
什么是XOR
XOR即”异或运算“,它在数学表达式中常常写作’’⊕’’,在常见的几种编程语言中,则是用符号’’^’’来表示。
XOR运算遵循这样的规则:
1⊕1 = 0
0⊕0 = 0
1⊕0 = 1
0⊕1 = 1
在实际运算中,它是按位运算的。现有二进制10010和11001,二者异或的结果为01011。
XOR的运算性质
XOR运算具有
1)交换律
2)结合律
3)归零律:A⊕A=0
4)恒等律:A⊕0=A
由其归零率和恒等率我们还可以推出:
A⊕B=C
即A⊕B⊕B=C⊕B
即A=C⊕B
这就说明了为什么单单使用XOR,属于对称密码。假设A是密文,B是密钥,经过上面的步骤可以看出只要知道密钥B,就能将密文和明文相互转化。
XOR题型举例
利用运算性质
本题来源于cryptohack
1 2 3 4
| KEY1 = a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313 KEY2 ^ KEY1 = 37dcb292030faa90d07eec17e3b1c6d8daf94c35d4c9191a5e1e KEY2 ^ KEY3 = c1545756687e7573db23aa1c3452a098b71a7fbf0fddddde5fc1 FLAG ^ KEY1 ^ KEY3 ^ KEY2 = 04ee9855208a2cd59091d04767ae47963170d1660df7f56f5faf
|
求FLAG只需让4式异或1式和3式
python实现如下:
1 2 3 4 5 6 7 8
| from pwn import * KEY1 = bytes.fromhex('a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313') KEY2_KEY1 = bytes.fromhex('37dcb292030faa90d07eec17e3b1c6d8daf94c35d4c9191a5e1e') KEY2_KEY3 = bytes.fromhex('c1545756687e7573db23aa1c3452a098b71a7fbf0fddddde5fc1') FLAG_KEY1_KEY3_KEY2 = bytes.fromhex('04ee9855208a2cd59091d04767ae47963170d1660df7f56f5faf') step1 = xor(FLAG_KEY1_KEY3_KEY2,KEY1) step2 = xor(step1,KEY2_KEY3) print(step2)
|
注:1. 使用了pwntools库中的xor()函数
2.bytes.fromhex()函数的作用是将十六进制字符组成的字符串转化为字节序列,即’a6c8b6’转化为0xa6 0xc8 0xb6的序列
碰撞已知的明文片段

本题我们已知密钥仅为一个字节,又知道最终flag为crypto{xxxxxx}的形式
根据XOR运算的性质,我们只需要让密文首个字节与字母’c’异或,就能得到密钥
python实现:
1 2 3 4 5 6 7
| from pwn import * m = '73626960647f6b206821204f21254f7d694f7624662065622127234f726927756d' m_bytes = bytes.fromhex(m) key = xor(0x73,'c') print(key) p = xor(m_bytes,key) print(p)
|
对图片的XOR
基本原理:图片由许多像素点排列组成,我们可以把每个像素点的灰度或RGB(red,green,blue,可以认为每个像素点的颜色是由这三种颜色不同比例混合而成的)的数值当作异或的对象。将异或得到的数值再转化为灰度或RGB,形成新的图片。
常用的工具:python的PIL库
例题来自cryptohack,感兴趣可自行查看

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| from PIL import Image image1 = Image.open("F:\pythonscript\cryptohack\Lemur_XOR\lemur_ed66878c338e662d3473f0d98eedbd0d.png") image2 = Image.open("F:\pythonscript\cryptohack\Lemur_XOR\\flag_7ae18c704272532658c10b5faad06d74.png")
#生成可操作的对象,pim类似于矩阵,通过坐标值来操控每个像素 pim1 = image1.load() pim2 = image2.load()
width,height=image1.size
for i in range(width): for j in range(height): r1,g1,b1 = pim1[i,j] r2,g2,b2 = pim2[i,j] pim1[i,j] = (r1^r2, g1^g2, b1^b2)
image1.show()
|
注:Image.open()函数即打开图片文件
.load()函数生成一个矩阵,通过坐标值来访问图片中的每个像素
.size能分别得出图片的宽和高(像素点个数)
r1,g1,b1 = pim1[i,j]这一句是得到[i,j]位置处的RGB值
.show()函数负责弹窗展示图片
感觉这一题更像是misc会出的东西。