An Analysis of Shikata-Ga-Nai

Trivia: Shikata ga nai is Japanese and means something like “nothing can be done about it”. https://en.wikipedia.org/wiki/Shikata_ga_nai

Learning is always fun and I was playing around with making ClamAV signatures. I wondered if it is possible to write a signature that matches the famous Shikata-Ga-Nai shellcode encoder shipping with metasploit.

After all I succeeded to write a signature that can match it, but it is so short that it also generates false positives. Here I explain why Shikata-Ga-Nai is so good, how the decoder stub can be analyzed and how a signature can be written.

Analysis

From the source code:

# The shikata encoder has an excellent ranking because it is polymorphic.

# Party time, excellent!

That is true, but let’s have a deep look at it. First here is the command for generating some of the test files:

# echo “planet express is now awesome express” | msfencode -e x86/shikata_ga_nai -c 1 -t raw -o sample01.raw

And here is how the samples look like:

root@bt:~/shikata# xxd sample01.raw

0000000: dbd4 d974 24f4 b8f2 d440 245a 31c9 b10a …t$….@$Z1…

0000010: 3142 1983 c204 0342 1510 2130 48b5 a4d4 1B…..B..!0H…

0000020: e415 5c6f 7527 fbfc 06e7 6a70 c989 0301 ..\ou’….jp….

0000030: 2934 ab88 5ad9 3e36 bd40 b9c8 cfef 4a5a )4..Z.>6.@….JZ

0000040: 3a :

root@bt:~/shikata# xxd sample02.raw

0000000: d9cc ba01 f308 bdd9 7424 f45f 2bc9 b10a ……..t$._+…

0000010: 83c7 0431 5715 0357 15e3 0678 d182 861c …1W..W…x….

0000020: 5d64 32a7 ed16 d924 7df6 48b8 a198 e549 ]d2….$}.H….I

0000030: 8205 8dd0 b1aa 1c7e 1651 a7f0 24fc 2482 …….~.Q..$.$.

0000040: c2 .

root@bt:~/shikata# xxd sample03.raw

0000000: bfbf c40b 27db d0d9 7424 f45e 2bc9 b10a ….’…t$.^+…

0000010: 317e 1483 eefc 037e 105d 317b 4bc0 d419 1~…..~.]1{K…

0000020: e722 4c9a 7750 eb29 0bb4 9abe cbda 3336 .”L.wP.)……36

0000030: 2c43 bbdd 5fec 2e7b 8097 c8f3 b232 5a87 ,C.._..{…..2Z.

0000040: 38 8

root@bt:~/shikata# xxd sample04.raw

0000000: dad0 d974 24f4 baf3 0b7d 9558 31c9 b10a …t$….}.X1…

0000010: 3150 1983 c004 0350 1511 fe0d f9b4 6f8b 1P…..P……o.

0000020: 7516 152b 0624 b0b8 95e8 534c 7a86 ccc5 u..+.$….SLz…

0000030: 5a37 644f e8d8 e7ea 2e43 8084 5cee 0316 Z7dO…..C..\…

0000040: ab .V

As can be seen the output of the samples look pretty different.

Disassembling the shellcode with ndisasm:

root@bt:~/shikata# ndisasm -u sample01.raw

00000000 DBD4 fcmovnbe st4

00000002 D97424F4 fnstenv [esp-0xc]

00000006 B8F2D44024 mov eax,0x2440d4f2

0000000B 5A pop edx

0000000C 31C9 xor ecx,ecx

0000000E B10A mov cl,0xa

00000010 314219 xor [edx+0x19],eax

00000013 83C204 add edx,byte +0x4

00000016 034215 add eax,[edx+0x15]

00000019 1021 adc [ecx],ah

0000001B 3048B5 xor [eax-0x4b],cl

0000001E A4 movsb

0000001F D4E4 aam 0xe4

00000021 155C6F7527 adc eax,0x27756f5c

00000026 FB sti

00000027 FC cld

00000028 06 push es

00000029 E76A out 0x6a,eax

0000002B 70C9 jo 0xfffffff6

0000002D 8903 mov [ebx],eax

0000002F 0129 add [ecx],ebp

00000031 34AB xor al,0xab

00000033 885AD9 mov [edx-0x27],bl

00000036 3E36BD40B9C8CF ss mov ebp,0xcfc8b940

0000003D EF out dx,eax

0000003E 4A dec edx

0000003F 5A pop edx

00000040 3A db 0x3a

This approach is not useful here, instead for further analysis libemu was used. Libemu is a library offering x86 shellcode emulation and comes with the tool sctest.

More information about libemu:

http://libemu.carnivore.it/

https://govolution.wordpress.com/2014/01/24/slae-assignment-5-shellcode-analysis/

http://resources.infosecinstitute.com/shellcode-detection-emulation-libemu/

Here are the steps for producing a nice flowchart:

echo “planet express is now awesome express” | msfencode -e x86/shikata_ga_nai -c 1 -t raw | sctest -vvv -Ss 100000 -G Exec.dot

cat sample01.raw | sctest -vvv -Ss 100000 -G Exec.dot

root@bt:~/shikata# dot Exec02.dot -Tpng -o Exec02.dot.png

Now let’s compare the ndisasm output from before and the flowchart:

shikata01

The flowchart shows how the decryption algorithm works. And there are some interesting points. At offset 02 (417002) the fnstenv instruction is being executed which is a hint for an encoder stub. This instruction helps to obtain the EIP, the value of the EIP register is now in EDX.

