J. A. Guerrero-Saade Profile picture
AVP of SentinelLabs @ SentinelOne. Distinguished Fellow @ Hopkins SAIS Alperovitch Institute. LABScon Founder, Cyber Paleontologist, Fourth-Party Collector.

Feb 24, 2022, 15 tweets

Day2, hopefully briefer and less hectic. Our friends at Symantec have published a great blog with way more detail about the attack chain and additional IOCs, including a decoy ransomware–

The 'ransomware' (4dc13bb83a16d4ff9865a51b3e4d24112327c526c1392e14d56f20d6f4eaf382) is written in Go and C and has some interesting quirks and taunting–

Despite a ton of standard Go functions (as is usually the case), all we really want to focus on are the main and Cgo functions.

Among those, you can already see some of the bizarre taunting–

More importantly, in execution, the malware seems to lose control of concurrent threads creating hundreds of events in our consoles– super loud and ineffective as ransomware (Credit to Jim Walter for the dynamic analysis)

Btw, for folks looking to analyze the Go malware, we released AlphaGolang (a set of IDA plugins for v7.6 and under). The folder organizing feature was adopted by IDA v7.7 natively :)
github.com/SentineLabs/Al…

Filenames to keep in mind from the Symantec blog. I have to admit that I find the idea of *independent* ransomware sample being used as a decoy or distraction from a wiper is counterintuitive but who knows.

403forBiden.wHiteHousE.primaryElectionProcess() recursively enumerates folders –

Ok... so I've been looking to understand the concurrency here. I think there might be big mistake in the code (and one that happens to amateur Go programmers all the time). Concurrent threads are handled by sync WaitGroup that functions as a sort of mutex/counter for threads.

Usually, you wrangle those concurrent threads with an upperbound – max 8 threads or whatever.

In this case, 'partyTicket_len' which is determined by the wHiteHouse.GoodOffice1() function

It looks like they upper bound is dynamically determined and huge (an enumerated file count maybe?) and... they *never* call sync.WaitGroup.Done()! Because that lives in main.subscribeNewPartyMember()... and that's never called!

So that's my explanation for why this thing runs a bajillion threads. It's more effective as a local DoS of the system than a piece of ransomware...

Aaaaand seeing as our friends at @threatintel didn't name this one either... I'm gonna go with @TomHegel's suggestion that we call this PartyTicket!

@threatintel @TomHegel @TomHegel coming in with the YARA rules :)

As @joakimkennedy pointed out, main.subscribeNewPartyMember() is called as a new_proc so there is some waitGroup decrementing at some point.

Share this Scrolly Tale with your friends.

A Scrolly Tale is a new way to read Twitter threads with a more visually immersive experience.
Discover more beautiful Scrolly Tales like this.

Keep scrolling