It's On Fire! 🔥

The FLARE team is now enthusiastic about Google products and services but we suspect there is more to this Android game than meets the eye.


The first thing is to decompile the apk to inspect the application files. Since this is a Flare-On challenge, attempt to search for flare-on.com shows up in the strings.xml :

Untitled

Where is this string used in the code?

Untitled

private final String d(Context context) {
        String slice;
        String string = context.getString(R.string.c2);
        Intrinsics.checkNotNullExpressionValue(string, "context.getString(R.string.c2)");
        String string2 = context.getString(R.string.w1);
        Intrinsics.checkNotNullExpressionValue(string2, "context.getString(R.string.w1)");
        StringBuilder sb = new StringBuilder();
        sb.append(string.subSequence(4, 10));
        sb.append(string2.subSequence(2, 5));
        String sb2 = sb.toString();
        Intrinsics.checkNotNullExpressionValue(sb2, "StringBuilder().apply(builderAction).toString()");
        byte[] bytes = sb2.getBytes(Charsets.UTF_8);
        Intrinsics.checkNotNullExpressionValue(bytes, "this as java.lang.String).getBytes(charset)");
        long a2 = a(bytes);
        StringBuilder sb3 = new StringBuilder();
        sb3.append(a2);
        sb3.append(a2);
        String sb4 = sb3.toString();
        Intrinsics.checkNotNullExpressionValue(sb4, "StringBuilder().apply(builderAction).toString()");
        slice = StringsKt___StringsKt.slice(sb4, new IntRange(0, 15));
        return slice;
    }

You find an interesting function. To understand what it does:

# In psuedocode:
c2 = "[https://flare-on.com/evilc2server/report_token/report_token.php?token=](https://flare-on.com/evilc2server/report_token/report_token.php?token=)"
w1 = "wednesday"

def func_d():
	str_ = c2[4:11] + w1[2:6] # "s://fl" + "dne"
	key = crc32(str) # 450830537
	key += key # 450830537450830537
	return bytes(key[:16]) # 4508305374508305

This function is called in another function:

alg = 'AES/CBC/PKCS5Padding'
iv = 'abcdefghijklmnop'
def c():
	key_b = func_d()
	decrypt_img = decrypt_aes(alg, iv, key)
	with open('dec.png', b) as f:
		f.write(decrypt_img)
		

Now you understand what is required:

  • Find the original image.
  • Decrypt it.

Untitled

Untitled

Get the resource : raw.iv

Your python script to decrypt the iv.png using the iv and key that we have retrieved.

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.backends import default_backend
import base64

def decrypt_aes_cbc_pkcs5(encrypted_image, key):
    iv = b'abcdefghijklmnop'
    encrypted_data = encrypted_image

    # Create a Cipher object for AES/CBC/PKCS5Padding decryption
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
    decryptor = cipher.decryptor()

    # Decrypt the data and remove padding
    decrypted_padded = decryptor.update(encrypted_data) + decryptor.finalize()
    unpadder = padding.PKCS7(128).unpadder()
    decrypted_data = unpadder.update(decrypted_padded) + unpadder.finalize()

    return decrypted_data

# Read the encrypted image
with open('iv.png', 'rb') as f:
    encrypted_image = f.read()

decrypted_data = decrypt_aes_cbc_pkcs5(encrypted_image, b'4508305374508305')

# Write the decrypted image
with open('decrypted.png', 'wb') as f:
    f.write(decrypted_data)

Cracked!

Untitled

Case 10 → The Battle Of Trojan 🐴

Case 09 → Taken ☎️

comments powered by Disqus