[LINUX] Create a rudimentary ELF packer

A packer, or binary protector, is a means of protecting software from reverse engineering. Malware authors use packers to evade signature-based detection, such as to thwart RE. Important among packers is the stub code for restoring protected binaries, which usually incorporates techniques such as anti-debugging, anti-VM, and anti-emulator that interfere with parsing.

Unpackers are implemented in some antivirus software. As far as I know, Kaspersky and Norton. An unpacker is a program that unpacks a packed program, that is, extracts the original binary. There are unpackers that can only be unpacked by a specific packer, and unpackers that can be unpacked even if there is no information about the packer in advance, such as how the packer restores the program. This is called a general-purpose unpacker. Research on general-purpose unpackers has been conducted since about 2005, and OmniUnpack, PolyUnpack, Pindemonium, Lenovo, RAMBO, etc. have been developed.

Well-known PE packers include UPX and Armadillo, but few are actually available in ELF. If it's at the POC stage or just explained on the slides, there are Shiva ,, Burneye, Maya's Veil and so on. I recommend taking a look at Maya's Veil.

If you want to create a packer with ELF, you can refer to Announcing Userland Exec. Also, take a look at Modern Userland Exec.

Originally, the packer would have to restore the original program in memory and transfer execution to it. But this time I write the binary to disk and run the original binary with execve (). The function as a packer is not good, but I will start with a simple one. This way you should be able to pack both 32bit / 64bit programs. If you don't know anything about ELF, I recommend you to look at the reference first. The following is an image of packing the binaries you want to protect. The left side is the structure of a normal ELF binary, and the right side is the state where the binary is stored. There are probably several ways to store the binaries, but this time I'll extend the data segment and put the binaries there.

20190107153129.png                                   For that purpose, it is necessary to change the value of the member of the program header of the data segment. Specifically, you only need to add the size of the binary you want to store in p_filesz and p_memsz of the program header of the stub binary data segment. The stub code needs to know its offset and size in order to restore the original code. They are added after the original code. Therefore, the final structure is as follows.

20190107154440.png                                                         As I forgot to say, don't forget to add those sizes to p_filesz and p_memsz to store the sizes and offsets. Also, I forgot to draw it in the figure, but the stub code also needs to know the key to restore the encrypted original code. Add the size for that. That is, the size of the original data segment + the size of the size + the size of the offset + the size of the key is the size of the final data segment. After that, extract the binary from your own data segment, write it to disk, and write the stub code to execute the program using execve (). The code to achieve this can be found on GitHub. Probably Linux should work fine.

Download the code and type make to create a file called wrapper.

It can be packed with "./wrapper the binary you want to pack" and an executable binary called packed is generated. The code was written in a few hours and isn't complete yet (I don't want to). It's almost scribbled, so you'll see duplicate functions and obscure options, but you'll get the idea of packing binaries. (Next, I'll make something more decent)

Recommended Posts

Create a rudimentary ELF packer
Create a Django schedule
Create a Python module
Create a Bootable LV
Create a Python environment
Create a slack bot
Create a local pypi repository
Create a dictionary in Python
Create a (simple) REST server
Create a homepage with django
Create a python numpy array
Create a dummy data file
Create a Django login screen
Create a heatmap with pyqtgraph
Create a classroom on Jupyterhub
Create a simple textlint server
Create a directory with python
Create a CSV reader in Flask
Create a python GUI using tkinter
Create a DI Container in Python
Steps to create a Django project
Create a pandas Dataframe from a string.
Create a nested dictionary using defaultdict
How to create a Conda package
Create a virtual environment with Python!
Create a binary file in Python
Create a SlackBot service on Pepper
Create a Linux environment on Windows 10
Create a python environment on centos
How to create a Dockerfile (basic)
Create a Unix Domain Socket server
Create a 1MByte random number file
Create a Python general-purpose decorator framework
Create a Kubernetes Operator in Python
5 Ways to Create a Python Chatbot
Create a CRUD API using FastAPI
Create a poisson stepper with numpy.random
Create a random string in Python
How to create a config file
Create a C wrapper using Boost.Python
Create a file uploader with Django