Didier Stevens

Saturday 30 December 2006

Another postcard…

Filed under: Malware — Didier Stevens @ 0:50

There was another virus run today, it inspired me to make a Season’s Greetings video.

The movie is hosted here on YouTube, and you can find a hires version (XviD) here.

XORSearch is a new tool.

Happy New Year!

Thursday 28 December 2006

Brute Forcing Enigma

Filed under: My Software — Didier Stevens @ 12:32

A colleague of mine is getting married and her friends gave her a bunch of puzzles to solve. One puzzle is about the Enigma cipher machine, that’s why she asked me for help.

She has to go to this page (a flash simulation of the Enigma cipher machine) and solve this puzzle: If ANSWER is YRKRHL, then insert ENIGMA into enigma to find the answer…

It was immediately clear to me that we were dealing with a KPA: find the key (Enigma cipher machine configuration) that encrypts ANSWER into YRKRHL, and then we’ll be able to find the encrypt ENIGMA.

I quickly wrote a C# program to brute force all the starting positions (AAA – ZZZ), based on this article. At first my program didn’t find a solution, so I added brute forcing of the rotors and steckers configuration. By then my colleague had received a hint from her friends, which allowed us to set the correct configuration of the rotors, starting positions and steckers.

The funny thing is that my program found several other solutions:

Solution: rotor 243 key JRP steckers ACLX cleartext ANSWER ciphertext YRKRHL
cleartext2 ENIGMA ciphertext2 JRHSCB
Solution: rotor 513 key TJB steckers ADNT cleartext ANSWER ciphertext YRKRHL
cleartext2 ENIGMA ciphertext2 IRLHUN
Solution: rotor 234 key UHH steckers AGJS cleartext ANSWER ciphertext YRKRHL
cleartext2 ENIGMA ciphertext2 XRNBIK
Solution: rotor 234 key UHH steckers AGKU cleartext ANSWER ciphertext YRKRHL
cleartext2 ENIGMA ciphertext2 XRNBIU
Solution: rotor 321 key ESM steckers AHFY cleartext ANSWER ciphertext YRKRHL
cleartext2 ENIGMA ciphertext2 BRDHAQ
Solution: rotor 125 key HMH steckers AHRU cleartext ANSWER ciphertext YRKRHL
cleartext2 ENIGMA ciphertext2 QRYFNZ

Download:

BruteForceEnigma.zip (https)

MD5: A9FEBBABA207E7C3790D075FD3A3D22B

Tuesday 19 December 2006

Teaching a SpiderMonkey a new trick

Filed under: Reverse Engineering — Didier Stevens @ 9:28

Have you read NJ Verenini post on Websense’s Blog were he explains how to use SpiderMonkey to deobfuscate Javascript? As SpiderMonkey has no document object, Verenini shows a way to define your own document object to support document.write().

I’ve adapted the SpiderMonkey source code to include the document object. Not that my method is better than Verenini’s, I just wanted to play with SpiderMonkey.
An upcoming “Virus Lab” post will explain how I use this adapted SpiderMonkey, but for now I want to explain how I proceeded to modify SpiderMonkey.

If you’re not familiar with the SpiderMonkey source-code (like me), were do you start? I want to implement a document object with a write method. Is there something similar in JavsScript? Take a look at the Math object.

js
js>Math
[object Math]

The Math object has several methods, like sin:
js> Math.sin(3.1415926/2)
0.9999999999999997

document does not exist:
js> document
2: ReferenceError: document is not defined

The trick is to add a document object that has the same behaviour as the Math object (i.e. same members), and if this works, we adapt the document object by removing all Math members and adding a write method.

Greping for Math in the source code reveals that the object is defined in jsmath.c and jsmath.h. This is good, the Math object is defined in it’s own source files. So we will make our own source files for document based on Math: copy jsmath.[ch] to jsdocument.[ch]. Then edit jsdocument.[ch] and replace Math with document (there are some execeptions, like math.h).

Then we add jsdocument.[ch] to the makefile.
Greping for jsmath.h reveals that it’s included in jsapi.c. A quick search for
Math in jsapi.c reveals this code:
js_InitMathClass(cx, obj) &&
{js_InitMathClass, ATOM_OFFSET(Math)},

We add our own code:

js_InitDocumentClass(cx, obj) &&
{js_InitDocumentClass, ATOM_OFFSET(Document)},

Now when we build, we’ll get an error because we use a Document ATOM that we didn’t define. A bit of searching in the source code shows that atoms are defined in jsatom.[ch]. We search for Math and add extra code for Document.
And now the build succeeds!

