Skip to content

Instantly share code, notes, and snippets.

@NMHai
Forked from laanwj/BLATSTING.txt
Created July 25, 2018 11:30
Show Gist options
  • Save NMHai/9ba25ff1dd569790956f32b28a88db5d to your computer and use it in GitHub Desktop.
Save NMHai/9ba25ff1dd569790956f32b28a88db5d to your computer and use it in GitHub Desktop.
BLATSTING
BLATSTING reverse-engineering notes. Based on files from Firewall/BLATSTING/BLATSTING_201381/LP/lpconfig
Overview
===============
BLATSTING "modular rootkit" implant modules
(not showing implied dependencies, e.g. everything depends on core mod)
┌───────────┐
│ m00000003 │
│ core │
└─────┬─────┘
┌┄┄┄┄┄┄┄┄┄┄┄┄┄┬┄┄┄┄┄┄┄┄┄┄┄┄┄┄┬┄┄┄┄┄┴┄┄┄┄┄┄┄┬┄┄┄┄┄┄┄┄┄┄┄┄┄┬┄┄┄┄┄┄┄┄┄┄┄┄┄┐
v v v v v v
┌─────┴─────┐ ┌─────┴──────┐ ┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐
│ m01010001 │ │ m01020000 │ │ m0c010001 │ │ m03010000 │ │ m05000003 │ │ m08010001 │
│ crypto │ │ crypto_rsa │ │ bpf │ │ network │ │ install │ │ hash │
└─────┬─────┘ └──────┬─────┘ └─────┬─────┘ └─┬──┬─┬────┘ └─┬───┬──┬──┘ └───────────┘
┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆
└┄┄┄┄┄┄┄┄┄┄┄┄┬┄┘ ┆ ┆ ┆ ┆ ┆ ┆ ┆
┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆
┌┄┄┄┄┄┄┄┄┄┄┄ ┆ ┄┄┄┄┄┄┬┄┄┄┄┄┄┄┴┄┄┄┄┄┄┄┄┄┴┄ ┆ ┆ ┄┄┄┄┄┄┄┘ ┆ └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐
┆ ┆ ┆ ┆ ┆ ┆ ┆
┆ ┆ ┆ ┆ └┄┄┄┄┄┄┄┄┄┄┄┄┴┄┄┄┄┄┄┄┄┄┄┐ ┆
┆ ┆ ┆ ┆ ┆ ┆
┆ ┆ ┆ ┌┄┄┴┄┄┄┄┄┄┄┄┄┐ ┆ ┆
v ┆ v v v v v
┌─────┴───────────┐┆ ┌─────┴─────┐ ┌───────┴────┐ ┌─────┴─────┐ ┌───────┴───┐ ┌─────┴─────┐
│ m0d000001 │┆ │ m10000001 │ │ m0e000001 │ │ m07000001 │ │ m09000002 │ │ m02000001 │
│ networkProfiler │┆ │ sniffer │ │ seconddate │ │ cnc │ │ tunnel │ │ file │
└─────────────────┘┆ └───────────┘ └────────────┘ └───────────┘ └───────────┘ └─────┬─────┘
┆ ┆
└┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┬┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘
v
┌─────┴──────┐
│ m12000000 │
│ tadaqueous │
└────────────┘
Interfaces
============
m00000003 core
Imports:
Exports: i00000003
m01010001 crypto
Imports: i00000003
Exports: i01010000
m01020000 crypto_rsa
Imports: i00000003
Exports: i01020000
m0c010001 bpf
Imports: i00000003
Exports: i0c010000
m03010000 network
Imports: i00000003
Exports: i03010001 i11000000
m05000003 install
Imports: i00000003
Exports: i05000000
m08010001 hash
Imports: i00000003
Exports: i08010000
m0e000001 seconddate
Imports: i00000003 i03010001
Exports:
m02000001 file
Imports: i00000003 i05000000
Exports: i02000000 i04000000
m0d000001 networkProfiler
Imports: i00000003 i03010001 i05000000 i0c010000
Exports: i0d000000
m09000002 tunnel
Imports: i00000003 i03010001 i05000000
Exports: i09000000
m10000001 sniffer
Imports: i00000003 i03010001 i05000000 i0c010000
Exports: i10000000
m07000001 cnc
Imports: i00000003 i03010001
Exports: i07000000
m12000000 tadaqueous
Imports: i00000003 i01010000 i01020000 i04000000
Exports:
Other notes
=================
- It looks like BLATSTING is a Linux kernel module (or at least: runs in the Linux kernel). Various
references symbol such as `skb_linearize` point in this direction. The BLATSTING modules then, in their
turn, are submodules.
- `the_interface` is a pointer to the main interface of the modules to the outside world. It is part
of the `core` module, and points to a table of function pointers. Modules register their own
interface(s) using `call *(*the_interface+0x40)`. Other modules (which depend on this interface)
can then request this interface (using ??) and use it.
- All interfaces are represented by a function call table (a list of pointers to .text segment,
prefixed with the interface ID and the module ID).
- There is an executable `./Firewall/BLATSTING/BLATSTING_20322/sei/cored`, which is probably the dropper
for BLATSTING. It is the only file, apart from the `core` module which contains the mysterious
symbol `UYO8_U7c5D`. It also contains the symbol `UWV1S` in obfuscated form, also referenced in other modules.
Kernel injection
==================
╔════════════════╗ ╔════════════════╗
║ kernel ║ ║ cored ║
╟┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄╢ ╟┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄╢
║ ║ ║ ║
║ Symbol table ───────────> Symbols hash ║
║ ║ ║ table ║
║ ║ ║ ║
║ Syscall table <───────── Hook syscall ║
║ ^ ║ ║ 137 ║
║ │ ║ ║ ║
║ v ║ ║ ║
║ Injected <──────────── .data ║
║ code ║ ║ ║
╚════════════════╝ ╚════════════════╝
The executable `./Firewall/BLATSTING/BLATSTING_20322/sei/cored` performs Linux kernel injection,
and appears to host the other modules.
Some notes on what it does:
- Uses `setrlimit` system call with `RLIMIT_CORE` to prevent dumping core files (avoid leaving evidence). Exit if this fails.
- Swap is disabled later on with the sys_swapoff system call. Possibly for a similar reason.
- Get the kernel version (`/proc/version` as well as `/proc/sys/kernel/version`). Pad up to 256 bytes and compute SHA1 hash (what is this used for?). Exit if this fails.
- Looks in `/data/.tos_cores/` for `b%03x%03x.%03x` and `bs%03x%03x.%03x` files, where
the %...x is prinf syntax. These appear to be modules and data files respectively.
- First, a configuration file is read, bse226a3.f24. This directs it to open other
modules and load them in to memory.
- If opening the configuration file fails it tries to look inside the executable itself
for information and modules.
- The SHA1 hash computed earier of /proc/version || /proc/sys/kernel/version is compared against
a predefined set of hashes:
d66347bcad1c62daba8f3683251bf60d09d34a01
3c1084e94c1679223269deb81882e8ccd8fffcc4
6bd6cc8e463ce36e843af9325bc9bbd4989bdc02
13b20dfe138cc894e273c10414ad1c2bd1c536c0
Each of these is associated with a two parameter words that are used later in the injection process.
The set of hashes, as well as a 663-byte configuration area is read from the end of the executable.
Likely there exists an off-line configuration utility to prepare the executable for a certain target
kernel and environment.
- See also `BLATSTING_20040/utils/procversionhashmaker`, an utility described as
"Get the hash bpinsmod uses during implant load."
- One of these parameters is the kernel-space base address.
If none of them matches the proces exits (with return code 26).
- It finds `Kernel code` and `Kernel data` in `/proc/iomem`.
- Then mmaps `/dev/mem` directly. It maps the range encompassing kernel code and kernel data.
Note that this trick to gain access to kernel space is no longer possible in kernels newer
than about 2009 (see http://lwn.net/Articles/267427/) at least if NONPROMISC_DEVMEM,
nowadays called CONFIG_STRICT_DEVMEM is enabled. All distributions enable this on x86, that I know of.
This points at the age of this software. Newer loaders may exist that use an alternative mechanism.
- Looks for symbol `__tos_kmalloc` in the kernel.
- Creates a hash table of kernel symbols.
- Looks for various symbols in the kernel, mostly associated with memory management.
- It seems to hook a syscall interface at some point, and communicate through syscall 137
(`sys_afs_syscall`/`sys_ni_syscall`, a reserved value).
Modules
=========
Each mXXXXXXXX directory contains one of, or both of:
- An `impmod` file which is an ELF file embedded in a special format. To be loaded at
the implant side.
- An `lpmod` file which is an ELF dynamic library loaded by a 'listening post' backend, which is
the command-and-control side of things. These communicate with the associated module
at the implant side.
## IMPlant MODules
- These are likely loaded into the kernel, but are not Linux kernel modules themselves.
They lack the information and symbols normally associated with Linux kernel modules.
- The format describes the module ID, as well as the interfaces exported and imported by the module.
The latter determine the dependency relationships between modules. All modules depend on `core`,
which has module ID `m00000003` and exports the core interface `i00000003`.
- Symbols:
- `the_interface`: The core interface (`i00000003`) - only exported by core module
- `UWV1S`: Unknown - exported by `cored`
- `UYO8_U7c5D`: Unknown - exported by `cored`
- `init_bp_module`: Initialization function - exported by every module
- `cleanup_bp_module`: Deinitialization function - exported by every module
- `cleanup_core_module`: Deinitialization function - exported by core module
- One module, `tadaqueous`, has two ELF files embedded. The first one
is a module as normal, the other is an executable. It seems related to process
management.
What do the modules do?
=========================
m00000003 core
---------------------
Exposes functionality to interface with the kernel and host process, register
and unregister interfaces.
m01010001 crypto
---------------------
Symmetric cryptography functions. This module implements RC5 or RC6.
The constants 0xb7e15163 and 0x61c88647 are used in the same way as described in
chapter 16 of https://securelist.com/files/2015/02/Equation_group_questions_and_answers.pdf
This suggest that BLATSTING is using the same, or similar crypto implementation as
other malware attributed to the Equation Group.
m01020000 crypto_rsa
---------------------
RSA cryptography functions (no details known).
m0c010001 bpf
---------------------
Berkeley Packet Filter functionality. BPFs are programs, encoded
as bytecode, for a simple virtual machine that can inspect
(among other things) network packets, and accept or reject them.
This virtual machine is part of the Linux kernel.
Expressions in network sniffers such as pcap are often compiled to this
representation. See also https://blog.cloudflare.com/bpf-the-forgotten-bytecode/
m03010000 network
---------------------
Network functionality (no details known).
m05000003 install
---------------------
Installation/persistence?
m08010001 hash
---------------------
Apparent from some of the constants in the code (0x5a827999, 0xca62c1d6) this likely implements SHA1 hashing algorithm.
Note that there are no consumers of interface i08010000. No module depends on this one.
m0e000001 seconddate
---------------------
This is by far the most interesting, also the largest binary.
- SECONDDATE is an exploitation technique that takes advantage of web-based
protocols and man-in-the-middle (MitM) positioning.
- SECONDDATE influences real-time communications between client and
server and can quietly redirect web-browsers to FOXACID servers
for individual client exploitation.
- This allows mass exploitation potential for clients passing through
network choke points, but is configurable to provide surgical target
selection as well.
From: https://edwardsnowden.com/2014/03/12/willowvixen-and-seconddate/ (third slide).
See https://gist.github.com/laanwj/96841340cecb5ada220af39551df2896#file-seconddate-3-1-1-0-c-L119 for a
few data structures that are likely used in communication with this module.
m02000001 file
---------------------
No details known.
m0d000001 networkProfiler
---------------------
Execute predefined or custom (passive) scans based on BPF rules,
collect statistics.
See e.g. `Firewall/BLATSTING/BLATSTING_201381/LP/lpconfig/m0d000000/predefinedScans`.
These files contain a description of the filter, and a compiled BPF program in
binary form.
m09000002 tunnel
---------------------
No details known.
m10000001 sniffer
---------------------
Sniff network traffic.
m07000001 cnc
---------------------
Command-and-control functions.
m12000000 tadaqueous
---------------------
Something with OS processes. The non-conventional name seems to apply this is another
internal project such as SECONDDATE.
Kernel interface
====================
After injection into the kernel a spare syscall, number 137 (0x89), is hooked to provide an
interface from user space to specific kernel functionality.
Register ebx seems to be used to communicate a sub-function, which is one of.
0x9d3d143a
0x384713aa
0x93b4e2d2
0xe53c2e96
0xfd13acf3
What exactly these invocations do is not clear to me yet, but they are supposedly
related to module initialization/deinitialization and kernel-side memory management.
Other trivia
==============
- Various strings in the `cored` executable are obfuscated using a simple substitution
cipher. It makes use of multiplication mod 256, which is a clever little trick
I've not seen before for obfuscation. For example: multiply with 29 to decrypt then
multiply with its multiplicative inverse mod 256, 53, to encrypt again.
- The "SHA1" function in `cored` (0x0804ae38) is actually a variant of SHA1. This does cause
the output hashes to be completely different. Not sure if they botched this or this is a subtle
change on purpose:
- Instead of adding 0x80 at the end of the input then padding with zeros, this function
processes the input in 4-byte words, and adds 0x80000000 (little-endian) at the end of the
input, then pads with zeros. This is before the endian-swap at the beginning of the transform
(necessary on little-endian architectures), so for example the buffer for 'test' will end up looking:
74 65 73 74 00 00 00 80 <zeros> 00 00 00 00 20 00 00 00
Whereas it would normally be:
74 65 73 74 80 ...<zeros>... 00 00 00 00 00 00 00 20
- Also note that the endian of the bit count at the end is flipped per 32-bit unit.
- Due to a bug in this padding method, only a multiple of 4 bytes can be processed without
ignoring up to three bytes of input. It looks like the function is only used to hash 256 bytes,
so this bug does not surface in practice.
- However if the `hash` module also implements this variant (it seems that way), and
this module is actually used by anything, things are different.
- The hash module implements an almost-correct SHA1. The buffer itself is built in the same
way as previously, and in the inner function all endian swapping normally required for implementing
SHA-1 on little-endian architectures is left out. But this is handled in an outer function, which
works around the problems: allocates a new buffer (padded to 4 with zeros), copies the input, endian-swapped
intothis new buffer, calls the inner function on this buffer, then frees the buffer, byte-swaps the result
and returns that digest. It's kind of circuitous, but for buffers where the size is a multiple of 4
this returns the same as 'normal' SHA1. For other sizes it return a different output due to the padding.
- BLATSTING's implementers are a big fan of mmap. It seems to be used for all file access, not just
for manipulating kernel memory through `/dev/mem`. Is it done this way to reduce the number
of system calls, to be less conspicious, as well as not reveal what exactly is accessed when
running in `strace`? Or maybe a later stage of the rootkit blocks certain kinds of syscalls
on certain "hidden" files.
- While reverse engineering I haven't found any explicit countermeasures or anti-debugging tricks.
However:
- BLATSTING's implementers took a lot of care not to leak string that could help with
reverse engineering. This is true for `cored`, but also for the modules themselves. There are no
log messages, no debug prints, no error messages, nothing.
- The few strings that are absolutely necessary (such as symbol names) are obfuscated.
- The code was compiled with `-fomit-frame-pointers` (or similar), which makes it somewhat harder
to keep track of the stack frame while reading assembly.
- The code of `cored` is a strange mix of static and dynamic linking. For example, at one point it uses
a direct `sys_open` syscall to open a file then performs `mmap` through the C library.
In the same function.
- The abbreviation `bp_` in symbols likely stands for BEECHPONY. According to
https://marcoramilli.blogspot.nl/2016/08/summing-up-shadowbrokers-leak.html this is
"BEECHPONY A firewall implant that is a predecessor of BANANAGLEE." I haven't looked at
BANANAGLEE much but to me it looks like BUZZDIRECTION is a newer version of this framework.
It wouldn't surprise me if BLATSTING was the oldest of the bunch.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment