病毒逆向分析

Joliph發表於2018-03-18

收到一個病毒樣本,被告知高危,需要進行逆向分析。分析完成之後寫篇你想分析報告,第一次寫病毒逆向報告,還不太會排版,見諒。
首先,先拿到病毒傳到世界防毒網上先看看檢出率,不出意料,檢出率還挺高(60 / 66),畢竟不算是特別新的病毒了, 但是在高檢出率的同時,virustotal和騰訊的哈勃分析系統都沒能檢測到什麼關鍵的病毒行為(騰訊只檢出了開啟事件,virustotal只檢出Isdebuggerpresent呼叫),所以這個東西簡單加個殼改一改就繞過了一堆殺軟了

騰訊哈勃分析結果:哈勃分析結果頁
virustotal分析結果:VirusTotal結果頁
病毒樣本下載:百度網盤
解壓密碼:virus

繞了一會兒
首先用PEDI查下殼發現是VC++的,並沒有加殼。
拖進IDA檢視下呼叫API列表,字串等資訊,然後看下關鍵API呼叫周圍的虛擬碼,
不過一開始用IDA靜態分析一直在他的主執行緒裡面繞,並沒有發現啥惡意行為,上OD給GetProcAddress下斷,之前認為他是動態呼叫API,結果並沒有斷下,一開始做了半天無用功。。。。

OD載入
看了半天感覺這病毒把惡意程式碼給放到新建立的執行緒中了,然後再執行緒中通過動態呼叫API來躲避OD和IDA的函式呼叫檢測。
1.OD 下用 BP CreateThread 給系統建立新執行緒API下斷
成功斷下,檢視函式呼叫資訊:

00127638   00A20594  /CALL 到 CreateThread 來自 00A20591
0012763C   00000000  |pSecurity = NULL
00127640   00000043  |StackSize = 43 (67.)
00127644   00A53F61  |ThreadFunction = 00A53F61        //新執行緒的起始地址
00127648   00A70081  |pThreadParm = 00A70081
0012764C   00000000  |CreationFlags = 0
00127650   00A2AEA0  \pThreadId = 00A2AEA0

2.給 00A53F61 地址下斷,跟蹤這個執行緒的執行流程

00A53F61    5D              pop ebp                                  //新執行緒的起始地址
00A53F62    5D              pop ebp                                  
00A53F63    60              pushad
00A53F64    E8 11000000     call 00A53F7A                            //Call 1
00A53F69    E8 00000000     call 00A53F6E                            //SEH處理函式
00A53F6E    58              pop eax
00A53F6F    8D88 0A030000   lea ecx,dword ptr ds:[eax+0x30A]
00A53F75    E9 DE0E0000     jmp 00A54E58
00A53F7A    64:FF35 0000000>push dword ptr fs:[0]                    //獲取SEH連結串列
00A53F81    64:8925 0000000>mov dword ptr fs:[0],esp                 //新增SEH異常處理連結串列
00A53F88    8B8D D6070000   mov ecx,dword ptr ss:[ebp+0x7D6]
00A53F8E    8D81 8B74FFFF   lea eax,dword ptr ds:[ecx-0x8B75]
00A53F94    50              push eax
00A53F95    05 3DFEFFFF     add eax,-0x1C3
00A53F9A    50              push eax
00A53F9B    C3              retn

3.繼續 F8,發現呼叫了CreateMutex建立互斥體

00A53FC4    50              push eax
00A53FC5    6A 00           push 0x0
00A53FC7    FFB5 4A070000   push dword ptr ss:[ebp+0x74A]
00A53FCD    FF55 00         call dword ptr ss:[ebp]                  //建立互斥體CreateMutexA
00A53FD0    85C0            test eax,eax
00A53FD2    0F84 A0020000   je 00A54278
00A53FD8    8985 12080000   mov dword ptr ss:[ebp+0x812],eax
00A53FDE    6A 00           push 0x0
00A53FE0    6A 00           push 0x0
00A53FE2    6A 00           push 0x0
00A53FE4    FF55 00         call dword ptr ss:[ebp]                  //建立互斥體kernel32.CreateMutexA
00A53FE7    85C0            test eax,eax
00A53FE9    0F84 89020000   je 00A54278
00A53FEF    8985 22080000   mov dword ptr ss:[ebp+0x822],eax

4.獲取自身全路徑,然後檢測全路徑中有無敏感詞,敏感詞列表:

00A5C0FE                                            7B 00                {.
00A5C10E  7D 00 24 00 74 65 6D 70 00 6E 6F 72 74 6F 6E 00  }.$.temp.norton.
00A5C11E  6D 63 61 66 65 65 00 61 6E 74 69 00 74 6D 70 00  mcafee.anti.tmp.
00A5C12E  73 65 63 75 72 65 00 75 70 78 00 66 6F 72 74 69  secure.upx.forti
00A5C13E  00 73 63 61 6E 00 7A 6F 6E 65 20 6C 61 62 73 00  .scan.zone labs.
00A5C14E  61 6C 61 72 6D 00 73 79 6D 61 6E 74 65 63 00 72  alarm.symantec.r
00A5C15E  65 74 69 6E 61 00 65 65 79 65 00 76 69 72 75 73  etina.eeye.virus
00A5C16E  00 66 69 72 65 77 61 6C 6C 00 73 70 69 64 65 72  .firewall.spider
00A5C17E  00 62 61 63 6B 64 6F 6F 72 00 64 72 77 65 62 00  .backdoor.drweb.
00A5C18E  76 69 72 69 00 64 65 62 75 67 00 70 61 6E 64 61  viri.debug.panda
00A5C19E  00 73 68 69 65 6C 64 00 6B 61 73 70 65 72 73 6B  .shield.kaspersk
00A5C1AE  79 00 64 6F 63 74 6F 72 00 74 72 65 6E 64 20 6D  y.doctor.trend m
00A5C1BE  69 63 72 6F 00 73 6F 6E 69 71 75 65 00 63 69 6C  icro.sonique.cil
00A5C1CE  6C 69 6E 00 62 61 72 72 61 63 75 64 61 00 73 79  lin.barracuda.sy
00A5C1DE  67 61 74 65 00 72 65 73 63 75 65 00 70 65 62 75  gate.rescue.pebu
00A5C1EE  6E 64 6C 65 00 69 64 61 00 73 70 66 00 61 73 73  ndle.ida.spf.ass
00A5C1FE  65 6D 62 6C 65 00 70 6B 6C 69 74 65 00 61 73 70  emble.pklite.asp
00A5C20E  61 63 6B 00 64 69 73 61 73 6D 00 67 6C 61 64 69  ack.disasm.gladi
00A5C21E  61 74 6F 72 00 6F 72 74 20 65 78 70 6C 00 70 72  ator.ort expl.pr
00A5C22E  6F 63 65 73 73 00 65 6C 69 61 73 68 69 6D 00 74  ocess.eliashim.t
00A5C23E  64 73 33 00 73 74 61 72 66 6F 72 63 65 00 73 61  ds3.starforce.sa
00A5C24E  66 65 27 6E 27 73 65 63 00 61 76 78 00 72 6F 6F  fe'n'sec.avx.roo
00A5C25E  74 00 62 75 72 6E 00 61 6C 61 64 64 69 6E 00 65  t.burn.aladdin.e
00A5C26E  73 61 66 65 00 6F 6C 6C 79 00 67 72 69 73 6F 66  safe.olly.grisof
00A5C27E  74 00 61 76 67 00 61 72 6D 6F 72 00 6E 75 6D 65  t.avg.armor.nume
00A5C28E  67 61 00 6D 69 72 63 00 73 6F 66 74 69 63 65 00  ga.mirc.softice.
00A5C29E  6E 6F 72 6D 61 6E 00 6E 65 6F 6C 69 74 65 00 74  norman.neolite.t
00A5C2AE  69 6E 79 00 6F 73 69 74 69 73 00 70 72 6F 78 79  iny.ositis.proxy
00A5C2BE  00 77 65 62 72 6F 6F 74 00 68 61 63 6B 00 73 70  .webroot.hack.sp
00A5C2CE  79 00 69 73 73 00 70 6B 77 61 72 65 00 62 6C 61  y.iss.pkware.bla
00A5C2DE  63 6B 69 63 65 00 6C 61 76 61 73 6F 66 74 00 61  ckice.lavasoft.a
00A5C2EE  77 61 72 65 00 70 65 63 6F 6D 70 61 63 74 00 63  ware.pecompact.c
00A5C2FE  6C 65 61 6E 00 68 75 6E 74 65 72 00 63 6F 6D 6D  lean.hunter.comm
00A5C30E  6F 6E 00 6B 65 72 69 6F 00 72 6F 75 74 65 00 74  on.kerio.route.t
00A5C31E  72 6F 6A 61 6E 00 73 70 79 77 61 72 65 00 68 65  rojan.spyware.he
00A5C32E  61 6C 00 61 6C 77 69 6C 00 71 75 61 6C 79 73 00  al.alwil.qualys.
00A5C33E  74 65 6E 61 62 6C 65 00 61 76 61 73 74 00 61 32  tenable.avast.a2
00A5C34E  00 65 74 72 75 73 74 00 73 70 79 00 73 74 65 67  .etrust.spy.steg
00A5C35E  61 6E 6F 73 00 73 65 63 75 72 69 74 79 00 70 72  anos.security.pr
00A5C36E  69 6E 63 69 70 61 6C 00 61 67 6E 69 74 75 6D 00  incipal.agnitum.
00A5C37E  6F 75 74 70 6F 73 74 00 61 76 70 00 70 65 72 73  outpost.avp.pers
00A5C38E  6F 6E 61 6C 00 73 6F 66 74 77 69 6E 00 64 65 66  onal.softwin.def
00A5C39E  65 6E 64 65 72 00 69 6E 74 65 72 6D 75 74 65 00  ender.intermute.
00A5C3AE  67 75 61 72 64 00 69 6E 6F 63 75 6C 61 74 65 00  guard.inoculate.
00A5C3BE  73 6F 70 68 6F 73 00 66 72 69 73 6B 00 61 6C 77  sophos.frisk.alw
00A5C3CE  69 6C 00 70 72 6F 74 65 63 74 00 65 73 65 74 00  il.protect.eset.
00A5C3DE  6E 6F 64 33 32 00 66 2D 70 72 6F 74 00 61 76 77  nod32.f-prot.avw
00A5C3EE  69 6E 00 61 68 65 61 64 00 6E 65 72 6F 00 62 6C  in.ahead.nero.bl
00A5C3FE  69 6E 64 77 72 69 74 65 00 63 6C 6F 6E 65 63 64  indwrite.clonecd
00A5C40E  00 65 6C 61 62 6F 72 61 74 65 00 73 6C 79 73 6F  .elaborate.slyso
00A5C41E  66 74 00 68 69 6A 61 63 6B 00 72 6F 78 69 6F 00  ft.hijack.roxio.
00A5C42E  69 6D 61 70 69 00 6E 65 77 74 65 63 68 00 69 6E  imapi.newtech.in
00A5C43E  66 6F 73 79 73 74 65 6D 73 00 61 64 61 70 74 65  fosystems.adapte
00A5C44E  63 00 73 77 69 66 74 20 73 6F 75 6E 64 00 63 6F  c.swift sound.co
00A5C45E  70 79 73 74 61 72 00 61 73 74 6F 6E 73 6F 66 74  pystar.astonsoft
00A5C46E  00 67 65 61 72 20 73 6F 66 74 77 61 72 65 00 73  .gear software.s
00A5C47E  61 74 65 69 72 61 00 64 66 72 67 6E 74 66 73 00  ateira.dfrgntfs.

