← All talks

(Szybka) Analiza Dropperów Z Użyciem Wine

BSides Warsaw · 201841:37570 viewsPublished 2018-10Watch on YouTube ↗
Speakers
Tags
CategoryTechnical
StyleTalk
Mentioned in this talk
Show transcript [en]

Let's start. Can you hear me well? Everything OK? OK. So, the topic of today's presentation will be a quick analysis of wine-used droppers. However, during today's presentation we will focus mainly on droppers. Oh, something... Hmm... Technical problem? OK, it works. So, my name is Paulus Rokosz. I am an IT Security specialist at CERT Poland. And I mainly deal with software programming analysis. I also play CTF and P4. I also study at the University of Warsaw, at the Department of Electronics. So, who knows what are droppers? Who has met droppers? Droppers are very easy to meet. You just need to open your e-mail box. and there we can most often find messages about some late payments, late invoices that need to be paid and that are

listed for a huge amount. Fortunately, our message sender thought about us and added this alleged invoice as a link. And he also compressed it into some zip archive. When we create this zip, We see a small file, in this case a VBS file. And as people dealing with security, interested in security, we are already used to such tricks and we know that it is not a fact and it is better not to run it. But who of you did not try to unpack such a script and try to see what is inside? What is it doing? In this case, Windows opens two possibilities for us. We can choose the "Open" or "Edit" options. This is a bad script, why would we edit it? So let's

try to create it. Then we can find out what's inside. Analysis completed, dynamic analysis. We have another expensive fee, namely we have to pay criminals for a key that will allow us to get our data. If we are more careful, we can have an option "edit" and then we will learn as much about this script because it is mostly blank and at first glance it is completely unreadable. Of course, droppers in the form of scripts are not the only available format that is available. It can be some small files that can be executed, although it will happen quite often because they are quickly rejected by anti-spam filters. It could be Microsoft Office package documents, with a valid macro, you need to have a macro on to make it work,

or an exploit that uses some kind of a vulnerability in the Microsoft Office package. And finally, what interests us in today's presentation, which is scripts in JScript and VBScript languages. And without any type of value, the idea of such a dropper is more or less always the same. So we have some small script, a small file that is easy to send, which downloads the correct programming from a network resource and installs Yuhami on the Off-Yar's computer. I said that today's presentation will focus mainly on scripts, but what is this Windows Script Host? Who of you has met the Windows Script Host? Who of you knows what it is? Let's think about it. Why would Windows execute scripts in

JScript, VBScript, exotic languages? Where did this feature come from? This feature is really old. It comes from Windows 95. As we know, Windows comes directly from MS-DOS. The only script language there was Batch, which had quite poor capabilities. So they decided to make It was a great environment, which was created with the help of administrators. It was intended to improve the process of automating various activities in the system. Using scripts in any script language. This is Windows Script Host. It is a mechanism that allows you to interact with the system using various types of scripts. The environment is fully scalable, we can install any interpreter there. The links supported natively include JScript, which is a language that belongs to the JavaScript

family, and VBScript, which is a scripted version of Visual Basic. Basic was quite popular then. And in addition, if we wanted to sell these scripts, for example, and we didn't want to publish the code too much, Microsoft would of course think about it and create a built-in obfuscation, i.e. format JScript ENCODE and VBScript ENCODE. The whole thing was based on Active Scripting technology. These were the times when everything was active. We downloaded an object, for example an index player, we referred to the application, and by borrowing a component of the browser we could go to the website and find out what the title of this page is. Active Scripting generally uses the COM technology, the component of the model. The idea was

to have any system element and any application to display certain components that would be usable in other applications. These components function as controls that communicate with the so-called OL objects, which communicate with the mechanism COM. Generally, this is a very complex mechanism. The application we rent control from can work on a completely different machine. Communication can be done via RPC. The whole mechanism to communicate with scripts was enriched with so-called "all automation". Generally, COM is a binary interface. We operate on objects with a known structure. In scripts, however, we mainly use names and identifiers. So we had to enrich this com with all automation, which allows to use these objects in script languages. Unfortunately, some languages

were dynamic, for example Visual Basic. This mechanism of operating dynamic objects was enriched, i.e. iDispatchX. In this way, in the language of Alibaba Script, we can first create a component of a document in the Explorer browser, and then go to the right page by calling the method of this object. And generally, the DLL is loaded at the bottom, a middle object is created, and it redirects the method calls to the right component, which can work in another process, for example, in the window of the browser. Windows Script Host has really huge possibilities, practically with any operating system component we are able to communicate. We can distinguish elements that allow us to access files. We can

