 Hello, this is Steven, Senior Hender at the Internet Storm Center. In this diary entry, Maldok Non-Ascii VBA identifiers, I analyze a malicious document where the identifiers, function names and variable names, are actually not Ascii characters. So the characters that are being used have the high bit set, so a byte value and 8 bits, the high bit is set. So this is not easily readable and I have a plugin that can help us with that and that's what I'm going to show here. I'm first going to explain the plugin and then I'll do the analysis of this sample. So I have some examples. I run onlyDump on the first example. It contains markers in stream 7. So I select stream 7 and do the decompression of the VBA code and here you can see the VBA code. This is an example that I made. It's a downloader that uses ActiveX object. It's very readable, create objects, variable OXML, ACTP, error URL and so on. So this is not obfuscated code, easily readable. I have another example. This one here, again in stream 7. So I select stream 7, decompress and now you have code here, which is far less readable and functionally it's exactly the same, but it's way less readable because of random variable names, extra code, commands and so on. You can still see the strings, they are not obfuscated, but if you have a lot of code like that, it's harder to analyze and you would, for example, do grips for create object, for example, then you find these two objects. Now that is something that I used to do quite some time ago, but I made a plugin to help me with this. The plugin is called PluginVBA-DCO. It's a plugin that will look for declare and create objects and in the meantime also some other stuff like also get object called by name shell. So it will grab for that automatically for you. So you just have to run the plugin on the sample and here you get the summary. So what you have before or above the line here is the different create objects here in this case, but also declare for example, it will grab for those lines and put those lines here on top. So we have two create objects and then we also have the identifiers that go with them. So when this object is created, it is put in this identifier. Well, those identifiers, the plugin will also grab for. So beneath here, this is a grab for these two identifiers and then you get all of the statements that are relevant for the analysis, like the creation of an XML HTTP object and then it gets a send a response body, but that makes the analysis easier even when the code is obfuscated. Now this plugin is very simple. It's not a VBA parser. It uses some simple tricks to extract identifiers and it can also be easily sidetracked on something that is not an identifier. For example, it will just handle line comments like any other line will not make it distinguishing and ignore it. Okay. So now our sample. This is a sample in stream seven and stream 11. We have uppercase M. So that's where we have actual microcode. Let's decompress this. Okay. And this is just a sup. That doesn't do anything. And 11. Okay. So here you can see things like create object adodp stream XML HTTP. So this is a download process. You can see here a lot of the identifiers cannot be read. They are not asking these are not letters or digits. These are special characters depending on the code page that was used to create this. If we run the plugin on this one, you get this output. So here the grab for create object as script shell XML HTTP shell application adodp stream and here this variable name. Okay. The USH shell that one is readable, but these here, they are not readable. And so finding them back here, the script can do it, of course, but for us it's very hard. So what I did here is add a new option, plugin options. An option for the plugin option, generalize. This will standardize the name of the identifiers like this. And now you can see here that the code is way more readable because all of those unrecognizable identifiers have been replaced with readable like identify one, two, three, four, and so on. And you can easily see the code. For example, here we have an XML HTTP identifier two. I can do a search and replace for that. Identifier 00002. That will be, I will call this object XML globally. Like this. And here you can see the use of object XML. It is created to get a send response body. Here you can see an issue here. You see the translation here. That's because the plugin is not that smart. So here now we see identifier 15 and this is a URL that we cannot read it. It's also with non-printable characters. And it is passed to a function identifier 15. So I'm going to add another option, option A, all. When you do that together with option generalize, you will have all the code that is displayed. So not only the one with create object and identifiers that are known but all the code. And here we see identifier 15 again. That is the function that does the decoding. So let me do another search and replace with set identifier 15. And I'm going to call this decoder, that is a decoder function. So here you have decoder. Also here, so to create a kind of filename, they also use the decoder and for the URL also the decoder. And if you look at the decoder function, you can see that there are two long strings. Here a string with letters, digits and unrecognizable characters and here another one. So what this function does is the translation. It looks up each character in a URL for example and then matches it with the corresponding character in the other identifier. So identifier 18 and 17. And I did copy this code into a small Python script. So here you have the translation table and the two variables with translation. And here you have the URL, I picked that out of the code and then I wrote a very simple function that will work here through each character. Look it up here in the cipher and then look up the corresponding one in clear. And if you run this, then you have the clear text URL.