New Pepex Variant (this one works)

I spent the morning sorting through samples from all the GRAB honeypots, and settled on a sample that happened to come in via the NYC honeypot. 50/53 detection ratio on VirusTotal, so let’s look into it in more depth.

Static Analysis

Running strings on the sample reveals only four strings that make any sense at all:


Looks packed to me, but not UPX like the last sample. PEiD identifies the packer as Upack 0.39 beta. I opened the file in PE Explorer and that automatically unpacked the malware (revealing many more strings than before), but I am going to take a shot at manually unpacking it anyway.

Upack is trickier than UPX, in my opinion. Opening the packed sample doesn’t show a clear jump to OEP, so I opened it in Olly and went to where the code for LoadLibraryA is found by pressing ctrl-G and then going to kernel32.LoadLibraryA, then set a breakpoint on the first instruction:


I watch the malware call LoadLibraryA seven times, ending with Mpr.dll, and then hitting run again causes it to run and not hit the breakpoint again. Restoring the VM snapshot, I go back to where Mpr.dll was called and then set another breakpoint on GetProcAddress, and then run through that five times until it appears that GetUserNameEx is the final function called with GetProcAddress before the rest of the program runs and the second breakpoint is no longer hit.

Stepping through the rest of that particular call to GetProcAddress and returning to the rest of the code, I’m ready to start stepping through the remains of the unpacking stub to get to the actual code entry point:


After following a few branches, I see what I believe to be the entry point:


This doesn’t look too typical for me in terms of address and code, but mainly what I was looking at here was a relatively long block of code compared with the branches I just looked at, plus starting at 756AA4E9 you can see what looks like it could be the start of a function with PUSH EBP | MOV EBP, ESP. Trying to dump that as an OEP didn’t really work – I did get something that I could disassemble and also do other analysis on, but this doesn’t seem to be the right place. Using OllyDump and its feature “Find OEP by Section Hop (Trace Over)” got me to this general area which looks much more promising:


Checking this against the automatically unpacked file, this is the entry point area. What’s sort of strange is that whether I dump this process from the other address above (756AA4E9) or the one right here (4023A0), I end up with basically the same dumped file and OllyDump can’t do anything with the import table. ImpRec doesn’t work either, and either way I’m left with something that doesn’t function but nevertheless offers a lot of interesting data statically or in disassembly. Since I was successful with the automated tool, I’m going to move on to static analysis of the unpacked sample that I obtained with PE Explorer.

Going through the meaningful strings from the unpacked malware, we now see a more normal set of sections:


I don’t typically see a .code section, but this must be the equivalent of the .text section containing the sample’s code. I also don’t usually see .idata, but this should have the import function info which I’m more accustomed to finding in the .rdata section. I’m guessing that something is contained in .rsrc, but we’ll get to that later.

I see some function names, and date/time strings, but then I see a very long list of three digit numbers (here’s just an excerpt):


I wonder if this is being used in some fashion to “construct” IP addresses. I notice that some of the “special” numbers like 239 and 255 are not included in this list, though if this is what it’s being used for, one would think you’d see numbers below 130 also. These could also be ports.

Below this, I see some interesting strings that remind me of some of the stuff revealed in my analysis of Pepex:

That SMTP server is an exact string from the Pepex sample I took apart previously. Those other addresses could make for some interesting signatures once we get to that point. After this, we see many strings of inexcusably horrendous passwords (crap like 1234, angel, password, passwd, BUMBLE, asdf, asdfgh, 4321, db2admin, and so on).

I see what looks like the framework for constructing an IP address dynamically:


Below that, something very interesting:

Subject: Hello
From: <
From: “Microsoft” <>
Reply-To: “Microsoft” <>
Windows Genuine Update
Windows Update

This looks EXACTLY like some of the info pulled from Pepex. We see the same email addresses in use as in that other sample. The IP address points to Google. I’m starting to think that this is a Pepex variant, if it wasn’t already pretty clear. Strangely, the antivirus products weren’t too consistent in naming this sample when scanned, though I recall that one of them did identify it as Pepex. I wonder if that lsascv.exe file is what the sample uses to install itself and achieve some stealth, and the Windows Genuine Update string points to additional stealth / persistence methods.

Further on, we see:

Subject: %s|%s|%s

Again, something to keep in mind. This might do something with lsass because of lsass’ privilege levels and API access. Finally, that Subject: %s|%s|%s is the same string we saw in the other Pepex sample for constructing the spam subject line.

We see a bunch of OS names:

Unkown [sic]

I find it interesting that this is the same list as in the other Pepex sample, however Win7 is not here (which I wouldn’t expect from a sample created in 2004). Perhaps the reason why we had so many problems with the other sample was because someone tried updating the code and screwed up.

I see many imported function names, but I’ll look at those when I view the file in PEview, as it’s an easier interface. One final and very interesting set of strings:

!This program cannot be run in DOS mode.
Corrupt Data!

Looks like we have another file inside. I’m not sure what a .petite section is but it’s not a normal section like .text, .rsrc, .rdata, or others. Some weird error messages follow, so perhaps this is a packed file within the previously packed malware. After that I see a handful of process names and library imports, so I think we’ll need to continue digging to get to the bottom of this.

PEiD doesn’t detect and packers, under any settings. KANAL, however, detects a zlib deflate reference at 0000BE74 / 0040D474. Resource Hacker shows an obvious file stored in the resource section that is named “FILE”:


This file, however, is packed, using Petite 2.x:


KANAL also sees a reference to zlib in this file from the .rsrc section. Depending on how it goes analyzing this malware, I may look at this file in a follow-on analysis. Also, please see the following note from the readme file inclued with the current version of Petite, which is another reason why I’m probably going to tackle this in a subsequent analysis:

There is no Petite decompressor. So if it is not possible for you to
reinstall or recompile a file, then you should keep a backup of the
original incase[sic] you should want to go back to it at any time.

Opening the main malware file in PEview doesn’t reveal anything weird as far as some possible anti-debugging stuff – number of data directories is 0x10 and no TLS table. Imported libraries are Kernel32, User32, AdvApi32, and WS2_32. Here are some of the interesting things that can be seen as imported functions under each library:

RegOpen/CloseKeyExA, RegSetValueExA, Create/Open/Start/DeleteServiceA: Based on these imports and the prior work done on the other Pepex variant, I’m guessing that this is used to both achieve persistence and also start the malware as a service.

CopyFileA, WriteFile: I see a call to CopyFileA but not to DeleteFileA, so maybe this file makes a copy of itself and then deletes itself some other way when it installs. This also could mean that this file relocates some system file so that it can put itself in between the user and the legitimate file (maybe it gets in between lsass.exe, for instance). I suppose that one clue that this is not the case is that I don’t see any exports, but we still don’t know how the file from the .rsrc section functions yet. WriteFile is always good for looking for file system signatures.

WaitForSingleObject: perhaps this malware creates a mutex.

CreateProcessA: Always good for signatures, and also this means we’ll need to look out for child processes of this main malware process. Could possibly also be used to load drivers.

The interesting thing here is that I’m only seeing client-side functions imported (socket, connect, send, recv) but not server-side functions (like bind, listen, accept).

Dynamic Analysis

For the dynamic analysis, I ran and recorded the packed malware two times – once as a regular user, and once as an administrator.

Watching the run as a regular used showed a ton of activity taking place in Wireshark. RegShot didn’t reveal much going on. There was a UserAssist value added under HKU, but other than that, no other changes in the registry or file system that could be linked to the malware (speaking strictly from the RegShot perspective). Process Explorer revealed only the single malware process being created (PID 2576) but nothing else. It could be we missed other stuff happening in Process Explorer, so we’ll look at Process Monitor and other places too. I’m not seeing anything in Autoruns, so perhaps persistence wasn’t achieved.

Looking in Process Monitor, I see that the malware did not appear to spawn any child processes. The main things observed, some of which match up with the static analysis, include:

– reads the current version of Windows through HKLM
– many registry keys related to networking are queried
– the malware gets the computer name from the registry
– the malware creates 256 threads, and this is the final set of actions recorded by Process Monitor

I’m not seeing any files being written, or any registry entries being added or modified (values or keys). The Wireshark traffic is more interesting. In only a few minutes I could see a few tens of thousands of packets being sent out to apparently random IP addresses. Take a look at the protocols:


Basically all TCP. I didn’t see any addresses resolved, however endpoints revealed something interesting:


Thousands and thousands of lines of traffic on port 445, which is associated with SMB (which is where this sample came from on the honeypot, by the way). Looking over on the UDP tab of this window:


We see traffic on some broadcast IP addresses and on ports 137 and 138 which, for UDP, are associated with SMB also (NetBios API). There’s also traffic on port 1900, which is the UPnP port that we saw a lot of action on in the honeypot statistics.

Reviewing the recorded malware activity that was run as an administrator didn’t reveal any new or different behavior. The same activity both on the host and the network was observed.