5.敏感詞字串對比函式
esi:自身的全路徑 edi:檢測列表
若未檢測到則EAX值為0,檢測到則為非0

00A54338    8A07            mov al,byte ptr ds:[edi]
00A5433A    84C0            test al,al
00A5433C    74 2A           je short 00A54368
00A5433E    8A26            mov ah,byte ptr ds:[esi]
00A54340    84E4            test ah,ah
00A54342    74 24           je short 00A54368
00A54344    38E0            cmp al,ah
00A54346    75 1A           jnz short 00A54362
00A54348    8BCE            mov ecx,esi
00A5434A    8BD7            mov edx,edi
00A5434C    8A21            mov ah,byte ptr ds:[ecx]
00A5434E    8A02            mov al,byte ptr ds:[edx]
00A54350    84C0            test al,al
00A54352    74 11           je short 00A54365
00A54354    84E4            test ah,ah
00A54356    74 10           je short 00A54368
00A54358    38C4            cmp ah,al
00A5435A    75 04           jnz short 00A54360
00A5435C    41              inc ecx
00A5435D    42              inc edx      
00A5435E  ^ EB EC           jmp short 00A5434C
00A54360    8A07            mov al,byte ptr ds:[edi]
00A54362    46              inc esi
00A54363  ^ EB D9           jmp short 00A5433E
00A54365    8BC6            mov eax,esi
00A54367    C3              retn
00A54368    33C0            xor eax,eax
00A5436A    C3              retn

