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 pq p + q p+q p+q,可得
p = ( p − q ) + ( p + q ) 2 p = \frac{(p-q)+(p+q)}{2} p=2(pq)+(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}

【着急长大的孩子们,总以为童年是一本永远写不完的书,急哄哄去翻看一步少年书。】

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值