Further the instruction from offset 19 (41019) is not still correct in the disassembled output (on the right), where as the shellcode emulator revealed the correct instruction which is adding the loop instruction for the decryption algorithm.

Here is a diagram for a two round shikata-ga-nai encoded payload:

root@bt:~/shikata# echo “planet express is now awesome express” | msfencode -e x86/shikata_ga_nai -c 2 -t raw -o sample_2_rounds.raw

root@bt:~/shikata# cat sample_5_rounds.raw | ~/libemu/libemu/tools/sctest/sctest -vvv -Ss 100000 -G Exec01_5_rounds.dot

root@bt:~/shikata# dot Exec01_5_rounds.dot -Tpng -o Exec_5_rounds.dot.png

 

shikata02

 

As can be seen the encryption code is generated twice. With three rounds the code is generated three times and so on. What can be seen here very good is the fact, that the code for the encryption loop is looking different.

By the way, the encryption code has a size of something about 27 bytes, this can also be seen from the size of the files:

root@bt:~/shikata# ll sample01.raw *_rounds.raw

-rw-r–r– 1 root root 65 2015-08-16 20:56 sample01.raw

-rw-r–r– 1 root root 92 2015-08-21 17:45 sample_2_rounds.raw

-rw-r–r– 1 root root 173 2015-08-21 17:39 sample_5_rounds.raw

Further reading for shellcoding and analyzing shellcode:

http://phrack.org/issues/62/7.html

http://repository.lib.ncsu.edu/ir/bitstream/1840.16/5484/1/etd.pdf

Writing a ClamAV signature

If you are not familiar with the ClamAV sigtool have look here:

http://www.pwnage.io/2013/06/fun-with-clamav.html

https://raw.githubusercontent.com/vrtadmin/clamav-devel/master/docs/signatures.pdf

The source code that builds up the encoder can be found here (or on your harddrive):

https://github.com/rapid7/metasploit-framework/blob/master/modules/encoders/x86/shikata_ga_nai.rb

Note that a sub-signature must have a size if at least two bytes, I am using logical signatures in this example.

The samples above look polymorphic, but nevertheless a pattern can be found that looks similar.

Here is the first line of the four samples for comparing them directly:

0000000: dbd4 d974 24f4 b8f2 d440 245a 31c9 b10a …t$….@$Z1…

0000000: d9cc ba01 f308 bdd9 7424 f45f 2bc9 b10a ……..t$._+…

0000000: bfbf c40b 27db d0d9 7424 f45e 2bc9 b10a ….’…t$.^+…

0000000: dad0 d974 24f4 baf3 0b7d 9558 31c9 b10a …t$….}.X1…

By having a look to the corresponding source code it is possible to determine what assemly code is used for clearing the ECX register:

clear_register = Rex::Poly::LogicalBlock.new(‘clear_register’,

\x31\xc9“, # xor ecx,ecx

\x29\xc9“, # sub ecx,ecx

\x33\xc9“, # xor ecx,ecx

\x2b\xc9“) # sub ecx,ecx

And this translates to the pattern:

31C9;29C9;33C9;2BC9

For the next part one or two bytes can be used to enhance the two bytes:

if (length <= 255)

init_counter.add_perm(“\xb1” + [ length ].pack(‘C’))

elsif (length <= 65536)

init_counter.add_perm(“\x66\xb9” + [ length ].pack(‘v’))

else

init_counter.add_perm(“\xb9” + [ length ].pack(‘V’))

end

In combination with the first two bytes here are the sub-signatures:

31c9b1;31c966b9;31c9b9;29c9b1;29c966b9;29c9b9;33c9b1;33c966b9;33c9b9;2bc9b1;2bc966b9;2bc9b9

The file with the signature can be saved for example as test.ldb, here is the complete signature:

Shikata2;Target:0;(0|1|2|3|4|5|6|7|8|9|10|11);31C9B1;31C966B9;31C9B9;29C9B1;29C966B9;29C9B9;33C9B1;33C966B9;33C9B9;2bC9B1;2bC966B9;2bC9B9

Here is a quick test in my old Windows XP machine:

shikata03

And as it can be seen, it works like expected, but there is a problem.

False Positives

And this problem is that the signature is too short, it has only three or four bytes. This is producing hell of a lot false positives. Here is one example:

shikata04

ClamAV has a false positive list which might be worth a look for a later project :-).

For testing purposes I run ClamAV with the signature over the c:\windows\system32 folder, the signature matched for 55 files out of 2033. But at least the signature might work as an indicator for further analysis.

Cat-and-Mouse

From a pentesters perspective the Shikata-Ga-Nai decoder does awesome work and even can be used for antivirus evasion for some products. Writing a signature seems not to be feasible.

To defeat the signature I wrote it is enough to add a NOP between the second and the third byte if that is possible. Further it might be possible to add more polymorphic code for the first two bytes of the signature, for example with something like:

xor eax, eax

mov ecx, eax

And combinations of that. This will of course add a few bytes to the encoder.

Conclusion

As said before, the Shikata-Ga-Nai decoder is great and can only be recognized by using techniques like code emulation and sandboxing. Another way to recognize complex decoder stubs might be to write scripts that implement more complex rules, but I doubt this is practical.

Further, here it can be seen why it is so hard to write good signatures for antivirus tools, since malware comes with many faces.

Thanks to @blubbfiction for proofreading.