首页
社区
课程
招聘
[原创]我的第三阶段◇第一题思路
发表于: 2008-11-2 19:18 24289

[原创]我的第三阶段◇第一题思路

2008-11-2 19:18
24289

考虑第一种方案的时候还没有不重启加10分的规定,先从苯办法开始

基本思路是:

[*]先开调试权限
[*]然后利用木马为了自我更新保留的后门,先恢复SDT并屏蔽掉木马的文件保护
[*] 接下来尝试查找并挂起SYSTEM进程内的木马驱动线程
[*] 将木马文件移动到临时目录下,并调用MoveFileEx在重启后删除
[*] 删除木马驱动服务
[*] 设置重启后自动运行修复工具一次
[*] 重新启动计算机
[*]重启后删除剩余的两个木马自启动注册表键值相对比较有意思的函数包括:


//----------------------------------------------------------------------
// 扫描指定进程内的所有线程,如果发现恶意线程则将其挂起
//----------------------------------------------------------------------
BOOL ScanSystemThreads(DWORD dwProcId, DWORD dwThreadCount, PSYSTEM_THREAD_INFORMATION pThreads)
{
THREADENTRY32 te;
HANDLE hSnapshot;
BOOL bRet =FALSE;
PSYSTEM_THREAD_INFORMATION pThreadTemp;

if (dwProcId != 0)
{
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcId);
if (hSnapshot != INVALID_HANDLE_VALUE)
{
te.dwSize = sizeof(THREADENTRY32);
if (Thread32First(hSnapshot, &te))
{
pThreadTemp = pThreads;
do {
if (te.th32OwnerProcessID == dwProcId)
{
if (dwThreadCount == 0)
break;

if (((DWORD)(pThreadTemp->StartAddress) & 0xFFF) == 0x092E)
{
//printf("Trojan thread detected. TID: %.4X EP: %.8X\n", te.th32ThreadID, pThreadTemp->StartAddress);
bRet = (SuspendTrojanThread(te.th32ThreadID) != -1);
if (bRet)
printf("Trojan thread TID %.4X has been suspended.\n", te.th32ThreadID);
else
printf("Trojan thread TID %.4X cannot be suspended.\n", te.th32ThreadID);
}

pThreadTemp ++;;
dwThreadCount --;
}
}while (Thread32Next(hSnapshot, &te));
}
CloseHandle(hSnapshot);
}
}

return bRet;
}

//----------------------------------------------------------------------
// 读取系统中线程的信息,查找SYSTEM进程,扫描SYSTEM进程内的线程
//----------------------------------------------------------------------
BOOL ScanProcess()
{
PROCESSENTRY32 pe;
HANDLE hSnapshot;
BOOL bRet =FALSE;
DWORD dwReqSize, dwMaxSize, dwCount = 0;
long nStatus;
PSYSTEM_PROCESS_THREAD_INFORMATION pSpti, pSptiTemp;
PFNTQUERYSYSTEMINFORMATION pfNtQuerySystemInformation;

pfNtQuerySystemInformation = (PFNTQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandle("NTDLL.DLL"), "NtQuerySystemInformation");
if (pfNtQuerySystemInformation != NULL)
{
dwMaxSize = DEFAULT_SPTI_ARRAY_SIZE;
pSpti = (PSYSTEM_PROCESS_THREAD_INFORMATION)malloc(dwMaxSize);
while ((pSpti != NULL) &&
((nStatus = pfNtQuerySystemInformation(SystemProcessesAndThreadsInformation, pSpti, dwMaxSize, &dwReqSize)) == STATUS_INFO_LENGTH_MISMATCH))
{
dwMaxSize = (dwReqSize >= dwMaxSize)?dwReqSize:(dwMaxSize+DEFAULT_SPTI_ARRAY_SIZE);
pSpti = (PSYSTEM_PROCESS_THREAD_INFORMATION)realloc(pSpti, dwMaxSize);
}

if (nStatus == 0)
{
dwCount = 1;
pSptiTemp = pSpti;

//计算总数
while (pSptiTemp->Process.NextEntryOffset)
{
pSptiTemp = (PSYSTEM_PROCESS_THREAD_INFORMATION)((LPBYTE)pSptiTemp + pSptiTemp->Process.NextEntryOffset);
dwCount ++;
}

pSptiTemp = pSpti;
//查找SYSTEM进程
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot != INVALID_HANDLE_VALUE)
{
pe.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hSnapshot, &pe))
{
do {
if (dwCount == 0)
break;

if (stricmp(pe.szExeFile, "system") == 0)
{
bRet = ScanSystemThreads(pe.th32ProcessID, pSptiTemp->Process.ThreadCount, pSptiTemp->Threads);
break;
}
pSptiTemp = (PSYSTEM_PROCESS_THREAD_INFORMATION)((LPBYTE)pSptiTemp + pSptiTemp->Process.NextEntryOffset);
dwCount --;
}while (Process32Next(hSnapshot, &pe));
}
CloseHandle(hSnapshot);
}
}

