Morto: More than Meets the Eye

There's been a lot of talk the past week or so about Morto. For those unfamiliar or unaware, Morto is a tricky little worm which looks for instances of Remote Desktop exposed online with weak Administrator passwords. How weak you ask? Pretty weak. I won't lie to you, if I got infected with this worm, I'd be pretty embarrassed. Which is probably why there's only about 3,000 or so infected machines last time I heard. Based on some preliminary analysis done by others, and knowing how it propagated, I figured reversing this thing would be a walk in the park. Oddly enough, there were anti-debugging tactics and other little nuances in place that, honestly, really surprised me. Two tactics in particular, while not terribly sophisticated, had enough merit that I felt it would be an interesting look for our readers at what some malware authors are doing. Before I get into the specifics, I should point out that this write-up won't be going into the details of what Morto does, or how it works. There's been plenty of great write-ups on this very topic done by both Microsoft and F-Secure (to name a couple), and I suggest taking a look at them if you're looking for this kind of information.

Both of the tricks the malware authors performed were both done in the DLL, which is dropped on the infected system after the initial infection takes place. When initially opening the DLL in IDA, you can see right away that something is off. If this were a scene in the movie Inception, this would be the equivalent of jumping into a guy's dream and (spoiler alert?) having a freight train start plowing down main street.


So what's going on you ask? Well, to put it simply, a large chunk of code in DLLMain is being obfuscated somehow. Further digging shows just what's happening.


Breaking this code down, essentially the authors are performing a simple rotation cipher of -7 against that large chunk of code we saw earlier. So if you have a value of 0x08, that becomes 0x01, 0x15 becomes 0x0E, and so forth.

What's the really interesting part is how this -7 value is being calculated. This value is calculated based on the name of the process this DLL is being injected into. By adding the sum of every letter in the process name, ignoring the value '2', and dividing this result by 0x64, or 100 in decimal, the authors are able to determine if the DLL is being injected into the correct process or not. A quick little code snippet in ruby shows how this is done-

  k = 0  "regedit".each_byte {|x| k+=x }  -1 * (k / "64".hex)    => -7

If any other process tries to load this DLL, the chunk of obfuscated code will not be de-obfuscated, and none of the malicious code will execute.

The next trick was discovered by essentially staring at the code until I started to get a headache. That was, until I realized it was more likely to be allergies, and I proceeded to take what I thought was non-drowsy medication... but that's a story for another posting. While looking at the code of this DLL, I kept looking for the LoadLibrary function to get called, but it alluded me. It was right about this time that I started looking at these strange blobs of data further down in the code. There was obviously some sort of obfuscation going on, but at first glance it's hard to see exactly what's happening. The key to solving this, (and when I say key, I mean the actual key) is in this larger blob of data that shows up before everything else.

We can see that these small obfuscated strings are all being referenced from the same function. Now, if we look at the size of these obfuscated strings, it looks to me that these might be function names.

Screen shot 2011-09-06 at 1.30.41 PM
Using this hypothesis, lets start looking for patterns. One of the big things that hits me is that every hex value in every one of these obfuscated strings shows up in that large blob of data we saw at the top. What's the significance of this you ask? Well, since everything seems to be showing up in that large blob of data, it seems to me that this might be using a substitution table. In actuality, the rotation cipher we saw earlier is also a substitution table as well. It's just a different kind. Now hopefully I'm not completely confusing you. Remember, I did say it was drowsy medication. Let's just start working through this in order to show you what process I took to figure this out.

Now first, let's take a look at this large blob of data that we think is the key-


Nothing really pops out at us, but that's OK. Let's start taking a look at this small obfuscated strings and see if any patterns show up. Now remember earlier we guessed that these might be obfuscated function names, so let's think of that in the back of our heads going forward.

Screen shot 2011-09-06 at 1.11.14 PM

Something jumps out on the top obfuscated string. Five characters, where 3+4 are the same.

In a way it's a lot like that show Wheel of Fortune if you think about it. Well, talking about Wheel of Fortune... the word 'wheel' actually fits the bill. I'm not sure of any function name called 'wheel', but let's use it to take a shot anyways. Specifically, let's use what we think the letter 'e' is and map it up to that large blob of data.



OK, now that we've got that mapped up, we can see if the letter 'l' lines up.


No luck there, as we were looking for 0x0D, but got 0x29 instead. However, 0x29 does line up to where the 'l' is supposed to be. So going from this, we now theoretically have _lee_. Let's see if we can use what we have to guess the other values.


Looks like the letter 'p' fits. If I were a betting man, I'd take a stab and say this is the function 'sleep', but it doesn't look like the letter 's' lines up. Well, knowing that the ASCII value of 'S' is different from 's', perhaps the first letter is simply capitalized. Let's take a stab at that and see if things line up.


Nice! It looks like this might work out. Let's try some of the other small obfuscated strings, and see if we have similar luck.


And just to put our minds at ease, here's the code in the DLL which actually converts these strings via the substitution cipher (Not in it's entirety, as it's quite long).

As you can see, our initial guess about these being function names appears to be correct. Using this method we can decrypt the 10-15 other methods which appear in this DLL as obfuscated garbage (at least at first glance).

This pretty much wraps up the two little tricks we saw in use while performing a static analysis on the Morto DLL. While the method of infection is relatively simplistic in nature, the authors show they still have a couple tricks, albeit not terribly sophisticated, up their sleeves.

Update 9/7/2011: Josh was trying to go to for the world record for screen shots in a blog post and forgot to include one of them. His quest is now complete. -c7five

Trustwave reserves the right to review all comments in the discussion below. Please note that for security and other reasons, we may not approve comments containing links.