Hgame2022-Week1
WEEK1
附件获取,密码:hadc
Crypto
兔兔的车票
picture只有0-14,然而原文异或是0-15,所以肯定有个图片就是本身。也就是key的某一个,有一个enc = flag ^ key某一个。所以两两异或可以弄出来。
exp
from PIL import Image
from Crypto.Util.number import *
from random import shuffle, randint, getrandbits
sampleImg = Image.open('./兔兔的车票/attachment/pics/enc0.png')
width = sampleImg.width
height = sampleImg.height
def xorImg(keyImg, sourceImg):
img = Image.new('RGB', (width, height))
for i in range(height):
for j in range(width):
p1, p2 = keyImg.getpixel((j, i)), sourceImg.getpixel((j, i))
img.putpixel((j, i), tuple([(p1[k] ^ p2[k]) for k in range(3)]))
return img
im = Image.open(f'./兔兔的车票/attachment/pics/enc1.png')
for j in range(2, 16):
im_j = Image.open(f'./兔兔的车票/attachment/pics/enc{j}.png')
img = xorImg(im, im_j)
img.save(f'./兔兔的车票/attachment/res/dec{j}.png')
RSA
利用在线网站分解质因数。
exp
from Crypto.Util.number import *
c = 110674792674017748243232351185896019660434718342001686906527789876264976328686134101972125493938434992787002915562500475480693297360867681000092725583284616353543422388489208114545007138606543678040798651836027433383282177081034151589935024292017207209056829250152219183518400364871109559825679273502274955582
n = 135127138348299757374196447062640858416920350098320099993115949719051354213545596643216739555453946196078110834726375475981791223069451364024181952818056802089567064926510294124594174478123216516600368334763849206942942824711531334239106807454086389211139153023662266125937481669520771879355089997671125020789
p = 11239134987804993586763559028187245057652550219515201768644770733869088185320740938450178816138394844329723311433549899499795775655921261664087997097294813
q = 12022912661420941592569751731802639375088427463430162252113082619617837010913002515450223656942836378041122163833359097910935638423464006252814266959128953
e = 65537
phi = (p-1)*(q-1)
d = inverse(e, phi)
m = pow(c, d, n)
print(long_to_bytes(m))
Be stream
给了一个递推式:
要我们算water = stream((i//2)**6) % 256
.这个n很大,不可能通过递归去算,考虑矩阵快速幂简化递归。
通项:
构造乘幂矩阵:
递推式就化简成了:
我们要计算stream(n), 就是取出\(X_n\)的第一项。
exp
import numpy as np
enc = b'\x1a\x15\x05\t\x17\t\xf5\xa2-\x06\xec\xed\x01-\xc7\xcc2\x1eXA\x1c\x157[\x06\x13/!-\x0b\xd4\x91-\x06\x8b\xd4-\x1e+*\x15-pm\x1f\x17\x1bY'
key = [int.from_bytes(b"Be water", 'big'), int.from_bytes(b"my friend", 'big')]
X = [key[1], key[0]]
A = [[4, 1], [7, 0]]
X = np.matrix(X)
A = np.matrix(A)
def stream(i):
if i == 0:
return key[0]
elif i == 1:
return key[1]
else:
ans = X*(A**(i-1))
return ans.tolist()[0][0]
flag = b''
for i in range(len(enc)):
water = stream((i//2)**6) % 256
flag += bytes([water ^ enc[i]])
print(flag)
神秘的电话
morse密码解出来是
-----/··---/··---/···--/·/··--·-/·--·/·-·/··/··/-···/·-··/-·--/··--·-/··--·-/····/---/-·/·--/·-/··--·-/·---/--/--·/····/··--··/··-·/--·/-·-/-·-·/--·-/·-/---/--·-/-/--/··-·/·-·/
0223E_PRIIBLY__HONWA_JMGH?FGKCQAOQTMFR
encrypted_message.txt里面是base64密文,解出来是这样的:
几个星期前,我们收到一个神秘的消息。但是这个消息被重重加密,我们不知道它的真正含义是什么。唯一知道的信息是关于密钥的:“只有倒着翻过十八层的篱笆才能抵达北欧神话的终点”。
猜测栅栏解密,北欧神话的终点映射的是什么解密就不清楚了。但应该都是古典密码,2023都在一块。
传统栅栏和W栅栏都试了一下,发现18栏的W栅栏符合要求:
rmocfhm_wo_ybipe2023_ril_hnajg?katfqqg
猜测最后的加密是维吉尼亚,爆破密钥:
welcome_to_hgame2023_and_enjoy?hacking
部分修正以后得到flag:
hgame{welcome_to_hgame2023_and_enjoy_hacking}
密钥:vidar