I didn’t see any activity on the IP address we found in the strings of the malware ( I dumped the traffic from Wireshark and then ended up with 39,203 unique IP addresses from that. I did a little research into where these IP addresses were located, and with whatever whois data I was able to obtain, the vast majority of the IP addresses are in the USA with some falling outside the country:


Disassembly and Debugging

Opening the unpacked malware in Ida, the first thing we see the sample do (in winmain) is call WSAstartup, and then then there is a call to a sub at 4020E0 which imports some DLLs. The DLL names are obfuscated, and 4020E0 builds the imports in the same manner as the other Pepex variant. Following some branches, which I’m finding difficult to figure out just using Ida, we either move towards a “scanning” branch (which is the behavior that I’ve observed so far) or towards the installation branch. The installation branch begins with a call to 401950, which starts with loading the binary that is in the .rsrc section and then writing it as %SYSTEM%\lsasvc.exe, which makes for a nice file system signature:

Then, later on in this sub, we see the file being written and then a process being created from it.

The next sub that is called, 4018E0, sets up persistence for the newly installed malware by adding it to the registry (under the name “Windows Update”) to run at startup:


This also makes for a nice host signature under “SOFTWARE\Microsoft\Windows\CurrentVersion\Run”.

Sub 401000 involves some calls to gethostbyname and then a loop that writes a series of IP address strings to a buffer. After this, we see a string being put in a buffer:


Then we see a call to GetVersion and then the system derives an OS name (one of the strings mentioned earlier such as “WinVista”) and this string is passed to the buffer also:


Following this, we see an email address being pushed onto the stack and then we get into some really interesting stuff beginning with a call to 401210:


Before getting into 401210, I’m going to take a quick look at the alternate branch that this sample seemed to follow when I ran it in my test environment. This is the branch that was taken at the conditional jump at 40243F which branched us away from the installation/system inventory/email generation branch and instead did the IP scanning and thread creation.

Going down this alternate branch results in a call to Sleep (for 100ms) and then an indirect call to sub 402C50. This is a somewhat large sub that generates IP addresses through a combination of calls to GetTickCount and generated random numbers. There is a loop related to thread creation, and we can see where the condition jump is put in place in order to create the 256 threads we observed during the dynamic analysis:


Note that I displayed the number in base 10 for clarity.

Also within this overall thread creation/scanning sub, there is a call to a fairly deep branch called sub 402840. This sub begins with establishing some network connectivity and then calls another sub, 401F20. This sub contains several indirect calls (annoying). I see something being done with the string “administrator” so it’s possible that this is some sub that either logs into an account somewhere (or tries to do so). We do see a call to sub 401AE0, though. This sub makes a reference to IPC, and then appears to send system inventory information to the address:


Then after that we can see stuff being done with lsass.exe (notice also the hard coded directory of \winnt\ rather than an environment variable). Here are another couple of examples of hard-coded directory references:


After setting up with these paths, we see a call to 401800. Here we see the malware being set up and started as a service:


Windows Genuine Update” and “Wupdate” are nice signatures to be aware of.

Going back to the large branch, where we really get into the heart of this thing, sub 401210 begins with a connection to and then a check of connectivity. If we get past that, then the malware starts to build a set of SMTP commands:


This gets sent, and then checked for errors again:


If at any time we have an error, the sub will exit. Next we see more SMTP commands being built, this one showing that this mail is from


Continuing through the code, we see where the recipient email address is passed via SMTP, and then we see where the malware starts to build out the area for the body of the email:


After this, we get to an area that I’m not sure I fully understand:


What it looks like is happening here, is that the string “” is pushed onto the stack twice, and then these two strings are compared with a call to strcmpi (which is deprecated according to MSDN). Then, there is a conditional jump based on this comparison – If the strings are the same, then the function should return 0 and therefore this conditional jump should always be followed in this instance, which would take us down the branch on the left. If anyone out there has a better understanding of what is going on here, please let me know, as it appears that we have a situation where there’s a condition jump that is never followed. In any case, on the left branch, we see some more signatures that were common with the other Pepex variant analyzed (,

At the end, we see the wrap up of the SMTP traffic and the return:


At this point, I’m done looking at this sample. As we’ve seen, it’s closely related to a prior sample, except that this one actually seems to work so we were able to observe more functionality. I might take a look into manually unpacking the file in the resource section since this is a packer that is new to me and this might make for an interesting analysis.

Findings and observations:
Mass-mailer worm. Similar to the prior sample analyzed, which I believe was derived from this new sample as this sample did not appear to have the execution issues observed previously. Sample appears to both scan new IP addresses, both for remote and local systems, probably with the intent of spreadnig itself. It also contains functionality around reporting system inventory and sending spam messages.

– Block ports 445, 137, and 138 as this is where this sample was obtained and this sample was observed connecting to remote and local systems on these ports
– Usual recommendations against opening unsolicited mail (especially with attachments)
– Filter email associated with “”, “”, and “”, “”, “

Interesting, old malware. It was good to see this worm running successfully so as to get a better opportunity to view its capabilities.



Manually Unpacked:

Automatically Unpacked:


New sample in from the NYC honeypot – 50/54 detections on Virustotal, so let’s take a look.pepex1

UPX is a popular packer used more for compression than security. Packing the malware does obfuscate it, but typically UPX isn’t very hard to figure out compared with certain other packers. We can actually see some stuff “leaking” through the packing:


At the end we see a tiny number of function names, along with .dlls such as WS2_32.dll and others. Along the way I saw bit and pieces of a string that suggest that this malware might construct emails, so maybe this malware is spam-focused.

PEiD confirms this, and also gives us some other info like the entrypoint:


There are various ways you can approach unpacking. Something like UPX can probably be unpacked with an automated tool (which I actually end up doing later on in this analysis), but I actually like unpacking things manually. One thing you can do is open the file in IDA and see if there are any “far” jumps within the code, as this is probably the start of the unpacked code. In this sample, the entry point of the malware was at 4098A0, but a little bit down from there at 409A2C I see this:


Sort of strange to see a jump to a place relatively far away from where we are now. I opened this in Olly and set a memory breakpoint (on access) at 404C50. After this breakpoint was hit the first time and I noticed that code started to appear where there was previously just meaningless data, I set a regular breakpoint and then came back to this area once that was hit:

pepex5I’m using a plugin called Ollydump to dump the unpacked process:


We still see some of the same UPX-related junk in the beginning, but looking through the strings, we start to see some really interesting (and unobfuscated) stuff:


Now we can really take a look through this thing.

Static Analysis

Running strings on the unpacked sample, one of the first things we come across are what appear to be really bad password choices:


There are some that on first glance appear like they might be not completely horrible choices like “baseball”, but those that look like they might be OK are actually just some silly keyboard patterns, such as “qazwsxedc” which is just the first three alphabetic columns on the left side of an English keyboard. Moving on through the strings, we start to see a few more interesting things such as what appears to be the construction of an IP address and what might be a name given to this process in case it’s run as a service:


Few more pages in, we see some SMTP commands and some strings that look like they are part of an email to make it seem more legitimate, as well as some specific IP addresses:


Going through function names revealed by strings and by PEview reveals some interesting info about how this sample likely operates (meaning, until I observe the sample I can’t just assume that this is definitely what it does regardless of what functions are mentioned or imported):

– I see several functions around opening/copying/deleting files as well as functions related to the temp file path. I always like to see these because it implies that there is going to be some file system change taking place that can be used to both construct a signature and also identify the malware objectives. One string recovered was “Isass.exe” which is supposed to mimic “lsass.exe” – perhaps this sample copies itself somewhere as “Isass.exe” as a stealth measure.
– WaitForSingleObject appears to be called, so there might be a mutex created by this malware that could also form a signature.
– I see multiple functions related to services such as OpenService, CreateService, StartService, DeleteService, that suggest that this might be how the malware achieves persistence and stealth. I saw a few strings earlier that might make for good fake service names to blend in with other, legitimate services running on the host.
– There is an import of WS2_32.dll and several functions such as connect, socket, listen, bind, send/recv, gethostbyname,WSAstartup, inet_addr and so on that suggest that 1) there is a networking component to this malware and 2) since this is a lower-level networking dll, there will probably be some fabrication of traffic info (such as header info) to make the malware traffic blend in better with legitimate traffic, which also helps us identify network signatures (particularly in the case of poorly-written fake headers).