if (pSpti != NULL)
free(pSpti);
}

return bRet;
}

//----------------------------------------------------------------------
// 提升权限
//----------------------------------------------------------------------
BOOL EnablePrivilege(char *pszPrivilege)
{
HANDLE hToken;
LUID luid;
TOKEN_PRIVILEGES tp;

if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
return FALSE;

if (!LookupPrivilegeValue("", pszPrivilege, &luid))
return FALSE;

tp.PrivilegeCount = 1;
tp.Privileges[0].Luid=luid;
tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;

return AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL);
}

//----------------------------------------------------------------------
// 修改注册表键的权限
//----------------------------------------------------------------------
BOOL RegSetKeyPermission(HKEY hRootKey, char *pszSubKey)
{
HKEY hKey;
BOOL bRet = FALSE;
SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
PSID pAdminSid = NULL;
PACL pDacl = NULL;
SECURITY_DESCRIPTOR sd;
DWORD dwAclSize;

if ((pszSubKey != NULL) &&
(RegOpenKeyEx(hRootKey, pszSubKey, 0, WRITE_DAC, &hKey) == ERROR_SUCCESS))
{
if (AllocateAndInitializeSid(&sia, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdminSid))
{
dwAclSize = GetLengthSid(pAdminSid) + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);

pDacl = (PACL)HeapAlloc(GetProcessHeap(), 0, dwAclSize);
if (pDacl != NULL)
{
if (InitializeAcl(pDacl, dwAclSize, ACL_REVISION))
{
if (AddAccessAllowedAce(pDacl, ACL_REVISION, KEY_ALL_ACCESS, pAdminSid))
{
if (InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION) && SetSecurityDescriptorDacl(&sd, TRUE, pDacl, FALSE))
bRet = (RegSetKeySecurity(hKey, (SECURITY_INFORMATION)DACL_SECURITY_INFORMATION, &sd) == ERROR_SUCCESS);
}
}
HeapFree(GetProcessHeap(), 0, pDacl);
}
FreeSid(pAdminSid);
}

RegCloseKey(hKey);
}

return bRet;
}

