Tuesday, November 29, 2022

OpenSSL-1.0.0-fipps Linux Backdoor - Notes

Introduction:

EDIT - Sep 2024: This was originally written in November 2022. Recently (in 2024), CISA published an advisory where this was attributed to be used by North Korea. See: https://www.cisa.gov/news-events/cybersecurity-advisories/aa24-207a 
 
In some security/malware chat room, someone posted about an ELF backdoor, at the time, I couldn't find much information about it and any related samples or reports. Few weeks ago, I saw similar sample being discussed on twitter, which was found by a researcher in an open directory.

In this post, I just have some notes on my analysis/research of this sample and related samples. This might help with writing a signature or doing further research. I'm just calling this OpenSSL-1.0.0-fipps backdoor since that's what it initially sends to the C2 server and "fipps" has an extra p. 

As far as I'm aware, I haven't found similar samples with the searches I've done and I have not seen any samples successfully connect to C2 on any public sandboxes. I was also not able to find any executables for the C2 with some of the yara rules I wrote and queried Hybrid-Analysis for.

Notes:

It's a reverse shell/backdoor. The binary researches out to the C2 IP and Port defined in the binary. You can find C2 IP by just running strings.

Samples:
MD5 hashes:
eb7ba9f7424dffdb7d695b00007a3c6d VT: First Submission 2022-04-21 18:44:09 UTC, submission name: suspicious
97f352e2808c78eef9b31c758ca13032 VT: First Submission 2022-08-26 22:47:54 UTC, submission name: client
3e9ee5982e3054dc76d3ba5cc88ae3de VT: First Submission 2022-11-04 00:18:27 UTC, submission name: client

Sha256 hashes:
8cd16feb7318c0de3027894323a0ccaacb527e071aa4c4b691feb411b6bd0937
40da2329b2b81f237fc30d2274529e6fda4364516b78b4b88659c572fbc4bc02
4e5e42b1acb0c683963caf321167f6985e553af2c70f5b87ec07cc4a8c09b4d8

C2s:
162.220.10.214
107.175.64.203
185.29.10.38

After doing some historic searches, the C2's were running Windows, not that it matters much.

TELFhash for the binaries is: t1afe0d814d67c0dad4ab20c30d4989a94a047eb2688752922ab98d9c1883d917f15cf5f

File command results & diff:
ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.18, BuildID[sha1]=16eee120b0a557907a782d1405c8f86415902fa5, stripped
ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.18, BuildID[sha1]=16eee120b0a557907a782d1405c8f86415902fa5, stripped
ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.18, BuildID[sha1]=2c46d3c40075dc7a193f8041f9458b40fd1f31cf, stripped

BuildID are the same for eb7ba9f7424dffdb7d695b00007a3c6d and 97f352e2808c78eef9b31c758ca13032 and only diff is the IP.

< 00004110: 0000 0000 0000 0000 3130 372e 3137 352e  ........107.175.
< 00004120: 3634 2e32 3033 0067 6574 6966 6164 6472  64.203.getifaddr
---
> 00004110: 0000 0000 0000 0000 3136 322e 3232 302e  ........162.220.
> 00004120: 3130 2e32 3134 0067 6574 6966 6164 6472  10.214.getifaddr

Not 100% sure about the reason for this and why someone modified just the IP and why it wasn't recompiled.


eb7ba9f7424dffdb7d695b00007a3c6d was the sample being discussed in a chat room, the user mentioned that the file was dropped after log4j exploitation. 

The most recent sample 3e9ee5982e3054dc76d3ba5cc88ae3de was found in an open directory. Here's the tweet regarding it: https://twitter.com/r3dbU7z/status/1588337205595951106 In the reply tweet below (https://twitter.com/1ZRR4H/status/1588398704913895425 ) the user mentions finding a webshell as well. Maybe the threat actor is initially gaining access through external web vulns. I'm not really sure.

Finally, there is 97f352e2808c78eef9b31c758ca13032 and I'm not sure where it came from. The sample was discovered after searching for the following yara rule on Hybrid Analysis:

rule elf_backdoor_fipps
{
    strings:
        $a = "found mac address"
        $b = "RecvThread"
        $c = "OpenSSL-1.0.0-fipps"
        $d = "Disconnected!"
    condition:
        (all of them) and uint32(0) == 0x464c457f
}

(there is also "dbus-statd" that appears in the all the binaries)

