MaximeLionel 发表于 2022-5-1 23:10

新手学习 PracticalMalwareAnalysis lab18-01

# 静态数据
* MD5
```
    sha1,5C1F90ABD22AA3ED55638228862B7A24D4A38CDB
    sha256,2AC6635A26049D354C0C46243F6451E6594B130745A08C5A99E96A64FBBBEC0F
```
* 有壳UPX - signature,UPX -> www.upx.sourceforge.net.
* 导入表 - 发现有GetProcAddress函数,可以作为脱壳线索
```
    GetUserNameA,0x00,0xA0F8,reckoning,implicit,-,-,advapi32.dll
    URLDownloadToCacheFileA,0x00,0xA106,network,implicit,-,x,urlmon.dll
    VirtualProtect,0x00,0xA0BE,memory,implicit,-,x,kernel32.dll
    VirtualAlloc,0x00,0xA0CE,memory,implicit,-,-,kernel32.dll
    VirtualFree,0x00,0xA0DC,memory,implicit,-,-,kernel32.dll
    ExitProcess,0x00,0xA0EA,execution,implicit,-,-,kernel32.dll
    LoadLibraryA,0x00,0xA0A0,dynamic-library,implicit,-,-,kernel32.dll
    GetProcAddress,0x00,0xA0AE,dynamic-library,implicit,-,-,kernel32.dll
```

# 脱壳
## 寻找OEP
* 使用OllyDbg打开,搜索GetProcAddress函数并下断点,运行程序,如下:
```
    76855F20 >8BFF            mov   edi, edi                                          ; Lab18-01.0040800F
    76855F22    55            push    ebp
    76855F23    8BEC            mov   ebp, esp
    76855F25    FF75 04         push    dword ptr
    76855F28    FF75 0C         push    dword ptr
    76855F2B    FF75 08         push    dword ptr
    76855F2E    FF15 200C8C76   call    dword ptr [<&KERNELBASE.GetProcAddressForCaller>] ; KERNELBA.GetProcAddressForCaller
    76855F34    5D            pop   ebp
    76855F35    C2 0800         retn    8
```
* 发现该函数只是对GetProcAddress的封装,跳出该函数如下,发现该段loop函数应该是建立导入表:
```
    00409EE1 > > /8A07          mov   al, byte ptr                               ;build import table
    00409EE3   . |47            inc   edi
    00409EE4   . |08C0          or      al, al
    00409EE6   .^|74 DC         je      short 00409EC4
    00409EE8   . |89F9          mov   ecx, edi
    00409EEA   . |57            push    edi
    00409EEB   . |48            dec   eax
    00409EEC   . |F2:AE         repne   scas byte ptr es:
    00409EEE   . |55            push    ebp
    00409EEF   . |FF96 54900000 call    dword ptr                               ;call GetProcAddress
    00409EF5   . |09C0          or      eax, eax                                          ;KERNEL32.Sleep
    00409EF7   . |74 07         je      short 00409F00
    00409EF9   . |8903          mov   dword ptr , eax
    00409EFB   . |83C3 04       add   ebx, 4
    00409EFE   .^\EB E1         jmp   short <build import table>
```
* 往下拉,发现有个疑似tail jump,后面全是0x00,跳转后第一条指令也是 push ebp,初步判断0x0040154F即为OEP:
```
    00409F3C   .39C4          cmp   esp, eax
    00409F3E   .^ 75 FA         jnz   short 00409F3A
    00409F40   .83EC 80       sub   esp, -80
    00409F43   .- E9 0776FFFF   jmp   0040154F                                          ;目标 jump
    00409F48      00            db      00
    00409F49      00            db      00
    00409F4A      00            db      00
    00409F4B      00            db      00
    00409F4C      00            db      00
```
## 建立输入表
* dump上面找到OEP的process,记录OEP;
* 使用imprec工具修复import table,并转存。

# 脱壳后静态数据:
* 导入表 - 存在网络下载,文件写入,内存操作等功能函数。
```
    URLDownloadToCacheFileA,0xE3,0xB4EA,network,implicit,-,x,urlmon.dll
    HeapCreate,0x34D,0xB3A8,memory,implicit,-,-,kernel32.dll
    VirtualAlloc,0x5CC,0xB438,memory,implicit,-,-,kernel32.dll
    GetFileType,0x254,0xB37A,file,implicit,-,-,kernel32.dll
    WriteFile,0x618,0xB3DC,file,implicit,-,-,kernel32.dll
    CreateProcessA,0xE6,0xB21C,execution,implicit,-,-,kernel32.dll
```
* 字符串检查 - 存在一个URL。
```
    ascii,49,0x00006062,-,format-string,-,http://www.practicalmalwareanalysis.com/%s/%c.png
```

# 动态数据:
执行程序后,发现有DNS query发往www.practicalmalwareanalysis.com。
```
    17        11.641527456        192.168.190.129        192.168.190.1        DNS        92        Standard query 0xc711 A www.practicalmalwareanalysis.com
```

# IDA 分析
* 进入main,首先是使用GetCurrentHWProfileA获取hardware的GUID.
* 然后将GUID的最后12个数字以mac地址的格式写入字符串:
```
    movsx   edx,
    push    edx
    movsx   eax,
    push    eax
    movsx   ecx,
    push    ecx
    movsx   edx,
    push    edx
    movsx   eax,
    push    eax
    movsx   ecx,
    push    ecx
    movsx   edx,
    push    edx
    movsx   eax,
    push    eax
    movsx   ecx,
    push    ecx
    movsx   edx,
    push    edx
    movsx   eax,
    push    eax
    movsx   ecx,
    push    ecx
    push    offset aCCCCCCCCCCCC ; "%c%c:%c%c:%c%c:%c%c:%c%c:%c%c"
    lea   edx,
    push    edx             ; char *
    call    _sprintf
```
* 再GetUserName获得当前用户的用户名,并与之前的GUID字符串结合成'guid_last12bytes-username'的格式。
* 接着,程序会将该字符串用Base64的方式进行加密,注意该程序将a作为了默认padding字符。
* 并将密文以http://www.practicalmalwareanalysis.com/ODA6NmU6NmY6NmU6Njk6NjMtWW9kYWEa/a.png的格式使用URLDownloadToCacheFileA函数进行下载文件。
* 最后使用CreateProcess进行执行。

# 总结
该程序使用了UPX壳,使用在GetProcAddress下bp的方式找到OEP,再重建输入表进行脱壳。
脱壳后分析程序,首先获取了主机的硬件信息和用户名信息,使用Base64方式进行加密,并将加密字符串发往www.practicalmalwareanalysis.com,下载相应的文件,并执行。

daisypojie 发表于 2022-5-2 08:12

heihuhu2012 发表于 2022-5-2 09:26

学习了 谢谢

snakenba580 发表于 2022-5-2 10:51

谢谢分享这么好的经验正在学习中。

cookieandww 发表于 2022-5-15 12:31

思路很好用,谢谢分享!
页: [1]
查看完整版本: 新手学习 PracticalMalwareAnalysis lab18-01