use WMI, for example, to check what processes work in the system, what is the serial number of the disk, we can make any commands, we can make HTTP requests, so basically everything that such a potentially malicious script needs. For example, such a download, here is a script in VBScript language, Such download from the Internet and save to disk is creating two objects, one that allows us to communicate with the Internet, and the other that will allow us to save the contents of this downloaded file to the disk. And the code looks more or less like this. Here we perform the request, and here we make a record. So, since we know more or less how these droppers work,

and we know that it's better not to do them, then let's think about how to analyze them. We saw on previous slides that the description is heavily complicated. In addition, the languages themselves are quite enigmatic for modern programmers. But first, let's think about what we are actually looking for. We have a script that downloads and installs the programming. The first question is: where does it download? What is the distribution address? or what are the distribution addresses, because there may be more of them, there may also be spare addresses. We can be interested in additional commands made, for example, the dropper can provide a certain programing with a persistence right away and add appropriate entries to the Windows registry. And it would be nice to have

a code from the script, in case this dropper would do something more, for example, it was actually a full-fledged Trojan, which also happens, and to enable more precise analysis. We have two possibilities. As Pjeleren mentioned before, we have a similar situation here. We can analyze malware statically or dynamically. And static analysis is about trying to make it happen. We can use various tools such as beautifiers. If there is no of the component nuances, for example, the Aglify.js department, which will help us identify it. This can help us to identify what the code is made of. For example, in this script, you can see many repeating elements, you can see some patterns. And of course, individual elements that are repeated here, are responsible for creating one

sign, some chain of signs, for example, useful. And after putting in a sufficient amount of effort, we can add this script to such a form, a pre-drafted one. And in this way, once we have a pre-drafted script, we can read it directly from the code, For example, the distribution address, the attributes needed to download malware and other details about how this script works. The problem is that it is time-consuming because it is not so easy to add a script from this form to this one. On a larger scale, it may take too much time. It would be nice to be able to automate it somehow. If we want to automate it, it is best to reach dynamic analysis, because we

can make such a sample after 100. We will not make it so simply, but we will do it in a controlled and monitored environment. For example, we can monitor network traffic, we can monitor what call of the operating system is called, what files are created on the disk. To do this, we can use classic malware analysis solutions, such as Kuku Sandbox or HiWit Analysis. The problem is that these are universal solutions, and scripts and the whole COM mechanism are governed by their own laws. So, most often we get a lot of information from these analyses about the payload that was taken, but not necessarily about the script itself. The problem is that these scripts have been developing more and more recently and they start to have

mechanisms similar to native malware. For example, at the very beginning they can check if they are performed in the sandbox, they can perform additional verification. So, for example, if we have in our VM some of these processes, for example, some proxy file or Python, for example, Kuku Sandbox has a Python agent or some other known processes that can appear in previous sandboxes, then the process closes. And in addition, it closes in an enigmatic way because it calls Document Alert. but because we work in the Windows Script Host environment, there is no document there, so it will just throw an exception and it will not work. There is one more thing, because if our execution is very effective, for example, the first address is immediately unbundled and malware

is downloaded from it, then the dropper will most often complete its operation and go to run the main sample. There is a high chance that we won't find out about these backup addresses that work in this dropper, and there may be a lot of them. And maybe if this address is removed, we would also like to know about these addresses. Especially since these are often fire pages. Most often this small one is created on some hole-like CMSs. And for example, if it is, for example, some domain in .pl, then we would like to inform the hosting or the owner of this website that his site is compromised and distributes malware. Okay, so if it's not sandboxes, if it's not

some kind of hybrid analysis, then how to approach it? Well, before we think about how to get it, let's take a certain environment model. Well, what kind of ecosystem does such a dropper work in? We have an interpreter, Windows Script Host. We have a layer that allows the script to communicate with the system, in this case Windows Auto Automation. This layer is the intermediary between the script and WinAPI. In addition, we have the Internet, where it is downloaded, where our HTTP requests for DNS questions are sent. We can distinguish these four levels. In the case of the sandbox in the "Habit Analysis" section, This part is in the sandbox. On the outside we can have some SSL strip, for example, which allows us

