This one was a DLL. Ooh another nice one. Most of my previous reversing success has either been PE or ELF so it's really cool to do all these cool challenges and improve.
Now a DLL is something that has a ton of functions that an EXE calls. You can't directly run a DLL...you need to make an EXE import it and then debug the EXE. At least that's how I've done it in the past :).
So I tried doing this with Olly 1.10 which comes with LoadDLL.exe. That failed and Olly got stuck. So I abandoned that idea and decided to use regsvr32 and rundll32 instead. What eventually worked was rundll32. So you load Olly up..open rundll32.exe and set Olly's arguments to the DLL (5get_it.dll, Dllmain).
http://www.iacertification.org/reverse_engineering_malware_971.html
http://www.openrce.org/forums/posts/313
Also ensure that you're using Olly 2.01 and have set it to break each time a new DLL is loaded. I had a small blog post on this here.
So eventually...I broke in at DllMain...and with the help of IDA and some F8 in Olly it was clear that svchost.dll in the system32 directory was being overwritten. A registry key was also created in HKLM\....\Run... to ensure the DLL was run each time the machine rebooted. That much was relatively easy.
Now after all this...the code seemed to jump into one of the largest functions (at 10009EB0) I have ever seen. It seemed like a massive massive switch/case loop. Here's a pic..that shows how big it truly was:
There was an API called GetAsyncKeyState...that was called and then it went into the switch-case structure. Here's a screenshot showing the code inside a couple of these functions. Take a guess what it is?
See the 'v' and 'w' in the screenshot? That's basically what's pushed to the function at 10001000 which then appends the character 'v or 'w to the svchost.log file in System32. Each little function does similar things....just for a different character each time. In other words...this is a keylogger :)
Now I've been duped many times in the past following code down dead ends so I decided to write a little IDA script renaming all functions of this type..so I could ignore all of them and understand the rest of the program.
That code is here:- https://gist.github.com/arvinddoraiswamy/a16749ee76941e8d86c8
That made my life much easier...coz most of the code got renamed and there was very little left to look at :). The bad part was... none of the other code seemed to have anything relevant to the flag at all. :(
Okay lets run it in Olly...maybe something will turn up. Nope. It just remains in an endless loop...and logs keystrokes to svchost.log.. every single character. Now what?
Okay... lets now start opening up each of those functions...nothing super interesting until we come to 'm' and toggle the ZeroFlag....there's something different there. It makes a call to 10001240... something that none of the other letters do. Running this function causes a small message box with some ASCII ART (FLARE) to pop up.
Well awesome. That's progress. But now what? The box doesn't have the flag in it, does it? But since the box pops up...it must mean something. What? Okay.. so when does the box pop up? When I hit 'm' and the variable at 100194fc is not <=0 . Hmm.
I know how to hit 'm'... but how do force 100194fc = 1 ... or ..not <=0.. so the correct branch is taken? Right? If I can answer that...I have the flag. So we want to now search for references to 100194fc. Lets search in the IDB. Click Search - Sequence of Bytes and enter fc 94 01 10 (little endian). The only reference that's useful is an instruction...
.text:10009BF7 keylog_charbychar_10009B60 mov dword_100194FC, 1
This means...that somewhere...some single location...it is setting 100194FC to 1. This is inside the function starting at 10009B60. What letter does that map to?
Ah...it maps to "o"... so stepping back...if we enter "o" it will set 100194fc to 1 ..and then if we press 'm' the ASCII art will pop up. Nice :).
So in other words we have to go backwards...study the values of every variable..see where it gets set to 1 and find out the next letter.
The mov instruction content to search for is given below. Byte in square brackets changes for each letter.
c7 05 [fc] 94 01 10 01 00 00 00
For "o" we need to find where 100194ec is set to 1. That is inside "c". So the last 3 letters are "com". We're very close :)
Keep going this way... and eventually you end up with the flag that is:
l0ggingdoturdot5tr0ke5atflaredashondotcom
Now a DLL is something that has a ton of functions that an EXE calls. You can't directly run a DLL...you need to make an EXE import it and then debug the EXE. At least that's how I've done it in the past :).
So I tried doing this with Olly 1.10 which comes with LoadDLL.exe. That failed and Olly got stuck. So I abandoned that idea and decided to use regsvr32 and rundll32 instead. What eventually worked was rundll32. So you load Olly up..open rundll32.exe and set Olly's arguments to the DLL (5get_it.dll, Dllmain).
http://www.iacertification.org/reverse_engineering_malware_971.html
http://www.openrce.org/forums/posts/313
Also ensure that you're using Olly 2.01 and have set it to break each time a new DLL is loaded. I had a small blog post on this here.
So eventually...I broke in at DllMain...and with the help of IDA and some F8 in Olly it was clear that svchost.dll in the system32 directory was being overwritten. A registry key was also created in HKLM\....\Run... to ensure the DLL was run each time the machine rebooted. That much was relatively easy.
Now after all this...the code seemed to jump into one of the largest functions (at 10009EB0) I have ever seen. It seemed like a massive massive switch/case loop. Here's a pic..that shows how big it truly was:
There was an API called GetAsyncKeyState...that was called and then it went into the switch-case structure. Here's a screenshot showing the code inside a couple of these functions. Take a guess what it is?
See the 'v' and 'w' in the screenshot? That's basically what's pushed to the function at 10001000 which then appends the character 'v or 'w to the svchost.log file in System32. Each little function does similar things....just for a different character each time. In other words...this is a keylogger :)
Now I've been duped many times in the past following code down dead ends so I decided to write a little IDA script renaming all functions of this type..so I could ignore all of them and understand the rest of the program.
That code is here:- https://gist.github.com/arvinddoraiswamy/a16749ee76941e8d86c8
That made my life much easier...coz most of the code got renamed and there was very little left to look at :). The bad part was... none of the other code seemed to have anything relevant to the flag at all. :(
Okay lets run it in Olly...maybe something will turn up. Nope. It just remains in an endless loop...and logs keystrokes to svchost.log.. every single character. Now what?
Okay... lets now start opening up each of those functions...nothing super interesting until we come to 'm' and toggle the ZeroFlag....there's something different there. It makes a call to 10001240... something that none of the other letters do. Running this function causes a small message box with some ASCII ART (FLARE) to pop up.
Well awesome. That's progress. But now what? The box doesn't have the flag in it, does it? But since the box pops up...it must mean something. What? Okay.. so when does the box pop up? When I hit 'm' and the variable at 100194fc is not <=0 . Hmm.
I know how to hit 'm'... but how do force 100194fc = 1 ... or ..not <=0.. so the correct branch is taken? Right? If I can answer that...I have the flag. So we want to now search for references to 100194fc. Lets search in the IDB. Click Search - Sequence of Bytes and enter fc 94 01 10 (little endian). The only reference that's useful is an instruction...
.text:10009BF7 keylog_charbychar_10009B60 mov dword_100194FC, 1
This means...that somewhere...some single location...it is setting 100194FC to 1. This is inside the function starting at 10009B60. What letter does that map to?
Ah...it maps to "o"... so stepping back...if we enter "o" it will set 100194fc to 1 ..and then if we press 'm' the ASCII art will pop up. Nice :).
So in other words we have to go backwards...study the values of every variable..see where it gets set to 1 and find out the next letter.
The mov instruction content to search for is given below. Byte in square brackets changes for each letter.
c7 05 [fc] 94 01 10 01 00 00 00
For "o" we need to find where 100194ec is set to 1. That is inside "c". So the last 3 letters are "com". We're very close :)
Keep going this way... and eventually you end up with the flag that is:
l0ggingdoturdot5tr0ke5atflaredashondotcom