Rewriting LibC functions in malwares

hacking
malware
programming

(Yenii) #1

Hello everyone;

I wonder why some malware dev, rewrite some libc functions in their malware, like strcat, strcpy, malloc …

Thanks !!


(oaktree) #2

Where have you seen this? Mentioning some examples would be great.


(Yenii) #3

Carberp :


A virus from Github


#4

May be b’coz malware analysts heavily rely on FLIRT signatures,a feature provided by IDA,which actually finds libc functions in the assembly code and renames it with the library name.
https://www.hex-rays.com/products/ida/tech/flirt/in_depth.shtml
IDA relies on some tactics to find this libc functions,so defeat this techniques they should have written libc functions by hand.
If i’m wrong plz correct me!


(Yenii) #5

First thanks for replying, but whats is the problem if IDA detect LibC functions ? They are not malicious …


(Yenii) #6

Hope to have some clarifications from @dtm :slight_smile:


#7

The only reasons I can think of for implementing your own functions would be the following:

  1. Evading signature-based or heuristic detection.

Let’s say I have a keylogger and I want it to upload logs to my FTP server. If I directly link the executable such that functions like FtpOpenFile and FtpPutFile exist in the imports in plain text and can be seen to be used in the code section, it would be very suspicious. If I can replace them by implementing my own self-coded networking library that has an FTP protocol, it could reduce the chance of it being suspicious. This is probably not the reason for why the above samples implement their own libc functions because they wouldn’t be classified as potentially unwanted.

  1. Reducing dependencies in the binary.

Sometimes, dependencies are troublesome for malware that infects other objects. In the case of viruses, having as little dependencies is ideal because the environment of the host is considered to be volatile. What I mean by this is that if you select a host at random, there is no guarantee that the execution environment will contain what the virus may need to properly do its task, therefore, to eliminate dependency is to become entirely self-sufficient.

A very classical example of this is dynamically obtaining WinAPI functions by walking the process’ PEB’s executable modules under the assumption that all processes must have the ntdll.dll and kernel32.dll libraries present. Because of this, any malcode that lives in the process space of a host has access to whatever it needs to interact with the OS without having to rely on what already exists in the host’s environment.

Other than that, your guess is as good as mine. ¯\_(ツ)_/¯


(pico) #8

On top of @dtm points I’d add:

  1. Your binary will be way smaller which is, in general, a desirable feature for a malware

I think point 2 is a very good reason


(Yenii) #9

Thanks @dtm and @0x00pf … does it have any relation with having a position independent in memory?


#10

In the Windows environment, using functions from libc (e.g. memcpy, strcpy) requires the msvcrt.dll library to be present in the process space which means that the binary must be linked with it in its import table assuming the source contains its direct usage (as opposed to dynamically retrieving it as aforementioned or by using the GetProcAddress/LoadLibrary pair but using these two functions also requires linking). The import table by itself is not position-independent but can be pseudo-independent with the reliance on another table structure known as the relocation table.

Depending on these two structures needs more information to be able to locate them. In a standard PE binary, the PE headers are responsible for describing the structure of the program which includes the import and relocation tables. To programmatically calculate these offsets requires the use of such data structure which only introduces more size and as @0x00pf mentioned, smaller sizes are ideal for viruses. To programmatically fix the offsets of the import table such that it is “position-independent” requires more code which in turn expands the size.

So as you can see, it’s just much simpler and effective to implement these functions yourself. The trade-off clearly isn’t worth it with libc. Shellcode is the way to go.


(pico) #11

It indeed makes things easier, if your program will be moving around in its own addressing space (or in another processes addressing space) and not just standing at the entry point specified in its ELF header (for GNU/Linux systems), then it is very handy to do not depend on anything external.

To better understand why, we need to roughly known a libc C function is invoked:

  • Call an entry on a memory table (PLT Procedure Linkage table)
  • At the first invocation, the dynamic linker is fired to resolve the address of the function you want to call in the library (and even load the library if needed)
  • Then, the entry in that memory table is patched with the resolved address so, next time, it does not need to call the dynamic linker (you already know where the function is located).

So, even in the stationary case (whenever all the symbols your program uses have been resolved), all your calls to a libc function goes through an indirection. For the gory details check theses two great post at 0x00sec

So, coming back to your question. Once the PLT table is resolved/updated, you can just call any libc function from any memory position, through that table. In order to make your program Position Independent you need to let the compiler know, independently of the libraries you use. So, I do not see a big advantage on that side.

However, if you want your code to be loaded using non standard techniques (as it may happen with a virus or other malwares), having all your program self-contained makes things easier as you do not have to care about linking or resolving symbols… on the other hand, whatever functionality you need, you will have to implement your self/add to your program manually… Which, depending on what the program has to do may be quite some work…


(Yenii) #12

@dtm @0x00pf Thank youu very much :smiley::smiley::smiley::smiley:
I understand ^^


(system) #13

This topic was automatically closed after 30 days. New replies are no longer allowed.