DamCTF Writeup – sneaky-script

# Information:

CTF Name: DamCTF

CTF Challenge: malware/sneaky-script

Challenge Category: Forensics

Challenge Points: 333

By: captainGeech

DamCTF 2021

# Used Tools:

# Challenge Description:

We recovered a malicious script from a victim environment. Can you figure out what it did, and if any sensitive information was exfiltrated? We were able to export some PCAP data from their environment as well.

# Writeup

Hello, welcome to my writeup for the DamCTF challenge sneaky-script. This was an amazing challenge! I enjoyed cracking this one!

In this one, we are presented with a zip file, inside it we have a pcap file and a sh script.

Well, as you probably know, pcap is a network scan file. One tool I use to read and analyze such files is Wireshark, lets jump on it!

Step 1

First I opened the file with Wireshark. After doing so I checked the mal.sh script, and I noticed this:

There we can see that an HTTP request is being done with curl to the IP address 54.80.43.46.

Let’s go back to the Wireshark and filter with this new information, in the first image you can see we added the filter ip.addr == 54.80.43.46 this will ensure that only the communication with the IP address in question is displayed. On the second image, we did “Follow TCP Stream” to see what was the full communication. This sometimes is important because in network protocols like TCP the full communication can be broken down into smaller chunks that are in turn rebuilt together on the destination side, this way we reduced the bandwidth usage per request, making the transmission faster. Finally, in the third image, you can see the result of the “Follow TCP Stream operation:

Okay, we now have some useful information resulting from the Follow TCP Stream. This is the entire communication, we can see the request done to the host and the reply, as well as the body of the message. By looking closely to the body of the message I noticed that it ended with “==” which is characteristic from base64 encoding. (We could also know that from the script, in which the request is done to the host, and then the output from the request is base 64 decoded and executed in Python 3. This tells us a lot of useful information. In particular, the body of the request can very well be a Python 3 script. Let’s copy that and decode it ourselves!

Step 2

I copied the contents of the body into a file called temp.txt, and ran the following command:

mregra㉿kali:$ cat temp.txt | base64 --decode > script_retrieved
mregra㉿kali:$ file script_retrieved
script_retrieved: python 3.6 byte-compiled

So, apparently the Python 3 file is compiled, which means it is a .pyc type of file. We cannot read it as .pyc, we need to convert it back to .py.

After searching online for a while I found this tool, Uncompyle6

mregra㉿kali:$ uncompyle6 script_retrieved.pyc > script_retrieved.py

And we got the Python 3 script now readable!

Step 3

I read the file, and noticed that the script was sending information and data from the host to a certain IP address, I assume this is the attacker’s IP:

I went back to Wireshark to check the traffic sent and received by this IP address, 34.207.187.90:

In the first image you have the filter of the communication with the IP 34.207.187.90, in the second image you can find the result of the “Follow TCP Stream”:

So, we have a the uploaded content sent back to the attacker’s IP. By looking at the Python 3 script once again, in particular the send function, we can see the encoding used. I decided to copied the contents from the TCP stream into a file (just the uploaded contents).

Afterward, I created a script to revert the encoding. Below you can find the code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16import base64, json

def solve():
    f = open("retrieved_from_attacker.txt", "r")
    for line in f:
        c = base64.b64decode(line)
        k = b'8675309'
        d = bytes([c[i] ^ k[(i % len(k))] for i in range(len(c))])
        json_decoded_text = json.loads(d)
        with open("output.txt", 'w') as f: 
            for key, value in json_decoded_text.items(): 
                f.write('%s:%s\n' % (key, value))
        f.close()
        print()

solve()

As we can see, first we open the file retrieved_from_attacker.txt (which is the file I decided to store the uploaded contents). Then, we reverse the encoding, we go from the last operation done to the first.

The last thing in the send function regarding encoding is to encode to base64 using a key, and before that, we have json encoding.

Therefore, in my script, I first decoded from base64 using the same key. And the same exact method. Then I decoded from json, and finally, I wrote all the decoded items into a file named output.txt.

Now that we have a file with all the messages sent to the attacker’s IP I assumed the flag must be inside, so I simply ran the command:

mregra㉿kali:$ cat output.txt | grep "dam"

And we have a match!!

And the flag is:

Show flag
dam{oh_n0_a1l_muh_k3y5_are_g0n3}

Thank you very much for reading!

Cheers,

MRegra

Share this post:

Popular posts

Leave a Reply

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