2024 赣政杯CTF --- Crypto & Misc wp
【着急长大的孩子们,总以为童年是一本永远写不完的书,急哄哄去翻看一部少年书。】
前言
哈哈哈,终于记起账号密码了! 更个博客玩玩哩!
Misc
misc1
base62一把梭了
misc2
用010打开图片,发现尾部藏了两个压缩包,一个是flag.zip
,另外是一个The Old Farmer.zip
,直接binwalk分一下
第二个压缩包还是伪加密,里面放了6个txt,内容做了base64编码
一顿瞎解密再拼接,得到一篇英文文章的部分内容,尝试将其作为密码解压flag.zip
,不对。
做着做着突然发现,这6个txt的文件创建时间被修改过
一眼顶针,大概率是转成时间戳然后取后三位或者两位数字再转成字符
搓了个脚本转一下
得到
42B:^@
感觉很ez啊,立马拿去解密压缩包,吖!!!!密码错误?????
想了个小时没想明白为什么不对,后来发现是Python的取整问题,它自己会将float类型的值进行四舍五入,导致有几个时间戳会比正确的时间戳少一
或者多一
为了避免误差,直接手工用厨子一个个转了
最后得到解压密码
43C;_@
flag.txt
:
--xr--rw-
--xr-xr--
--xr----x
--xr--rwx
--xrwx-wx
--xrw--w-
--xrw-rwx
--xrwx---
---rw---x
--xrw--wx
--xr-x--x
--xr-xrw-
--xrw-r--
---rw--wx
--xrw--w-
--xr--r-x
--xrw--wx
--xrw-r--
--xr-xr--
--xr-xrw-
--xr--rwx
--xrwxr-x
瞄了一眼,是多组Linux下的文件权限值,这些数字分别对应文件所有者(user)、所属组(group)和其他人(others)的读(r=4)、写(w=2)和执行(x=1)权限。
1,2,4一看就是8进制相关,将各组里面rwx对应的数字累加,得到
146 154 141 147 173 162 167 170 061 163 151 156 164 063 162 145 163 164 154 156 147 175
8进制再转成字符得到flag
flag:
flag{rwx1sint3restlng}
Crypto
babyrsa
题目:
from Crypto.Util.number import *
from secret import m
# flag:flag{m}
p = getPrime(1024)
q = getPrime(1024)
N = p * q
phin = (p - 1) * (q - 1)
e = 0x10001
print p - q
print (pow(p, q, N) + pow(q, p, N)) % N
print pow(m, e, N)
#20770635068836854804018903805008274067606000732091812088238375893754679640326321257910151064059716965482617819160659713254090859126046141458972905487013741518783669630953762873993452695113483606585058842333278760035501674856078879985170771134359059700014915486712258779746177202951233148271263631410890377232
#251977009704719043743957619372378316406223795099157998414691903797809614210766146172352847795941692644697920223081135559569675529760707334360190956033383311694634897462481351591012494086953992705311723805943628217472583590984732115189975349762945362614562113037949693380507592345673101621967347851223606019046
#14995812512746185651910734800932895576935544754470741361466551314570898979311726306584899621438972712582924943415884710845121791809505629915261107804877561685151242127110164411070108243963494497183701079877455045335552388674243493671826742915022788173294714593074327627124687813228571288464125571147722618789880159378410459947504727652488670566785848040210193551439939650137530070837978563532615422159238816438778871886278048032743079651090028578863471972993233322616971760071203484200291313014177089130623760325915701496447348193574435416078670767669796544421222892712622043852976376993032677402616461577281986136739
我们已知
p
−
q
p-q
p−q和
p
+
q
p+q
p+q,可得
p
=
(
p
−
q
)
+
(
p
+
q
)
2
p = \frac{(p-q)+(p+q)}{2}
p=2(p−q)+(p+q)
之后走RSA解密流程即可计算出m
import gmpy2
e = 0x10001
p_q = 20770635068836854804018903805008274067606000732091812088238375893754679640326321257910151064059716965482617819160659713254090859126046141458972905487013741518783669630953762873993452695113483606585058842333278760035501674856078879985170771134359059700014915486712258779746177202951233148271263631410890377232
tmp = 251977009704719043743957619372378316406223795099157998414691903797809614210766146172352847795941692644697920223081135559569675529760707334360190956033383311694634897462481351591012494086953992705311723805943628217472583590984732115189975349762945362614562113037949693380507592345673101621967347851223606019046
c = 14995812512746185651910734800932895576935544754470741361466551314570898979311726306584899621438972712582924943415884710845121791809505629915261107804877561685151242127110164411070108243963494497183701079877455045335552388674243493671826742915022788173294714593074327627124687813228571288464125571147722618789880159378410459947504727652488670566785848040210193551439939650137530070837978563532615422159238816438778871886278048032743079651090028578863471972993233322616971760071203484200291313014177089130623760325915701496447348193574435416078670767669796544421222892712622043852976376993032677402616461577281986136739
p = (p_q+tmp)//2
d = gmpy2.invert(e,p-1)
m = pow(c,d,p)
print(m)
#flag{18236864817391037194782912873917391739173913}
nsfr
题目:
from flag import flag
assert flag.startswith("flag{")
assert flag.endswith("}")
assert len(flag) == 30
def lfsr(R, mask):
output = (R << 1) & 0xffffff
i = (R & mask) & 0xffffff
lastbit = 0
while i != 0:
lastbit ^= (i & 1)
i = i >> 1
output ^= lastbit
return (output, lastbit)
def round(R1, R1_mask, R2, R2_mask, R3, R3_mask, R4, R4_mask):
(R1_NEW, x1) = lfsr(R1, R1_mask)
(R2_NEW, x2) = lfsr(R2, R2_mask)
(R3_NEW, x3) = lfsr(R3, R3_mask)
(R4_NEW, x4) = lfsr(R4, R4_mask)
return (R1_NEW, R2_NEW, R3_NEW, R4_NEW, (x1 * x4) ^ ((x2 ^ 1) * (x3 ^ 1)))
R1 = int(flag[5:11], 16)
R2 = int(flag[11:17], 16)
R3 = int(flag[17:23], 16)
R4 = int(flag[23:29], 16)
assert len(bin(R1)[2:]) == 17
assert len(bin(R2)[2:]) == 19
assert len(bin(R3)[2:]) == 21
assert len(bin(R4)[2:]) == 22
R1_mask = 0x10020
R2_mask = 0x4100c
R3_mask = 0x100002
R4_mask = 0x200002
outputs = ""
for j in range(1024):
output = 0
for k in range(8):
(R1, R2, R3, R4, out) = round(R1, R1_mask, R2, R2_mask, R3, R3_mask, R4, R4_mask)
output = (output << 1) ^ out
outputs += chr(output)
f = open("./output", "ab")
f.write(outputs)
f.close()
lsfr流密码,且output中的数据是连续的,那么就可以参考之前的博客2024 hgame — Crypto wp
week1中ezPRNG一题,直接通过z3约束来计算出R1,R2,R3,R4
最开始是用32个循环来跑的,运行时间大概400s,后来发现16个循环来构造方程也是可以解出R1,R2,R3,R4的,只需要150s左右
PS:不能直接套用出题人的lsfr
函数,z3库会出现报错,需要小改一点代码
from z3 import *
import time
def lfsr1(R, mask):
nextR = (R << 1) & 0xffffffff
i=(R&mask)&0xffffffff
nextbit=0
for k in range(17):
nextbit^=(i%2)
i = i>>1
nextR^=nextbit
return (nextR,nextbit)
def lfsr2(R, mask):
nextR = (R << 1) & 0xffffffff
i=(R&mask)&0xffffffff
nextbit=0
for k in range(19):
nextbit^=(i%2)
i = i>>1
nextR^=nextbit
return (nextR,nextbit)
def lfsr3(R, mask):
nextR = (R << 1) & 0xffffffff
i=(R&mask)&0xffffffff
nextbit=0
for k in range(21):
nextbit^=(i%2)
i = i>>1
nextR^=nextbit
return (nextR,nextbit)
def lfsr4(R, mask):
nextR = (R << 1) & 0xffffffff
i=(R&mask)&0xffffffff
nextbit=0
for k in range(22):
nextbit^=(i%2)
i = i>>1
nextR^=nextbit
return (nextR,nextbit)
def round(R1, R1_mask, R2, R2_mask, R3, R3_mask, R4, R4_mask):
(R1_NEW, x1) = lfsr1(R1, R1_mask)
(R2_NEW, x2) = lfsr2(R2, R2_mask)
(R3_NEW, x3) = lfsr3(R3, R3_mask)
(R4_NEW, x4) = lfsr4(R4, R4_mask)
return (R1_NEW, R2_NEW, R3_NEW, R4_NEW, (x1 * x4) ^ ((x2 ^ 1) * (x3 ^ 1)))
R1_mask = 0x10020
R2_mask = 0x4100c
R3_mask = 0x100002
R4_mask = 0x200002
R1= BitVec('R1',32)
R2 = BitVec('R2',32)
R3 = BitVec('R3',32)
R4 = BitVec('R4',32)
res = [237, 90, 54, 76, 11, 72, 32, 235, 83, 56, 17, 57, 2, 200, 18, 102, 193, 115, 68, 220, 130, 25, 80, 216, 108, 200, 113, 180, 97, 167, 36, 39]
s = Solver()
ori_time = time.time()
for j in range(16):
output = 0
for k in range(8):
(R1, R2, R3, R4, out) = round(R1, R1_mask, R2, R2_mask, R3, R3_mask, R4, R4_mask)
output = (output << 1) ^ out
s.add(output == res[j])
if s.check()==sat:
result = s.model()
print(result)
#[R2 = 460833, R1 = 72653, R4 = 3080057, R3 = 2068857]
flag = "flag{"+(hex(72653)+hex(460833)+hex(2068857)+hex(3080057)).replace("0x","")+"}"
print(flag)
print(time.time()-ori_time)
#flag{11bcd708211f91792eff79}
【着急长大的孩子们,总以为童年是一本永远写不完的书,急哄哄去翻看一部少年书。】
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)