Gunakan quipquip , mendapatkan string yang bisa terbaca namun ada beberapa kesalahan. Lakukan pembenaran secara manual dengan memetakan nilai yang tepat. Berikut pemetaan yang kami gunakan untuk mendapatkan flag
Bisa dilihat hasil enkripsi berulang dan nilai untuk setiap index sama pemetaannya. Misal AB dengan CB , maka nilai ciphertext B akan sama. Jadi tinggal leak semua kemungkinan dan petakan ke plaintext. Berikut solver yang kami gunanakn
from pwn import *
import string
length = 38
r = remote("103.185.38.244",9989)
r.recvuntil(b"Pilih: ")
r.sendline(b"3")
r.recvuntil(b"Hasil: ")
ct = r.recvline().strip().decode()
list_pt = string.printable[:-6]
list_map = [[] for _ in range(length)]
for i in list_pt:
r.recvuntil(b"Pilih: ")
r.sendline(b"1")
r.recvuntil(b"string: ")
payload = i.encode()*length
r.sendline(payload)
r.recvuntil(b"Hasil: ")
tmp = r.recvline().strip().decode()
for j in range(len(tmp)):
list_map[j].append(tmp[j])
flag = ""
for i in range(len(ct)):
flag += list_pt[list_map[i%length].index(ct[i])]
print(flag)
Flag : IFEST22{ad03h_k03ntj1ku_k3t4hu4n_ini_random_string_biar_ga_di_brute_force_sama_kamu}
Kepapasan (431 pts)
Description
-
Solution
Diberikan source code sebagai berikut
from Crypto.Cipher import AES
import random
from Crypto.Util.Padding import pad
# J: So for the key, I use 5 random digits and repeat it until i get 16 bytes
# M: What? Man, i was using the exact same formula!
first_key = b""
second_key = b""
FLAG = b"IFEST22{REDACTED}"
def generateKey():
global first_key, second_key
first_key = (str(random.randint(0, 99999)).zfill(5)*4)[:16].encode()
second_key = (str(random.randint(0, 99999)).zfill(5)*4)[:16].encode()
def encrypt(plaintext, a, b):
cipher = AES.new(a, mode=AES.MODE_ECB)
ct = cipher.encrypt(pad(plaintext, 16))
cipher = AES.new(b, mode=AES.MODE_ECB)
ct = cipher.encrypt(ct)
return ct.hex()
def main():
generateKey()
print("Here's your flag, but encrypted heheh:", encrypt(FLAG, first_key, second_key))
while True:
print("Text to encrypt:")
plain = input(">> ")
print("result:", encrypt(plain.encode(), first_key, second_key))
if __name__ == '__main__':
main()
Mirip soal pico ctf , kebetulan kemaren ngerjain. Jadi gunakan script yang sama tinggal ubah des (di pico) menjadi aes. Vulnya adalah meet-in-the-middle , intinya decrypt hasil enkripsi known untuk key1 dan encrypt known untuk dapat key1 dimana hasil decrypt enkripsi known dengan key2 == hasil encrypt known dengan key1 . Berikut solver yang kami gunakan
from Crypto.Cipher import AES
import random
from Crypto.Util.Padding import pad
from pwn import *
payload = b"a"
inp = pad(payload,16)
r = remote("kepapasan.user.cloudjkt01.com",9977)
r.recvuntil(b"heheh: ")
ct_flag = bytes.fromhex(r.recvline().strip().decode())
r.recvuntil(b">> ")
r.sendline(payload)
r.recvuntil(b"result: ")
enc_inp = bytes.fromhex(r.recvline().strip().decode())
r.close()
list_key1 = {}
list_key2 = {}
for i in range(0, 99999+1):
key = (str(i).zfill(5)*4)[:16].encode()
cipher1 = AES.new(key, AES.MODE_ECB)
enc_msg = cipher1.encrypt(inp)
dec_msg = cipher1.decrypt(enc_inp)
list_key1[enc_msg] = key
list_key2[dec_msg] = key
tmp = list_key1.keys() & list_key2.keys()
print(tmp)
index = tmp.pop()
key1 = list_key1[index]
key2 = list_key2[index]
print(f"Key 1 : {key1}")
print(f"Key 2 : {key2}")
cipher1 = AES.new(key1, AES.MODE_ECB)
cipher2 = AES.new(key2, AES.MODE_ECB)
enc_msg = cipher2.decrypt(ct_flag)
flag = cipher1.decrypt(enc_msg)
print(flag)
Flag : IFEST22{Prepare_for_AES_Trouble_and_make_it_AES_Double}
Rabun Genap (431 pts)
Description
-
Solution
Diberikan source code sebagai berikut
from Crypto.Util.number import *
import random
from sympy import *
FLAG = b"IFEST22{REDACTED}"
def generate_prime():
p = getPrime(512)
q = nextprime(p)
while p%4 != 3 or q%4 !=3:
p = getPrime(512)
q = nextprime(p)
return p, q
def encrypt(m, n):
return pow(m, 32, n)
p, q = generate_prime()
n = p*q
m = bytes_to_long(FLAG)
ct = encrypt(m, n)
file = open('out.txt', 'w')
file.write(f"n = {n}\nct = {ct}")
from Crypto.Util.number import *
import gmpy2
from sympy import *
n = 167369799324048138104052175535407583505752871957215436773759031023017258211926244898005523956634683846521843112989667257058661590892952518940981897603075244277403071620405906110395876285850586645267366109871364424530232323323093329164542366451609555755793278574306885322737868611730986497942446035931912990173
c = 21531359371326785000813539498235533853399851284161815602787505606478539937473829218703225074127036671433545623422527404993307032442845415396127106566947516725271774364574823414757530290809389432379888075234068890851808191948433382743838583087849527954870829102252458108566336758346284806983878333023038231317
tmp = gmpy2.iroot(n,2)[0]
q = nextprime(tmp)
p = n//q
e = 32
phi = (p-1)*(q-1)
d = inverse(e,phi)
# m = pow(ct,d,n)
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
g ,yp,yq = egcd(p,q)
mp = pow(c,(p+1)//4,p)
mq = pow(c,(q+1)//4,q)
for i in range(4):
mp = pow(mp,(p+1)//4,p)
mq = pow(mq,(q+1)//4,q)
r = (yp*p*mq + yq*q*mp) % n
mr = n - r
s = (yp*p*mq - yq*q*mp) % n
ms = n - s
for num in [r,mr,s,ms]:
print(long_to_bytes(num))