//----------------------------------------------------------------------
// 修改注册表键及其子键的权限
//----------------------------------------------------------------------
void RegSetKeyPermission(HKEY hRootKey, char *pszSubKey, BOOL bInherit)
{
HKEY hKey;
LONG nRet;
DWORD dwIndex, dwNameSize;
char pszName[256];

if (RegSetKeyPermission(hRootKey, pszSubKey))
{
if ((bInherit) && (nRet = RegOpenKeyEx(hRootKey, pszSubKey, 0, KEY_ENUMERATE_SUB_KEYS, &hKey) == ERROR_SUCCESS))
{
dwIndex = 0;
dwNameSize = 256;
while (RegEnumKeyEx(hKey, dwIndex, pszName, &dwNameSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
RegSetKeyPermission(hKey, pszName, TRUE);
}

RegCloseKey(hKey);
}
}
}

//----------------------------------------------------------------------
// 检测并关闭相应的HBKernel32.sys文件句柄,用于解锁驱动文件
//----------------------------------------------------------------------
void ScanSystemHandle(DWORD dwProcId, HANDLE hHandle)
{
HANDLE hProcess, hTemp;
DWORD dwFileSize, dwMagic, dwNumOfBytesRead;

hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcId);
if (hProcess)
{
if (DuplicateHandle( hProcess, hHandle, GetCurrentProcess(), &hTemp, 0, FALSE, DUPLICATE_SAME_ACCESS))
{
dwFileSize = GetFileSize(hTemp, NULL);

//HBKernel32.sys的文件长度为18080字节
if (dwFileSize == 18080)
{
if (SetFilePointer(hTemp, 0x294F, 0, FILE_BEGIN) == 0x294F)
{
//读一个DWORD测试是否为HBKernel32.sys
if ((ReadFile(hTemp, &dwMagic, 4, &dwNumOfBytesRead, NULL)) &&
(dwNumOfBytesRead == 4) &&
(dwMagic == 0xFFF0BDC0))
{
CloseHandle(hTemp);

//复制并关闭原始句柄
if (DuplicateHandle( hProcess, hHandle, GetCurrentProcess(), &hTemp, 0, FALSE, DUPLICATE_CLOSE_SOURCE))
{
printf("Trojan handle: %.4x closed.\n", hHandle);
CloseHandle(hTemp);
}
}
else
CloseHandle(hTemp);
}
else
CloseHandle(hTemp);
}
else
CloseHandle(hTemp);
}

CloseHandle(hProcess);
}
}

//----------------------------------------------------------------------
// 扫描所有SYSTEM进程的句柄并且关闭相应的HBKernel32.sys文件句柄
//----------------------------------------------------------------------
void ScanSystemHandles(DWORD dwSystemProcId)
{
PSYSTEM_HANDLE_INFORMATION_EX pShie;
PSYSTEM_HANDLE_INFORMATION pShiTemp;
PFNTQUERYSYSTEMINFORMATION pfNtQuerySystemInformation;
DWORD dwReqSize, dwMaxSize, dwCount = 0;
long nStatus;

pfNtQuerySystemInformation = (PFNTQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandle("NTDLL.DLL"), "NtQuerySystemInformation");
if (pfNtQuerySystemInformation != NULL)
{
dwMaxSize = DEFAULT_SHI_ARRAY_SIZE;
pShie = (PSYSTEM_HANDLE_INFORMATION_EX)malloc(dwMaxSize);
while ((pShie != NULL) &&
((nStatus = pfNtQuerySystemInformation(SystemHandleInformation, pShie, dwMaxSize, &dwReqSize)) == STATUS_INFO_LENGTH_MISMATCH))
{
dwMaxSize = (dwReqSize >= dwMaxSize)?dwReqSize:(dwMaxSize+DEFAULT_SHI_ARRAY_SIZE);
pShie = (PSYSTEM_HANDLE_INFORMATION_EX)realloc(pShie, dwMaxSize);
}

if (nStatus == 0)
{
dwCount = pShie->NumberOfHandles;
pShiTemp = pShie->Information;

while (--dwCount != 0xFFFFFFFF)
{
if (dwSystemProcId == pShiTemp->ProcessID)// && (pShiTemp->ObjectTypeNumber == OB_TYPE_FILE))
{
//printf("Handle: %.4X Type: %d Object: %.8X\n", pShiTemp->Handle, pShiTemp->ObjectTypeNumber, pShiTemp->Object);
ScanSystemHandle(dwSystemProcId, (HANDLE)(pShiTemp->Handle));
}
pShiTemp = (PSYSTEM_HANDLE_INFORMATION)((LPBYTE)pShiTemp + sizeof(SYSTEM_HANDLE_INFORMATION));
};
}

if (pShie != NULL)
free(pShie);
}
}