to use HTTP and HTTPS, we can display our own fake services. Unfortunately, because these are dedicated solutions, we usually monitor only these two layers, i.e. Internet communication and WinAPI. I haven't seen any other monitor that would perform hooks, monitoring at the level of OLE objects, and even more so at the level of Windows Script Host. From what I know, one of the few sandboxes that makes such tricks is Kuku Sandbox. And it does it only to extract a decoded script, for example JScript Encode, which is decoded to a public form in Windows Script Host. So, most often I don't have the proper instrumentation at this level. And it ends with the fact that we can

effectively disable the analysis of such a dropper in the sandbox by simply adding a sleep at the beginning. The problem is that this sleep doesn't directly translate into the creation of a sleep from WinAPI. This trick often appears in different types of parkers and protectors. Because who has a computer on for only 10 minutes? It rarely happens, we often sit for hours. And the analysis time in a sandbox is usually limited. And if sandboxes are able to avoid such slips, they usually avoid these native slips. I haven't met a sandbox that would avoid slips on the level of Windows Script Host. And it ends with the fact that if we put such a script into Hubby's Analysis, we don't get any activity. That's

why dedicated solutions were created. Such as Box.js, which is a great tool. In this case, it is a solution dedicated to software programming in JScript. and use JSCRIPT, ECMAScript, JAVAScript, similar languages. Maybe this code can be run on a modern ECMAScript engine, for example Node.js. But the code itself, the understanding of the code by the interpreter is not enough. We still have to provide this emulation of this layer of communication with the system, i.e. OLE. In this case, Box.js does a great job, because it has such a good emulation that most scripts in JScript can be made. If we are able to catch the attempts to make requests, we can no longer need this internet, because we are

able to simulate this internet script directly on the interpreter layer. This leads to the fact that if we simulate the response of 404, or 500, or other error responses, we will make the dropper try to ask for more backup addresses and in the end we will find out about all of them. Besides, this system has one more advantage. We don't have a big, heavy VM where we have to convert snapshot, which takes up RAM, takes up resources. We only have an interpreter node.js, which is relatively light. So these analyses are scaling well, they can be performed very quickly. However, a problem appears. I'm talking about JScript all the time. Why do I avoid JavaScript so much? JavaScript is mostly associated with browsers, with ECMAScript. Microsoft

claims that JScript was created on the basis of ECMAScript. mainly ECMAScript in version 3.0. But the truth is that these languages are very different, which I will try to show you in a moment. And here Box.js has another super feature, namely it has a transpiler, which can bring code in JScript to equivalent code in ECMAScript. Thanks to this, Node.js is able to understand and be able to make these scripts. And of course, I added my own brick. Unfortunately, there are a lot of differences between JScript and ECMAScript. Not all of them can be covered, not all of them can be transpiled in 100%. In this case... Generally, if someone wants, they can try to find this issue, it's pull request number 31. There are

details included. It's a bit more complicated, so I decided that it might be beyond the time of this presentation. I started to think about what difference I could show in this presentation, which would be not complicated enough, so that it wouldn't take much time. And I noticed something like this. Let's try to play a little quiz. We set two variables. A, which I set to 1, and B, which I set to false. And now we have the documentation of this variable a. What will we get in the result? Does anyone know? Zero. Fortunately, still zero. Although I see that someone was watching "What the fuck, JS?" so... Yes, different things are happening. And JavaScript is so cool that it allows us

to logically deny this value. And this negation from zero gives us the effect of truth. Because zero is a false, we deny zero, we get the truth. Ok, so now another feature of JavaScript2. We can compare logically not only the chain of signs and numerical values, but also logical values. And here we compare whether b is less than true, b is equal to false, so we get what result? Is false less than true? Yes, false is less than true. Now let's put it all together. We're documenting A, we're making a logical negation and we're checking if this value is bigger than B, if B is smaller than this. What do you think, what does it do? Since we got the truth

here, and this part is the truth, should we get the truth? I think so, but not in JavaScript. Not in ECMAScript. And I'll give you a moment to think why it is so. Maybe someone will come in. Maybe someone will notice some kind of a difference. Someone here in the room said "the order of operators". Well, no. It's much more fun. Does anyone associate this operator with any other language? HTML. Because this operator is equivalent to this one. Who in the standard said that it will be safer, because JavaScript often coexists with HTML, that it will be safer to treat something like a comment in one line. And something like this actually works in the standard. In the JavaScript 6.0, for example, there is

a "when x is b". There was a bit of grammar here, so I decided that it would be nicer to show a screen with stack overflow. In JScript there was no such problem, so it is evaluated normally and we have "true". What does it give us? We can detect emulations, because this code gives us a false in ECMAScript and gives us the truth in JScript, so we know if we are performing in a native interpreter or in an emulator.