PEview reveals nothing unusual in terms of possible anti-debugging steps (i.e., number of data directories looks fine, no TLS). KANAL detects no known crypto signatures. I saw strings that look like a “normal” set of sections (.text, .data, .rdata, .rsrc) but Resource Hacker wasn’t finding anything. I might try to mess around with this later to rename the sections in the unpacked header, but for now I’m just taking note of this in case it’s useful later.

Dynamic Analysis

I tried running this sample multiple times, as a regular user and as administrator, both with a simulated Internet connection and on a real one, but absolutely nothing appeared to happen. The packed sample ran and then exited, while the unpacked sample crashed shortly after execution.

Nothing interesting is coming up in Wireshark, process explorer, autoruns, or anything else. The process monitor data basically shows the malware process being created, some registry lookups (nothing obviously interesting there either), some libraries being loaded, and then the malware terminates.

I’ve seen strings that suggest that this malware could run on various versions of Windows, including Windows 7 which is what I’m running in the analysis VM. Perhaps there is an issue with the Windows environment, but at this point I think that there must be some issue with the malware not liking VirtualBox. I’m going to have to look through it in the disassembly and the debugger to see what seems to be preventing this sample from fully executing.

Before doing this, I tried a couple of other things. One was I ran the unpacked sample through Import Reconstructor (ImpRec) to see if maybe there was just an issue with the way the import table was set following the unpacking.


This didn’t help, the sample still crashes. During a quick glance through the disassembly, and during debugging, I didn’t notice anything checking for artifacts left over from VirtualBox or VMware, but even so I tried terminating all VirtualBox related functions and then rerunning the sample, but it didn’t help. It’s possible that this is just a poorly formed piece of malware that isn’t working right in my environment, but that seems too simple of an explanation, so I need to dig into the disassembly more.

Disassembly and Debugging

Basically what’s observed when debugging is that this sample almost immediately starts to encounter exceptions. My feeling is that this isn’t simply an anti-debugging / anti-analysis technique in place. There absolutely are some things that look suspicious when I run the sample in the debugger (for example, a call to NtRaiseException followed by INT 3, or there MIGHT be something going on with the PEB structure beginning at fs:[30]), but the thing is that this sample doesn’t seem to function at all outside of the debugger either. The unpacked version crashes shortly after execution, and the packed version runs some innocuous functions and then terminates. I see many exceptions taking place, but nothing that appears to look for a VM (either VMware, VirtualBox, or another). I looked through all of the process monitor results to see if the malware checked:

– user/computer name (it checked the username, but this would not indicate a VM)
– registry keys/values (it did check some, but nothing checked would indicate a VM)
– Files/directories associated with VirtualBox or Vms

Nothing was apparent. I checked the unpacked disassembly for:
– CPU instructions (sidt, sgdt, sldt, smsw, str, in, cpuid)
– Timing instructions (rdtsc, GetTickCount, QueryPerformanceCounter)
– GetTickCount is actually seen many times but not in an anti-debugging context
– Checks on running processes, services, or mutexes
– Hardware info checks
– OS info checks (it checks for the Windows version but nothing that would indicate a VM)
– Checks for INT 3 or others such as 0xCD03 (there is a line where 0CCh is moved into AL, but this is part of a coding sub, and not related to anti-debugging)

I’m just not seeing anything that indicates that this thing is checking for a VM or a debugger. One thing I did notice however, was that there seems to be an issue in the code between the packed and unpacked versions of the malware:

Packed location 404C50:


Unpacked location 404C50:


The OR DWORD PTR DS: [EBX+68FF6AEC], 004051C8 instruction doesn’t make sense and immediately starts causing exceptions, which then seems to send the unpacked version into a tailspin. I’ll use the unpacked version just for disassembly, but will continue trying to debug the packed version.

I eventually got UPX and used it to automatically unpack the sample, and the unpacked version is much cleaner than what I had dumped manually. There is a section at 404C50 that pretty much matches exactly what we can see at the RCE Endeavors blog as something that sets a new exception handler which would allow for sneaky code execution. I feel like there has to be something there. Looking at the code that was unpacked by the malware again:


Following along with the article, at 404C53 we see 0FFFFFFFFh being PUSHed and then 004051C8 PUSHed (scope table and the try level). At 404C5A we see PUSH 00404DD0, which is a jump to __except_handler3 (4 being the topmost exception handler, IIRC). Then we see the value at fs:[0] being put into EAX (fs:0 is the start of the TIB, and in my case is 0018FFC4). Then this is PUSHed, and the stack pointer is moved into fs:[0] (which, in my case, is 0018FF78). This is what we see at 0018FF78:


This is something I’ll have to come back to someday, as I can recognize that something is going on here but I just can’t figure out what. On one hand, it makes no sense to me that someone would create and propagate a worm that didn’t work. On the other, there are some design decisions in this sample (like hard coding directories, plaintext domains and IP addresses) that calls into question the quality of the construction. I’m going to concentrate on disassembly of the rest of the unpacked file to try to see how the rest of it works.

404C50 is where we see the shenanigans with the SEH:


Down below at 404D7F we see the call to WinMain.

Inside of WinMain, we see a call to __p____argc and then a comparison, then where the code wants to go is to the left side (i.e., not take the jump):


However, as soon as the call to StartServiceCtrlDispatcherA happens, a non-continuable exception triggers. Following this doesn’t get my anywhere, so I’m going to go back to where this JNZ occurs and make sure that we follow the jump:


