Confluera Engineering

Confluera engineering is not perfect, but we pursue perfection. We write our journey here.

Reflective Code Loading in Linux — A New Defense Evasion Technique in MITRE ATT&CK v10

--

MITRE ATT&CK. Source: attack.mitre.org

Summary

This blog discusses a Linux reflective code loading technique newly added in the MITRE ATT&CK framework v10 update. Our research team contributed this technique to the MITRE ATT&CK organizers to help improve the industry standard.

Reflective code loading allows threat actors to execute file-based malware without touching the disk! We will discuss how this technique works in Linux and how threat groups use this technique to evade detection.

In our next blog, we will discuss detections and response to this technique. This blog is co-authored with Joel Schopp.

What is An Anonymous File?

Before we dive in to the details of reflective code loading in Linux, we need to understand anonymous files. Linux uses file as a generic abstraction for many underlying interfaces. Linux kernel 3.17 has introduced the memfd_create() system call. memfd_create()creates an anonymous file and returns a file descriptor that refers to it. The file behaves like a regular file, and it can be modified, truncated, memory-mapped, and so on.

However, unlike a regular file, it lives in RAM and has volatile backing storage. This means that filesystem scanners can’t scan it. Once all references to the file are dropped, it is automatically released. Anonymous memory is used for all backing pages of the file. Therefore, files created by memfd_create()have the same semantics as other anonymous memory allocations such as those allocated using mmap() with the MAP_ANONYMOUS flag.

Reflective Code Loading in Linux

Linux also supports direct execution of an anonymous file in memory by either execve or execveatsystem call. The reflective code loading contains the following steps:

  1. Creates an anonymous file within the application memory
  2. Writes file content in the anonymous file
  3. Executes the anonymous file from the memory

During reflective code loading, the anonymous does not touch the disk. We will use a simple example to demonstrate the idea. Part of the code is inspired by a 0x00sec blog.

The program primarily performs the following steps:

  1. Connects to a network socket. For demo purposes, we use localhost and port 1111 as the destination address and port, correspondingly.
  2. Creates an anonymous file
  3. Reads file content from the network and write to the file in a loop until the file ends or other error condition happens
  4. Creates a child process and execute the anonymous file from the child

Here are the steps to test the reflective code loading:

  1. Pipe an ELF payload to a netcat listener. For demo purposes, we are just using a simple xeyes binary from Ubuntu distributions.
$ cat /usr/bin/xeyes | nc -l $((0x1111))

2. Run the above reflective code loading program. If everything works, we can see the program loads and executes. We will also see an xeyes window pops up in the GUI. To view the running process artifacts:

$ ps -ef --forest

Note that we can changed the program name to an arbitrary string. We use [kworker/u!0] to demonstrate it is possible to confuse an inexperienced analyst.

How is Reflective Code Loading Used by Threat Groups?

APT threat group TeamTNT has been using the ezuri loader in the wild to deploy malware. TeamTNT is well known for targeting container and cloud environments. We recommend the readers to this blog from AT&T cybersecurity lab for a detailed analysis of the malware.

The ezuri loader is an open source project that uses the reflective code loading technique we described above. The loader contains a decryption routine before it loads the actual payload. At the actual loading stage, it uses the same technique:

Conclusion:

Reflective code loading using anonymous files in Linux is being used by the threat actors actively. Its fileless nature can bypass security tools that are not able to detect and respond to this behavior. MITRE ATT&CK framework has adopted this technique as part of its latest standard.

Cloud security teams should obtain the capability to detect and respond to such threats and focus on the application behavior sequences. To learn more, please check the second part of this blog.

Feel free to reach out with any questions you may have through contact.

--

--

Confluera Engineering
Confluera Engineering

Published in Confluera Engineering

Confluera engineering is not perfect, but we pursue perfection. We write our journey here.

Rex Guo
Rex Guo

Written by Rex Guo

Product Builder | Blackhat/Defcon speaker | @Xiaofei_REX

No responses yet