typedef HMODULE (FAR WINAPI *PFGETMODULEHANDLEA)
(
LPCSTR lpModuleName
);

typedef BOOL (FAR WINAPI *PFFREELIBRARY)
(
HMODULE hModule
);


typedef struct _REMOTE_THREAD_PARAMS
{
PFGETMODULEHANDLEA pfGetModuleHandleA;
PFFREELIBRARY pfFreeLibrary;
char pszModuleName[256];
} REMOTE_THREAD_PARAMS, *PREMOTE_THREAD_PARAMS;

//----------------------------------------------------------------------
// 卸载指定模块的远程线程
//----------------------------------------------------------------------
BOOL UnloadModule(PREMOTE_THREAD_PARAMS pRtp)
{
if (pRtp != 0)
{
HMODULE hHbqqxx = pRtp->pfGetModuleHandleA(pRtp->pszModuleName);

if (hHbqqxx != NULL)
{
return pRtp->pfFreeLibrary(hHbqqxx);
}
}

return FALSE;
}

//----------------------------------------------------------------------
// 在指定进程中卸载木马模块
//----------------------------------------------------------------------
void UnloadRemoteModule(DWORD dwProcId, LPCSTR pszModuleName)
{
HANDLE hProcess, hThread;
LPVOID lpBaseAddress;
LPVOID lpBuffer = (LPVOID)&UnloadModule;
SIZE_T nNumOfBytesWritten;
SIZE_T nSize = (SIZE_T)&UnloadRemoteModule;
REMOTE_THREAD_PARAMS rtp;
DWORD dwExitCode;

nSize = nSize - (SIZE_T)&UnloadModule;

hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, dwProcId);
if (hProcess != NULL)
{
lpBaseAddress = VirtualAllocEx(hProcess, NULL, nSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (lpBaseAddress != NULL)
{
rtp.pfGetModuleHandleA = (PFGETMODULEHANDLEA)GetProcAddress(GetModuleHandle("KERNEL32.DLL"), "GetModuleHandleA");
rtp.pfFreeLibrary = (PFFREELIBRARY)GetProcAddress(GetModuleHandle("KERNEL32.DLL"), "FreeLibrary");
strcpy(rtp.pszModuleName, "HBQQXX.dll");

if (WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, &nNumOfBytesWritten) && //写代码
WriteProcessMemory(hProcess, (LPBYTE)lpBaseAddress + nSize, &rtp, sizeof(REMOTE_THREAD_PARAMS), &nNumOfBytesWritten)) //写参数
{
hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpBaseAddress, (LPBYTE)lpBaseAddress + nSize, CREATE_SUSPENDED, NULL);
if (hThread != NULL)
{
ResumeThread(hThread);
WaitForSingleObject(hThread, INFINITE);
GetExitCodeThread(hThread, &dwExitCode);
if ((BOOL)dwExitCode)
printf("Trojan module \"%s\" has been unloaded from process \"%.8X\"\n", pszModuleName, dwProcId);
CloseHandle(hThread);
}
}
}
CloseHandle(hProcess);
}
}

mov eax, g_dwHBKernel32ImageBase
add eax, 3F20h
;patch这个用于无限循环判断的变量
mov dword ptr [eax], 1

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (48)
雪    币: 479
活跃值: (25)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
2
乌龟大师厉害,膜拜



大师我在实现的时候,直接用MoveFileEx重启,也把驱动给删除了,这样有问题吗?
2008-11-2 19:30
0
雪    币: 503
活跃值: (80)
能力值: (RANK:280 )
在线值:
发帖
回帖
粉丝
3
因为驱动是Boot Bus Extender组内的,所以除非先做掉驱动服务注册表键,否则sys会被优先加载

