NewStarCTF 2023 week1

本文最后更新于:2023年10月27日 下午

NewStarCTF 2023 week1 Crypto方向的一些题

Vigenère

维吉尼亚密码解密

打开txt后就一段字符:

pqcq{qc_m1kt4_njn_5slp0b_lkyacx_gcdy1ud4_g3nv5x0}

前四个应该是对应flag,直接找就欧克了

下表上面一行是明文,左边一列是密钥

1695730908860

这段字符害的我好苦,太傻了我,都找到key是kfck了,怎么就不能想到是key的长度是3呢

1695729736638

但是好像有什么更厉害的遍历网站/代码,可是我没找到😥(

babyxor

main

1
2
3
4
5
6
7
8
9
from secret import *

ciphertext = []

for f in flag:
ciphertext.append(f ^ key)

print(bytes(ciphertext).hex())
# e9e3eee8f4f7bffdd0bebad0fcf6e2e2bcfbfdf6d0eee1ebd0eabbf5f6aeaeaeaeaeaef2

exp

看了知道是异或

ord("a") 会返回字母 a 对应的ASCII码:97

将f转换成对应的ASCII码,与0xe9进行异或就可以获得key

1695732585874

得到key是143

1
2
3
4
5
6
7
8
9
10
11
import binascii         # 该模块包含了十六进制编码和解码的函数。
cipher = "e9e3eee8f4f7bffdd0bebad0fcf6e2e2bcfbfdf6d0eee1ebd0eabbf5f6aeaeaeaeaeaef2"
c = binascii.unhexlify(cipher) # 将十六进制字符串 cipher 解码为字节序列并将结果存储在变量 c 中
# binascii.unhexlify() 函数用于将十六进制字符串转换为二进制数据。

key = 143

result = ""
for i in c:
result += chr(i^key) # chr() 函数用于将一个整数转换为对应的字符。
print(result)

Affine

main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from flag import flag, key

modulus = 256

ciphertext = []

for f in flag:
ciphertext.append((key[0]*f + key[1]) % modulus)

print(bytes(ciphertext).hex())

# dd4388ee428bdddd5865cc66aa5887ffcca966109c66edcca920667a88312064


exp

仿射密码

exp是照着一个师傅的代码copy的

NewStarCTF公开赛week2密码学题目wp_ctf密码学题目_想要变强的47的博客-CSDN博客

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
import gmpy2

a = "dd4388ee428bdddd5865cc66aa5887ffcca966109c66edcca920667a88312064"

# 使用 bytes.fromhex() 方法将十六进制字符串转换为字节数据
byte_data = bytes.fromhex(a)

# 打印字节数据
print(byte_data)


# f1=ord('\xb1')
# #f2=ord('\x83') #因为'l'-'f'的值是6,6找不到模256的乘法逆元所以不能用f和l两个字母求解未知因数a
# f3=ord('\x82')
# f4=ord('T') #ord('T')=84,是g对应的密文

f1=ord('\xdd')
#f2=ord('C') #因为'l'-'f'的值是6,6找不到模256的乘法逆元所以不能用f和l两个字母求解未知因数a
f3=ord('\x88')
f4=ord('\xee')


m1=ord('f')
#m2=ord('l')
m3=ord('a')
m4=ord('g') #ord('g')=103,可以验证a=17,b=23时满足(103*a+b)%256 = 238 = ord('\xee')

a=(f3-f1)*gmpy2.invert(m3-m1,256)%256 #可以用'f'和'a'求解出a
print(a) #a=17
b=(f1-a*m1)%256
print(b) #b=23

# c="\xb1\x83\x82T\x10\x80\xc9O\x84\xc9<\x0f\xf2\x82\x9a\xc9\x9b8'\x9b<\xdb\x9b\x9b\x82\xc8\xe0V"

c="\xddC\x88\xeeB\x8b\xdd\xddXe\xccf\xaaX\x87\xff\xcc\xa9f\x10\x9cf\xed\xcc\xa9 fz\x881 d"
flag=''
for cc in c:
m=(ord(cc)-b)*gmpy2.invert(a,256)%256
flag+=chr(m)

print(flag)


为什么是dd、C、88、ee这样组合呢?

我的想法是你可以看原来的十六进制的数据 a = "dd4388ee428bdddd5865cc66aa5887ffcca966109c66edcca920667a88312064"

因为一个字节由8个二进制位组成,表示成十六进制就是2个十六进制位组成,那么就是两个一组表示一个字节

也就是dd、43、88、ee,即下面的dd、C、88、ee,写的时候要写成'',

f1 = ord('\xdd') 这行代码的作用是将十六进制表示的字节序列 '\xdd' 转换为对应的整数值,并将结果赋值给变量 f1

  1. \xdd: 这是一个字符串字面量,其中 \x 是表示后面两个字符是十六进制值的转义序列,dd 是两个十六进制数字,表示一个字节的十六进制值。在这里,\xdd 表示一个字节,其十六进制值为 0xdd
  2. ord(): 这是一个内置函数,用于获取给定字符的 Unicode 码点(整数值)。在这里,ord('\xdd') 将返回 221,因为十六进制 0xdd 对应的十进制值是 221
  3. ord("a") 会返回字母 a 对应的ASCII码:97

所以,f1 最终的值将是 221,因为它表示了字符 '\xdd' 对应的 Unicode 码点。

babyaes

main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from Crypto.Cipher import AES
import os
from flag import flag
from Crypto.Util.number import *


def pad(data):
return data + b"".join([b'\x00' for _ in range(0, 16 - len(data))])


def main():
flag_ = pad(flag)
key = os.urandom(16) * 2
iv = os.urandom(16)
print(bytes_to_long(key) ^ bytes_to_long(iv) ^ 1)
aes = AES.new(key, AES.MODE_CBC, iv)
enc_flag = aes.encrypt(flag_)
print(enc_flag)


if __name__ == "__main__":
main()
# 3657491768215750635844958060963805125333761387746954618540958489914964573229
# b'>]\xc1\xe5\x82/\x02\x7ft\xf1B\x8d\n\xc1\x95i'

exp

官方说法:

解密 flag 我们需要获取到 key 和 iv 的值,由条件:

key=os.urandom(16)*2

iv=os.urandom(16)

可知:key是32bytes,256bits ;iv是16bytes ,128bits

key^iv ,那么只有 iv 与 key 的低128位相异或,所以 key 的高128位是固定不变的。所以 xor 的高128bits,就是 key 的高128bits,进而可以得到 key 的所有值256bits。

之后 key 的低128bits,与 xor 的低128bits 相异或,所得结果就是 iv 的值了

得到 key , iv 后就可以直接用aes.decrypt()来解密了

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
# 这是我的exp,没成功,(后来发现是做出来了😡
from Crypto.Util.number import *
from Crypto.Cipher import AES
import os


out = 3657491768215750635844958060963805125333761387746954618540958489914964573229
# 转换成为字节类型
out =long_to_bytes(out)

flag_encrypted = b'>]\xc1\xe5\x82/\x02\x7ft\xf1B\x8d\n\xc1\x95i'

#高十六位是key的高十六位 并且key是按照16位进行重复 所以得到高16位就能得到整个key
key = out[:16]*2


# 把key的低十六位与out的低十六位做异或就能得到向量iv
iv = bytes_to_long(key[16:]) ^ bytes_to_long(out[16:])

#重新转换成为字节
iv = long_to_bytes(iv)
#创建aes解密器 需要秘钥key 解密模式 还有解密向量iv
aes = AES.new(key,AES.MODE_CBC,iv)
#使用解密器解密
flag = aes.decrypt(flag_encrypted)

print(flag)

# b'firsT_cry_Aes\x00\x00\x01'
# 然后flag{firsT_cry_Aes},测!

babyrsa

提示:很容易分解的n

main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from Crypto.Util.number import *
from flag import flag

def gen_prime(n):
res = 1

for i in range(15):
res *= getPrime(n)

return res


if __name__ == '__main__':
n = gen_prime(32)
e = 65537
m = bytes_to_long(flag)
c = pow(m,e,n)
print(n)
print(c)
# 17290066070594979571009663381214201320459569851358502368651245514213538229969915658064992558167323586895088933922835353804055772638980251328261
# 14322038433761655404678393568158537849783589481463521075694802654611048898878605144663750410655734675423328256213114422929994037240752995363595

exp

跟MoeCTF 2023 factor_signin 一题一样

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
from Crypto.Util.number import *
from gmpy2 import *
from functools import reduce

e = 65537
n = 17290066070594979571009663381214201320459569851358502368651245514213538229969915658064992558167323586895088933922835353804055772638980251328261
c = 14322038433761655404678393568158537849783589481463521075694802654611048898878605144663750410655734675423328256213114422929994037240752995363595


factor = '''P10 = 3831680819
P10 = 2338725373
P10 = 2370292207
P10 = 2706073949
P10 = 2970591037
P10 = 2923072267
P10 = 3654864131
P10 = 2463878387
P10 = 3939901243
P10 = 2804303069
P10 = 3207148519
P10 = 4093178561
P10 = 2217990919
P10 = 2794985117
P10 = 4278428893'''

factor = list(map(int,[i.split()[-1] for i in factor.split('\n')]))
phin = reduce(lambda a,b:a*(b-1),[1] + factor)

d = pow(e,-1,phin)
m = pow(c,d,n)

# print(bytes.fromhex(hex(pow(c2,d,n2))[2:]))


print(long_to_bytes(m))
# b'flag{us4_s1ge_t0_cal_phI}'

small d

main

提示: Michael J. Wiener 觉得很赞

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from secret import flag
from Crypto.Util.number import *

p = getPrime(1024)
q = getPrime(1024)

d = getPrime(32)
e = inverse(d, (p-1)*(q-1))
n = p*q
m = bytes_to_long(flag)

c = pow(m,e,n)

print(c)
print(e)
print(n)

# c = 6755916696778185952300108824880341673727005249517850628424982499865744864158808968764135637141068930913626093598728925195859592078242679206690525678584698906782028671968557701271591419982370839581872779561897896707128815668722609285484978303216863236997021197576337940204757331749701872808443246927772977500576853559531421931943600185923610329322219591977644573509755483679059951426686170296018798771243136530651597181988040668586240449099412301454312937065604961224359235038190145852108473520413909014198600434679037524165523422401364208450631557380207996597981309168360160658308982745545442756884931141501387954248
# e = 8614531087131806536072176126608505396485998912193090420094510792595101158240453985055053653848556325011409922394711124558383619830290017950912353027270400567568622816245822324422993074690183971093882640779808546479195604743230137113293752897968332220989640710311998150108315298333817030634179487075421403617790823560886688860928133117536724977888683732478708628314857313700596522339509581915323452695136877802816003353853220986492007970183551041303875958750496892867954477510966708935358534322867404860267180294538231734184176727805289746004999969923736528783436876728104351783351879340959568183101515294393048651825
# n = 19873634983456087520110552277450497529248494581902299327237268030756398057752510103012336452522030173329321726779935832106030157682672262548076895370443461558851584951681093787821035488952691034250115440441807557595256984719995983158595843451037546929918777883675020571945533922321514120075488490479009468943286990002735169371404973284096869826357659027627815888558391520276866122370551115223282637855894202170474955274129276356625364663165723431215981184996513023372433862053624792195361271141451880123090158644095287045862204954829998614717677163841391272754122687961264723993880239407106030370047794145123292991433

exp

[RSA2]4(Wiener)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 直接用xenny师傅的库
import libnum
from Crypto.Util.number import long_to_bytes
from xenny.ctf.crypto.modern.asymmetric.rsa import wiener
# e很大 wiener攻击
c = 6755916696778185952300108824880341673727005249517850628424982499865744864158808968764135637141068930913626093598728925195859592078242679206690525678584698906782028671968557701271591419982370839581872779561897896707128815668722609285484978303216863236997021197576337940204757331749701872808443246927772977500576853559531421931943600185923610329322219591977644573509755483679059951426686170296018798771243136530651597181988040668586240449099412301454312937065604961224359235038190145852108473520413909014198600434679037524165523422401364208450631557380207996597981309168360160658308982745545442756884931141501387954248
e = 8614531087131806536072176126608505396485998912193090420094510792595101158240453985055053653848556325011409922394711124558383619830290017950912353027270400567568622816245822324422993074690183971093882640779808546479195604743230137113293752897968332220989640710311998150108315298333817030634179487075421403617790823560886688860928133117536724977888683732478708628314857313700596522339509581915323452695136877802816003353853220986492007970183551041303875958750496892867954477510966708935358534322867404860267180294538231734184176727805289746004999969923736528783436876728104351783351879340959568183101515294393048651825
n = 19873634983456087520110552277450497529248494581902299327237268030756398057752510103012336452522030173329321726779935832106030157682672262548076895370443461558851584951681093787821035488952691034250115440441807557595256984719995983158595843451037546929918777883675020571945533922321514120075488490479009468943286990002735169371404973284096869826357659027627815888558391520276866122370551115223282637855894202170474955274129276356625364663165723431215981184996513023372433862053624792195361271141451880123090158644095287045862204954829998614717677163841391272754122687961264723993880239407106030370047794145123292991433

d, p, q = wiener.attack(n, e)
m = pow(c, d, n)
flag = libnum.n2s(int(m))
print(flag)
# print(long_to_bytes(m))

NewStarCTF 2023 week1
http://viper2383.github.io/2023/10/02/NewStarCTF 2023 week1/
作者
w1per3
发布于
2023年10月2日
许可协议