Malware protection
Table of Contents
Introduction
This guide is mostly related to Windows malware, however, some tips here can (and should) be applied to Linux and even MacOS viruses.
Steps
Good malware pretty much always needs to log something to the remote server, which is controlled by hacker. These log details can be stolen credentials, system data and other useful information collected from end user.
Obviously, implementing data logging into your application (does not necessarily mean 'malware' application) exposes your logging domain and/or possibly remote servers IP addresses. This, of course, applies for proprietary applications as well, since I do not take in a count security by obscurity here. Everybody, provided having enough technical knowledge, can reverse engineer your program and DDOS your remote server. No doubt, this can result in your entire botnet takedown.
First (and, presumably, most obvious) solution that comes to mind when you start think about this kind of problem, is to control, what modules are actually loaded in your program. In WinAPI you can get this information by parsing entries in PEB
(Process Environment Block). The rest of the solution is simple: when you need to log out some data to remote server, your application first sends information about loaded modules. Server checks that data for some suspicious and unknown entries and if there are any - closes the connection. This approach is good, and, on my opinion, should be implemented anyway.
Second, you should make sure to compile your application with various kinds of runtime checks such DEP
(Data Execution Prevention), ASLR
(Address Space Layout Randomization) - only if available (mostly ON by default) or security cookies. This would at least prevent stupid ways of code injection in your application.
Third, solution might involve a little bit more attention as it is one of the most effective so far. Of course, the point here is to permanently block DLL injection
. However, there is no direct implementation for it as all implementations rely on the current WinAPI release (If you want ready solution, take a look at Chromium source code, as they have this stuff actually implemented). Basically, you need to patch ntdll.dll
and/or kernel32.dll
libraries (of course, in your process address space). Insert int3
or debugbreak
or any other instruction that would break loader code (make sure to change memory permissions to copy-on-write): LoadLibraryEx[WA]
, ... etc.
Fourth. This is more related to server security, rather than peer/application security. It is difficult, resource heavy, stupid and useless to implent data validation routines on the server. You will never know, if the data you are trying to log comes from your victim pc or from masked VM in malware analysis lab. One way to fix this, is to implement PC fingerprinting. And, of course, collecting data like CPU
, GPU
, MB
or other components might not be enough, since it is not that hard to reproduce everything inside VM. My suggestion is to actually split malware deployment/installation process in 2 stages:
- Installation. Create a simple install script/program which would be proprietary (!!). It will gather some system data, and create some more identification data such as custom registry keys, files in random places ... etc. My recommendation is to create like
10,000
random instances throughout the entire system. All data would be collected and sent back to server. After installation, fingerprinting and data gathering, install script would delete itself, so nobody knows what exactly was collected. - Workout. Client/server work in
JWT
fashion. Refresh token is stored wide open. If somebody changes refresh token (i.e end user), client simply would not be able to generate access token, thus would not be able to send data to server. If client has access token, it can use it to send data to server without any checks. If client only has refresh token, it prompts server for access token. Server sends client a few random tasks, which should be executed. Each task has so-calledpotential value
- floating point number between0
and1
, which is stored privately on the server. Server calculates totalpotential value
based on client tasks execution results and desides, whether client host machine is same as it was during installation or not. Tasks might require client to print out contents of some file or get data stored in registry key or calculate checksum of some file ... etc.