Now we can write a code like this: first, we need to make a slip that will destroy our sandbox and then we need to make an operation that will try to hide our emulation. And Box.js will not work. It's already falling apart at the transpilation stage. because it uses a parser called acorn, which is a parser of MacMascript. It is also consistent with this standard. It also treats it as a comment. So here is a one-line comment and there is simply no introduction for this if. That's why it doesn't even parse. BoxJS is also used in other tools that aggregate many different emulators to cover as many droppers as possible. We created such dedicated tools to be able to put such

a dropper into a sandbox that, for example, does not want to be performed on a Harvita Analysis or some Joe Sandbox. And such a tool is Sequoia Dropper Analysis. I highly recommend it. However, when it comes to JScript, it uses BoxJS internally, so If we add such script to Malware Sequoia, we won't get any results. It won't work. So, did we manage to create perfect malware? Now we're moving to Wine. I started to wonder how to avoid it. How to deal with it? Malware is getting more and more complicated, more and more tools are being used. And we're starting to reach a race of weapons, like in the case of native malware, between emulator creators and and analisers, and malware in JScript

or VBScript. And from our perspective we would like to be as native as possible and at the same time provide full instrumentation. I thought that maybe I wouldn't like to do it in sandbox, maybe I wouldn't like to implement additional functionality of this monitor. Maybe I could use Wine. Wine is a environment that allows us to make Windows applications on Linux. And it does a really good job of it. It allows you to run Counter Strike or Microsoft Office. Why shouldn't it deal with some script? In addition, Wine is open source, so if we want to instrument it, we don't have to dig in ID and combine with binaries patching. We can just modify the source code, we can easily recognize how the emulation works.

I imagined an ecosystem in which I would use Wine for HMI droppers and it turned out that Wine It surprised me even more, because it turned out that Windows Script Host is also implemented there. In the form of open source. There is actually a simple engine that makes JScript, VBScript. However, it turned out that droppers are not quite possible to do, because the author suggested the standards of ECMAScript. So in many places he covered the same problems. And further transpilation would be required. But I decided not to give up. I decided that Wine can run any application, why can't I just take these DLLs and files from the original interpreter and just put them into Wine and run Dropper

on it. So replace this interpreter. And then allow Wine to provide this emulation, to provide this simulation of this Windows operating system interface. I tried to run a few droppers and it turned out that it works quite well, but not quite because Wine is not yet fully implemented. Wine is created with the idea of applications. It implements only a subset that will be enough to run some larger applications under the Windows system. And not necessarily target of Wine's creators was to run malware. That's why things like WBMDispatch, which allows us to communicate with WMI, in many places contains "not implemented". And when dropper will call WMI, Wine will refuse to obey and say "sorry, I don't have this,

I won't return this object". which ends up with Windows Script Host making a mistake that it is impossible to create such an object. Before I doubted this solution, because I wanted to give up at this point, because I thought: "Okay, it's a bad idea." I wondered if it would still be possible to get something more out of this setup. Because Wine is still much lighter than Sandbox, it's quite tempting. Maybe it's possible to do instrumentation at the interpreter level and get something out of it. The problem is that it would have to be binar instrumentation. But it turned out that Microsoft gives us quite good possibilities when it comes to this instrumentation, because it has public symbols for most libraries. We can take them from Microsoft

Symbol Server. These are symbols that help us debug some crashes, for example, in Windows. And this set of symbols for Windows Script Host interpreters turned out to be very good. I found that if I can more or less understand what code is responsible for what, then by putting hooks on the right functions I can monitor and control the code execution on the native interpreter. At first it seemed a bit crazy, but after some time I decided that it was quite feasible. But why? I wondered what we were looking for. We are looking for distribution, we are looking for code, we are looking for script. Maybe we don't have to execute this dropper, maybe we can do something

before. All these elements are chains of characters. We are looking for chains of characters that appear somewhere on the interpreter's stack, somewhere in the memory. There is a good chance that this type of data will be reflux before the main code is executed, which will cause problems. This is being thought of by the Strings tool, which is often used in static analysis, which is used to extract chains of characters from some memory dump or some native bin. In the case of the script, we are dealing with one large string, so it would be very useless. That's why I decided to create an emu-strings tool, which will allow us to extract such strings from the emulation. At this point, I would like to thank

