首页
社区
课程
招聘
[原创]恶意代码分析笔记4(下)
发表于: 2015-7-13 22:49 4540

[原创]恶意代码分析笔记4(下)

2015-7-13 22:49
4540
承接上部分继续分析:

运行目标文件之后就会在目标程序目录里面生成msgina32.dll 文件,将其加载到IDA里面进行分析。
对msgina32.dll 进行分析

1.查看相关的导入表中的API,分类如下:
地址        函数名                 所属模块   
10002000  RegSetValueExW          ADVAPI32
10002004  RegCreateKeyW          ADVAPI32
10002008  RegCloseKey             ADVAPI32
    就是这一类注册表,可以说明此文件的一个操作就是创建注册表,注意这只是一部分操作,因为目标文件是一个.dll动态链接库文件,存在它自身要实现的功能也就是导入表的API函数。

2.查看相关的导出表中的API
函数名                地址   序号   
gina_1                100010E0 1
…………
gina_28               10001290 28

ShellShutdownDialog   100012A0 29
WlxActivateUserShell   100012B0 30
WlxDisconnectNotify    100012C0 31
WlxDisplayLockedNotice 100012D0 32
WlxDisplaySASNotice   100012E0 33
WlxDisplayStatusMessage 100012F0 34
WlxGetConsoleSwitchCredentials 10001300 35
WlxGetStatusMessage   10001310 36
WlxInitialize           10001320 37
WlxIsLockOk          10001330 38
WlxIsLogoffOk         10001340 39
WlxLoggedOnSAS      10001350 40
WlxLoggedOutSAS      100014A0 41
WlxLogoff              10001360 42
WlxNegotiate            10001370 43
WlxNetworkProviderLoad 10001380 44
WlxReconnectNotify     10001390 45
WlxRemoveStatusMessage 100013A0 46
WlxScreenSaverNotify    100013B0 47
WlxShutdown           100013C0 48
WlxStartApplication     100013D0 49
WlxWkstaLockedSAS      100013E0 50

DllRegister                10001440 51

上面的API函数也是分为三类:
1)gina类函数。根据函数名应该可以联系到GINA,GINA是一个组件。Winlogon把用户提供的账号和密码传达给GINA,由GINA负责对账号和密码的有效性进行验证,然后把验证结果反馈给Winlogon程序。进而猜想gina类函数是不是实现获取Winlogon传输给GINA的数据来替代GINA功能,如果这样的话就gina类函数就必须实现GINA所有的功能。
而实现GINA的功能有两种:
① 将GINA的功能全部复制过来,再加上自身要实现的功能。而这种方式工程是十分庞大和复杂的;
② 只需在实现自己的功能之后,再调用GINA,让GINA实现它“本分”职责。这种方式就是在Winlogon与GINA之间插入自己的插件然后获取Winlogon传给GINA的数据,然后经过某些操作之后,再传给GINA。这种方式实现简单,操作方便,同时也不需要考虑太多。    这就产生2种想法:
1.如果我再Winlogon与GINA之间插入的插件是获取系统登录用户名和密码在存储到某个地方或者直接远程发送不就成了,数据用户名和密码窃取了么?
2.将事先(可通过方法1等)获取到相关的普通用户/管理员账号和密码替换为Winlogon传给GINA的数据,再传给GINA,如此无论Winlogon传出的数据是否正确,都将能够以指定的用户身份登录系统。

2)Wlx类函数。这类函数比较陌生,于是找了一下度娘。了解到自建的替换GINA必须实现WlxNegotiate函数,它是Winlogon调用的第一个GINA函数。WlxNegotiate允许GINA确认是否支持目前安装的Winlogon版本。
    这也就证明这个函数实现的是上想法中的1想法,实现自己的功能后调用GINA。
3)Register类函数。 充函数明上看也就是实现注册表操作。
   
    具体是实现什么功能,如何详细实现,还得接下来对相关导出函数进行详细分析。