Getting to the next block at 402F3B, the jump is taken again so I’ll modify the flags and avoid the jump again. Getting to the call to ds:strncpy, the sample again hits exceptions, so I’m just going to through the disassembly and stop debugging completely for now.

The code on the right is a bit funny because I did get that to execute successfully in the debugger, and you’d think that a malware author would not want the malware to have error messages pop up. This is one of those examples I’m thinking of when I question the design of this sample.

Below all of this, we see a couple more branches but both ultimately call sub 402C30. This sub calls 402050, which reads a file called stm8.inf located in the Windows directory (or we see this being created if it doesn’t exist). After this takes place, we see a call to a sub at 402970 which involves moving lots of data into various registers and then several calls to sprintf to write this stuff to buffers. After those sprintf calls, there are several calls to LoadLibraryA and then several calls to GetProcAddress, so here we’re seeing the sample call several different libraries and functions before moving on to the rest of the code.



Again, if this sub fails, then the code exits. The pattern here is pretty much if any of these parts fail to execute successfully, the code will terminate. This might help explain why the code appears to do nothing when being executed in the VM. Following the success of the previous sub, there’s a call to WSAstartup (version 2.2 requested) and then the code flows to a call to sub 403BF0.

403BF0 is a large sub that begins with moving the byte 88h into BL before storing a string (a total of 0x40 times, based on the value moved into ECX) and moving several more bytes into other offsets:


I opened this in the debugger and patched the code to call 403BF0. This initial block creates the following string in memory:


The next bit of code loops through this string (up to 16 bytes long) and then XORs each byte with 0xEF, which leaves us with the string


This string then gets PUSHed and then sub 403170 is called to work with it. There are several subs nested here, one of the main ones called next is 4049F0. Within sub 4049F0, you see a call to DnsQueryA and then you see several strings being put on the heap:


The strings are:

If 4049F0 is successful, then you jump over the call to 404AF0 which appears to gather network info on the local host and then I presume tries to gather the info above in another way since following this branch would mean that 4049F0 failed. Back in sub 403170, there’s a call to GetTickCount and then a test between AL and 3, then a conditional jump to either exit and return 0 or continue with the function. In my debugger the code continued and took the string and passed it to a call to 403070. We see more work being done with the string, the heap, and calls to GetTickCount. We then pass the string to 403030. More comparisons, more movement of the string, and finally the entire 403170 sub returns and we end up at 403C75, where we come upon another interesting set of branches:


The debugger isn’t following the jump (which leads to another XOR decoding). For now I want to see what’s in the XOR branch so I’ll mess with the flags so we go there.


As you can see, it just ends up decoding Much later on in this branch, we see that string being passed to sub 4031D0. There we see a call to GetHostByName, and if that fails, then the function returns 0 and eventually this branch dies (I’m not connected to the Internet while I am running this instance), but I’ll change the flags and keep this going. Eventually this branch loops back up and runs through the same iterations but for the “alt%d” variations such as alt1,2,etc.

All roads seem to lead to location 403E4E, which checks to see if any of the branches leading up to this point were successful or not – if not, we exit. If they were, then we continue on to the hard-coded IP address blocks.


You can see the string being moved into EDI, and then shortly after there’s a comparison using that string, and then in my case it moves on to the next string which is 173.1944.68.27, and so on until it finds the IP it wants or it runs through all of them. Then, the return is made to 402C30, which we left a long time ago, it feels.

At this point, something weird happens again involving exception handling, and we find ourselves blown out into 7- land (so to speak), but I patched something to get us back to 402C92 which is where I wanted to continue from. We see a call to GetModuleFileNameA (which fails, incidentally) and then a call to GetUserNameA (perhaps to form part of the data used to create the mass emails?) and then the username is passed to strupr to make it all upper case.


We work our way down to 402D79 without any further intervention in the debugger, and it appears we’re in the right place to begin constructing totally legit-looking emails:


But first, a call to 4019C0 where it looks like we have another one of those encoding subs. The first encoding loop here decodes this little string:


ows\\CurrentV. Next loop in this sub decodes:


E\\Micro. Next loop:


ersion\\R, then:


SOFTW, then:


soft\\wind, then finally this entire mess gets passed as “SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run” under HKLM to RegOpenKeyExA:


If this operation is successful, then we skip the rest of this sub. If not, then we go on to decode more stuff and do more things, so I’m going to keep going on this branch.

Soon we see a call to LoadLibraryA for advapi32.dll, and then another XOR decoding:


The malware decodes the string RegSetValueExA:


kernel32.dll gets loaded, then the function RegSetValueExA is imported:


Then later we see what appears to be this malware being set up to run at boot under the guide of “Local Security Authority Process”:


We can see this change being made in Process Monitor:


It’s also apparent in Autoruns, though it appears the name of the file isn’t quite there just yet:


Then after all of this, a call to RegCloseKey and then back to the other sub where we can finally get into crafting some email (I hope)!

A few dozen lines in, I see a strange subject line being created:


I also saw the user name string that was converted into all upper case earlier. I accidentally stepped-over one of the subs here at 401E90, but in there you see that and a nested function create and bind a TCP socket and then call listen, looping until the string “” is seen, then back to the previous sub. We see the string “Subject:” put in a buffer with a call to sprintf, and some further manipulations of strings. There’s a call to sub 402350, where we see a call to GetHostByName (a deprecated function, according to MSDN, which probably speaks to the age of this sample). If this function fails (which it did in my debugger), then the sub returns, otherwise it builds a string out of an IP address from the GetHostByName call. Soon after this, we see the “Subject:\09h\30h\09h\30h” string in its current form being passed to a call to 402170.