js
js> document
[object document]
js> document.sin(3.1415926/2)
0.9999999999999997

Now we have to remove all members and add our own write method, but this is for another post, where I’ll publish my modified spidermonkey (it’s GPLed).

Reversing with the commented source code is not so difficult as reversing binaries, especially the patching process. If you want to add a new feature, look for an existing similar feature and do an “intelligent” copy-paste of the source code.

Once upon a time, long ago, I read the Dragon Book, and this also explains how I was able to quickly understand how to modify SpiderMonkey.

Friday 15 December 2006

My Virus lab part 1: downloading a malicious file

Filed under: Malware — Didier Stevens @ 7:55

While downloading a malware this evening, I realized I never blogged about my Virus lab.

How do I download a malicious file from an (infected) website without infecting my Windows box?

I use a hosted shell account on a FreeBSD system to download the file. There are not many viruses that will infect a FreeBSD system. Connecting to my shell account requires SSH, so how do I browse the Internet in a text-only shell? With Links! Links is like Lynx, a text-only browser I used in the early 1990s (I started on the Internet with Gopher, mailx and tin on a Unix box 😉 )

But when I have the exact URL of the file I want to download, I can use wget instead of Links.

Once I have the file on my shell account, I want to transfer it to my virus lab for analysis. To avoid infecting my Windows box or deletion of the file by my AV software when I transfer the file, I encrypt it first with Ncrypt (I chose Ncrypt because it ‘s one small executable that doesn’t require installation, it encrypts and decrypts and it compiles for Windows, Linux and FreeBSD).

BTW, I had a problem compiling Ncrypt on my FreeBSD account (error: elements of array `long_options’ have incomplete type). I solved this by including the line #include “getopt.h” in file ncrypt.c.

Tuesday 12 December 2006

USBVirusScan v1.2.0

Filed under: My Software — Didier Stevens @ 20:52

This new version has a new command line option -e. This will disable the Exit command in the pop-up menu.

Thanks to Earl Yeo for the suggestion.

Tuesday 5 December 2006

Customized Anti-Virus alert messages

Filed under: Malware — Didier Stevens @ 21:04

Some anti-virus software has a feature to customize the alert message when a virus is detected. The administrator can use this feature to instruct the user to contact the help-desk.

But most of the time, you cannot customize the message to the extend that it changes according to the type of alert. For example, an alert in the Temporary Internet Files folder is generated when a user browses a malicious website with IE. You want the custom message to tell him to “get the hell out of there”, in a politically correct way.

I wrote a quick C# PoC program that monitors the event log for virus alerts and displays customized messages for the user. Monitoring the event log is really easy with .NET:

   EventLog myLog = new EventLog("Application");
   myLog.EntryWritten += new EntryWrittenEventHandler(OnEventAdded);
   myLog.EnableRaisingEvents = true;

The OnEventAdded function will be called each time an event is added to the Application event log.

   private void OnEventAdded(object source, EntryWrittenEventArgs e)
   {
      if (e.Entry.Source == "Alert Manager Event Interface")
      {
         Regex regexVirus = new Regex(@"VirusScan Enterprise\: The file (.+) is infected with the (.+)\. ");
         Match matchVirus = regexVirus.Match(e.Entry.Message);

         if (matchVirus.Success)
         {
            String fileName = matchVirus.Groups[1].Value;
            String virusName = matchVirus.Groups[2].Value.Substring(0, matchVirus.Groups[2].Value.IndexOf(". "));
            // the rest of the code comes here
         }
      }
   }

I test if the source is “Alert Manager Event Interface” (this is the case when you use McAfee VirusScan Enterprise), and then I parse the event message with regular expression to extract relevant data.

Example of a customized alert:

alert1.PNG

Example of a customized alert for IE:
alert2.PNG

PoC source code available here.

Sinterklaas kapoentje, leg wat in mijn schoentje…

Filed under: Certification — Didier Stevens @ 20:04

Robert Scoble blogged from Amsterdam about Sinterklaas.

From Wikipedia:

Sinterklaas in Dutch is a holiday tradition in the Netherlands and Belgium, celebrated every year on Saint Nicholas’ eve December 5 or, in Belgium, the morning of December 6.

Sinterklaas brings gifts for children who have been good.

I must have been a good boy this year, because (ISC)² e-mailed me they would print my CISSP certificate today. I’ll follow-up with a more detailed post.

Blog at WordPress.com.