3.gina类函数。
在进入gina类函数查看详细时发现都是再调用一个获取进程地址的API(我已将此函数的名字修改为“GetProcAddress_0”)。但具体是要实现的是什么目的现在还不清楚。获取在下面分析能得到答案。
Wlx类函数。 查看ShellShutdownDialog 函数,从函数名猜测这是一个关闭对话框的shell。但进去去发现里面的代码很调用的正是gina类函数的GetProcAddress_0,实现的正是获取ShellShutdownDialog的地址。
push    offset ProcName ; "ShellShutdownDialog"
call    GetProcAddress_0
jmp     eax
ShellShutdownDialog endp
ShellShutdownDialog这是一个不公开的函数,根据查到的消息这个函数的实现的是对系统进行关机,重启,注销,睡眠等系统功能。查阅http://blog.csdn.net/jzj_jony/article/details/805085
再继续查看其他的Wlx类函数,都是调用GetProcAddress_0函数,获取相关函数的地址,也就是调用GINA的功能,执行相关操作。再继续从Wlx类函数中找出有价值的函数,不熟悉函数名深意的只有一个个枚举查看,了解Wlx函数的就知道,这里面哪个更有价值。
一直枚举到WlxLoggedOutSAS此处,发现该函数除了获取WlxLoggedOutSAS地址还进行了其他操作。调用了一个函数:sub_10001570
push    ecx
mov    ecx, [esi+4]
push    edx
push    ecx
push    eax             ; Args
push    offset aUnSDmSPwSOldS ; "UN %s DM %s PW %s OLD %s"
push    0               ; dwMessageId
call    sub_10001570
再来到相应的函数中。首先是发现他要打开一个文件msutil32.sys
push    esi
push    eax             ; Args
push    ecx             ; Format
push    800h            ; Count
push    edx             ; Dest
call    _vsnwprintf
push    offset Mode     ; Mode
push    offset Filename ; "msutil32.sys"
call    _wfopen
这看上去像是驱动文件。哪来的这个文件的?这个文件存放在何处?它存在的作用是什么?
F5对此函数进行伪代码生成便可知道,此文件的作用,这一个记录时间日期的文件,并非驱动。因此他也起到了一定的隐藏作用。
FILE *sub_10001570(DWORD dwMessageId, const wchar_t *Format, ...)
{
  FILE *result;               // eax@1
  FILE *v3;                 // esi@1
  wchar_t *v4;               // ST14_4@2
  wchar_t *v5;               // eax@2
  HLOCAL hMem;           // [sp+4h] [bp-854h]@3
  wchar_t Buffer;             // [sp+8h] [bp-850h]@2
  char v8;                   // [sp+30h] [bp-828h]@2
  wchar_t Dest;              // [sp+58h] [bp-800h]@1
  va_list va;                 // [sp+864h] [bp+Ch]@1

  va_start(va, Format);
  vsnwprintf(&Dest, 0x800u, Format, va);
  result = wfopen(L"msutil32.sys", &Mode);
  v3 = result;
  if ( result )
  {
    v4 = wstrtime(&Buffer);
    v5 = wstrdate((wchar_t *)&v8);
    fwprintf(v3, L"%s %s - %s ", v5, v4, &Dest);
    if ( dwMessageId )
    {
      FormatMessageW(0x1100u, NULL, dwMessageId, 0x409u, (LPWSTR)&hMem, 0, NULL);
      fwprintf(v3, L"ErrorCode:%d ErrorMessage:%s. \n", dwMessageId, hMem);
      LocalFree(hMem);
      result = (FILE *)fclose(v3);
    }
    else
    {
      fwprintf(v3, "\n");
      result = (FILE *)fclose(v3);
    }
  }
  return result;
}

但是还没确定是在何处生成msutil32.sys文件,需要回头查看Lab11_01.exe文件导入表上的CreateFile。由于动态调试也检测也没有发现到msutil32.sys此文件,所以无法解释此文件的缘由。
接下来分析msgina32.dll主函数确定执行流程。在正常情况下,该文件的执行流程是:
push    esi
mov     esi, [esp+20Ch+hinstDLL]
push    esi             ; hLibModule
call    ds:DisableThreadLibraryCalls
lea     eax, [esp+20Ch+LibFileName]
push    104h            ; uSize
push    eax             ; lpBuffer
mov     dword_100033F0, esi
call    ds:GetSystemDirectoryW
lea     ecx, [esp+20Ch+LibFileName]
push    offset String2  ; "\\MSGina"
push    ecx             ; lpString1
call    ds:lstrcatW
lea     edx, [esp+20Ch+LibFileName]
push    edx             ; lpLibFileName
call    ds:LoadLibraryW
xor     ecx, ecx
mov     hModule, eax
test    eax, eax
etnz   cl
mov     eax, ecx
pop     esi
add     esp, 208h

    在载入OD进行动态调试时,来到 GetSystemDirectoryW函数时发现,此函数实现的获取系统目录。