There is also a Suricata signature published by Proofpoint/EmergingThreats that exists:

alert tcp any any -> any 443 (msg:"ET MALWARE Malicious ELF Activity"; dsize:<50; content:"OpenSSL-1.0.0-fipps"; startswith; fast_pattern; reference:md5,eb7ba9f7424dffdb7d695b00007a3c6d; classtype:trojan-activity; sid:2036592; rev:1; metadata:affected_product Mac_OSX, affected_product Linux, attack_target Client_Endpoint, created_at 2022_05_12, deployment Perimeter, former_category MALWARE, signature_severity Major, tag RAT, updated_at 2022_05_12;)

The suricata signature above is for initial connection from the backdoor to the c2 server.
When the sample runs, it prints "!!!Hello World!!!" and the mac address it found, connects to the C2 server, sends OpenSSL-1.0.0-fipps and the mac address.


There also appears to be I guess a heartbeat packet which looks like this:


Processing of commands takes place at FUN_00401f23 (i'm just using names ghidra assigns):


The binary is stripped and I wasn't able to figure out every single function or execute every single function but it has typical backdoor capabilities and it's also able to gather some info and send it back to the C2. There also seems to be encoding of the output (by FUN_00402181 ??) before it gets sent via network. 

1: grab user and system info

3: shell?
5: write file?
7: not sure
0xb: delete a file
0xd: directory/file listing?
0xf: not sure
0x11: not sure
0x13: not sure
0x17: seems to return c2 connection info

It does have functions for doing network connections, killing processes, etc...

From doing some testing, the command input that it expects seems to be 16 bytes. The following worked for me for deleting a file:
\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00 (command) \x05\x00 (input size)\x00\x00\x00\x00delme
0b is the command (byte next to 0b is supposed to the secondary command if that function supports it) and 05 is the number of bytes to read afterwards, delme is 5 bytes.


I'm not sure about the impact of changing other values in that 16 byte input but I know it changes the way the backdoor processes the input & encodes (first 8 bytes).


Conclusion:

It's a weird backdoor that I haven't found much info about or have seen fully run in a sandbox while being connected to its C2. 

I assume it's being used after initial access through web/external vulnerability (according to the tweets related to the latest sample, the threat actor had some usernames and active directory info they had taken from an organization they breached) but I'm not sure as there aren't many samples (or reports) I was able to find with the TELFhash and yara rule I made. It's very easy for the threat actor to modify the strings in the binary. I did see some specific assembly instructions that I wrote a yara rules for but they came back with the files that I already had.

Links:





Monday, November 21, 2022

Looking for EvilProxy - Notes

Introduction:

This started with someone asking about EvilProxy and any signatures for detecting it. 

EvilProxy is a phishing as a service (PhaaS), which can be used to capture credentials and cookies from a user auth, which also also works with MFA being enabled. It's essentially a reverse proxy that captures information for the attacker when you auth/start a session on a service that's doing reverse proxy for.

More information can be found here: https://resecurity.com/blog/article/evilproxy-phishing-as-a-service-with-mfa-bypass-emerged-in-dark-web

Similar projects include evilnginx, modlishka, and muraena.


Usually for http/https traffic signature, we may want to look for status code, post/get parameters & pattern, URI pattern, JA3/JA3S, cert properties, html properties/body, and etc

Here's an example for evilnginx:


https://github.com/kgretzky/evilginx2/blob/master/core/certdb.go#L400

https://twitter.com/malwrhunterteam/status/1354039003121647624


There can be multiple types of detections as well. For example, detection of a service by utilizing scanning/scan response (shodan/censys) and detection from traffic monitoring (zeek extracting cert info and logging).


In this post, I'm just documenting just methods and what I've found researching EvilProxy. I don't have anything conclusive and from screenshots/videos the EvilProxy looks pretty thought-out and I'm sure it's easy for the devs to change behavior. They let you customize pretty much everything.

Notes:

Looking at the video shared by Resecurity, I see the following:


subdomain is set to lmo by default. 


Stream BotGuard redirects to brave.com by default. Later on there is also redirect to example.com and office.com


URL GET query can have username=email@example.com but that seems optional.

URL with eqp=base64_email_address is also supported.


Some of the interesting IOC's listed by Resecurity are:

  • 147[.]78[.]47[.]250
  • 185[.]158[.]251[.]169
  • 194[.]76[.]226[.]166
  • msdnmail[.]net
  • evilproxy[.]pro
  • top-cyber[.]club
  • rproxy[.]io
  • login-live.rproxy[.]io

The other IOC comes from ThreatInsight/Proofpoint posting a domain and attributing it to EvilProxy phishing kit

  • hxxps://auth[.]royalqueenelizabeth[.]com/?

Status Code:

Searching for some of the IP's on Shodan and viewing history shows this:



Looking at webpage scan runs on Anyrun shows this:


This is what URLScan shows as well:



Maybe we can look for servers being used for EvilProxy phishing sites by looking for "444 Unknown Status Code"?

Censys Query: (services.http.response.status_code:444 and services.http.response.status_reason:"Unknown Status Code") and services.software.vendor=`nginx`

Shodan Query: http.status:444 "Unknown Status Code" "nginx"

URLScan Query: page.status:444 AND server:"nginx"

Shodan & Censys: out of 5 & 4 results, 2 IP's were publicly known for phishing.

URLScan showed a ton of data and it's easy to tell from the domain & subdomain names which sites are phishing:

The searching for 444 approach works fine but it doesn't seem to be too accurate when it comes to Shodan and Censys. It's much more useful when looking at URLScan though. 

Also, 444 doesn't show up for everything. It may have shown up for some of the domains due to misconfiguration possibly? i don't know.

Subdomain name:

The other approach for looking for EvilProxy domains could be using subdomain names (with maybe additional queries). This will likely have false positives and since EvilProxy offers a lot of configuration options, if the user changed the default settings, you wouldn't have too much success.

Some of the subdomain names EvilProxy has used are (based on VT & videos): lmo (microsoft), auth, login-live, wwwofc, accounts (google), mso (microsoft), github (github).

URLScan can be queried with: page.domain:(login-live.* OR accounts.* OR lmo.* OR auth.* OR wwwofc.* OR mso.* OR github.*) but github, auth, and accounts might lead to false positives.

This might be much better: page.domain:(login-live.* OR lmo.* OR wwwofc.* OR mso.*)


Crt.sh can also be searched for certs issued for some of the subdomains, however, that may not work very well since it looks like in the past wildcard certs were issued.

URL parameters/pattern:

One of the things we see above (in urlscan screenshot) is and in ThreatInsight/Proofpoint example is question mark '?' at the end of the URL. That could be searched for. Additionally, username= or eqp= can be searched for. Searching for /? and username= will lead to a lot of false positives. The search could be combined with some of the URLScan queries to potentially get less false positives.

URLScan query would look like this: page.url:"/?eqp=" NOT page.domain:ups.com


It kinda shows some malicious sites with some false positives. Also this search doesn't produce many results. At the time of writing, there were only 49 results.

Again, since EvilProxy is customizable, the parameters can be changed by the user. 

Redirects:

From the streams feature that was shown in the video, EvilProxy can perform actions such as redirect based on rules regarding the traffic source. Some of the defaults included brave.com, google.com and example.com. I'm sure other configuration settings include more redirections.

Only problem with this is, many sites might be doing these redirects, including other phishing kits so this doesn't mean source site is EvilProxy. The previous query for default subdomains can be combined to potentially get better results.

In URLScan this query provides results for any redirects to brave.com: page.redirected:off-domain AND ("brave.com") AND task.url:(login-live.* OR lmo.* OR wwwofc.* OR mso.*)

HTML Body:

One of the things I noticed while doing the following query: page.redirected:off-domain AND page.domain:(login-live.* OR lmo.* OR wwwofc.* OR mso.*) is that some of the screenshots for malicious websites look like this:



This results from some javascript which can be found here: https://urlscan.io/responses/e85dcff15d140f96a949d9a186c44edb2723e90073bc902d5e278ecad0d1661a/ 

I didn't spend too much time researching it but it looks like it may be trying to do fingerprinting. Some of the things in the javascript show up here: https://github.com/fingerprintjs/fingerprintjs/blob/master/src/sources/dom_blockers.ts 

Searching for javascript code that does fingerprinting in network traffic or on URLScan might be useful for hunting, however, I'd assume other people are using javascript to fingerprint so it might not always be useful.

The code kinda looks like this:



Essentially, it's title Wait... /title, script big_js_block /script, script let randomvar = base64 /script

Regex rule applied to http traffic might be able to find this maybe?

HTTP Requests:

While doing research/queries, I found a website that was not doing any redirection and is possibly EvilProxy (getting 444 on one of the pages related to this).

Traffic to this site shows the following POST request after fingerprinting:


The response looks like this:

Once that's done, a cookie with cookiekey:cookievalue get's added to the session.

There is also a websocket connection/heartbeat, which doesn't happen with real microsoft login page:



The request for sending username/password look identical for the phishing site and normal login site.

websocket, fingerprinting POST, and response with cookies might be something that can be detected on wire if TLS/SSL interception and suricata/zeek monitoring is in place.


Conclusion:

EvilProxy offers a lot of customization so a lot of stuff mentioned above can be modified the by user but some users might just use default settings. 

Without a lot of attribution directly to EvilProxy and research out there, a lot of the stuff above is just an educated guess with the information I have available. I could be wrong about a lot of things. These are just notes and not anything conclusive.

Links:

https://resecurity.com/blog/article/evilproxy-phishing-as-a-service-with-mfa-bypass-emerged-in-dark-web

https://twitter.com/JeffreyAppel7/status/1591911982848172032/photo/1

https://www.microsoft.com/en-us/security/blog/2022/07/12/from-cookie-theft-to-bec-attackers-use-aitm-phishing-sites-as-entry-point-to-further-financial-fraud/

https://github.com/kgretzky/evilginx2

https://github.com/drk1wi/Modlishka

https://github.com/muraenateam/muraena



Monday, October 17, 2022

Researching golang malware and how I hate security industry naming conventions - Part 1

 


While doing some research on the use of golang in malware, I came across this golang sample here: https://www.virustotal.com/gui/file/020f6b3e045fa6b968226a8f2b2800dc55c65e842607d04d68b47ef4d18b0eee/detection
At the time of writing this, it has 3/72 detections.

It's named winnta.exe
MD5 7e17c9e4ebe61e43966e9f65e334727e
SHA-1 2172901d2a13304dd53a83e518fd5be84ed9ec08
SHA-256 020f6b3e045fa6b968226a8f2b2800dc55c65e842607d04d68b47ef4d18b0eee

Here are the results for yara scan: https://yaraify.abuse.ch/sample/020f6b3e045fa6b968226a8f2b2800dc55c65e842607d04d68b47ef4d18b0eee/

It connects to 195.149.87[.]87:443 (https://www.virustotal.com/gui/ip-address/195.149.87.87/relations )

The data above doesn't really tell us much about the sample.

Running strings on the sample is kinda interesting, it shows the following:
-ldflags="-s -w -extldflags '-static' -X main.name=WindowsNTApp -X main.addr=195.149.87.87:443 -X main.service=WindowsNTApp"

Also there are a bunch of references to go files and code in this directory: "/home/builder18g/goroot/" for example:
/home/builder18g/goroot/src/c/gsh/main/main.go
/home/builder18g/goroot/src/c/gsh/main/windows.go

Looking for 'main.' shows the following:
runtime.main.func1
runtime.main.func2
main.main
main.(*winService).Stop
main.(*winService).Execute
main.(*winService).Start
main.(*winService).Execute.func1
main.startInteractive
main.Start

At this point, assumption is this is some kinda backdoor.

Researching the C2 IP, I found this:
https://raw.githubusercontent.com/stamparm/maltrail/master/trails/static/malware/apt_unc961.txt
https://otx.alienvault.com/pulse/6244606893ddbc9a6a5bbdeb
https://www.mandiant.com/resources/blog/mobileiron-log4shell-exploitation

Here's what Mandiant has to say about this:
"UNC961 deployed two previously unobserved backdoors: HOLEDOOR and DARKDOOR. HOLEDOOR is written in C, whereas DARKDOOR is written in Go."

"DARKDOOR is a backdoor written in Go that is highly modular in design. It supports communication over TLS and HTTP. It has capabilities to execute arbitrary code and list running processes."

I continued to do more research to see what else I can find out about this sample doing any reverse engineering.

Searching for winnta.exe results in a paper from SentinelOne (https://www.sentinelone.com/wp-content/uploads/2021/05/Watchtower_2021_May_White.pdf)

They mention the backdoor under section "Mercenary APT Groups Targeting the Financial Services Industry"

Here's what they had to say about it:
File: winntaWindows EXE written in golang that calls out to
45.76.236[.]136:443
Backdoor functionality
Potential name “gsh”

File: main
Golang compiled EXE of same “gsh” family as mentioned
for winnta
Calls out to 198.199.104[.]97:443 and has backdoor
capabilities

Under potential attribution section, they refer to an RSA report regarding Carbanak."Carbanak has been reported using a custom golang backdoor named GOTROJ. This backdoor
has code overlap and functionality similar to the “geodezine” backdoor discovered in the attacker’s toolkit. "

The RSA paper "The Shadows of Ghosts" can be found here: https://www.netwitness.com/wp-content/uploads/2021/12/the-shadows-of-ghosts-carbanak-report.pdf

Here's a snippet about GOTROJ from the paper:
"On D+30, the attackers installed a Windows Trojan, written in Go, as a Windows
Service on one of the two primary Active Directory Domain Controllers. They
would move to utilizing the GOTROJ as their primary method of ingress for the
duration of the engagement. The GOTROJ Trojan communicated with C2 IP
address 107.181.246.146 over TCP/443 for its remote access channel."

I continued doing more research. I searched for "WindowsNTApp" service, which came up with a crowdstrike report on ProphetSpider. The report is here: https://www.crowdstrike.com/blog/prophet-spider-exploits-oracle-weblogic-to-facilitate-ransomware-activity/

They also refer to the malware as GOTROJ. This is what they say:
"The adversary commonly creates Windows services, e.g. WindowsNTApp for GOTROJ, to establish persistence for downloaded malware."

I finally searched for GOTROJ to see if there is anything else I can find. I only found one article here (besides ones I already looked at): https://www.fortify24x7.com/2022/04/ragnarlocker-ransomware-iocs/ where they found GOTROJ along side with Ragnarlocker infection.

I downloaded some of the samples to look at. I recommend this Ghidra extension: https://github.com/mooncat-greenpy/Ghidra_GolangAnalyzerExtension/releases/tag/1.1.0

The samples look similar and functions kinda look like this (different samples will have slightly different names and code):


The golang build path's embedded inside the samples are different, likely because each sample was probably compiled on different hosts likely by different people. Interestingly, the sample I started with is the only sample that has the build string in it with ldflags.

Other reports have already analyzed the capabilities of this golang backdoor but you can see from the function names what it can do as well.

Researching golang malware and how I hate security industry naming conventions - Part 2


I did some string searches in Hybrid-Analysis as well to look for more files. (Thanks Hybrid-Analysis for a researcher account!) I finally ended up with this yara rule (i'll learn to write better rules one day):

rule gsh_backdoor
{
    strings:
        $a = "startInteractive"
        $b = "main.winService"
        $c = "main.(*winService).Start"
    condition:
        ($a and $b and $c) and filesize < 6MB and filesize > 2MB
and uint16(0) == 0x5A4D
}

Searching that on Hybrid-Analysis results in the following hashes:
57150938be45c4d9c742ab24c693acc14cc071d23b088a1facc2a7512af89414
b63ea16d5187c1fa52a8a20c3fd7b407033bcd4142addb1ce91923d6b2f19555
57a45d3010d74cbd089cacf23bc0f68eaa3fb8dc5479dbe8ed8e19004badfdb6
9d42c2b6a10866842cbb6ab455ee2c3108e79fecbffb72eaf13f05215a826765
95c6d0d4e619334b3d8adb5340198c420f78f937f3dc944bc12a2be7f73fb952
18077efa0c23e9370eb95ca6c5ece82bcf61e63505a87aea8cb6a14d15500a8c
55320dcb7e9e96d2723176c22483a81d47887c4c6ddf063dbf72b3bea5b279e3

You can also run strings on the file and extract C2 information by doing egrep:
strings -f * | egrep '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?):(\d{0,5})'

18077efa0c23e9370eb95ca6c5ece82bcf61e63505a87aea8cb6a14d15500a8c.bin.sample: 142.93.213[.]221:21
55320dcb7e9e96d2723176c22483a81d47887c4c6ddf063dbf72b3bea5b279e3.bin.sample: 107.181.246[.]146:443
57a45d3010d74cbd089cacf23bc0f68eaa3fb8dc5479dbe8ed8e19004badfdb6.bin.sample: 198.199.104[.]97:443
95c6d0d4e619334b3d8adb5340198c420f78f937f3dc944bc12a2be7f73fb952.bin.sample: 64.227.88[.]98:443
9d42c2b6a10866842cbb6ab455ee2c3108e79fecbffb72eaf13f05215a826765.bin.sample: 107.181.246[.]146:443
b63ea16d5187c1fa52a8a20c3fd7b407033bcd4142addb1ce91923d6b2f19555.bin.sample: 45.76.236[.]136:443
winnta.bin: 195.149.87[.]87:443

One more thing I noticed while researching this is mention of "geodezine" backdoor. Some of the samples connect to the same C2 server as the golang backdoor connects to. I haven't looked too much into it but here's a rule:

rule geo_backdoor
{
    strings:
        $a = "geodezine"
        $b = "cmd.exe"
        $c = "URLDownloadToFilDeleteUrlCacheEn"
    condition:
        ($a and $b and $c) and filesize < 100KB and uint16(0) == 0x5A4D
}

And here are the hashes that show up on Hybrid-Analysis:
98647c242e5df8122929f4bbdc21495ef28038c64186b4cc8ec8d6e34b838d6a
51141d45e6257b0f4b15e98ceef00c18869e7958cddd1454385671c14c51492e


Summary of where this Golang malware shows up and timeline:
December 2017
The Shadows of Ghosts Inside the response of a unique Carbanak intrusion
Filename: ctlmon.exe
Malware name: GOTROJ
C2: 107.181.246[.]146
Hashes:
450605b6761ff8dd025978f44724b11e0c5eadcc
08f527bef45cb001150ef12ad9ab91d1822bb9c7
7b27771de1a2540008758e9894bfe168f26bffa0
Attack involved exploitation of CVE-2017-5638


May 2021
Mercenary APT Groups Targeting the Financial Services Industry
Filename: winnta / main
Malware name: GOTROJ-related / gsh
C2: 45.76.236[.]136, 198.199.104[.]97
"cyber mercenary attack targeting a major US-based financial services organization"


August 2021
PROPHET SPIDER Exploits Oracle WebLogic to Facilitate Ransomware Activity
Filename: winnta
Malware name: GOTROJ
Hashes:
2b03806939d1171f063ba8d14c3b10622edb5732e4f78dc4fe3eac98b56e5d46
55320dcb7e9e96d2723176c22483a81d47887c4c6ddf063dbf72b3bea5b279e3
57150938be45c4d9c742ab24c693acc14cc071d23b088a1facc2a7512af89414
9d42c2b6a10866842cbb6ab455ee2c3108e79fecbffb72eaf13f05215a826765
exploitation of CVE-2020-14882 and CVE-2020-14750


March 2022
Forged in Fire: A Survey of MobileIron Log4Shell Exploitation
Malware name: DARKDOOR
C2: 162.33.178[.]149, 195.149.87[.]87
Attributed to UNC961 and related to exploitation of Log4j in Horizon and MobileIron


April 2022
Ragnarlocker Ransomware IOCs
Filename: ctlmon.exe
Malware name: GOTROJ
C2: 45.63.89[.]250
Related to breach involving Ragnarlocker according to the post


September 2022
This is the sample that I started out my research with
Filename: winnta.exe
Hash: 020f6b3e045fa6b968226a8f2b2800dc55c65e842607d04d68b47ef4d18b0eee
C2: 195.149.87[.]87
I just found the sample. I'm not sure what campaign it's related to or any other details. The C2 matches the Mandiant report though.

You should be able to pivot from C2 to sample hash or sample hash to C2 using VirusTotal. Some vendors didn't supply C2s or hashes.

As far as I know, I have not seen any of these samples running and successfully connecting to C2 in any of the public sandboxes. I haven't seen results in Shodan or Censys that show the C2 port open even with historical search for the September 2022 sample.

There may be more samples on VirusTotal but I'm doing this independently and don't have access to VT.

I'm not a CTI person. To me this looks like a golang backdoor used by multiple actors. I just hope this post helps anyone Googling things because this sample has been called different things by different vendors and that's annoying. 

Saturday, October 15, 2022

Looking at process relationships from malware sandbox execution data

Introduction:

This blog post discusses looking at process relationships, specifically from malware sandbox execution data. One of the essential functions of malware sandbox is to gather and display process execution, for example if winword launches powershell, you'd want to know that.

One issue that I run into while doing research is that many of the public/free malware sandboxes don't allow me to search based on process relationships. For example, if I have a sample on an endpoint that executed whoami, nslookup, systeminfo, i would like to be able to search sandbox reports to see which malware families or samples do that.

The other thing I'm interested in as a researcher is trends a long for initial access execution, for specific malware families or in general. One of the twitter accounts I follow is https://twitter.com/pr0xylife and they post information about how malware such as qakbot is doing command/process execution on a system. 

I find the information interesting and obviously, the threat actors have made changes over time. Maybe the threat actors are using new LOLBINs more than before.

The final thing about process relationship data that can be useful is just looking for new things or rare executions. If you're collecting the data, you can do searches to look for rare executions.

All this research should be helpful with detection engineering too or with emulation, if you're trying to match a specific threat.


POC Implementation:

As a proof-of-concept, I decided to implement a searchable database that lets me collect data from malware sandbox report and lets me search for parent-child process relationships. 

I acquired my data from Hybrid-Analysis Public Feed, which gives you JSON file with around 250 recent malware analysis results. I also got data from Zero2Auto CAPE sandbox (https://zero2auto.com/ Thanks for letting me use the data!)


I initially looked at graph databases but asking graph database questions/doing queries seemed annoying to me so I didn't look into them too much.


The second thing I tried was to join data from process execution in Python manually, which was a horrible idea. The code turned out horrible and dataset wasn't fun to work with. (https://github.com/BoredHackerBlog/sandbox_process_relationships/blob/main/hybrid-analysis_public_feed.py)


CAPE and Hybrid-Analysis both record process execution data differently but one thing they have in common is a process list json object. Each process object has process metadata and parent process id and obviously the process id. 

I decided to use duckdb to analyze the data. (Usually I'd use sqlite but wanted to try out duckdb and it worked fine)

I created a table with:

  • report id - specific execution task/detonation in the sandbox
  • process id
  • parent process id
  • process name
  • process path
  • process command line

Then I loaded the results from CAPE or Hybrid-Analysis to the table. I'm loading the same type of data but parsing their json reports is obviously different.

Finally, I created a view with join, where I ensure that report id is the same and parent process id and process id's match.

The resulting view contains:

  • Report ID
  • Parent Process ID
  • Parent Parent Process ID
  • Parent Name
  • Parent Path
  • Parent Command Line
  • Process ID
  • Process Name
  • Process Path
  • Process Command Line

Gathering data from the sandbox reports and putting it in the database allows me to ask questions like these:

  • what process launched ping? select parent_name, proc_commandline from joined_proc_list where proc_commandline ilike '%ping.exe%';
  • what process launched powershell with command line to add Defender exclusion? select parent_name, proc_commandline from joined_proc_list where proc_commandline ilike '%add-mppreference%';
  • what processes launch wscript? select parent_name, count(*) as count from joined_proc_list where proc_commandline ilike '%wscript%' group by parent_name
  • what does cmd.exe launch from the appdata folder? select parent_name, proc_name from joined_proc_list where parent_name ilike '%cmd.exe%' AND proc_path ilike '%appdata%';


The results look kinda like this:






If you have large enough dataset, you can extract more info like malware or campaign name and etc and keep track of the trends.


Other solutions:

If you already are doing malware execution in your sandbox, you can check if you are able to search based on process relationships. 

You could also have a backend database that you can query, for example MongoDB or Elasticsearch, although I personally don't know about join capabilities of those databases.

Alternatively, if your sandbox supports either pushing data out to splunk or elasticsearch or any other place, you could try to work with that data. You can also maybe intercept that data and send it to a webhook or lambda for additional processing.

If you have a system that supports pulling data, maybe through an API, that's also a solution. Maybe have a script that pulls reports, parses data, and processes it.

You can store processed data in whatever database you feel comfortable utilizing. I would personally use Clickhouse or Postgresql if I was doing this. 


Links/Resources:

Code: https://github.com/BoredHackerBlog/sandbox_process_relationships

https://courses.zero2auto.com/

https://www.hybrid-analysis.com/

Also check out Grapl - https://github.com/grapl-security/grapl

Thursday, August 18, 2022

Remotely managing Sysmon configuration through Graylog Sidecar

Introduction:

Sysmon is a tool from Microsoft that can help with collecting better logs (compared to default Windows logs) regarding the system. The logs can be very helpful for detection of malicious behavior. Sysmon get's installed as a service and a driver usually along with whatever configuration file you provided. 

It can be kinda annoying to update sysmon configuration as sysmon doesn't come with a remote management system. If you have group of PC's that need different configuration, it can be a bit annoying to go push that out. 

There are some options for updating sysmon configs. 

  • You could setup a scheduled task that runs a script to look for a new config and does update. 
  • You can also use EDR tools that you may already have in place to run scripts or commands to update sysmon. 
  • You can utilize one of the Windows remote management features such as remote powershell. 
  • Ansible would work too. It would let you update sysmon config based on groups as Ansible lets you put machines into groups.
Some of the issues you may have with update methods above is 
  • problem with managing different group of PC's 
  • updates not being pushed out as soon as possible 
  • having to open up ports/services on Windows that you'd rather not.

I decided to go with Graylog sidecar for managing configuration. Graylog sidecar is usually used to manage configuration for log shippers (Beats for example) but it can be adapted to manage sysmon configuration as well!! Sidecar runs as an agent that will connect to Graylog server to get sysmon config updates. 

Tools:

Graylog & sysmon, obviously.

You need graylog server installed. You can technically use graylog sidecar without using graylog to store your windows or sysmon logs.

I'm using an admin account for the POC but use whatever the appropriate account is for your requirements.

Setting up sidecar:

We'll manually set this up first but you can deploy sidecar agent and sysmon, and install both at the same time by creating a package or an initial installation script.

First, we'll need to create a sidecar token.


Go to the sidecars page, create a new token.



Next, on Windows host, download and install sidecar agent


By default, Sidecar files are located at: C:\Program Files\Graylog\sidecar

After installation, run the following commands (as admin) to install graylog as a service and start the service:

"C:\Program Files\graylog\sidecar\graylog-sidecar.exe" -service install

"C:\Program Files\graylog\sidecar\graylog-sidecar.exe" -service start

(you can do all of this automatically if you build a package for your organization)

The host should show up on Sidecar overview page



Setting up sysmon support on Windows host:

Now that sidecar connection works fine, we need to setup sysmon. I'm placing sysmon executable at C:\Program Files\Graylog\sidecar\sysmon64.exe (make sure its lower case or at least the case matches the sidecar.yml config file)

Next, we need to edit sidecar.yml file to allow the use of sysmon64.exe (again, you can build a package and include sidecar.yml file that already supports this)

Here's what I have in the config file:


Restart the graylog sidecar service to ensure that it starts up again and sidecar.yml config file doesnt have any errors:


Next, we'll need to install sysmon w/ initial configuration (do this during initial graylog sidecar agent installation)


Now we can setup sysmon configuration in sidecar to do updates.

Setting up sysmon sidecar configuration in Graylog:

Go to collection configuration page in Graylog and click Create Log Collector button.



Create something that looks like this:


We're using foreground execution since we just need to execute the command to update sysmon config and exit.

The update command is sysmon -c CONFIG_FILENAME so we're using -c "%s", %s is the filepath of our config, when it's written to the disk.

Default template can be used to use a default config but I'm leaving it empty here.

Next on Collection configuration page, click Create Configuration


Name your configuration and add the xml config content.

You can create and add more configurations for different systems you may have.

Pushing configuration to a host:

Go to the sidecar Administration page


Check Sysmon and select the right sysmon configuration and apply the configuration.


Graylog webui may say the update failed but you can click the host you updated and click Show details to see more:


Above you can see that the configuration updated without an issue. 

You can also confirm the update by looking at event id 16 from sysmon in your SIEM or Event Viewer like below



Building initial installation package recommendations:

Your initial sidecar agent package should do the following:

  • Drop sysmon executable in the sidecar folder
  • Sidecar.yml file needs to contain path for sysmon executable in the allowed files
  • Install sysmon with whatever initial configuration you'd like to use
If you build an installation package yourself, you don't have to do all the stuff manually above...

Once you deploy sidecar agent + sysmon initially, you can remotely manage the sysmon configuration through Graylog sidecar UI.

Links/Resources:

https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon

https://www.graylog.org/

https://www.graylog.org/features/sidecar

https://github.com/Graylog2/collector-sidecar/releases

https://docs.graylog.org/docs/sidecar

https://github.com/olafhartong/sysmon-modular

https://github.com/SwiftOnSecurity/sysmon-config

https://github.com/LaresLLC/SysmonConfigPusher - I came across this after finishing this write up...