Sub 402170 is the sub where the Windows version is obtained and named using one of the strings we observed earlier, e.g. “WinVista”, “WinNt”, “Win2000”, “Unknown”, “WinXp”, “Win2003”, “Win7”. This done via a call to GetVersion and then parsing that info to identify the version. The sample correctly identified the version running in my test environment (Windows 7). Before returning, there is a call to a sub at 4022C0 which is to obtain the local and system time, and then this information is parsed into various pieces such as day, month, year, hour, etc. I imagine for the purpose of constructing the mass emails. Returning from these subs, we see that our subject line continues to change:


After all these changes to the string, including a few more minor ones, we return back to 402E92, and the a few lines later there’s a call to 4033C0 – THIS finally seems to be the construction sub. It begins with a whole lot of byte movements, reminiscent of the XOR encoding though I don’t see that happening here:


After ALL of these many things are MOVed around, we pass through a few conditional jumps that either take the whole mess and return (returning 0) or we do actually get to an XOR decoding loop – I didn’t have to intervene to get there, and the first string decoded is “nbweinf12160”:


So as not to make you sit through every loop like I did earlier, here’s what we get at the end of these three loops:


nbwein12160 [this email is no longer valid, by the way]

We get kicked over to a call to 403340, which is a sub that tries to set up some networking with one of the hard-coded IPs mentioned earlier, where we also see a call to ioctlsocket (nonblocking).

The debugger wants to follow the code over to where there’s another decoding sub called (402C70), which receives our subject line as an argument. Oddly, this branch re-encodes the subject line that was being constructed and then basically breaks everything down and exits. I’m reloading the VM snapshot and trying the other branch…

Unfortunately, that other branch also died, running into exceptions. Perhaps this is because of the patching I’ve done, maybe things are messed up now. I’m going to just try to get back to the SMTP part of the malware and see how that works.

I patched that last line of code to JMP 403690, so I can see how the SMTP commands are sent. Not too far into that sub we see the first SMTP command being constructed and then a large block of code related to a call to send:


Long story short, we see HELO ( being sent:


Since I’m not really letting this thing connect to the Internet, it tries to exit but I’ll keep intervening to keep it sending info. Next up is another big block of code, all pertaining to a call to send:

We can continue to observe the SMTP commands being sent in this manner. There are numerous conditional jumps throughout the code that necessitate intervention in order to keep going on the path I want. We see a few calls to GetSystemTime and some random number generation before the construction of the command that specifies the destination email address (in this run, no email address was populated):


It seems that this is meant to be a “Microsoft News Letter”:



We eventually see QUIT being sent, and then the socket getting closed:


And then the malware had a meltdown since I had been patching all kinds of stuff to jump around. This is about all I want to really check out in the malware in tandem with the debugger. Some other highlights include:

– Sub 401000 is where the malware appears to install itself by copying itself as the file Isass.exe (a string we saw earlier – it places this file in the %system% directory, though I’d point out that in this file it tends to hard code these areas (e.g., one branch of its code refers to the c:\windows\ directory, rather than using the environment variable)
– Sub 404010 shows that it attempts to run itself as a service called “Windows Genuine Updater”:


– Sub 404110 attempts to open this newly created service and start it
– 4015D0 looks like it might generate IP addresses using a combination of calls to GetTickCount and random numbers

Dynamic Analysis, Revisted

Now that I actually got the sample to do something, I’m going to revisit some of the things I would normally try under dynamic analysis which were unrevealing due to the sample not fully executing.

Taking a look at Wireshark, there actually was almost nothing that seemed like it could have been attributed to the malware except for a DNS resolution to which was something that was observed when I was forcing execution through the debugger. I suspect that the reason why there isn’t any SMTP traffic being observed is that while I was forcing execution of the malware in Ollydbg, networking was never completely started via a successful call to WSAStartup.

RegShot does show the following change being made to the Registry, as we saw earlier in the debugger and in Autoruns:

HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run\Local Security Authority Process: “ %1”

Other than this, nothing else interesting came out of RegShot. Process Monitor also didn’t have anything interesting in it, apart from what was already discussed above.


This was a weird sample to work on because of the issues getting it to run. I don’t have a dedicated physical testing system, otherwise I would have tried it on there to see if I could get it to run properly. I’m torn between whether this was a very sophisticated sample that employed anti-VM techniques that I couldn’t detect (like the SEH shenanigans referenced in the post) or if it was just not well-written and this was causing the execution issues. Just because I didn’t find something doesn’t mean that it wasn’t there, but on the other hand my opinion is that there were several questionable design decisions throughout the sample, so… Not sure on this. This type malware appears to be very old. I’ve seen references to this worm going back as far as 2002, so perhaps this would help explain some of the execution issues also.

I didn’t see anything obvious as far as how the malware gets its email addresses to mail to, however we did see many examples of what appear to be bad passwords hard-coded in the sample. My intuition is that this program tries to harvest email addresses from the host computer. I didn’t see any C2 functionality in here, so I suppose this is sort of a fire-and-forget piece of malware. This sample doesn’t appear to have any clear goal in mind, so maybe it was created for its own sake.

Persistence is attempted via the registry and creating a copy of itself (Isass.exe) that is meant to resemble the lsass.exe file. Persistence wasn’t fully achieved, probably due to the malware not functioning correctly as I forced it through the debugger. I also didn’t see any movement of this sample through a network (or really anything like this in the code), though again, the sample wasn’t functioning 100% so I’m not sure it’s wise to completely rule it out.

Finally, it seems that Pepex is a fairly consistent name for this sample, so no need to name it like I did with BEAR.


Findings and observations:
Mass-mailer worm with execution issues. Design flaws reveal functionality and signatures. This sample was first observed 14+ years ago, but doesn’t seem to have any obvious malicious function besides wasting resources.

Detection is very high for this sample, probably due to age, so up-to-date AV probably would help mitigate this sample. Not opening suspicious files received via email or other routes also stands for this sample. Use of strong passwords (and definitely NOT the very poor examples found in this malware) is advised. Removal can be done by modifying the registry entry for persistence (if successful in the first place) and also the Isass.exe file.

Interesting to see this very old piece of malware, even if it didn’t fully run in the test environment. Not a terribly destructive sample, mostly just annoying.

Report: MalEXE002pdf


Manually Unpacked:

Automatically Unpacked:


Egyptian Hak

I decided to check out an unusual file I received in my Hotmail account. This one was much older (received in November of 2014) but I thought it was interesting because it was a 9 mb Rich Text file. The sender was Some excerpts from the letter can be found below in the raw notes. I think a nice touch is that the letter is signed “Mr. Andrew Moor” but the signature appears to be Abraham Lincoln’s.

I went through the RTF specification looking for control words that could offer information about the author or lead to code execution and the like. Checking various tags didn’t reveal much, however I did see some info such as:

Author: user [oh, him]
Operator: PC13
Company: egyptian hak
Generator: Microsoft Word 11.0.5604

The reference to Egyptian Hak is a whole other topic that I might address at some point, but for now let’s leave it at this: There seems to be a cracked version of Windows XP SP3 (that comes packaged with several cracked utilities) circulating through the Arabic-speaking world (and concentrated in Egypt) and it was created by someone calling themselves Egyptian Hak. At some point I’d like to sit down and really dig into this but that’s all I want to do for now. My working assumption is that whoever created this document was running a copy of this XP “variant”, if you could call it that.

The version and build of this version of Word is interesting. The version indicates that this document was created with Word 2003. I would expect to see two numbers, one indicating the build number for the program and the second for build of the core Office shared library (MSO). This build number doesn’t seem to adhere to this format, but according to David Vielmetter’s website, this appears to be an original MS Office Word 2003 build (i.e., not a Service Pack build).

There is a reference to a website in this file:


This is interesting to me because this link goes to what appears to be a legitimate website and organization (a museum in British Columbia). I wonder if 1) this is a legitimate image that happens to have been hosted there for legitimate reasons that has been appropriated by the document author or 2) if this image itself is malicious and/or was put there due to some sort of unauthorized access on the part of the document author.

