0%

i春秋 第二届春秋欢乐赛 CryMisc Writeup

解压

把压缩文件解压,得到crypto.zipjiami.py,而前者中包含有jiami.py,构造一个zip出来查看CRC,发现是同一文件,所以进行明文攻击。

然后将其中的gogogo.zip解压,得到三个文件

查看代码

打开AESencrypt.py,查看代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# -*- coding:utf8 -*-
from Crypto.Cipher import AES

s=open('next.zip','rb').read()
BS=16
pad_len=BS-len(s)%BS
padding=chr(pad_len)*pad_len
s+=padding

key='我后来忘了'
n=0x48D6B5DAB6617F21B39AB2F7B14969A7337247CABB417B900AE1D986DB47D971
e=0x10001
m=long(key.encode('hex'),16)
c=pow(m,e,n)
c='0{:x}'.format(c).decode('hex')
with open('RSA.encrypt','wb') as f:
f.write(c)

obj=AES.new(key,AES.MODE_ECB)
with open('AES.encryt','wb') as f:
f.write(obj.encrypt(s))

c='0{:x}'.format(c).decode('hex')发现是python2的代码(似乎还多写了个0….)
发现key被RSA加密了,给出了n和e,将n分解(当p、q的取值差异过大或过于相近的时候,使用yafu可以快速的把n值分解出p、q值)

解出两个质数是177334994338425644535647498913444186659185783328357334813222812664416930395483
使用gmpy2解出d = 21459038613121460434132216103140795081593356519819592462521069311922260546829

1
2
d = gmpy2.invert(e,(p-1)*(q-1))
#21459038613121460434132216103140795081593356519819592462521069311922260546829

(其实用RSA-Tool2也行,这样就没必要装gmpy2了)
以16进制读取RSA.encrypt文件,得到68c2e12fadebbd344e82fa9e1eac0f0bde5aecbd7840f18352cf761f872233d
再转化为数字

转化代码

1
2
3
4
#python3
byte = open("RSA.encrypt" , "rb").read()
hexstr = binascii.b2a_hex(byte).decode("utf-8")
c = int(hexstr,16)
1
2
#python2.7
c = int(open("RSA.encrypt" , "rb").read().encode('hex'),16)

使用RSA-Tool2(需要把字母转为大写,神奇的bug….)或使用python代码解密

解密key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#python3
from Crypto.Cipher import AES
import binascii

def HextoAscii(hexnum):
hexStr = str(hexnum).replace("0x","")
return binascii.a2b_hex(hexStr).decode("utf-8")

c = 0x068C2E12FADEBBD344E82FA9E1EAC0F0BDE5AECBD7840F18352CF761F872233D
n = 0x48D6B5DAB6617F21B39AB2F7B14969A7337247CABB417B900AE1D986DB47D971
e = 0x10001
p = 185783328357334813222812664416930395483
q = 177334994338425644535647498913444186659
d = 21459038613121460434132216103140795081593356519819592462521069311922260546829
m=pow(c,d,n)
print(m)
hexnum = hex(m)
print(HextoAscii(hexnum))
1
2
3
4
5
6
7
8
9
10
11
12
13
#python2.7
from Crypto.Cipher import AES

c = 0x068c2e12fadebbd344e82fa9e1eac0f0bde5aecbd7840f18352cf761f872233d#read RSA.encrypt
n = 0x48D6B5DAB6617F21B39AB2F7B14969A7337247CABB417B900AE1D986DB47D971
e = 0x10001
p = 185783328357334813222812664416930395483
q = 177334994338425644535647498913444186659
d = 21459038613121460434132216103140795081593356519819592462521069311922260546829
m=pow(c,d,n)
print(m)
key = "{:x}".format(m).decode('hex')
print(key)

m=132172197780003798270878941356862694777
16进制就是636F70795F5F77686974655F5F6B6579
HexDecode得到copy__white__key

解密AES.crypt文件

修改一下AESencrypt.py,然后运行,得到next.zip
代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
from Crypto.Cipher import AES

s=open('AES.encryt','rb').read()
BS=16
pad_len=BS-len(s)%BS
padding=chr(pad_len)*pad_len
s+=padding

key='copy__white__key'

obj=AES.new(key,AES.MODE_ECB)
with open('next.zip','wb') as f:
f.write(obj.decrypt(s))

解压缩next.zip得到三个文件

查看encrypt.py,代码如下

1
2
3
4
5
6
7
8
9
from base64 import *

s=open('flag.jpg','rb').read()
s='-'.join(map(b16encode,list(s)))
s=map(''.join,zip(*(s.split('-'))))
with open('first','wb') as f:
f.write(b16decode(s[0]))
with open('second','wb') as f:
f.write(b16decode(s[1]))

发现是把flag.jpg拆成两部分,都使用base16 decode了一次

合并出flag.jpg

1
2
3
4
5
6
7
8
9
10
from base64 import *
s = [0,1]
with open('first','rb') as f:
s[0] = b16encode(f.read())
with open('second','rb') as f:
s[1] = b16encode(f.read())
s=map(''.join,zip(*s))
s=b16decode(''.join(s))
with open('flag.jpg','wb') as f:
f.write(s)


(可自行保存分析)
按照惯例,肯定是藏在文件尾,010Editor打开,提取出尾部文件
发现是psd文件
![](https://xhy-1252675344.cos.ap-beijing.myqcloud.com/imgs/CryMisc_PS.png =439x)
key为copy__white__key,这是一个提示,把背景导出为png

查看bg.png

使用stegsolve打开,点一下左箭头,得到一个二维码,解码得到flag

参考

CryMisc__writeup
CTF中RSA套路
RSA史上最强剖析,从小白变大神,附常用工具使用方法及CTF中RSA典型例题