0012F650  |10001084  返回到 msgina32.10001084 来自 kernel32.GetSystemDirectoryW
0012F654  |0012F660  UNICODE "C:\WINDOWS\system32"
    也就是说将要获取的系统目录是"C:\WINDOWS\system32"
    在调用到lstrcatW,这函数实现的是将一个字符串附加到另一个字符串。
10001088  push msgina32.10003014                   ; /StringToAdd = "\MSGina"
1000108D push ecx                          ; |ConcatString = "C:\WINDOWS\system32"
1000108E  call dword ptr ds:[<&KERNEL32.lstrcatW>] ; \lstrcatW

也就是将C:\WINDOWS\system32字符串追加"\MSGina"为C:\WINDOWS\system32\MSGina
接下来在执行载入模块函数:
10001098 push edx                      ; /FileName = "C:\WINDOWS\system32\MSGina"
10001099 call dword ptr ds:[<&KERNEL32.LoadLibrar>; \LoadLibraryW
1000109F xor ecx,ecx                             ;  kernel32.7C810FE9

但是因为不存在这个MSGina文件而是存在msgina.dll,而msgina.dll文件正是GINA实现功能加载的模块。理由如下:要实现Wxl类功能就必须载入msgina.dll模块,因为Wxl类函数集合在msgina.dll模块中。只要载入msgina.dll模块才能调用目标文件导出表中的Wxl类函数。

现在再查看RegShot在运行前与运行后的注册表修改情况。
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GinaDLL

HKU\S-1-5-21-1229272821-1326574676-1801674531-500\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{75048700-EF1F-11D0-9888-006097DEACF9}\Count\HRZR_EHACNGU:P:\Qbphzragf naq Frggvatf\Nqzvavfgengbe\桌面\调试\Yno11-01.

HKU\S-1-5-21-1229272821-1326574676-1801674531-500\Software\Microsoft\Windows\ShellNoRoam\MUICache\C:\Documents and Settings\Administrator\桌面\调试\Lab11-01.exe: "Lab11-01"

总结:1.目标文件Lab11_01.exe文件主要执行两个操作:
1)创建msgina32.dll ,并存储于Lab11_01.exe目录里面
2)在注册表HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\中创建一个GinaDLL键值,进而实现在用户登录系统时就调用,该键值中的木块msgina32.dll。

3)msgina32.dll文件主要是实现在用户登录系统时就存储时间和日期到msutil32.sys 文件中。但因为可执行文件运行时,将调用模块名写错,无法加载,也无法执行相应的函数,所以无法创建该函数。


思考:假设:如果文件正确相关模块,从而执行。
1.然后在用户登录的时候将用户名的账号和密码秘密截获并存储到msutil32.sys 文件中。
2.是否存在这样的情况。将获取的管理员用户名和密码,存放在msgina32.dll文件中,当用户登录时,截取他传出的数据,然后在即将存放在msgina32.dll文件中的管理员用户名和密码,传输个GINA进行验证,那无论使用什么用户,什么密码,匹配是否正确,都将会以管理员身份登录系统。


4.

相关服务器信息分析
(可以提供一些详细的目标域名,IP地址,邮件地址…………相关信息)


预防及修复措施

技术热点及总结

1.生成新文件,
2.在HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\路径创建注册表,实现自启动功能
3.能够将用户登录系统时存储他的时间和日期(真正的病毒实习的是总结上的两个思考)


可惜此文件使用环境(XP一下)早已过时,仅适用于与初学者提高知识境界。

[课程]Linux pwn 探索篇!

收藏
免费 3
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//