Running this through various sandboxes revealed nothing too special. I’m a bit frustrated because it seems like I have this document file that doesn’t seem to be much else other than a written scam (no links, no executables, no shellcode signatures detected, etc.). Opening the file didn’t indicate anything happening – no files written/dropped (aside from the usual), no network traffic, no registry changes. I can’t believe that people would bother to send out documents that are nothing more than form letters – I could be looking for something that isn’t there, so I should be careful not to find things that aren’t there, but I also feel like I need to dig deeper into this sample.

My next step was to look through the document for anything that might indicate shellcode. Where the images are displayed in the Rich Text Format, you see lots of raw data:

I searched the text of the file for any sections that might look like code to convert to a binary file. As you can see, there were two strings with three instances of NOP which are going to be where I’ll focus. The first hit at offset 0x8B20E3 also had three instances of opcode 0x4F, which would be DEC EDI in x86 assembly, following the NOPs (these two groups being separated by 00). The second group of NOPs at offset 0x8B1C8A didn’t have any opcodes in the 0x40 to 0x4F range following it, but I’ll look at that offset anyway.

I searched for occurrences of at least three of the following opcodes, and I got the following results:


My list of “interesting” offsets, such as the already mentioned triple NOPs and also other areas where I saw many possible opcodes together (e.g., a string like 4242424A4A4A424242 or up to five occurrences of the same potential opcode) is as follows:


At this point, I feel that these are probably the most promising areas to look at in terms of possible shellcode. To save the trouble of converting these sections into binary files, I decided to use the online disassembler at again.

Going through the disassembly of all these areas was disappointing, as it all resulted in garbage. I even put the entire file through just to see if anything stood out, and nothing resulted. The .JPG that the file links to didn’t have any triple occurrences (or more) or any of these opcodes either.

I’m pretty much at a dead end with this one. I also went back through procmon in detail and didn’t see anything interesting going on in the system. If nothing else this was a good exercise on the Rich Text Format. I’m also going to reach out to the website’s admin and see if they know about this file and how it’s being used.


Findings and observations:
RTF file containing written instructions for some sort of financial scam, clumsily executed. Possible Arabic speaker as author. No dynamic behavior observed myself or via sandbox.

Usual guidelines against opening strange attachments still stand. Admin of the site linking the image might want to review security, specifically around how that file appeared on their site.

Scam message, no apparent malicious activity. Possible that any exploits in this sample might just not be effective running on the current test system.



First attempt at analyzing a “real” file

I collected a bunch of presumably malicious documents from my Hotmail account that has turned into a great repository of spam and malware over the years. I’ve had this email address since 1997 and I regularly get phishing email sent to me, containing both links and files (typically MS Office documents, .PDFs, and various compressed files). Since I just finished working through Practical Malware Analysis, I thought I’d try analyzing some of the crap that gets sent to me on a daily basis.

I created a shady Russian email address that I use for forwarding all my malicious email. I don’t really want to have my email account that I actually use open while I open or run any of these attachments, so I just forward the messages to this new address and then use that to download the attachments. I access the account through a VM running on a different platform than the guest OS (in this case, I run Linux as the host and Win7 as the guest) on a burner laptop so that any “containment” issues hopefully won’t become too much of a problem.