6.CreateThread又攔截了新執行緒的建立

00D3FF50   00A5B769  /CALL 到 CreateThread 來自 00A5B766
00D3FF54   00000000  |pSecurity = NULL
00D3FF58   00001000  |StackSize = 1000 (4096.)
00D3FF5C   00A5B3F8  |ThreadFunction = 00A5B3F8
00D3FF60   00A413C0  |pThreadParm = 00A413C0
00D3FF64   00000000  |CreationFlags = 0
00D3FF68   00A70974  \pThreadId = 00A70974

7.跟入新執行緒下斷分析:

00A5B433    64:8925 0000000>mov dword ptr fs:[0],esp
00A5B43A    50              push eax
00A5B43B    FF95 A4000000   call dword ptr ss:[ebp+0xA4]             
00A5B441    FF77 36         push dword ptr ds:[edi+0x36]
00A5B444    50              push eax
00A5B445    FF95 A0000000   call dword ptr ss:[ebp+0xA0]
00A5B44B    8B8D AC000000   mov ecx,dword ptr ss:[ebp+0xAC]    //呼叫Isdebuggerpresent反除錯
00A5B451    E3 08           jecxz short 00A5B45B
00A5B453    FFD1            call ecx
00A5B455    0185 DE070000   add dword ptr ss:[ebp+0x7DE],eax

8.獲取本機程式目錄,進行遍歷查詢

00A547F7    6A 02           push 0x2
00A547F9    FF55 4C         call dword ptr ss:[ebp+0x4C]             //呼叫CreateToolhelp32Snapshot獲取系統程式列表控制程式碼
00A547FC    8BD8            mov ebx,eax
00A547FE    40              inc eax
00A547FF    0F84 CC000000   je 00A548D1
00A54805    8BF4            mov esi,esp
00A54807    C706 28010000   mov dword ptr ds:[esi],0x128
00A5480D    56              push esi
00A5480E    53              push ebx
00A5480F    FF55 58         call dword ptr ss:[ebp+0x58]             //呼叫Process32First拿到第一個程式控制程式碼
00A54812    53              push ebx
00A54813    8D5E 24         lea ebx,dword ptr ds:[esi+0x24]
00A54816    53              push ebx
00A54817    FF95 00010000   call dword ptr ss:[ebp+0x100]            //轉小寫
00A5481D    8BBD D6070000   mov edi,dword ptr ss:[ebp+0x7D6]
00A54823    81C7 2DF5FFFF   add edi,-0xAD3
00A54829    E8 886D0000     call 00A5B5B6                            //呼叫字串比較函式
00A5482E    5B              pop ebx                                  

比對列表

