2024 RAICOM【网络安全】MISC+Crypto wp全
Crypto
变异凯撒
题目
115!111!111!155!1!515!1511!151511!15555!11555!15555!5515!15555!5515!15555!55551!11555!55551!11555!55111!11555!11115!55111!51111!55555!5515!15555!5515!15555!11111!11555!55551!55551!1555!55555!11155!55555!1555!15555!11155!55555!55555!15555!55555!15555!55555!55555!11111!15555!15555!55555!11111!55555!51111!55551!5!15555!11111!55555!55551!55555!11115!55555!11555!15555!55555
分析
这段密文由1,5,!组成,是摩斯密码
1---> -
5---> .
!----> 空格
--. --- --- -.. - .-. -.-- -.-.-- -.... --... -.... ..-. -.... ..-. -.... ....- --... ....- --... ..--- --... ----. ..--- .---- ..... ..-. -.... ..-. -.... ----- --... ....- ....- -... ..... ---.. ..... -... -.... ---.. ..... ..... -.... ..... -.... ..... ..... ----- -.... -.... ..... ----- ..... .---- ....- . -.... ----- ..... ....- ..... ----. ..... --... -.... .....
摩斯密码转换-文字转摩尔斯电码 - 在线工具 (wqtool.com)
在线网站莫斯电码解码得到
goodtry!676f6f64747279215f6f60744b585b68556565506650514e6054595765
hex 解码
十六进制Hex在线编解码 ASCII字符串编解码 16进制编解码 16进制编解码原理 (cyeam.com)
goodtry!_o`tKX[hUeePfPQN`TYWe
变异的凯撒
s="_o`tKX[hUeePfPQN`TYWe"
flag="ctf{"
for _ in range(4):
print(ord(s[_])-ord(flag[_]))
-4
-5
-6
-7
x = "_o`tKX[hUeePfPQN`TYWe"
y = ""
k = 4
for i in range(len(x)):
y += chr(ord(x[i]) + k)
k+=1
print(y)
# ctf{Saesars_vacation}
RSA1
题目
# n1=143786356117385195355522728814418684024129402954309769186869633376407480449846714776247533950484109173163811708549269029920405450237443197994941951104068001708682945191370596050916441792714228818475059839352105948003874426539429621408867171203559281132589926504992702401428910240117807627890055235377744541913
# n2=119235191922699211973494433973985286182951917872084464216722572875998345005104112625024274855529546680909781406076412741844254205002739352725207590519921992295941563460138887173402493503653397592300336588721082590464192875253265214253650991510709511154297580284525736720396804660126786258245028204861220690641
# e1=114194
# e2=79874
# c1=39479494167559452654985203289943719259163299251143220210309279768527498133064312809391876988552192522859264358652395407629640466082031052656165869397115318550484593316249054547664541873839700453293616924050629495860848690688870172047629969577393843044814764071500077651746511098271700607708161262328875272901
# c2=40021890693634802149455301480516680638387865544579062658450227396887653003943965894831376566469207517639996015081669502676021814746137321282912913041491783405771352022999065383538465160772628190865722102773656005841880894373415342052123730741647940772923577126372141812876272857339232055779588277573908481700
分析
给了两个模数n1,n2,尝试求出两个魔术之间的gcd
发现真的存在,那n就可以i分解出来了,两个模数共用一个因子p
接下来就是RSA了
n1=p*q1
n2=p*q2
求d时,报错,发现e与p不互素,gcd(e1,p)==2
gcd(e,φ(n))比较小时可以考虑nth_root直接开根
Number Theory - SymPy 1.13.3 documentation
sympy.ntheory.residue_ntheory.nthroot_mod(a, n, p, all_roots=False)[source]
Find the solutions to x**n = a mod p
.
from sympy.ntheory.residue_ntheory import nthroot_mod
nthroot_mod(11, 4, 19)
8
nthroot_mod(11, 4, 19, True)
[8, 11]
nthroot_mod(68, 3, 109)
23
n1=143786356117385195355522728814418684024129402954309769186869633376407480449846714776247533950484109173163811708549269029920405450237443197994941951104068001708682945191370596050916441792714228818475059839352105948003874426539429621408867171203559281132589926504992702401428910240117807627890055235377744541913
n2=119235191922699211973494433973985286182951917872084464216722572875998345005104112625024274855529546680909781406076412741844254205002739352725207590519921992295941563460138887173402493503653397592300336588721082590464192875253265214253650991510709511154297580284525736720396804660126786258245028204861220690641
e1=114194
e2=79874
c1=39479494167559452654985203289943719259163299251143220210309279768527498133064312809391876988552192522859264358652395407629640466082031052656165869397115318550484593316249054547664541873839700453293616924050629495860848690688870172047629969577393843044814764071500077651746511098271700607708161262328875272901
c2=40021890693634802149455301480516680638387865544579062658450227396887653003943965894831376566469207517639996015081669502676021814746137321282912913041491783405771352022999065383538465160772628190865722102773656005841880894373415342052123730741647940772923577126372141812876272857339232055779588277573908481700
# print(e1.bit_length())
# s1,s2 = gcdext(e1, e2)
p = gcd(n1, n2)
d = inverse(e1//2, p-1)
c = pow(c1, d, p)
print(nthroot_mod(c, 2, p))
print(long_to_bytes(nthroot_mod(c, 2, p)))
# 13040004482820293603269114883242394483287716106167021539826788081912401803814088775006434173
# b'flag{77646EC317E5081E05AC366AD4729903}'
bytes_lfsr
题目
from os import urandom
from Crypto.Util.number import bytes_to_long
from random import getrandbits
from flag import FLAG
class byte_lfsr:
def __init__(self, init, msg):
self.state = init
self.mask = list(map(int, list(bin(msg)[2:])))
while len(self.mask) % 8 != 0:
self.mask.append(0)
def next(self):
nextstate = 0
test=0
for i, s in enumerate(self.state):
nextstate ^= self.mask[i] * s
self.state = self.state[1:] + nextstate.to_bytes(1, byteorder = 'big')
bl = byte_lfsr(urandom(8 * len(FLAG)), bytes_to_long(FLAG))
for i in range(getrandbits(10)):
bl.next()
leak_seq = b""
trick = 1 + getrandbits(2)
print(trick)
print(bl.state[-1] >> trick)
for i in range(len(FLAG) * 16):
bl.next()
leak_seq += (bl.state[-1] >> trick).to_bytes(1, byteorder = 'big')
with open(r"output.txt", "w") as f:
f.write(leak_seq.hex())
leak_seq = "360c2b0209350b2a3a202029300a0222292e211f203714190f1a29272c3d1610121c302819291e33051b291e352f091027031b153a350b0324022f1d390124300f0510363700360c2e063404203a193e292b0d091d2c2c1d0a2a051e2201172e3a011d2610261d0b2d1d0a140e3b0128301c13270014130d3d182e3b222c142e25081a3e38332d221b072804083a350b023c292d24063b0424331b0200211439062a3405033c3a0d083d17132134033924340c0019003b192f1e3c2e270a151c23152e0b3c201d3624373a240c0d3c1e2d16160b2a251131360e173a0c25280211153128370d08273d08272e23072d211e2a3c272b00073635060e1b111f15283c1133033f29101937343318151001383d1b3b3c26361b1a001a233d0d200d070f042d2c20323130141c21160c162a0b0a3c3e0d280e212d0e1433221709202c14140c1f3402181a17160e1a342b133439173e051a3212391d203e303a03312d2a22380b000d271702002f13371509200b273c0d18070f232a3119021e100f1d36281525282d2f27231f3136161728242d000a2b1c3b102038043f1f3f130c2b1437163a063f0e21392b2a11192a3922231c333c1f1f05222c2c1b3a11270032191035023632340f2439290f28213e001a04182c2f3522303c35273b2a0e002a1a081a3c1639290127100f110e123c04222c022137280435261e20262d2c2702101d3f0e0b361f002622153d302f3f1a1907171a1627271e200917201b3e112520130b270b3a2836041d3a0921341d361025271b3b1f391b15040f170a36303e1f300c283a28090e2c1821213d1e3213361334252d3a1d16101816370e37393f"
分析
mask = list(map(int, list(bin(msg)[2:])))
self.state = self.state[1:] + nextstate.to_bytes(1, byteorder = 'big')
state不断前移一位,舍弃第一个state,然后在后面加入nextstate
lfsr->init ->(state0)---->8*len(flag)
->mask --------------->len(flag)
LFSR的反馈函数级数为8*len(flag)
题目给出了state[-1] >> trick : 16*len(flag)个
mask未知,只知道2n输出序列
B-M 算法
如果已知长度为 2n 的输出序列,可以通过构造矩阵来求出 mask,时间复杂度:O(n^2)次比特操作,空间复杂度O(n) 比特。Berlekamp-Massey算法可以找到给定二进制输出序列的最短线性反馈移位寄存器(LFSR)。该算法还可寻找任意域中线性递归序列[最小多项式。域要求意味着 Berlekamp–Massey 算法要求所有非零元素都具有乘法逆元。
但这里的nextstate必须是01二进制,因为在GF(2)下,异或运算相当与加法运算
但题目中的state ,nextstate是字节,异或运算不等于加法运算,所以需要处理一下
假设data的二进制表示为a0a1a2a3a4a5a6,
state0^^state1^^state2^^state3 就是每一位分别进行异或
a00 a01 a02 a03 a04 a05 a06
a10 a11 a12 a13 a14 a15 a16
a20 a21 a22 a23 a24 a25 a26
a30 a31 a32 a33 a34 a35 a36
x0 x1 x2 x3 x4 x5 x6
每一位异或其实是不受影响的,我们要求的mask,所以可以将state只保留一位
trick = 1 + getrandbits(2)是可以求出的
nextstate 8bit 一定小于256
nextstate>>trick<<trick也一定小于256
max(nextstate)=63
63*2**trick<256 trick=2,state只保留一位,(state>>trick)>>5
其实也可以不用求出trick, state%2就直接得到state的一位,然后构造上面的矩阵,就可以得到m,但这里的m是经过padding后的结果,bin(ord('f'))--'0b1100110' 填充另一位,所以恢复出的M多了一个0,所以得出的结果需要除以2
from Crypto.Util.number import long_to_bytes
flag_length=304
leak_seq = "360c2b0209350b2a3a202029300a0222292e211f203714190f1a29272c3d1610121c302819291e33051b291e352f091027031b153a350b0324022f1d390124300f0510363700360c2e063404203a193e292b0d091d2c2c1d0a2a051e2201172e3a011d2610261d0b2d1d0a140e3b0128301c13270014130d3d182e3b222c142e25081a3e38332d221b072804083a350b023c292d24063b0424331b0200211439062a3405033c3a0d083d17132134033924340c0019003b192f1e3c2e270a151c23152e0b3c201d3624373a240c0d3c1e2d16160b2a251131360e173a0c25280211153128370d08273d08272e23072d211e2a3c272b00073635060e1b111f15283c1133033f29101937343318151001383d1b3b3c26361b1a001a233d0d200d070f042d2c20323130141c21160c162a0b0a3c3e0d280e212d0e1433221709202c14140c1f3402181a17160e1a342b133439173e051a3212391d203e303a03312d2a22380b000d271702002f13371509200b273c0d18070f232a3119021e100f1d36281525282d2f27231f3136161728242d000a2b1c3b102038043f1f3f130c2b1437163a063f0e21392b2a11192a3922231c333c1f1f05222c2c1b3a11270032191035023632340f2439290f28213e001a04182c2f3522303c35273b2a0e002a1a081a3c1639290127100f110e123c04222c022137280435261e20262d2c2702101d3f0e0b361f002622153d302f3f1a1907171a1627271e200917201b3e112520130b270b3a2836041d3a0921341d361025271b3b1f391b15040f170a36303e1f300c283a28090e2c1821213d1e3213361334252d3a1d16101816370e37393f"
leak_seq = list(bytes.fromhex(leak_seq))
# print(leak_seq)
leak_seq=[i>>5 for i in leak_seq]
# print(leak_seq)
m = matrix(GF(2), 304,304)
for i in range(304):
m[i] = leak_seq[i:i+304]
s = vector(GF(2), leak_seq[-304:])
k = s * m.inverse()
k = [str(i) for i in k]
k = "".join(k)
k = int(k, 2)//2
print(long_to_bytes(k))
# b'flag{ByT3_L45R_15_Just_A_w3ak3r_LFsr!}'
misc
你是黑客么
分析
附件爆破得到密码
将图片拖到010之后发现有base64字符串
加上前面的data:image
猜测是base64转图片,找个网站转换一下
扫码得到flag
flag{asdf%^&*ghjkl}
循环的压缩包
分析
正如题目,是循环的压缩包,解压得到的文件就两种:tarfile或者zipfile,写个脚本直接跑
import zipfile
import tarfile
number=516 #初始被压缩次数是516次
for i in range(516):
path="zipfile" #压缩文件被保存的目录
zip_file=zipfile.ZipFile(path)
zip_list=zip_file.namelist()
# zip_file.extractall("./tarfile")
for f in zip_list:
zip_file.extract(f, "./") #解压后生成的目录
zip_file.close()
path="tarfile" #压缩文件被保存的目录
tar_file = tarfile.open(path)
tar_list=tar_file.getnames()
for f in tar_list:
tar_file.extract(f, "./") #解压后生成的目录
tar_file.close()
number=number-1
if number==1:
break
GoodTime
分析
用ziperello爆破压缩文件密码,得到city
打开txt文件,发现里面是16进制文件,而且文件名是键盘密码
从上到下分别对应f,g,a,d,b,e,c
按照a,b,c,d,e,f,g的顺序依次拼接txt文件内容
text=b""
for i in 'abcdefg':
f=open(f'{i}.txt', 'r')
text+=bytes.fromhex(str(f.read()).replace(" ",""))
f.close()
with open(' GoodTime.txt', 'wb') as f:
f.write(text)
修复压缩包文件头,加上5048,即可得到压缩文件,里面包含 一张图
zsteg检测图片隐藏的数据,得到一串16进制
hex->base64
5a6d78685a3373794e4459345831395556585a75583139786432567966513d3d
->ZmxhZ3syNDY4X19UVXZuX19xd2VyfQ==
->flag{2468TUvnqwer}