MSM, Jarosław Jednak, for inspiring me when it comes to this logo. And so, to the defusing. As I mentioned, it often happens that the code is defused a little earlier. In addition, the chain of characters in JScript and VBScript are immutable, so we cannot simply replace any character in memory in one place. If we want to create a new chain of characters, we have to create a new string, its new instance. And this completion is carried out by a concatenation operation. For example, we have some single characters, They evolve to this single sign, e or l, and are added to each other. So if we were able to take over this concatenation operation, we might be able to achieve a lot of strings.

Let's think about how the interpreter works. The interpreter consists of some lexer that reads our code and divides it into tokens. Parser that puts it into some component tree and gives it a kind of something that a compiler can operate on. The compiler can then transfer it to some intermediate form, which is easier for the interpreter to perform. And at the end we have the execution of this script. In addition, we have a pipeline. Our input script usually lands in this lexer. But when such a code is added, it also has to perform evals, it also has to generate some code. So very often the additional code is also thrown at the beginning of this chain by some new

function, eval or execute global from the Visual Basic. In addition, the scanner operates on this plain text code, so it has to remove the JSKeyBan code if it appears. If we click in the right place, we can get permanent symbols from the scanner, we can get the script that we need. And from runtime we can intercept the concatenation operations. And finally, it should give us the majority of useful strings. I tried to find some useful functions, and it turned out that these are the functions. This is the code dumping, parseSource. Here we have scanStringConstant, which allows us to take constant characters. And concatStrings, which It provides the transfer of the concatenation operations. And also, to prevent this script from closing too

early, I noticed that it is worth ignoring a few additional calls, namely wscript_quit and wscript_slip. wscript_quit is often used if the script doesn't like something, if it makes a check earlier. And there is a good chance that this quit is omitted, because it is often a simple if, where a quit is made. If I just ignore this quit, the code will go on. And besides that, there are these slips that are used to delay analysis. How to hook? We hook binary code. Again, we have a choice between dynamic and static instrumentation. There are many tools for dynamic, for example, from Intel, PIN, Dynamo Rio. But every time we have to inject some DLL that will

allow us to hook on the right things in runtime. I didn't know Wine very well then, I didn't know if there was any LD preload. Wine works a bit specifically, because it has to simulate the memory layout from Windows, because there are also various structures in the style of Person, Vronet, Block, etc. It has to ensure all this. So I decided to go to an aesthetic instrument. A friend recommended me a tool like Liev, but unfortunately it turned out that it does not work very well yet. So the only thing I have left is to do it myself. I decided to download the symbols files, which also contain offsets for the appropriate places in the files to be executed, and parse them using PDBPars library. Then I

generated a DLL that provides me with a monitoring code. Since we operate in Linux system, I decided to compile it using MINGW, it will be the easiest. Now I just have to add hooks. So with the help of .p file, although a lot of things had to be done on empty bytes, I added additional entries to the import table, so that the appropriate DLLs, the appropriate files performed by Windows Script Host will import my DLL. I also added some hooks and trampolines in the code so that the control of these functions would be redirected to my monitor. It's time for a little demo. I hope everything will work out. I'll try to run VMs. I hope everything is

visible. Let's try to run some malware. Here we have a file. I hope it's this one.

And here we have to select different script engines. JSCM, JSCMNCODE, FBSCFMSCMNCODE, because we can give it in the parameters of the script. So let's try to start it. I hope it won't take much time. And at this point this script is running in Wine on a native interpreter. The whole thing works in Docker to ensure some kind of isolation from the host. Besides that, I also delivered a layer of fake-net that simulates some HTTP services, DNS services, to be able to do as much as possible. And finally I got the chain of characters. I hope you can see it. You can see some Expand Environment Strings, you can see that there are some generated function names, object names, paths, and among others our distribution address,

which we are looking for. So, the whole thing works. Of course, it is still a very early proof of concept, but the fact that we have reached this point is quite promising. I will try to go back somewhere. That's it for today. Any questions? Thank you. For those interested, I recommend the analysis on the CertPolska website. If someone is interested in this topic and would like to try static analysis, then last year's ECSM created a task called "False invoice". You can find it on the website hackcert.pl/challenges. There are many other interesting tasks there. If someone is interested in some kind of crack, they can try. These are tasks created by the testers. And this false invoice doesn't work on all systems, I admit I made

a mistake there. But on some virtualization with 3DM or Xpac it should work quite well. However, when you see this code, then... And contact me if you have any questions, here is my email, here is my Twitter, my website, where I sometimes try to post something. And thanks for your attention.