00A5C03E  73 61 76 65 64 75 6D 70 00 64 75 6D 70 72 65 70  savedump.dumprep
00A5C04E  00 64 77 77 69 6E 00 64 72 77 74 73 6E 33 32 00  .dwwin.drwtsn32.
00A5C05E  64 72 77 61 74 73 6F 6E 00 6B 65 72 6E 65 6C 33  drwatson.kernel3
00A5C06E  32 2E 64 6C 6C 00 73 6D 73 73 00 63 73 72 73 73  2.dll.smss.csrss
00A5C07E  00 73 70 6F 6F 6C 73 76 00 63 74 66 6D 6F 6E 00  .spoolsv.ctfmon.
00A5C08E  74 65 6D 70 00 00 00 00 00 76 74 66 00 74 62 00  temp

9.對上面遍歷到的存在的合適的程式進行遠端執行緒注入

00A545CC    6A 01           push 0x1
00A545CE    6A 00           push 0x0
00A545D0    56              push esi
00A545D1    FF95 B0000000   call dword ptr ss:[ebp+0xB0]             //CreateRemoteThread注入執行緒
00A545D7    97              xchg eax,edi
00A545D8    85FF            test edi,edi
00A545DA    0F84 2F010000   je 00A5470F
00A545E0    EB 2D           jmp short 00A5460F
00A545E2    E8 69FFFFFF     call 00A54550
00A545E7    97              xchg eax,edi
00A545E8    85FF            test edi,edi
00A545EA    0F84 1F010000   je 00A5470F
00A545F0    57              push edi
00A545F1    FF55 44         call dword ptr ss:[ebp+0x44]
00A545F4    83F8 00         cmp eax,0x0
00A545F7    0F85 0E010000   jnz 00A5470B                            //迴圈判斷
00A545FD    57              push edi
00A545FE    FF55 2C         call dword ptr ss:[ebp+0x2C]            //掛起執行緒SuspendThread
00A54601    40              inc eax
00A54602    0F84 03010000   je 00A5470B
00A54608    48              dec eax
00A54609    0F85 F8000000   jnz 00A54707
00A5460F    85DB            test ebx,ebx
00A54611    74 18           je short 00A5462B

10.呼叫 VirutualAllocEX 在系統程式中申請空間,準備注入程式碼

00A54564    83BD E6070000 0>cmp dword ptr ss:[ebp+0x7E6],0x0
00A5456B    75 05           jnz short 00A54572
00A5456D    E8 6AFFFFFF     call 00A544DC
00A54572    894424 1C       mov dword ptr ss:[esp+0x1C],eax
00A54576    61              popad
00A54577    C3              retn
00A54578    60              pushad
00A54579    83BD E6070000 0>cmp dword ptr ss:[ebp+0x7E6],0x0
00A54580    74 13           je short 00A54595
00A54582    6A 40           push 0x40
00A54584    68 00100000     push 0x1000
00A54589    50              push eax
00A5458A    6A 00           push 0x0
00A5458C    56              push esi
00A5458D    FF95 B8000000   call dword ptr ss:[ebp+0xB8]             //VirtualAllocEX(空間地址隨機)
00A54593    EB 0D           jmp short 00A545A2
00A54595    6A 40           push 0x40
00A54597    68 00100008     push 0x8001000
00A5459C    50              push eax
00A5459D    6A 00           push 0x0
00A5459F    FF55 E7         call dword ptr ss:[ebp-0x19]             ; kernel32.VirtualAlloc
00A545A2    894424 1C       mov dword ptr ss:[esp+0x1C],eax
00A545A6    61              popad
00A545A7    C3              retn
00A545A8    33C0            xor eax,eax
00A545AA    60              pushad
00A545AB    8BDF            mov ebx,edi
00A545AD    85FF            test edi,edi
00A545AF    75 31           jnz short 00A545E2
00A545B1    83BD B0000000 0>cmp dword ptr ss:[ebp+0xB0],0x0
00A545B8    0F84 51010000   je 00A5470F
00A545BE    8D85 F3080000   lea eax,dword ptr ss:[ebp+0x8F3]

10.呼叫WriteProcessMemory寫入剛分配的記憶體區域