很抱歉我没有做那个尝试,但是个人理解应该是会失败
2008-11-2 19:33
0
雪    币: 398
活跃值: (343)
能力值: (RANK:650 )
在线值:
发帖
回帖
粉丝
4
科班出身就是不一样啊,学习
2008-11-2 19:45
0
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
看得很很很舒服呀。
2008-11-2 20:04
0
雪    币: 2575
活跃值: (502)
能力值: ( LV2,RANK:85 )
在线值:
发帖
回帖
粉丝
6
2008要向乌龟学习
2008-11-2 20:10
0
雪    币: 8209
活跃值: (4528)
能力值: ( LV15,RANK:2473 )
在线值:
发帖
回帖
粉丝
7
在ScanSystemThreads里面能保证可以取到pThreadTemp->StartAddress吗?
2008-11-2 20:16
0
雪    币: 8209
活跃值: (4528)
能力值: ( LV15,RANK:2473 )
在线值:
发帖
回帖
粉丝
8
Toolhelp32Snapshot取出的线程起始地址可能是0,我的机器上取出的都是0
2008-11-2 20:28
0
雪    币: 7325
活跃值: (3803)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
9
木马分析得太强悍了 啊

膜拜啊
2008-11-2 20:29
0
雪    币: 7325
活跃值: (3803)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
10
有权限的情况下用
NtQueryInformationThread
来找StartAddress比较保险
2008-11-2 20:35
0
雪    币: 503
活跃值: (80)
能力值: (RANK:280 )
在线值:
发帖
回帖
粉丝
11
我没有用toolhelp32snapshot取线程ep,只是用来获取tid,ep其实是来自PSYSTEM_THREAD_INFORMATION这个指针
2008-11-2 22:04
0
雪    币: 503
活跃值: (80)
能力值: (RANK:280 )
在线值:
发帖
回帖
粉丝
12
我也试了一下NtQueryInformationThread,找普通线程的入口地址没问题,但可能是因为SYSTEM进程权限不够,起始地址返回0
2008-11-2 22:06
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
13
乌龟大师肯定是游戏/安全公司的强人.
一般的分析病毒木马没这么专业的.

膜拜啊~~~~
2008-11-2 22:09
0
雪    币: 503
活跃值: (80)
能力值: (RANK:280 )
在线值:
发帖
回帖
粉丝
14
这一题尝试在用户层下寻找不同的解决方案是有些头大
但木马分析部分相对强壳或vm之类而言还是很轻松的,还是需要向shoooo大牛学习脱壳啊
2008-11-2 22:18
0
雪    币: 8209
活跃值: (4528)
能力值: ( LV15,RANK:2473 )
在线值:
发帖
回帖
粉丝
15
原来是这样的,现在看懂了
2008-11-2 22:26
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
16
使用MJ的XCB法可以应该干掉
2008-11-2 23:39
0
雪    币: 7325
活跃值: (3803)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
17
XCB全称是什么?
2008-11-2 23:41
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
18
这个帖子要顶。 膜拜膜拜^n
2008-11-2 23:59
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
19
2008-11-3 09:26
0
雪    币: 503
活跃值: (80)
能力值: (RANK:280 )
在线值:
发帖
回帖
粉丝
20
膜拜大牛,学习
2008-11-3 09:32
0
雪    币: 233
活跃值: (15)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
21
膜拜LS所有……
2008-11-3 09:56
0
雪    币: 7325
活跃值: (3803)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
22
学习加膜拜啊
2008-11-3 10:01
0
雪    币: 251
活跃值: (25)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
23
很好奇乌龟大师的职业,居然有这么强大的人
2008-11-3 10:14
0
雪    币: 8209
活跃值: (4528)
能力值: ( LV15,RANK:2473 )
在线值:
发帖
回帖
粉丝
24
乌龟大师是专业吃这碗饭的,应该把猪蹄省下来给我们吃
2008-11-3 10:20
0
雪    币: 503
活跃值: (80)
能力值: (RANK:280 )
在线值:
发帖
回帖
粉丝
25
猪蹄是你的,上一题和你的差距太大了
2008-11-3 10:21
0
游客
登录 | 注册 方可回帖
返回
//