Automne's Shadow.

RadarCTF 2019 Crypto WriteUp

2019/04/19 Share

Crypto

RSA

RSA.zip提供了公钥(n,e)和密文,而且n比较短,可以直接分解。

老规矩,使用sage进行分解。

sage: n = 7576962585305391589
sage: p,q = n.factor()
sage: p,q = p[0],q[0]

然后计算欧拉函数和私钥d

sage: phi = (p-1)*(q-1)
sage: e = 65537
sage: d = inverse_mod(e,phi)

得到d为:

4406608918927534373

然后看一下提供的密文形式

automne

注意这里需要逐行进行解密,以密文的第一行解密为例,得到结果716989

automne

该结果可以分别拆分为71/69/89三个,然后转为字符串。这里的脑洞还是蛮大的。
转换后的字符串可以进行base32解码。解码后的内容再进行处理即可得到flag。

基于此,编写下面的解密脚本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#encoding:utf-8

import base64

n = 7576962585305391589
d = 4406608918927534373
result = []

with open("RSA.txt","r") as f:
print f.readline()
print f.readline()
print f.readline()
print f.readline()
for c in f:
result.append(str(pow(int(c),d,n)))
print result
print "".join(result)

combiners = "".join(result)

spliters = [chr(int(combiners[i:i+2])) for i in range(0,len(combiners),2)]
print spliters

combiners2 = "".join(spliters)
print combiners2

flag = base64.b32decode(combiners2)
print flag

out = flag.split(" ")
print out

flags = []

for i in range(len(out)):
flags.append(chr(int(out[i])))

print "".join(flags)

运行后的输出效果如下:

automne

得到flag:radar{factor1ng_c@n_cr@ck_rsa}

blanks

flag.txt 使用notepad++打开是空白,使用hex编辑器打开,如下图所示。

automne

开始我的思路是觉得这是morse电码。。后面转换后发现无法继续。

原来是替换为01二进制,这题目的脑洞。

使用下面的脚本,然后8位一组转换后得到flag。

1
2
3
4
5
6
7
8
9
10
11
12
13

#encoding:utf-8

new = open("new.txt","w")
flag = []

with open("old.txt","r") as f:
for c in f:
d = c.replace("09","0").replace("20","1").replace(" ","")
new.write(d)
flag.append(''.join(chr(int(d[i*8:i*8+8],2)) for i in range(len(d)//8)))

print ''.join(flag)

运行即可。

automne

AES

直接参考:https://github.com/manulqwerty/CTF-Stuff/blob/master/RADARCTF/AES/script.py

一直对AES等对称加密认识不深,当时看到这题也无从下手。
这次打过TG:Hack 2019里的一道AES解密题,再看这题就比较容易理解了。
有了密文和加解密算法,没有密钥key,爆破key就是一种方法。

密码字典就使用的rockyou.txt

直接贴出参考的脚本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

#!/usr/bin/env python

# flag.enc and AEScipher class are given, we just have to brute force :P

from Crypto.Cipher import AES
from Crypto.Random import new as Random
from hashlib import sha256
from base64 import b64encode,b64decode
import time
import threading


class AESCipher:
def __init__(self,data,key):
self.block_size = 16
self.data = data
self.key = sha256(key.encode()).digest()[:32]
self.pad = lambda s: s + (self.block_size - len(s) % self.block_size) * chr (self.block_size - len(s) % self.block_size)
self.unpad = lambda s: s[:-ord(s[len(s) - 1:])]

def encrypt(self):
plain_text = self.pad(self.data)
iv = Random().read(AES.block_size)
cipher = AES.new(self.key,AES.MODE_OFB,iv)
return b64encode(iv + cipher.encrypt(plain_text.encode())).decode()

def decrypt(self):
cipher_text = b64decode(self.data.encode())
iv = cipher_text[:self.block_size]
cipher = AES.new(self.key,AES.MODE_OFB,iv)
return self.unpad(cipher.decrypt(cipher_text[self.block_size:])).decode()


def brute(test):
data = 'vLlZz11nZdu84N57/eqkJJ0EXIlgedx41w/akqmreH7aD8pr0Bds8dNaWvbWd9MW/zeCAFzjYav+XQtyv6eijA=='
try:
result = AESCipher(data, test.strip()).decrypt()
if 'radar' in result:
print result
except:
pass

path = '/usr/share/wordlists/rockyou.txt'
with open(path, 'r') as f:
lines = f.readlines()
for i in lines:
thread1 = threading.Thread(target=brute, args=[i,])
thread1.start()
time.sleep(0.01)

爆破30分钟左右得到flag:

automne

CATALOG
  1. 1. RSA
  2. 2. blanks
  3. 3. AES