00D6FAC8   00B446C9  /CALL 到 WriteProcessMemory 來自 00B446C6
00D6FACC   00000124  |hProcess = 00000124 (window)  //程式控制程式碼
00D6FAD0   00CD0000  |Address = 0xCD0000    //VirtualAlloc返回值
00D6FAD4   00B4D8C8  |Buffer = 00B4D8C8     //shellcode開始區
00D6FAD8   00007678  |BytesToWrite = 7678 (30328.)  //寫入長度
00D6FADC   00000000  \pBytesWritten = NULL

兩次呼叫,覆蓋寫入

00B446C4    50              push eax
00B446C5    56              push esi
00B446C6    FF55 3C         call dword ptr ss:[ebp+0x3C]            //WriteProcessMemory  長度0x7678
00B446C9    85C0            test eax,eax
00B446CB    59              pop ecx
00B446CC    74 33           je short 00B44701
00B446CE    6A 00           push 0x0
00B446D0    68 0A000000     push 0xA
00B446D5    8D85 3F060000   lea eax,dword ptr ss:[ebp+0x63F]
00B446DB    50              push eax
00B446DC    81C1 FF020000   add ecx,0x2FF
00B446E2    51              push ecx
00B446E3    56              push esi
00B446E4    FF55 3C         call dword ptr ss:[ebp+0x3C]           //WriteProcessMemory 長度:0xA
00B446E7    85C0            test eax,eax
00B446E9    74 16           je short 00B44701
00B446EB    C703 01000100   mov dword ptr ds:[ebx],0x10001
00B446F1    53              push ebx
00B446F2    57              push edi

11.呼叫SetThreadContext函式修改注入程式上下文,使注入程式碼執行

00B446EB    C703 01000100   mov dword ptr ds:[ebx],0x10001
00B446F1    53              push ebx
00B446F2    57              push edi
00B446F3    FF55 40         call dword ptr ss:[ebp+0x40]             ; SetThreadContext(threadid,pcontext)
00B446F6    85C0            test eax,eax
00B446F8    74 07           je short 00B44701
00B446FA    FF8424 E8020000 inc dword ptr ss:[esp+0x2E8]

檢視pcontext指標指向的記憶體區域

00D6FAD8   00B446F6  /CALL 到 SetThreadContext 來自 00B446F3
00D6FADC   0000011C  |hThread = 0000011C (window)
00D6FAE0   00D6FAE4  \pContext = 00D6FAE4

記憶體區:

00D6FAE4  01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00  ..............
00D6FAF4  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00D6FB04  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00D6FB14  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00D6FB24  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00D6FB34  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00D6FB44  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00D6FB54  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00D6FB64  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00D6FB74  38 00 00 00 23 00 00 00 23 00 00 00 00 00 00 00  8...#...#.......
00D6FB84  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00D6FB94  F8 C0 80 7C 00 00 00 00 5B 02 CD 00 1B 00 00 00  €|....[?...

偏移 0xB0 處為 EAX , 偏移 0xB8 處為 EIP
12.呼叫ResumeThread恢復執行緒,注入程式碼成功執行嗎,所以這裡不能直接步過這個函式,
建議下載 processhacker 這個工具,選擇此次注入的程式(WriteProcessMemory呼叫時的程式控制程式碼指向的,不會od看也可以用冰刃檢視)雙擊。找剛剛檢視的pcontext中eip的地址處,修改為無限迴圈(EB FE),原指令不要忘(60 9C),然後步過ResumeThread函式,用OD附件到注入的程式上,把原指令改回來就可以繼續注入程式碼了。

跟蹤後發現shellcode解密完就是其自身,程式碼通過注入完成複製。
程式通過Isdebuggerpresent,註冊SEH和檢測自身全路徑來判斷有沒有被除錯,把惡意行為放到新執行緒中,通過動態函式呼叫,來躲避靜態反編譯的API檢測,通過遠端執行緒注入,把自身程式碼注入到系統程式,然後通過上下文更改完成映象切換。

相關文章