It’ll be interesting to go through these files to see what types of malware one tends to find here. In speaking with people at conferences and reading various documents over time, I have gotten the impression that downloaders/launchers are probably what I’m going to find in my inbox. You could think of these as the “first stages” that help to get malware into orbit. You might have a piece of malware that’s particularly large, so the downloader/launcher might check the target system for certain conditions before downloading and launching the payload. For instance, you might have a downloader that might check for a particular vulnerability, or maybe check for various indicators of an analysis environment, such as being run within a virtual machine. Another reason one might want to use a downloader/launcher is so that the actual malware payload isn’t delivered until it seems “safe” to do so, so that any analyst doesn’t have much to work with.

This particular email came from on 28APR2016. This domain appears to have been registered about a month and a half ago. While it was registered in Malaysia, we are meant to believe that the owner is in the USA based on the whois information (though I can see that this name and email address associated with that person also appears to be associated with some other shady activities). This email also contains a link to download a purported PC Clean Up tool as well as a single link to an actual SANS webpage.



After downloading these files, I ran them through some basic static tools like Strings and KANAL, and then through various .PDF Python scripts such as those from Didier Stevens. The only interesting things I saw were a bunch of URI functions that linked to sketchy sounding websites and files such as PcCleanUp.exe. PDFStreamDumper suggested that there might be something hidden in a few streams.

I started up a bunch of tools for dynamic analysis and then opened the document, but didn’t observe anything special happening. The .PDF itself is a very ugly looking advertisement for SANS cyber security training classes, with links to various files such as an .EXE, a .ZIP file, a WinACE compressed file, an .SCR file (possibly a screen saver or a Steam-associated file), and an .RTF file. I would have really liked to have gotten some of the hosted files to look at, but by the time I opened these attachments (about two weeks after receipt), the links were already dead.

I didn’t get much out of this file with some of the online malware sites. Virustotal has only a 1/55 detection ratio (Sophos only Sophos detected what it thought to be a trojan). Malwr indicated that no hosts were contacted, but did detect some shellcode byte patterns and a SQLite 3.x database dropping.



I went back for another look through this sample to check out the SQLite db and the possible shellcode. Malwr says that the SQLite db dropped was in a file called SharedDataEvents, so I went and found that in an Adobe directory for the current user (see raw notes below for specifics). Some reading revealed that a SQLite db file will begin with the string “SQLite format 3\000”. It seems that any random binary could be given this string in the beginning and then create a false positive, so I went and got the SQLite file format from and took a look through the header.

The header seemed to check out. Everything seemed to be in the right place – the file size (3072 bytes) makes sense given the page size at offset 16 (1024 bytes) and size of DB in pages at offset 28 (3). Text encoding (offset 56) for the db is UTF-8. Opening this file in DB Browser shows two tables, pref_events and version_table. pref_events held no records while version_table held only a single record consisting of the integer “4”.

Looking on my main machine, though, this db just seems to be a part of Acrobat Reader’s normal operation. A little searching also indicated that you should see Acrobat making use of a SQLite db, so this seems to fit. I took a .PDF that I knew to be fine and ran that through the same sandbox, and got inconsistent results. With this clean .PDF, it didn’t report that it saw a SQLite db drop (though if you look in the files dropped area on the websiet, the db did drop, and in the same manner as with the the malicious .PDF). The clean .PDF also doesn’t show any shellcode signatures detected(which is to be expected). As interesting as it is to go through how Acrobat and .PDF files work, I’m going to conclude at this point that there’s nothing nefarious about this or other files that were observed being dropped or written to.

Moving on to search for shellcode, I had looked through the file in a couple of areas where PDFStreamDumper indicated there might be something hidden, but didn’t see anything that looked like obvious shellcode. I went back through the file again, this time looking for any instances of the following opcodes which would indicate a call or various kinds of jumps or loops (thanks again to PMA):

0x70 through 0x7F

I should note that disassembly and debugging is a bit of a challenge as I am working with the free license of IDA Pro (5.0) which will only support up to 32-bit disassembly, and I have a similar situation with Olly and Immunity. At some point, budget-permitting, I definitely plan to upgrade my license. I have a few different tools I can use for 64-bit, though, so I’ll rotate through them and see what I can get.

I noticed a few areas where there were bytes that could be used to make jumps, so I turned those into code in IDA to see what would happen. These led me to other areas where there might be code, but in looking at what IDA disassembled there in response to the earlier jumps, these sections don’t look like they actually do anything. I’m not seeing call/pop combinations or other things I would expect to see if this were shellcode. I see a few popa instructions but these also don’t appear to be used in ways that I would expect.

Trying with Arkdasm (a 64-bit disassembler) revealed even fewer instructions that made sense. X64dbg can’t attach to any of the processes associated with this file. Copying all this stuff from the .PDF file into Online Disassembler and then setting it to 64-bit results in more garbage. I even tried attaching Olly to a new Acrobat parent and child process but this just resulted in more junk (not surprisingly).

At this point I’m setting this file aside to move on to other samples that have come in more recently. I’m disappointed that I wasn’t able to get to the links before they were taken down, and I would have been particularly interested to see what the .EXE and .RTF files were doing. In the future I’m going to try to analyze these attachments as soon as I can after they arrive.

Findings and observations:
Sample is a .PDF file that was received in an Hotmail account that has been compromised multiple times over the years. This sample contains several links to download files from a few different sites, however upon trying to activate these links they had already been taken down. The sites linked to were generic file sharing sites, and file types included .EXE, .ACE, .RTF, .ZIP and .SCR files. The email was received from a domain currently registered in Malaysia and associated with a person purported to be living in Kansas, which could lead to further information about the source.

Try to examine samples within 72 hours of receipt next time. Upgrade licenses to enable better analysis of 64-bit code.

Missed the window to obtain additional files that would have been downloaded/launched by this document. Act faster on similar samples in the future. Online virus scanning sites may be ineffective in detecting malicious files such as these, and can also produce false positives and/or flag normal program behavior as suspicious.

20160526 MalPDF_001