0xGame2025
[week1]
crypto
笙莲
直接按照原始操作反向
from Crypto.Util.number import *
import base64
import gmpy2
f1 = b'MHhHYW1le7u2063AtLW9MHhHYW1lMjAyNQ=='
f2 = "a3accfd6d4dac4e3d2d1beadd1a7bbe143727970746fb5c4bb"
f3 = "wqwwwqqaawwwaaqawqwawwwwaaawwwawaqqwwwqaqwwqwaaqwaqqaaawqqqaqaqwaaawwwqaqaaaaqawaqqqwwqqwaqwqwwwawawqqwwqqawqwaqwwawwqwaqqaqwaw"
f4 = "5787980659359196741038715872684190805073807486263453249083702093905274294594502252203577660251756609738877887210677202141957646934092054500618364441642896304387589669635034683021946777034215355675802286923927161922717560413551789421376288823912349463080999424773600185557948875343480056576969695671340947861706467351885610345887785319870159654836532664189086047061137903149197973327299859185905186913896041309284477616128"
def awaqaq_inv(num):
mapper = {'a':0,'w':1,'q':2}
out = 0
for i in num[::-1]:
out += mapper[i]
out *= 3
out = long_to_bytes(out//3)
return out
part1_bytes = base64.b64decode(f1)
part2_bytes = bytes.fromhex(f2)
part3_bytes = awaqaq_inv(f3)
part4_little_int = gmpy2.iroot(int(f4), 7)[0]
part4_bytes = part4_little_int.to_bytes((part4_little_int.bit_length() + 7) // 8, byteorder='little')
full_flag_bytes = part1_bytes + part2_bytes + part3_bytes + part4_bytes
print(full_flag_bytes.decode('gb2312', errors='ignore'))
# 0xGame{欢迎来到0xGame2025,现在你已经学会Crypto的基本知识了,快来试试更难的挑战吧!}
# C~Fk劲4{愎芸翎
简单的四位爆破
from itertools import product
from Crypto.Util.number import *
from hashlib import sha256
from pwn import *
import string
context.log_level = "debug"
io = remote("nc1.ctfplus.cn", 28915)
alphabet = string.ascii_letters+string.digits
x_list = product(alphabet,repeat=4)
def find(hash_str_low,hash_out):
print(f'{hash_str_low}\n{hash_out}')
for x in x_list:
x = "".join(x)
if sha256((x+hash_str_low).encode()).hexdigest() == hash_out:
return x
return None
rev = io.recvline().decode().replace("\r","").split("==")
hash_str_low = rev[0].replace("[+] sha256(XXXX+","").replace(")","").strip()
hash_out = rev[1].strip()
x = find(hash_str_low,hash_out)
io.sendafter(b"[-] Give me XXXX:",x.encode()+b'\n')
rsa = io.recv().decode().split("[+]")
n = int(rsa[2].replace("n = ",""))
e = int(rsa[3].replace("e = ",""))
c = int.from_bytes(bytes.fromhex(rsa[4].replace("c = ","")), "little")
m = pow(c,inverse(e,n-1),n)
print(long_to_bytes(m))Diffie-Hellman
没有任何输入限制,直接输入数字1,得到的s也是1
from Crypto.Cipher import AES
from Crypto.Util.number import *
from hashlib import sha256
s = 1
key = sha256(long_to_bytes(s)).digest()
enc = bytes.fromhex("232c18be44b4ec9c67f7f940488aa1ed6dda78c426429400f95c07355882a9986cdb04894e7c01715b0e6f886912259f")
cipher = AES.new(key, AES.MODE_ECB)
enc = cipher.decrypt(enc)
print(f"Decrypted Flag: {enc.decode()}")EZ_rsa
p,q只有256位,到factordb查表直接得到
from Crypto.Util.number import *
p = 60979507724530093051797511853954365018147917052474373616663462193464369184711
q = 86718689499194998339746379891242621495538434539975542252458947218776577824467
n = 5288062996177288067805240670327919739339874127477405321607402348589147491552053048231920112750216696782518281218048178087877077018108705271341382858124037
c = 2454797328903978848197140611862882439826920912955785083080835692389929572917351093371626343669582289242212514789420568997224614087740388703381025018563979
e = 65537
assert p*q==n
print(long_to_bytes(pow(c, inverse(e,(p-1)*(q-1)), n)))
# b'0xGame{F4ct0rDB_1s_usefu1_r19ht?}'Vigenere
简单维吉尼亚,直接加号变减号
from string import digits, ascii_letters, punctuation
key = "Welcome-2025-0xGame"
alphabet = digits + ascii_letters + punctuation
cipher = "WL\"mKAaequ{q_aY$oz8`wBqLAF_{cku|eYAczt!pmoqAh+"
def vigenere_decrypt(ciphertext, key):
plaintext = ""
key_index = 0
for char in ciphertext:
bias = alphabet.index(key[key_index])
char_index = alphabet.index(char)
new_index = (char_index - bias) % len(alphabet)
plaintext += alphabet[new_index]
key_index = (key_index + 1) % len(key)
return plaintext
print(vigenere_decrypt(cipher, key))
# 0xGame{you_learned_vigenere_cipher_2df4b1c2e3}2FA
随便输入一个用户名注册一下,使用微信“腾讯身份验证器小程序”扫码得到令牌,然后登陆,[G]到flag
Login Machine
[R]egister
[L]ogin
[G]et Flag
Choice: R
Username: a
█████████████████████████████████████████████
█████████████████████████████████████████████
████ ▄▄▄▄▄ █▀██▄ ▀▀ ▀▀▀▄▀▀▀ ▀▄▀ █ ▄▄▄▄▄ ████
████ █ █ ██ █▄█▄█▄██▄█ ███ █ ▄ █ █ █ ████
████ █▄▄▄█ █▄ ██ █▄█ █ ▀▄▀ ▄▄█ █ █▄▄▄█ ████
████▄▄▄▄▄▄▄█▄▀ █▄▀ ▀ ▀ ▀ █▄█▄▀▄█ █▄▄▄▄▄▄▄████
████▄▀ ▀ █▄▀▀▀ ▀▄▀▀ █ ▀██ ███▄▄ █▀▀ ▀█▄▀████
████▀▄ ▀ ▀▄▀▄▄▀▄ ▄ ▄ ▀▀▀█ ▄▄▄▀▄▀▀▄▀█▄ ▄████
████▀ █▄█▀▄▄ ▀▄█ ▄ ▀▄▄▄ ▄█████▄▄▀ ▀█▀▄ ████
████▄▄ ██▀▄▄▀ ▀█▀ ▀▀ ▄▄█▄▀▄▀▄▀ ▀▄ ▀▀▀█▄▀▀████
████▀ ██▀▀▄█▄ ██▄ ▀█▀▄▀█ ██▀ ▀▄ ▄▄ ▀██ ████
██████▄ █▀▄ ▀▄▀▀ ▄▀█▀ ▄▄▀ ▄▄ ▀ █▄▀▀▀ ▄▄ ████
████▄▀ ▄▄▄▄ ███▀█▀█▀▀▀▄█▀▄ ▄█ ██▀▄ █ ▄ ▀████
████▀ ▄▄ ▄▀█▄ █ ▄▀▄█▀▄██▀██▄ ▀ ▀ ▀ ▄▄ █████
████▄█ ▀▀▄▄▀██▀█▄ ▄▀ ▀▄██▄▄██ ▀█ ▀█▄ ▀▀ ████
████▄▀ ▀▄█▄▄▄▀▀▄▀▀█▄ ▀ ▄ ▀ █▀ █ ▄▀ █▄ ████
████▄█▄▄▄█▄▄ ▀ ▀ ▄▄▄▄█ ▀▄█ ██ ▄▄▄ ███ ████
████ ▄▄▄▄▄ ███▄ ▀█▀▀ ▄█▀▀▄ ▀▀██▄ █▄█ ▄▄█▄████
████ █ █ █▄█▀████▀█▀███ ██▄ █ ▄▄ ▀ ████
████ █▄▄▄█ █▄ ▀ ▀█▀▀█▀▄ ▄ █▀▀▄█▀█ ▄▀▀▀▄████
████▄▄▄▄▄▄▄█▄▄▄▄▄▄██▄▄▄█▄▄█▄▄▄█▄▄█▄▄▄██▄▄████
█████████████████████████████████████████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
Choice: L
Verification Code: 849261
Login successful!
Choice: G
0xGame{e1efd3c2-33e2-4afd-a5c4-8fa1f2eb1ac2}
Choice:Vigenere Advanced
明文空间有限,并且给出了加密算法及密钥,可以正向爆破。
不过结果有些多。。。得人工识别可能的组合,还好明文不是很长()
from string import digits, ascii_letters, punctuation, ascii_lowercase
import numpy as np
key = "QAQ(@.@)"
alphabet = digits + ascii_letters + punctuation
test = ascii_lowercase
cipher = "0l0CSoYM<c;amo_P_"
def vigenere_decrypt(ciphertext, key):
plaintext = []
key_index = 0
for i in range(len(ciphertext)):
tmp = []
for j in alphabet:
if (vigenere_encrypt(j, key_index) == ciphertext[i]):
tmp.append(j)
key_index += 1
plaintext.append(tmp)
return plaintext
def vigenere_encrypt(p, key_index):
k = alphabet.index(key[key_index%len(key)])
c = alphabet.index(p)
new_index = ((c + k) * c) % len(alphabet)
return alphabet[new_index]
res = vigenere_decrypt(cipher, key)
for i in range(4):
for j in range(len(res)):
try:
print(res[j][i], end='\t')
except:
print(' ', end='\t')
print('\n')
得到:0xGame{excellent}
misc
签到-0xGame
签到:0xGame{🎉👋🕹️2️⃣0️⃣2️⃣5️⃣0️⃣❎🎮🎯🏟️🥳🎊⚽😄}
ez_shell
dep-01ad5429-1a2a-4731-b5fa-916964846008-86d6c98ddd-68wjq:~$ whoami
hacker
dep-01ad5429-1a2a-4731-b5fa-916964846008-86d6c98ddd-68wjq:~$ pwd
/home/hacker
dep-01ad5429-1a2a-4731-b5fa-916964846008-86d6c98ddd-68wjq:~$ ls -a
. .. .mysecret
dep-01ad5429-1a2a-4731-b5fa-916964846008-86d6c98ddd-68wjq:~$ cd .mysecret/
dep-01ad5429-1a2a-4731-b5fa-916964846008-86d6c98ddd-68wjq:~/.mysecret$ ls
flag1.txt
dep-01ad5429-1a2a-4731-b5fa-916964846008-86d6c98ddd-68wjq:~/.mysecret$ cat flag1.txt
It_is_funny_right?
dep-01ad5429-1a2a-4731-b5fa-916964846008-86d6c98ddd-68wjq:~/.mysecret$ sudo su
/home/hacker/.mysecret # cat /root/flag2.txt
You_hacked_me!!!
/home/hacker/.mysecret #ezShell_PLUS
welcome@dep-6fb7fc97-e3b0-44a2-b56a-76e9e8152014-7bb86cfc49-d8jdd:~/challenge/files$ sha256sum ./*
a381f76d64f92ae5dddb3e42577829e7e6a587d088d12ffcd18ffbff0c918c22 ./05f37de6793bb06a.dat
824d5b3df01502d7110438a23a3290ea14ff6ce98c6ba556b57edc0a84e0fd48 ./09bb2575a66d95cc.dat
466b4f5a37bde64825b946dbc7446be650a856023f90e05f6dc9e4968e509ac1 ./0ab1092c797e7dad.dat
c6bf279333248c23a227826c4d65fe37b834a0c9067d6205d6af2d5edb7a2964 ./0d20d055e6c67b8d.dat
f93e417cbe2758aee6098480cc783dcc1420913c123233ff3197d1bff265aeed ./0e94781b057281f8.dat
d56bfabd912feaf2737e2b25186de0b4173b4f9ad4b88b97172b1e38158ec6be ./140d8bd39e6bc726.dat
56805414d123deb36aef46faf22eede343375aaf3d00e62b097dbc38550445d8 ./1850be4792187008.dat
da53a4108814f73b232e24a949e88e407b218fd91e5c7ebde66bce4a061bae63 ./1967f63b978a7469.dat
d3d82451a870a0f134317c42d6c08d36d68b90086ae0f2c79a6501da48073380 ./22021e3839cc9213.dat
8975746eac3f77f700035ea5169b38fdae24b721b4251bd6e569c6f10099d986 ./25931e7369c94b78.dat
11c1e758ab1ca0a46da86207a6f1405708138200bae02e39cbb5b0096e7975da ./27bb7c729074632b.dat
4c6c749dafc87c37ee729a17cb588ead0efb946ef2b1c33234ffe997a76b3f35 ./29ca267e9b349973.dat
1f8719d40ccf5801683b451937acb5f79b2129bcf1e6e0c10f2d5437cdc0aa66 ./2b556eada33e8196.dat
0d2558b05cbb272cd934f554e53d9bd59f79b999f01953334cddb1e46a8ff04e ./2f68c7d139af2540.dat
563903a15e1949461a355fd21c64e1072ad57be4172d45526acfccfcb0efa906 ./3abc55eeb6632601.dat
575809ee24053a9cd112a0afd3ef30ca596561af9c6b5267108a8c02aef3677e ./3b6bd7f7d3609199.dat
c3532cac47ce974bbbdc7cfeb1d158b330d1c828324cd87762f07ff20ea60d3d ./3e6c0f74e4a7274f.dat
955ddf6fb4f4e562dc8b5cf83a7a0b612b47a8d125e610e0130e70fbea14b440 ./4019ad1293ce8d41.dat
aeefb7cebef3493d1ba05dbf5bbc44e9a739eab2907b408e84adbcfe622914ae ./416020357f38e531.dat
1d325597e2ab58679ef51db2bb2a1cdaac3f3ca2cc4dc89d3965b4b3013b3fde ./4601bd6ea716b994.dat
81f900efba0cb3497787072721b944ccace97eb5695c65fe29f93d45b4c2d905 ./4620d45f5e7edc88.dat
f1bc8add13770631f4739cd3c9d4c6d2983e8a4934bb6d2edf3c02a0b45f07e9 ./48c1e3f6ff5a5891.dat
8ccd0e1ec74b295ab59ea3f3c50ed29e563086867f5efeeec734f4a5e6a271eb ./4a1f583b5c310c1e.dat
983d0e25f17579496297fe14911eb50b4daabfb96d02bcf3f730d43e1b55c558 ./4d4be3e260e1d097.dat
031b02c77931448f3535efe1166256ce2d324fe2462d763f40741e5d409856d3 ./4fa1143e67b59089.dat
76293992c0b8c15b1fd3d1802cf0ce469596a414507ca0fd169600a4ea761bdd ./54281a951ce69760.dat
3d174be9eb9844aaad04000a1724f67259115fed2fd752a235e9d9bee9b57e4c ./54afed71a9c0a018.dat
aee885741fd06d432967a1f4a29f0237d4b43b458c82c005cd5844ed43aa9c9a ./54b8a0cc8005d7b7.dat
869a53493ff642150f70218a8e842e2172288cb4c5437381aff056af2b3b10e9 ./5539f152f12e9683.dat
586d9d55d41a1bc7c7c0c882c2a88f1732649c1e87ad3e4c94303205399790f4 ./5a22868a141ef543.dat
ec2b600f339bfe8ba92596a87ad2c44ba7e6991bd8858610bde1eaeec95f2bcd ./5dae1a69fb84ab58.dat
6d26256447502f50fc48e58574b82684134a37796a9b5fc86f157a79b3e54ae7 ./644eca357324878e.dat
179ae10871dd8863a57c41e62c86196e9b26227b782c263b0b300f76fd8c37c7 ./663b518ce7fb4397.dat
03d4b0d2040b4323c1ed389dff7ab949b10657fec4daa740be99f9ed7ab40ba8 ./69c6d66423cc604d.dat
29f2dd0ed0723eb2f9d24d927994a040bc47e7a6ec8d438283378d44bfc1167e ./6cc86146892477f4.dat
04e2a68b62a21474df30dce8ba54d037fd713f39211e74e65a4db6657c53c9be ./6d778958f9862b97.dat
cab3177f7a50f0092f75ca3be250511a31af84c031a880163e3fe741f158827b ./6e615e9eeced0ab0.dat
e3cb388abbc4cd5a00233d768db0a91f87974ccde7025580c072ed17dd704f49 ./6ed5dbe82a7674f7.dat
628184985aae65f1bcd1d08b20cfdf67118df86952e8846d8f567ce747a86ace ./733769a1c2e404ab.dat
ce3264b7d59617336acf3247e1ad4f7ba2780af4214befb32bb84331af149bd0 ./77e27e625c301836.dat
915b3989a30f63c794fc390d3dcdd6977f116766dea79011f59d36043702507e ./7ad4a4371468c79e.dat
8a5096511f5008acda317150a4922c87c5a0a3e9885f876def2c0babccc987e6 ./7c2152c7337ab4d0.dat
9c08250173029d79392733cd8229175e53c1c68799cd432ec66defac40c4aa16 ./7de537b6ff244c21.dat
f7a86d7e48873a9ebc8b343f6857f78c27692c7d401bee2596945d2dc59abd1a ./7ebf8b6bd70b7975.dat
ec03e95c07c33c1dad41043e2fb3151a1e3c5b796fe45e1b1752c5d00aa94c93 ./885bb152969bf9cb.dat
73f468eaa0f99d28c85c0c136b06377b285168f35c1d84133a108b145605e6f3 ./89ea292fc35b8eef.dat
486ebc3584afe82534ed3f64dae1fdf48697d472acf461ffb12a76427ae4487d ./8c1e67c0baa7906f.dat
e969652ba173c2eee3f9a1b33f1ac17e414b103fc641895f43941705afea01d8 ./8d8a755e5c4512d9.dat
04dd144059e84bbfadaa1c655743978d320cbd6d41a320b6bd6185d1a1cf6ab1 ./8e80e4145f5d26b6.dat
95c71bd5a45d431f2874ea1361f0940dd1f5f9bb9c7e700f8a178860f434ae83 ./8e84d001a472cffe.dat
eb4370555d0cf7e4ca16e5f6ccd1d56bd06b555a597550322d530c13ee5f77be ./91e0c00a4d37cb0e.dat
e037e1dcf16f6ed921aa77eed83ad697c019a982aff83da6d94c0b9875f64974 ./9313af290106451f.dat
e322defd2f7c9491f54e51434b36fe47d0d16c3a44c021548a74ad16e8669c58 ./93ad187033d8b9fd.dat
9eae1551fd0d92923e14610d2c64bfa5a6eee6738ff078b1fc982aea492ea2f9 ./947658d17f1ebc13.dat
b1f93933afff2fb16ab134ff4056c28cfce59548f281a9e46323f934bc6e72e0 ./94b06a48b1f0f3f4.dat
738db90ed4680c88e7cd49200cc21ca91cc31e634cd5d6ebc6400063113a5d82 ./9b7b836074225a42.dat
d92e4e3228aa8d8adf0e1511979af840511d277c236247c6ccb81106e861a067 ./9c4301682657876c.dat
11ec16b65b35e432a52697dc511d179b8df435dd28bf4ddf29019172a4b5f555 ./a0e735375c020e16.dat
e8c20bc3e1525bece66eb674acc7732e8c8d7503e11ed0870ab40a03c3bf6fc4 ./a49a6182571f9498.dat
4c1cb7b8cc51f11a4575cd073444e4f9e5898e5660d7e6773c6688e092bcecc2 ./a4ae020f66824cef.dat
c930f1a40e747b48c7a04ce06d6588a13cc320000f26f7ef7e917de10606aeb6 ./ace5f70219aa1d47.dat
92fbaf1fcd956d85fc4b1c0cd5e6789e411f12c7b27886bdc69c6452c8fe87be ./adf55f519fee9c83.dat
fe4cd86708d67da46c94360a6b46df23c80a86d86a3d222aa1f71166c2c9ee1c ./af7a788602ae7b59.dat
47a3bae31c5498205de547c60ee3ee0787e97f6631a85a053d7fdd96c22008b5 ./b05d59cd5be93b85.dat
58a725bd9b48b288bfa2536f9d16067e7767fe5d1b014c5063f12440c8dcf520 ./b17a1c79d807f426.dat
e021dc59791aea3cd7ac966c490cc9348a14a2fee8687123fc7d4e914099adf1 ./b42d9affdfba94e8.dat
a3168362f34b63e6100c46ff130fffc90f247ea5906381e65a686f1999f99c1c ./b55d1fb685711b20.dat
7cfe809de1de4d4b39f73b280e0f3631034b5164a8cb4fc915922453e973e947 ./b63424ff5ceee73a.dat
42bc4addfd68cd6915907b9c5fdaa981b700d5ef4372d741eeceadb3ac48b45d ./ba2b54d86715507a.dat
42460dc9801170d42d847fb06c9966a44af5617b490e9a088fa5d906dd183523 ./ba5e1edcf921c8aa.dat
e215c2083502ac47d482aee87d9fb7923d54a382c7f5364dd5038d745955373e ./bb0772cb3443362d.dat
64dd55164078a7cd31baacd5f08a0bb89aa153d4f662e7b1f3f0f1ff2ca0e0e1 ./bf19966d79922950.dat
9f3a352700df45aa0a2dac5fa7df8609232dc9c8f74e674588ad14daadea9c4d ./c0700ec7b222b3c7.dat
d6fd2e3cba535b2fbde644e5635c21bfa0a11143d57ee331a6070e0963f7276b ./c21c69c96363248c.dat
362d42729fbedd08df6a6d3f0799ea6dd6493efa6f394ccc368c9ae67c15a632 ./c2fdd3fef10c55f4.dat
70c181d8315400802dda2eb417db5b4b1bfbc0fc1233deb7a265108477c62067 ./c4399d90d91d920c.dat
a35f6ac52b6ec227410fdce1118975cc1873cc4e9b6a478bffde619318935a0e ./c54ad03e54d87a90.dat
adb8d75274f6123e33661b3ce4f53b599c349deb856e3c58659da8dcf99f6d11 ./c6e5f9aceab0fbb2.dat
35fe71a0ba99e5de695a192a354d84b4e067c96012c09517f063e22319df3842 ./ca8ae4beff87957e.dat
d1fad4f6d6ee60f2826d635825a609cd5987e94897b389a8218c979151de1871 ./cab8dc26e2540641.dat
c65c62544baffb22f625bae7a98324ee37cb3a80e838cb192fef096abc368a62 ./ccee8fd3efec83ba.dat
d3a64829d557ae640ce5f8610d9883b6de1c62f189ad40615256a23b02575e4b ./ceaa86c1881b0909.dat
a8bcdb7611b31013a989362af643c9fd9f6c9dd1e5f32097f9e32df808405f7a ./cef86f1e8dbd593b.dat
c083fd799936489337c875321bd5fa6bd31e02c7e34c6d9d92addcb6f8cf0bc2 ./d0ffebe12036c4b1.dat
bc28e21b1f5e333c41942f9895dbe41f389e6b7c9456f09e87811a6d82db912b ./d4086b60d23eb8ff.dat
f3e65c8b4396bd8dcd686928350e5f6cda179b6939435a13b3f63532eec06723 ./d5ffa6cc519c3d75.dat
40d24948c916e506d32eb7f9d0e9788b9c8d985baf07dd7d00ed1bec2289b902 ./d910eab0b607606d.dat
db2b45706ea8a9896d29606f4a3c2180e3b6275c0e612eb8ce3212b1c212c6c5 ./da5c05967f4d97ee.dat
87e38303ff99b8b4855f80bfec8126b4a6711a9f9ecb600cddbae474b7133ec0 ./df5e504d62ce4ab8.dat
838798f15264bcbbd4ffae82624803b4a0df92eb39826c01cf08b666c2df2772 ./e1372789f854455b.dat
727215c3922999535c711bef1999de4836f8feb0e338fe31c34fbf5ac4bf4462 ./e5a8e7003ef7372c.dat
d1c7d2b76eea585ccfe1fd8e99712058acfc7494369428789efb129973617694 ./e902f9052112f6da.dat
3c184521ab9a768edc66679b943eeabc77fc3cb4a84cc152007b36e46e7ced93 ./e95beba415b991a1.dat
7ed47f51daa491f431e8c0105efc3eb9a4228f03bec4c9d60628d520d50d6e0d ./ebe8e3bb07a045e2.dat
6ed4a2348141e7adfb779423cf5ad1a02ada38da7e17284e3df0714213aab69b ./eec20c96a70c7e5c.dat
6f1455c6575300d6485480f47a185a27334fb6e4c54523a6322d7bbbdeae8e19 ./ef6d6b794f39bff3.dat
eb02a6cd0aefbe902faf06938c89194e39e4fe4ec806d938db644e09e3873921 ./f17fc14e51d0b0a8.dat
b935f19e6d3ee2957d327c8112baa1c7be838808ee4bba90d0f51b044ad4f9e0 ./f28790035aa5a0e7.dat
2ee31c1542e1fec77bf506f7c1dd829abca9c2c518be73aebbee41b50d738710 ./f6639f766b69dfd0.dat
0572a2e2316f26b5e5f6093faedd5a6823a0626e858ea6eb4c578b19cb3da11b ./f6afbcf16e20a1d0.dat
0c13f6412136e9ac0898e151c9e520d83c04d8243e2ec92ba3b55e59f9d991ea ./fb3131c4822fa701.dat
welcome@dep-6fb7fc97-e3b0-44a2-b56a-76e9e8152014-7bb86cfc49-d8jdd:~/challenge/files$ cat ../hash_value
29f2dd0ed0723eb2f9d24d927994a040bc47e7a6ec8d438283378d44bfc1167e
welcome@dep-6fb7fc97-e3b0-44a2-b56a-76e9e8152014-7bb86cfc49-d8jdd:~/challenge/files$ ../decrypt.sh ./6cc86146892477f4.dat
0xGame{Welc0me_to_H@ckers_w0r1d}[week2]
Crypto
寒芒
AES加密以16个16进制位为一块,ECB加密出的32个16进制为,flag长度为44,以48作为块节点。依次爆破一位。比如:先发送47个'A',第48位实际为flag的第一位,爆破对比即可找到。
有35s的限制,要按照uuid4的格式和已经确定的flag尽可能减少请求次数:0xGame{********-****-4***-X***-************}(X处只能为:a,b,8,9)
不过后面发现,开一次容器的flag是确定的,完全可以分多次进行😅
from pwn import *
import random
from tqdm import trange
strs = list('abcdef0123456789')
random.shuffle(strs)
io = remote('nc1.ctfplus.cn',27013)
def attack(str_tmp):
payload = bytes.hex(str_tmp.encode())
io.sendlineafter(b'[-] Continue encryption(y/[n])?',b'y')
io.sendlineafter(b'[-] Plaintext(in hex):',payload.encode())
rec = io.recvline().decode().strip().split(':')[1][:96]
return rec
know = '0xGame{'
for i in trange(36):
if i in [8,13,18,23]:
know += '-'
continue
if i == 14:
know += '4'
continue
str_tmp = 'A'*(40-i)
tmp = attack(str_tmp)
for c in strs:
rec = attack(str_tmp+know+c)
if rec == tmp:
know += c
break
know+='}'
print(know)[+] Opening connection to nc1.ctfplus.cn on port 27013: Done
100%|██████████████████████████████████████████████████████████████████████████████| 36/36 [00:25<00:00, 1.39it/s]
0xGame{85a3bddb-825a-43dc-a051-56ce7ce826a3}
[*] Closed connection to nc1.ctfplus.cn port 27013Ez_ECC
s的范围为1到2的40次方,使用BSGS后大概2的20次方,可以直接爆破
from Crypto.Cipher import AES
from hashlib import sha256
from math import ceil, isqrt
from collections import defaultdict
p = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff
a = 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc
b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b
Px = 96072097493962089165616681758527365503518618338657020069385515845050052711198
Py = 106207812376588552122608666685749118279489006020794136421111385490430195590894
Qx = 100307267283773399335731485631028019332040775774395440323669585624446229655081
Qy = 22957963484284064705317349990185223707693957911321089428005116099172185773154
P = (Px, Py)
Q = (Qx, Qy)
O = None
ciphertext = b':\xe5^\xd2s\x92kX\x96\x12\xb7dT\x1am\x94\x86\xcd.\x84*-\x93\xb5\x14\x8d\x99\x94\x92\xfaCE\xbd\x01&?\xe1\x01f\xef\x8f\xe3\x13\x13\x96\xa6\x0f\xc0'
def inv_mod(x):
return pow(x % p, p-2, p)
def point_add(Pt, Qt):
if Pt is None: return Qt
if Qt is None: return Pt
x1,y1 = Pt; x2,y2 = Qt
if x1 == x2 and (y1 + y2) % p == 0:
return None
if Pt != Qt:
lam = ((y2 - y1) * inv_mod((x2 - x1) % p)) % p
else:
lam = ((3 * x1 * x1 + a) * inv_mod((2 * y1) % p)) % p
x3 = (lam * lam - x1 - x2) % p
y3 = (lam * (x1 - x3) - y1) % p
return (x3, y3)
def point_neg(Pt):
if Pt is None: return None
x,y = Pt
return (x, (-y) % p)
def point_sub(Pt, Qt):
return point_add(Pt, point_neg(Qt))
def scalar_mul(k, Pt):
if Pt is None or k % p == 0:
return None
if k < 0:
return scalar_mul(-k, point_neg(Pt))
R = None
Q = Pt
while k:
if k & 1:
R = point_add(R, Q)
Q = point_add(Q, Q)
k >>= 1
return R
def bsgs_ecdlp(P, Q, bound=1 << 40):
m = 1 << ( (bound.bit_length() + 1) // 2 )
baby = dict()
R = None
for j in range(m):
baby[R] = j
R = point_add(R, P)
factor = scalar_mul(m, P)
cur = Q
for i in range(m+1):
if cur in baby:
j = baby[cur]
s_candidate = i * m + j
if s_candidate != 0 and s_candidate < bound:
if scalar_mul(s_candidate, P) == Q:
return s_candidate
cur = point_sub(cur, factor)
return None
s = bsgs_ecdlp(P, Q, bound=1<<40)
key = sha256(str(s).encode()).digest()
cipher = AES.new(key, AES.MODE_ECB)
pt = cipher.decrypt(ciphertext)
print(pt)
# b'0xgame{ECC_1s_4w3s0m3_but_n0t_perf3ct}\n\n\n\n\n\n\n\n\n\n'Ez_LCG
RNG的参数全部给出,可以直接使用,能够推出a,b的候选值,随便选择一个加密后的flag,对候选值进行验证,得到可能的(a,b)组合。逆向LCG便可得到flag。
验证时,LCG公式:E=akx+ba−1ak−1(modM)可改写成:b=(E−akx)ak−1a−1(modM))更易于使用。
def rng_next(state, coeffs, MOD_RNG=2 ^ 20):
res = 0
x = state
powx = 1
for c in coeffs:
res = (res + c * powx) % MOD_RNG
powx = (powx * x) % MOD_RNG
return res
def rng_states(coeffs, seed, n, MOD_RNG=2 ^ 20):
s = seed % MOD_RNG
states = []
for _ in range(n):
s = rng_next(s, coeffs)
states.append(s)
return states
def fast_find_candidates(coeffs, seed, encs, max_k=1024, M=2 ^ 32 + 1, MOD_RNG=2 ^ 20):
states = rng_states(coeffs, seed, 2200)
a_candidates = set(states[2 : 2 + max_k])
b_candidates = set(states[3 : 3 + 2 * max_k])
E0 = encs[0]
results = []
for a in a_candidates:
if gcd(a, M) != 1:
continue
try:
inv_a_minus_1 = inverse_mod(a - 1, M)
except ZeroDivisionError:
continue
a_pow = 1
pow_table = []
for k in range(1, max_k + 1):
a_pow = (a_pow * a) % M
try:
inv_apow_1 = inverse_mod(a_pow - 1, M)
except ZeroDivisionError:
continue
pow_table.append((k, a_pow, inv_apow_1))
for k, a_pow, inv_apow_1 in pow_table:
for x in range(256):
b = (E0 - a_pow * x) % M
b = (b * (a - 1) * inv_apow_1) % M
if b < MOD_RNG and b in b_candidates:
results.append((a, b, k, x))
return results
coeffs = [886747, 469835, 54101, 634688, 666122, 144788, 623463, 178170, 886206, 859869]
seed = 0
encs = [
1879191300,
4069177573,
3388030621,
3253785321,
3820374785,
1997597844,
3301355831,
1788486891,
1539656978,
3466632440,
1232277188,
3335654723,
3590966179,
3390738879,
4172129715,
4187722236,
1074917839,
594488205,
1461103620,
3459342087,
1759529546,
177244655,
3777461715,
1069941831,
1460358693,
4244360931,
666693712,
204613855,
2356716862,
1270168282,
3243048969,
2488540050,
4273755952,
2812098892,
2792891923,
2594380906,
]
cand = fast_find_candidates(coeffs, seed, encs)
print(f"[+] 找到候选数量: {len(cand)}")
def verify_candidate(a, b, encs, max_k=1024, M=2 ^ 32 + 1):
try:
ainv = inverse_mod(a, M)
except:
return None
flag_bytes = []
for E in encs:
cur = E
found = None
for _ in range(max_k):
cur = (ainv * (cur - b)) % M
if 0 <= cur < 256:
found = cur
break
if found is None:
return None
flag_bytes.append(found)
return bytes(flag_bytes)
res = set()
for a, b, k, x in cand:
res.add(verify_candidate(a, b, encs))
print(f"[+] 解码成功数量: {len(res)}")
for r in res:
print(b"0xGame{" + r + b"}")
"""
[+] 找到候选数量: 1
[+] 解码成功数量: 1
b'0xGame{fa87373b-f4a8-4ae0-8146-5c29e476bdb9}'
"""LFSR
给出了256个连续状态,并且状态生成:
def next(self):
output = 0
for i in range(self.Length):
output ^= self.state[i] & self.mask[i]
self.state = self.state[1:] + [output]
return output就是GF(2)上的加法,直接构建方程组求解
"""SageMath version 10.7"""
from Crypto.Cipher import AES
random1 = 79262982171792651683253726993186021794
random2 = 121389030069245976625592065270667430301
ciphertext = b'\xb9WE<\x8bC\xab\x92J7\xa9\xe6\xe8\xd8\x93D\xcc\xac\xfdvfZ}C\xe6\xd8;\xf7\x18\xbauz`\xb9\xe0\xe6\xc6\xae\x00\xfb\x96%;k{Ph\xfa'
data = [int(i) for i in bin(random1)[2:].zfill(128)] + [int(i) for i in bin(random2)[2:].zfill(128)]
A = Matrix(GF(2), 128, 128, [[j for j in data[i:i+128]] for i in range(128)])
b = vector(GF(2), [int(i) for i in bin(random2)[2:].zfill(128)])
res = A.solve_right(b)
mask = int(''.join([str(int(i)) for i in res]), 2)
print(mask)
# 327376555627056524843299464289595904234
cipher = AES.new(mask.to_bytes(16, 'big'), AES.MODE_ECB)
plaintext = cipher.decrypt(ciphertext)
print(plaintext)
# b'0xGame{124ab3f1-4c3e-4d2a-8e6f-9b5e6c7d8f90}\x04\x04\x04\x04'PolyRSA
题目为一个在R=(Z/nZ)[x]/(x8−1)商环(n=pq)多项式RSA问题。
解决思路为:分别在(Z/pZ)[x]/(x8−1)和(Z/qZ)[x]/(x8−1)下,对(x8−1)分解的每一个子项进行解密,然后逐层CRT回R上,得到m,即:
"""SageMath version 10.7"""
from Crypto.Util.number import *
p = 211381997162225534712606028333737323293
q = 291844321073146066895055929747029949743
e = 65537
R_.<t> = PolynomialRing(Zmod(p*q))
R.<x> = R_.quotient(t**8 - 1)
c = 40882135200347703593754473549436673146387957409540306808209934514868940052992*x^7 + 13673861744940819052324430973254902841262867940443611208276249322420769352299*x^6 + 14825937682750201471490037222143248112539971745568733623844924679519292569979*x^5 + 38679688295547579683397975810830690182925250157203662993481664387755200460738*x^4 + 48188456496545346035512990878010917911654453288374940837147218298761674630209*x^3 + 573073037892837477865699910635548796182825197336726898256762153949994844160*x^2 + 33191976337303879621137795936787377133622652419928253776624421127421475322069*x + 46680445255028101113817388282005859237776046219558912765486646689142241483104
coeffs = c.lift().list()
n = p * q
def ms_poly_prime(prime, coeffs, e):
G = GF(prime)
R.<x> = PolynomialRing(G)
mod_poly = x**8 - 1
c_poly = sum(G(int(coeff))*x**i for i, coeff in enumerate(coeffs))
factors = (mod_poly).factor()
components = []
for g, _ in factors:
deg = g.degree()
order = prime**deg - 1
K.<a> = GF(prime**deg, modulus=g)
C = sum(K(int(coeff))*(a**i) for i, coeff in enumerate(coeffs))
d = inverse(e, order)
m = C ** d
coeffs_list = m.polynomial().list()
if len(coeffs_list) < deg:
coeffs_list += [0] * (deg - len(coeffs_list))
rep_in_R = sum(G(int(coeff))*(x**i) for i, coeff in enumerate(coeffs_list))
components.append((g, rep_in_R))
mods, reps = [g for g, pr in components], [pr for g, pr in components]
ms_poly_prime_R = crt(reps, mods)
ms = [int(ms_poly_prime_R[i]) for i in range(8)]
return ms
ms_poly_p = ms_poly_prime(p, coeffs, e)
ms_poly_q = ms_poly_prime(q, coeffs, e)
ms_poly_n = [crt([int(ap), int(aq)], [int(p), int(q)]) for ap, aq in zip(ms_poly_p, ms_poly_q)]
flag_bytes = b"".join(long_to_bytes(int(m_poly_n)) for m_poly_n in ms_poly_n)
print(flag_bytes)
# b'0xGame{D0_y0u_l1k3_RSA_w1th_p0lyn0m14l_r1ngs?}\x00\x00'CCB
CBC模式的关键在与明文块加密前与前一密文块或者IV向量异或了。这里可以随意选择明文,那就按照需求加密,根据密文利用:xor(mi,ci−1)=xor(mj,cj−1)构造出需要的明文,再加密。
from base64 import b64decode, b64encode
from pwn import xor
IV = b64decode("UwxbOoCBaHzuvag0sWSI5A==")
m1 = b'0123456789abcdef'
m2 = b'123456789abcdefg'
print(b64encode(m1+m2+m1))
# 得到下方密文:
cipher = b64decode("hTxYXtoJPswBOe3cgEeOXNVc2us7+cw15tvuAOEbb8MwtcksE0DleQNIibYpT1uC") # 加密m1+m2+m1
cipher2 = cipher[16:32]
m3_1 = xor(xor(cipher2,m1),IV) # 构造:iv^m1 = c2^m3_1 得到m3_1
cipher1 = cipher[:16]
m2_2 = xor(xor(cipher1,m1),IV) # 构造:iv^m1 = c1^m2_2 得到m2_2
print(b64encode(m1+m2_2+m1))
# 得到下方密文:
cipher_new = b64decode("hTxYXtoJPswBOe3cgEeOXIU8WF7aCT7MATnt3IBHjlzE8DPJFTHO3CmGQ0yXDkZR")
cipher2_new = cipher_new[16:32]
m3_2 = xor(xor(cipher2_new,m2),cipher1) # 构造:c1^m2 = new_c2^m3 得到m3_2
print(f'CBC: {b64encode(m1+m2+m3_1)}')
print(f'CCB: {b64encode(m1+m2_2+m3_2)}')
# 依次输入CBC和CCB:
# 0xGame{4f2a2df0-e82a-4b3f-b324-c6c8c70ab5e9}RC4
真没想到是中文(只想到密钥是不是不一样?)
突然灵光乍现,用gbk解个码试试,然后就出了...
from pwn import xor
key = b"This is keyyyyyy"
key_5 = b'\x83=x{\xbcb\r^3nl\xbe\xf4\xdb\xe5\xc5\x86\x9e-Rt\xf9\x93\t\x883I\xdd\xcdx\x01"\xb6d\xd3A\xa47|\x8d\xf8\xe9\xb1\x04\xfaz\x83t\xd5\x85\xd19\xfd\xbc\x88\xc8\x05fJZ\xae\xba%\x04B\xd6a>\xf7\xc6B\xc0`\xc2\xc4\x10\x83BbJ'
msg = b'n\xab\xa8\xf6%\xf5\xbd\xc5\x97\xe0\xa0zCpV{\x04&\x8a\xe5\xe1TP\xe0'
k_5 = key*5
keys = xor(k_5, key_5)
flag = xor(keys[:len(msg)],msg)
print('0xGame{'+flag.decode('gbk')+'}')
# 0xGame{哈哈哈没想到我是中文的吧}