Disclaimer/Legal responsibility
The work that follows is a POC to allow malware to “key” itself to a selected sufferer in an effort to frustrate efforts of malware analysts.
I assume no accountability for malicious use of any concepts or code contained inside this mission. I present this analysis to additional educate infosec professionals and supply further coaching/meals for thought for Malware Analysts, Reverse Engineers, and Blue Teamers at massive.
TLDR
The primary time the malware runs on a sufferer it AES encrypts the precise payload(an RDLL) utilizing environmental information from that sufferer. Every subsequent time the malware is ran it gathers that very same environmental data, AES decrypts the payload saved as a byte array inside the malware, and runs it. If it fails to decrypt/the payload fails to run, the malware deletes itself. Safety in opposition to reverse engineers and malware analysts.
Up to date 6 JUNE 2022
I did not really feel completed with this mission so I went again and did a reasonably substantial re-write. The unique analysis and tradecraft could also be discovered Right here.
Main adjustments are as follows:
- I’ve launched all supply code
- I built-in Stephen Fewer’s ReflectiveDLL into the mission to switch Stage2
- I formatted among the byte arrays on this mission into string format and parse them with UuidFromStringA. This Repo was used as a template. This was completed to decrease entropy of Stage0 and Stage1
- Stage0 has had a good bit of AV evasion constructed into it. Due to Cerbersec’s Challenge Ares for inspiration
- The builder software to supply Stage0 has been included
There are fairly a number of various things that might be taken from the supply code of this mission to be used elsewhere. Hopefully it is going to be helpful for somebody.
Issues with Unique Launch and Mitigations
There have been a number of shortcomings with the unique launch of BeatRev that I made a decision to try to handle.
Stage2 was beforehand a standalone executable that was saved because the alternate information stream(ADS) of Stage1. To be able to acheive the AES encryption-by-victim and subsequent decryption and execution, every time Stage1 was ran it might learn the ADS, decrypt it, write again to the ADS, name CreateProcess, after which re-encrypt Stage2 and write it again to disk within the ADS. This was a number of I/O operations and the CreateProcess name after all wasn’t nice.
I occurred to return upon Steven Fewer’s analysis regarding Reflective DLL’s and it appeared like a very good match. Stage2 is now an RDLL; our malware/shellcode runner/no matter we need to shield will be ported to RDLL format and saved as a byte array inside Stage1 that’s then decrypted on runtime and executed by Stage1. This removes all the I/O operations and the CreateProcess name from Version1 and is a welcome change.
Stage1 didn’t have any actual type of AV evasion measures programmed in; this was intentional, as it’s additional work and wasn’t actually the purpose of this analysis. Throughout the re-write I took it as an added problem and added API-hashing to take away features from the Import Handle Desk of Stage1. This has helped with detection and Stage1 has a 4/66 detection price on VirusTotal. I used to be snug importing Stage1 given that’s is already keyed to the unique field it was ran on and the file signature consistently adjustments due to the AES encryption that occurs.
I not too long ago began taking note of entropy as a way to detect malware; to try to decrease the in any other case very excessive entropy {that a} big AES encrypted binary blob provides an executable I regarded into integrating shellcode saved as UUID’s. As a result of the binary is saved in string illustration, there’s decrease general entropy within the executable. Utilizing this system The entropy of Stage0 is now ~6.8 and Stage1 ~4.5 (on a max scale of 8).
Lastly it’s a big chore to combine and produce an entire Stage0 as a consequence of all the items that should be manipulated. To make this simpler I made a builder software that may ingest a Stage0.c template file, a Stage1 stub, a Stage2 stub, and a uncooked shellcode file (this was construct round Stage2 being a shellcode runner containing CobaltStrike shellcode) and produce a compiled Stage0 payload to be used heading in the right direction.
Technical Particulars
The Reflective DLL code from Stephen Fewer comprises some Visible Studio compiler-specific directions; I am certain it’s potential to port the method over to MingW however I wouldn’t have the talents to take action. The primary drawback right here is that the CobaltStrike shellcode (stageless is ~265K) must go contained in the RDLL and be compiled. To get round this and combine it properly with the remainder of the method I wrote my Stage2 RDLL to include a worldwide variable chunk of reminiscence that’s the measurement of the CS shellcode; this ~265K chunk of reminiscence has a small placeholder in it that may be situated within the compiled binary. The code in src/Stage2 has this added already.
As soon as compiled, this Stage2stub is transfered to kali the place a binary patch could also be carried out to stay the true CS shellcode into the place in reminiscence that it belongs. This produces the whole Stage2.
To keep away from the I/O and CreateProcess fiasco beforehand described, the whole Stage2 should even be patched into the compiled Stage1 by Stage0; that is obligatory in an effort to enable Stage2 to be encrypted as soon as on-target along with stopping Stage2 from being saved individually on disk. The identical idea beforehand described for Stage2 is performed by Stage0 heading in the right direction in an effort to assemble the ultimate Stage1 payload. It must be famous that the memmem operate is used in an effort to find the placeholder inside every stub; this operate is not any accessible on Home windows, so a customized implementation was used. Due to Foxik384 for his code.
To be able to carry out a binary patch, we should allocate the required reminiscence up entrance; this has a compounding impact, as Stage1 should now be large enough to additionally include Stage2. With the added step of changing Stage2 to a UUID string, Stage2 balloons in measurement as does Stage1 in an effort to maintain it. A stage2 RDLL with a compiled measurement of ~290K ends in a Stage0 payload of ~1.38M, and a Stage1 payload of ~700K.
The builder software solely helps creating x64 EXE’s. Nonetheless with a little bit extra work in idea you could possibly make Stage0 a DLL, in addition to Stage1, and have the entire lifecycle exist as a DLL hijack as a substitute of a standalone executable.
Directions
These directions will get you in your option to utilizing this POC.
- Compile Builder utilizing gcc -o builder src/Builder/BeatRevV2Builder.c
- Modify sc_length variable in src/Stage2/dll/src/ReflectiveDLL.c to match the size of uncooked shellcode file used with builder ( I’ve included fakesc.bin for instance)
- Compile Stage2 (in visible studio, ReflectiveDLL mission makes use of some VS compiler-specific directions)
- Transfer compiled stage2stub.dll again to kali, modify src/Stage1/newstage1.c and outline stage2size as the dimensions of stage2stub
- Compile stage1stub utilizing x86_64-w64-mingw32-gcc newstage1.c -o stage1stub.exe -s -DUNICODE -Os -L /usr/x86_64-w64-mingw32/lib -l:librpcrt4.a
- Run builder utilizing syntax: ./builder src/Stage0/newstage0_exe.c x64 stage1stub.exe stage2stub.dll shellcode.bin
- Builder will produce dropper.exe. It is a formatted and compiled Stage0 payload to be used heading in the right direction.
Introduction
About 6 months in the past it occured to me that whereas I had discovered and completed lots with malware regarding AV/EDR evasion, I had spent little or no time involved with making an attempt to evade or defeat reverse engineering/malware evaluation. This was for a number of good causes:
- I do not know something about malware evaluation or reverse engineering
- When you find yourself speaking about authorized, sanctioned Purple Staff work there is not actually a have to try to frustrate or defeat a reverse engineer as a result of the exercise ought to have been deconflicted lengthy earlier than it reaches that stage.
Nonetheless it was an attention-grabbing thought experiment and I had a number of colleagues who DO learn about malware evaluation that I might bounce concepts off of. It appeared a problem of a complete totally different magnitude in comparison with AV/EDR evasion and one I made a decision to take a stab at.
Premise
My preliminary premise was that the malware, on the primary time of being ran, would one way or the other “key” itself to that sufferer machine; any subsequent makes an attempt to run it might consider one thing within the goal setting and evaluate it for a match within the malware. If these two elements matched, it executes as anticipated. If they don’t (as within the case the place the pattern had been transfered to a malware analysts sandbox), the malware deletes itself (As soon as once more closely leaning on the work of LloydLabs and his delete-self-poc).
This “key” should be one thing “distinctive” to the sufferer pc. Ideally it is going to be a mixture of a number of items of knowledge, after which additional obfuscated. For instance, we might collect the hostname of the pc in addition to the quantity of RAM put in; these two values can then be concatenated (e.g. Client018192MB) after which hashed utilizing a user-defined operate to supply a quantity (e.g. 5343823956).
There are a ton of decisions in what info to collect, however thought must be given as to what values a Blue Teamer might simply spoof; a MAC handle for instance could appear to be a sexy “distinctive” identifier for a sufferer, nonetheless MAC addresses can simply be set manually to ensure that a Reverse Engineer to match their sandbox to the unique sufferer. Ideally the values chosen and enumerated can be one which can be tough for a reverse engineer to copy of their setting.
With some self-deletion magic, the malware might learn itself right into a buffer, find a placeholder variable and change it with this quantity, delete itself, after which write the modified malware again to disk in the identical location. Mixed with an if/else assertion in Foremost, the following time the malware runs it can detect that it has been ran beforehand after which go collect the hostname and quantity of RAM once more in an effort to produce the hashed quantity. This may then be evaluated in opposition to the quantity saved within the malware throughout the first run (5343823956). If it matches (as is the case if the malware is working on the identical machine because it initially did), it executes as anticipated nonetheless if a special worth is returned it can once more name the self-delete operate in an effort to take away itself from disk and shield the writer from the malware analyst.
This appeared like a positive thought in idea till I spoke with a colleague who has actual malware evaluation and reverse engineering expertise. I used to be advised {that a} reverse engineer would have the ability to observe the conditional assertion within the malware (if ValueFromFirstRun != GetHostnameAndRAM()), and seeing because the anticipated worth is hard-coded on one facet of the conditional assertion, merely modify the registers to include the anticipated worth thus fully bypassing your entire safety mechanism.
This new data fully derailed the thought experiment and seeing as I did not actually have a use for a functionality like this within the first place, that is the place the mission stopped for ~6 months.
Overview
This mission resurfaced a number of occasions over the intervening 6 months however every time was little greater than a passing thought, as I had gained no new data of reversing/malware evaluation and once more had no want for such a functionality. A couple of days in the past the thought rose once more and whereas nonetheless neither of these elements have actually modified, I assume I had a little bit bit extra data below my belt and could not let go of the thought this time.
With the aforementioned drawback concerning hard-coding values in thoughts, I finally determined to go for a multi-stage design. I’ll check with them as Stage0, Stage1, and Stage2.
Stage0: Setup. Ran on preliminary an infection and deleted afterwards
Stage1: Runner. Ran every subsequent time the malware executes
Stage2: Payload. The malware you care about defending. Spawns a course of and injects shellcode in an effort to return a Beacon.
Lifecycle
Stage0
Stage0 is the recent executable delivered to focus on by the attacker. It comprises Stage1 and Stage2 as AES encrypted byte arrays; that is completed to guard the malware in transit, or ought to a defender one way or the other get their palms on a replica of Stage0 (which should not occur). The AES Key and IV are contained inside Stage0 so in actuality this may not shield Stage1 or Stage2 from a reliable Blue Teamer.
Stage0 performs the next actions:
- Sandbox evasion.
- Delete itself from disk. It’s nonetheless working in reminiscence.
- Decrypts Stage1 utilizing saved AES Key/IV and writes to disk instead of Stage0.
- Gathers the processor identify and the Microsoft ProductID.
- Hashes this worth after which pads it to suit a 16 byte AES key size. This worth reversed serves because the AES IV.
- Decrypts Stage2 utilizing saved AES Key/IV.
- Encrypts Stage2 utilizing new victim-specific AES Key/IV.
- Writes Stage2 to disk as an alternate information stream of Stage1.
On the conclusion of this sequence of occasions, Stage0 exits. As a result of it was deleted from disk in step 2 and is now not working in reminiscence, Stage0 is successfully gone; With out prior data of this system the remainder of the malware lifecycle can be an entire lot extra complicated than it already is.
In step 4 the processor identify and Microsoft ProductID are gathered; the ProductID is retreived from the Registry, and this worth will be manually modified which presents and straightforward alternative for a Blue Teamer to match their sandbox to the goal setting. Relying on what environmental info is gathered this may develop into simpler or harder.
Stage1
Stage1 was dropped by Stage0 and exists in the identical actual location as Stage0 did (to incorporate the identify). Stage2 is saved as an ADS of Stage1. When the attacker/persistence subsequently executes the malware, they’re executing Stage1.
Stage1 performs the next actions:
- Sandbox evasion.
- Gathers the processor identify and the Microsoft ProductID.
- Hashes this worth after which pads it to suit a 16 byte AES key size. This worth reversed serves because the AES IV.
- Reads Stage2 from Stage1’s ADS into reminiscence.
- Decrypts Stage2 utilizing the victim-specific AES Key/IV.
- Checks first two bytes of decryted Stage2 buffer; if not MZ (unsuccessful decryption), delete Stage1/Stage2, exit.
- Writes decrypted Stage2 again to disk as ADS of Stage1
- Calls CreateProcess on Stage2. If this fails (unsuccessful decryption), delete Stage1/Stage2, exit.
- Sleeps 5 seconds to permit Stage2 to execute + exit so it may be overwritten.
- Encrypts Stage2 utilizing victim-specific AES Key/IV
- Writes encrypted Stage2 again to disk as ADS of Stage1.
Word that Stage2 MUST exit to ensure that it to be overwritten; the self-deletion trick doesn’t seem to work on information which can be already ADS’s, because the self-deletion method depends on renaming the first information stream of the executable. Stage2 will ideally be an inject or spawn+inject executable.
There are two factors that Stage1 might detect that it isn’t being ran from the identical sufferer and delete itself/Stage2 in an effort to shield the menace actor. The primary is the examine for the executable header after decrypting Stage2 utilizing the gathered environmental info; in idea this step might be bypassed by a reverse engineer, however it’s a first good examine. The second safety level is the results of the CreateProcess call- if it fails as a result of Stage2 was not correctly decrypted, the malware is similiary deleted. The results of this name is also modified to forestall deletion by the reverse engineer, nonetheless this does not change the truth that Stage2 is encrypted and inaccessible.
Stage2
Stage2 is the meat and potatoes of the malware chain; It’s a totally fledged shellcode runner/piece of malware itself. By encrypting and defending it in the way in which that now we have, the actions of the tip state malware are significantly better obfuscated and shielded from reverse engineers and malware analysts. Throughout growth I used certainly one of my current shellcode runners containing CobaltStrike shellcode, however this might be something the attacker needs to run and shield.
Impression, Mitigation, and Additional Work
So what is definitely achieved with a malware lifecycle like this? There are a number of attention-grabbing quirks to speak about.
Alternate information streams are a characteristic distinctive to NTFS file methods; which means most methods of transfering the malware after preliminary an infection will strip and lose Stage2 as a result of it’s an ADS of Stage1. Particular care must be given in an effort to switch the pattern in an effort to protect Stage2, as with out it a number of reverse engineers and malware analysts are going to be very confused as to what’s taking place. RAR archives are in a position to protect ADS’s and instruments like 7Z and Peazip can extract information and their ADS’s.
As beforehand talked about, by the point malware utilizing this lifecycle hits a Blue Teamer it must be at Stage1; Stage0 has come and gone, and Stage2 is already encrypted with the environmental info gathered by stage 0. Not understanding that Stage0 even existed will add appreciable uncertainty to understanding the lifecycle and decrypting Stage2.
In idea (as a result of once more I’ve no reversing expertise), Stage1 ought to have the ability to be reversed (after the Blue Teamers rolls via a number of copies of it as a result of it retains deleting itself) and the knowledge that Stage1 gathers from the goal system ought to have the ability to be recognized. Supplied a well-orchestrated response, Blue Staff ought to have the ability to establish the sufferer that the malware got here from and go and collect that info from it and feed it into this system in order that it could be reworked appropriately into the AES Key/IV that decrypts Stage2. There are lots “ifs” in there nonetheless associated to the relative talent of the reverse engineer in addition to the sufferer machine being accessible for that info to be recovered.
Software Whitelisting would considerably frustrate this lifecycle. Stage0/Stage1 could possibly be facet loaded as a DLL, nonetheless I believe that Stage2 as an ADS would current some points. I wouldn’t have an setting to check malware in opposition to AWL nor have I bothered porting this all to DLL format so I can not say. I’m certain there are inventive methods round these points.
I’m additionally pretty assured that there are smarter methods to run Stage2 than dropping to disk and calling CreateProcess; Both manually mapping the executable or utilizing a instrument like Donut to show it into shellcode appear to be cheap concepts.
Code and binary
Throughout growth I created a Builder software that Stage1 and Stage2 could also be fed to in an effort to produce a purposeful Stage0; this won’t be offered nonetheless I can be offering most of the supply code for stage1 as it’s the piece that will be most seen to a Blue Teamer. Stage0 can be excluded as an train for the reader, and stage2 is no matter standalone executable you need to run+shield. This POC could also be additional researched on the effort and discretion of ready readers.
I can be offering a compiled copy of this malware as Dropper64.exe. Dropper64.exe is compiled for x64. Dropper64.exe is Stage0; it comprises Stage1 and Stage2. On execution, Stage1 and Stage2 will drop to disk however will NOT routinely execute, you could run Dropper64.exe(now Stage1) once more. Stage2 is an x64 model of calc.exe. I’m together with this for any Blue Teamers who need to check out this, however have in mind in an incident response state of affairs 99& of the time you can be getting Stage1/Stage2, Stage0 can be gone.
Conclusion
This was an attention-grabbing pet mission that ate up an extended weekend. I am certain it might be much more superior/extra full if I had expertise in a debugger and disassembler, however you do the very best with what you could have. I’m keen to listen to from Blue Teamers and different Malware Devs what they assume. I’m certain I’ve over-complicatedly re-invented the wheel right here given what precise APT’s are doing, however I discovered a number of issues alongside the way in which. Thanks for studying!