这个比较密码这块还是比较简单的,经过问了N人以后终于完成。
[Warm Up] Words
给了个猪圈密码的图片,这东西好久不见的感觉。
[Warm Up] Emails
MTP似乎也没多好的方法,猜更快,先给了几封email然后一个用MTP长度是32(有提示)的加密,每封信的格式其实是差不多的。猜一下就十几个字符了。再一点点猜就OK
from pwn import xor
msg = open('email5.enc','rb').read()
l = 32
key = xor(b'Good evening,\r\n\r\nFinally, I feel',msg[:l])
for i in range(0, len(msg), l):
v1 = msg[i:i+l]
print(xor(key,v1))
'''
b'Good evening,\r\n\r\nFinally, I feel like it's safe to send you the flag. It's:\r\nRS{Th4T's_n0T_h0w_Y0u_u53_OTP}\r\nDon't share it with anyone!! It's very secret!\r\n\r\nThanks,\r\n- Your Secret Conspirator
'''
Dastardly Evil Scientists
给了一个远端的DES加密,这有点像脑筋急转弯,因为这个远端交互的部分没用。
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad
from secret import KEY, FLAG
BLOCK_SIZE = 64
key = bytes.fromhex(KEY)
cipher = DES.new(key, DES.MODE_ECB)
flag = cipher.encrypt(pad(bytes(FLAG, "utf-8"), BLOCK_SIZE))
print("Here's the flag (in hex):", flag.hex())
print("=" * 64)
print("Encrypt something if you want, you can choose the key and the plaintext :)")
while True:
try:
key = bytes.fromhex(input("Key (in hex): "))
plaintext = bytes.fromhex(input("Message to encrypt (in hex): "))
print("=" * 64)
cipher = DES.new(key, DES.MODE_ECB)
ciphertext = cipher.encrypt(pad(plaintext, BLOCK_SIZE))
print("Here's your message! (in hex):", ciphertext.hex())
print("Here's your message! (in bytes):", ciphertext)
print("=" * 64)
except KeyboardInterrupt:
break
其实就是根据一个DES的密文在没有key的情况下恢复,问了才知道用弱密码。这东西技术本来就没解,猜。
'''
┌──(kali㉿kali)-[~/ctf/2403]
└─$ nc ctf.ritsec.club 30984
Here's the flag (in hex): 28e3a0ff9089aecc83465e470624a89253a1aac856a4f7ff08b4648b7c5eff9aa41a0dd1c7fc15995382dc3149dfcccf82241fb566fb5a0382241fb566fb5a03
================================================================
Encrypt something if you want, you can choose the key and the plaintext :)
Key (in hex):
'''
keys = [
'0101010101010101',
'FEFEFEFEFEFEFEFE',
'E0E0E0E0F1F1F1F1',
'1F1F1F1F0E0E0E0E',
'0000000000000000',
'FFFFFFFFFFFFFFFF',
'E1E1E1E1F0F0F0F0',
'1E1E1E1E0F0F0F0F']
from Crypto.Cipher import DES
enc = bytes.fromhex('28e3a0ff9089aecc83465e470624a89253a1aac856a4f7ff08b4648b7c5eff9aa41a0dd1c7fc15995382dc3149dfcccf82241fb566fb5a0382241fb566fb5a03')
for key in keys:
key = bytes.fromhex(key)
cipher = DES.new(key, DES.MODE_ECB)
print(cipher.encrypt(enc))
#RS{W0W_TH1S_K3YSP4C3_1S_4S_FL4T_4S_34RTH}
Failed File Transfer
这也是个急转弯,给了3组n,e,c 其中n1=n2是个共模攻击,与第3个毫无关系(分解了也解不出来)。
n1 = 0x00E066F78031520F1DD7AFF5EC5D59CD7AA68ECD4C394A1EC9792CF179E24C33F59AC856E61836C7AA34A3617316615F58743B9401507A423853AA31C5FCB8543E99DC23A52BF09CC65714406458C912CFB9CC3DAF41F1221294703846465F92B747FE3CB2E8444CACF38ECF5FAF78C4207569ECAE91D98ECA132E2C15BF6FDD51D399FE8A645B69C01CDCA2604AE9434BACD6C3B2BF41B4D41415425FC0D590E0579935C723FDA0887528BF20C8ADE06E7FF96FD0755694AE9501F905363F448A5546E083A1EDC901FBED1156E51BB095388EBE5672F695B395A2334FF156A6DD170A9D6EDD58E4415AB437E0D6A5C20C15CB946081ACDBA9AE1904668A2094A7
e1 = 0x11
n2 = 0x00E066F78031520F1DD7AFF5EC5D59CD7AA68ECD4C394A1EC9792CF179E24C33F59AC856E61836C7AA34A3617316615F58743B9401507A423853AA31C5FCB8543E99DC23A52BF09CC65714406458C912CFB9CC3DAF41F1221294703846465F92B747FE3CB2E8444CACF38ECF5FAF78C4207569ECAE91D98ECA132E2C15BF6FDD51D399FE8A645B69C01CDCA2604AE9434BACD6C3B2BF41B4D41415425FC0D590E0579935C723FDA0887528BF20C8ADE06E7FF96FD0755694AE9501F905363F448A5546E083A1EDC901FBED1156E51BB095388EBE5672F695B395A2334FF156A6DD170A9D6EDD58E4415AB437E0D6A5C20C15CB946081ACDBA9AE1904668A2094A7
e2 = 0x10001
n3 = 0x00B83B727303CCA9589A2A2B9AF5018C95F790608611EF866CF9A4C418A0D7DEF8D3F8EB1DDB4F209BED973903B815BBAE7C5528656265217DF68D54D699CA8B1E538DC6333681835A0B37F3040845E3CCE66B246AB2C85DAE92249527E370F4025C0328780F673422B06F50851F8E541F0F0A44FC3B196BC4E1AB8C6822987445555DC2F5950BF131EA0000D75572311837B52B7878D3A95E7C6ED2506481B5DA5E2F958AD4C9B6F5ECCB5A745308713A4FED8075FC91BCF2B4F21A692755E57806785019DEF5A2B268EA515F7C98D5F0D9D601F71FB4DF9C447BDB2AA41E297D2BDA6EA3542CD23B3355000CB8B88969E86831B684E5D9F17EB575ED1A9D4BC1
e3 = 3
from Crypto.Util.number import *
from gmpy2 import *
c1 = bytes_to_long(open('file1.txt','rb').read())
c2 = bytes_to_long(open('file2.txt','rb').read())
c3 = bytes_to_long(open('file3.txt','rb').read())
c1 = 11245878960087837261153516178684850454637136825484561550726912432349025296699694537872464349657733966826298283722786787933292056762759914076568007800566819942953557122977296478823083370205733249120718240013540365420405155115022388180051960802673652141559924942805827069850744998102254791685219410995184646316624102478708619178993243689040667230101593137349589107630305725689690939494305295499595455919109021945288211347640189838071821958185609046927008536889084147708562575440838230905838959519444560623562334687780414679184669161400916951922315233235810181868590747124614034500752457446358264532085815447285388073591
c2 = 16054994042311146186017609971632669838086039843925903279538251084169470320180830257196284538399796375682305705861424990272712206680326511935759065824972211750810396652005162857469803598720642557738604616794819369477983021340676007820878452867128139544526573553396360802705352396219060613392389540623902265215962677795832211589342073667420169650393268864124684435310861882097065213761756697025358974337991278905840043953671014003772900188734819841892901029660981787710334983605848616213210453940682289680252874387317386217578517608737723983756020598610426318181178794250467061361414561885082927773205471084373198179425
c3 = 20172398454481629709076152409120771119119636979189949766325302829870418847404497225982242452780243034238156558627368219057394137220128633740921274776445357416208523061501396375233405630630997666632960294747690427691310748022697040779115269467122991941859552531609447427683470428776973201589275412116191256662447910727158038828967329100259233048374570118492407923826709529836351193509410233823073092428830866679199977883169773243118628390507390065104100344830823694677958503145301186964407354825966110389585254787043844756466689845402596869978196900487069209922397756567505347271078963033190976335693178538107766271636
#n1=n2 共模攻击
import libnum
import gmpy2
def rsa_gong_N_def(e1,e2,c1,c2,n): #共模攻击函数
e1, e2, c1, c2, n=int(e1),int(e2),int(c1),int(c2),int(n)
print("e1,e2:",e1,e2)
s = gmpy2.gcdext(e1, e2)
print("mpz:",s)
s1 = s[1]
s2 = s[2]
if s1 < 0:
s1 = - s1
c1 = gmpy2.invert(c1, n)
elif s2 < 0:
s2 = - s2
c2 = gmpy2.invert(c2, n)
m = (pow(c1,s1,n) * pow(c2 ,s2 ,n)) % n
return int(m)
long_to_bytes(rsa_gong_N_def(e1,e2,c1,c2,n1))
#RS{Y0U_C4NT_R3AD_M3_R1GHT??}
Old Fashioned Crypto
一个背包加密,key*r,后部的10个取了模
import json
from Crypto.Random import get_random_bytes
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from math import gcd, log2, ceil
class CryptoSystem:
def __init__(self, size, pub_key=None, priv_key=None):
self.size = size
if pub_key is None and priv_key is None:
self._gen_keys()
elif pub_key is None:
self.priv_key = priv_key
self._prv_lst, self._prv_q, self._prv_r, self._prv_r_inv = self.priv_key
self._gen_pub_key()
else:
self.priv_key = priv_key
if self.priv_key is not None:
self._prv_lst, self._prv_q, self._prv_r, self._prv_r_inv = self.priv_key
self.pub_key = pub_key
def _gen_keys(self):
lst = []
total = 0
for i in range(self.size):
nxt = total + sum(get_random_bytes(4))
total += nxt
lst.append(nxt)
self._prv_lst = lst
self._prv_q = total + sum(get_random_bytes(4))
self._prv_r = 0
while gcd(self._prv_r, self._prv_q) != 1:
self._prv_r = sum(get_random_bytes(8))
self._inv(self._prv_r, self._prv_q)
self.priv_key = (self._prv_lst, self._prv_q, self._prv_r, self._prv_r_inv)
self._gen_pub_key()
def _inv(self, a, b):
x, y = self._inv_help(a, b)
self._prv_r_inv = x + b if x < 0 else x
def _inv_help(self, a, b):
if a == 1 and b == 0:
return 1, 0
x_p, y_p = self._inv_help(b, a % b)
x = y_p
y = x_p - y_p * (a // b)
return x, y
def _gen_pub_key(self):
self.pub_key = [(self._prv_r * w) % self._prv_q for w in self._prv_lst]
def encrypt(self, data):
if len(data) * 8 > self.size:
raise ValueError(f"Data too big! Data has {len(data)*8} bits, can only encrypt {self.size} bits")
val = int.from_bytes(data, 'big')
tot = 0
for i in range(self.size):
if val & (1 << (self.size - 1 - i)):
tot += self.pub_key[i]
return tot.to_bytes(ceil(log2(tot)/8), 'big')
def decrypt(self, ct):
if self.priv_key is None:
raise ValueError('This instance not created with private key; Cannot decrypt!')
inv = (int.from_bytes(ct, 'big') * self._prv_r_inv) % self._prv_q
data = 0
for i in range(self.size-1, -1, -1):
if self._prv_lst[i] <= inv:
inv -= self._prv_lst[i]
data |= (1 << (self.size - 1 - i))
return data.to_bytes(self.size//8, 'big')
def main():
n = 128
c = CryptoSystem(n)
key = get_random_bytes(n//8)
enc_key = c.encrypt(key)
iv = get_random_bytes(n//8)
sym_c = AES.new(key, mode=AES.MODE_CBC, iv=iv)
with open('flag.txt', 'rb') as f:
flag = f.read()
enc_flag = sym_c.encrypt(pad(flag, AES.block_size))
with open('output.json', 'w') as f:
json.dump({'enc_flag': enc_flag.hex(), 'enc_key': enc_key.hex(), 'pub_key': c.pub_key, 'iv': iv.hex()}, f)
if __name__ == '__main__':
main()
因为背包前边比较小,通过gcd可以得到r,然后10个需要爆破一下,同时模也需要同步爆破。
key[k] = sum(key[:k]) + delta ,delta<=1020
不过最后的结果是不管爆破的哪个值都能得到正确的flag,任取其一即可。
key = [640152, 1168382, 2253084, 4674574, 9047900, 18456670, 37021078, 73718942, 147269478, 294724098, 589585222, 1179181950, 2358463270, 4716668178, 9433832160, 18867248012, 37734327618, 75468823642, 150937904600, 301875276786, 603750933270, 1207501571568, 2415003160918, 4830006433758, 9660012935506, 19320025912852, 38640051750392, 77280103282170, 154560206677308, 309120413125542, 618240826573252, 1236481653212402, 2472963306421666, 4945926612902954, 9891853225704446, 19783706451335672, 39567412902928660, 79134825805593728, 158269651611315068, 316539303222675114, 633078606445099188, 1266157212889999636, 2532314425780479386, 5064628851560855218, 10129257703121405004, 20258515406242969000, 40517030812485923356, 81034061624971802780, 162068123249943657860, 324136246499887437056, 648272492999774915952, 1296544985999549766006, 2593089971999099471344, 5186179943998199255442, 10372359887996398278672, 20744719775992796462158, 41489439551985593093768, 82978879103971186299458, 165957758207942372543478, 331915516415884744919596, 663831032831769489761788, 1327662065663538979557048, 2655324131327077959251122, 5310648262654155918162294, 10621296525308311836756586, 21242593050616623673275730, 42485186101233247346600622, 84970372202466494693276556, 169940744404932989386548928, 339881488809865978773018360, 679762977619731957546165378, 1359525955239463915092196868, 2719051910478927830184595614, 5438103820957855660369059432, 10876207641915711320738278902, 21752415283831422641476275384, 43504830567662845282952694070, 87009661135325690565905228102, 174019322270651381131810641346, 348038644541302762263621052572, 696077289082605524527242502624, 1392154578165211049054484845210, 2784309156330422098108969790836, 5568618312660844196217939281470, 11137236625321688392435878881970, 22274473250643376784871757533820, 44548946501286753569743515154458, 89097893002573507139487030340296, 178195786005147014278974060857366, 356391572010294028557948121450094, 712783144020588057115896242990144, 1425566288041176114231792485875688, 2851132576082352228463584971803676, 5702265152164704456927169943738102, 11404530304329408913854339887111150, 22809060608658817827708679774659528, 45618121217317635655417359549268848, 91236242434635271310834719098693550, 182472484869270542621669438196865146, 364944969738541085243338876394136140, 729889939477082170486677752787944882, 1459779878954164340973355505576101056, 2919559757908328681946711011152194790, 5839119515816657363893422022304309038, 11678239031633314727786844044608554270, 23356478063266629455573688089217321924, 46712956126533258911147376178434543432, 93425912253066517822294752356869114060, 186851824506133035644589504713738135026, 373703649012266071289179009427476613140, 747407298024532142578358018854952805788, 1494814596049064285156716037709905827052, 2989629192098128570313432075419811602850, 5979258384196257140626864150839623163860, 11958516768392514281253728301679246338180, 23917033536785028562507456603358492659624, 47834067073570057125014913206716985424894, 95668134147140114250029826413433970529712, 4024280977508761976100681034599517010909, 8048561955017523952201362069199034004036, 16097123910035047904402724138398067786320, 32194247820070095808805448276796135496282, 64388495640140191617610896553592270815790, 128776991280280383235221793107184541765468, 70241995243789299946484614422100659064021, 140483990487578599892969228844201318336196, 93655993658385733261979485896134212196063, 187311987316771466523958971792268424462208]
enc_key = 0x0351cf110fa463b393d61b1dfc0419d8d30d
enc_flag = bytes.fromhex("40ffc331e0624779d6cc8b594debb0fdfd65a21d9841f61ab5cfd5b2809bd0d91e5a2da049dbdf2ad8dceaadeee718ce")
iv = bytes.fromhex("631232abc39e6d838e6e1072a88b369a")
from Crypto.Cipher import AES
from gmpy2 import invert
from math import gcd
#前部gcd得到r
r = key[0]
for i in key[1:118]:
r = gcd(r,i)
#r=1046
vkey = [i//r for i in key[:118]]
#[118,127]模过,求模q
#最大差1024
b117 = sum(vkey)
qa2 = []
minmod = max(key)
def get_qr(idx,lst,total,m): #[118,128)
global qa2
if idx>=128:
print(m-total)
qa2.append(lst+[m])
return
for i in range(1021):
k = total+i
nm = gcd(m,k*r - key[idx])
if nm>minmod and nm> total+k:
get_qr(idx+1,lst+[k],total+k, nm)
for i in range(1,1021):
a118 = b117+i
m0 = a118*r - key[118] #k118 = a118*r mod q = a118*r - kq
#print(a118,m0)
get_qr(119,vkey+[a118],b117+a118, m0)
def decrypt(ct, prv_lst, prv_q,prv_r):
inv = ct * invert(prv_r,prv_q) % prv_q
data = 0
for i in range(127, -1, -1):
if prv_lst[i] <= inv:
inv -= prv_lst[i]
data |= (1 << (127 - i))
if inv==0:
ek = long_to_bytes(data, 16)
aes = AES.new(ek, mode=AES.MODE_CBC, iv=iv)
flag = aes.decrypt(enc_flag)
print(flag)
'''
#任何一组都可以
for lst in qa2:
pk = lst[:-1]
q = lst[-1]
ek = decrypt(enc_key, pk, q, r)
'''
pk,q = qa2[0][:-1],qa2[0][-1]
decrypt(enc_key, pk, q, r)
#b"RS{You'll_Need_A_Super_Increasing_Knapsack}\x05\x05\x05\x05\x05"
最后两个没看懂,i没有代码只有远端