Incident Responder

Since we know the final attack chain was lambda function that encrypts stuff, lets try from the last step.

Grepping for encrypt, we can see that it encrypts the s3://hexnovadatabreach-databreach-content-dolphin/ImportantInformation.txt as well as the dynamodb/HevNovaDataBreachDynamoDB-databreach.

We are also given the API gateway URL for the lambda function

https://x7ia63zopb.execute-api.us-west-2.amazonaws.com

Trying to POST the the prod stage give us a 404 not found error

Playing around with the route, we managed to get a response out of the API Gateway.

curl -XGET https://x7ia63zopb.execute-api.us-west-2.amazonaws.com/decrypt/s3/hexnovadatabreach-databreach-content-dolphin/ImportantInformation.txt

It returns the encrypted important information.txt Doign a quick google, the gAAAA encryption is fernet encryption.

Looking at the CloudWatch log, we managed to find the encryption key.

Wrtiting a quick solve script we are able to get part1 of the flag.


import json
from cryptography.fernet import Fernet

# Fernet key from your input
fernet_key = "rFebkqIbEugh4uxwzR1HS49ICeE29fH-Rb7Ryk2exQA="
f = Fernet(fernet_key)
current = "gAAAA[truncated]"
while True:
    try:
        current = f.decrypt(current)
    except Exception:
        print(current)
        break

For Part2, the flag is in the dynamodb.

curl -X GET https://x7ia63zopb.execute-api.us-west-2.amazonaws.com/decrypt/dynamodb/HevNovaDataBreachDynamoDB-databreach > output.json

I used LLM to write another solve script to parse the output and get the flag.

import json
from cryptography.fernet import Fernet

# Fernet key from your input
fernet_key = "rFebkqIbEugh4uxwzR1HS49ICeE29fH-Rb7Ryk2exQA="
f = Fernet(fernet_key)

# Path to your JSON file
json_file = "output.json"

# Load the JSON
with open(json_file, "r") as f_in:
    data = json.load(f_in)

for idx, item in enumerate(data.get("items", []), start=1):
    try:
        data_val = item["Data"]["S"]
        key_val = item["DefCon33PartitionKeyDynamoDB"]["S"]

        # Function to repeatedly decrypt until it fails
        def deep_decrypt(value):
            current = value.encode()
            while True:
                try:
                    current = f.decrypt(current)
                except Exception:
                    return current.decode(errors="replace")

        final_data = deep_decrypt(data_val)
        final_key = deep_decrypt(key_val)

        print(f"[Item {idx}]")
        print(f"  Final Data after deep decrypt: {final_data}")
        print(f"  Final PartitionKey after deep decrypt: {final_key}")
        print()

    except Exception as e:
        print(f"[Item {idx}] Error: {e}")

During the CTF, I tried to submit FLAG{R35p0nd_N0w_D1sc0v3r_F0r3ns1cs} as the flag but it failed. So I thought that there were another part and wasted alot of time trying the parse the logs to find something different.

It is only until after the CTF ends then I realized I had formatted the flag wrongly 🤦‍♂️

The flag format is FLAG-{R35p0nd_N0w_D1sc0v3r_F0r3ns1cs}

Last updated

Was this helpful?