一个基于Windows DNA的B/S结构应用,被部署在Windows 2003 Server下。现在发现存在如下问题:
在一个asp页面中调用了一个中间件(DLL)中的某个方法,该方法中通过LoadLibrary又加载了另一个普通的DLL,并调用了这个普通DLL中的某个导出函数(这个普通DLL被放在系统system32目录下)。现在一旦从客户端请求这个asp页面,则返回ASP 0115错误。经检查发现好像是跟安全有关的问题(中间件中加载普通DLL时出错,匿名用户没有权限访问system32目录)。IIS中配置的是允许匿名访问。我又做了如下的尝试,将原先在system32目录下的普通DLL剪切至IIS中配置的站点主目录下的某个子目录中,并将这个子目录对匿名用户开放完全控制权限,将这个子目录的路径放到系统环境变量path中,重启机器后,问题依旧。以上问题在Windows 2000 Server中不存在。

解决方案 »

  1.   

    道理很简单Win32API CreateProcess最终会调用native api NtCreateProcessNtCreateProcess的一个参数就是父进程句柄,新建进程的用户身份就是从父进程继承过来的所以只要得到一个SYSTEM用户身份进程的句柄然后我们再将NtCreateProcess hack掉就可以了下面是程序的原始版本由于是1999年写的,所以只支持 nt3.5, nt4, 和2k// CreateProcessAsUserSystem.cpp (Windows NT/2000)
    //
    // This example will show how you can create a process
    // in the context of the user 'SYSTEM'
    //
    //
    // (c)1999 Ashot Oganesyan K, SmartLine, Inc
    // mailto:[email protected], http://www.protect-me.com, http://www.codepile.
    com#include <windows.h>
    #include <tchar.h>
    #include <stdio.h>#pragma pack(1)typedef struct
    {
            BYTE   mov_eax;
            LPVOID address;
            WORD   jump_eax;} ASMJUMP, *PASMJUMP;
    BOOL SetPrivileges(HANDLE hprocess, LPTSTR privilege, BOOL bSwitch);HANDLE hParentProc;
    DWORD  dwFunc;
    // Haked NtCreateProcess
    void __declspec(naked)HackedNtCreateProcess()
    {
        _asm
        {
            // Change parent process handle
            mov  eax,hParentProc
            mov  dword ptr [esp+16],eax
            // NtCreateProcess value depends on version
            mov  eax,dwFunc
            // Load parameters table
            lea  edx,dword ptr [esp+4]
            // Call the interrupt
            int  2Eh
            // return
            retn 20h
        }
    }void PrintWin32Error( char *message, DWORD error )
    {
            char *errMsg;        FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
    FORMAT_MESSAGE_FROM_SYSTEM,
                            NULL, error,
                            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                            (LPTSTR) &errMsg, 0, NULL );
            printf("%s: %s\n", message, errMsg );
            LocalFree( errMsg );
    }int main(int argc, char* argv[])
    {
        if (argc<3)
        {
            _tprintf(TEXT("Usage:\n\t sysproc.exe pid <program name>\n"));
            return -1;
        }    if (!SetPrivileges((HANDLE)-1,SE_DEBUG_NAME,TRUE))
        {
            PrintWin32Error("SetPrivileges failed",GetLastError());
            return -1;
        }    UINT uSysProcId = atoi(argv[1]);
        switch(LOBYTE(LOWORD(GetVersion())))
        {
            case 3:
                    dwFunc = 0x1E;
                    break;
            case 4:
                    dwFunc = 0x1F;
                    break;
            case 5:
                    dwFunc = 0x29; // 0x2A - for W2K beta;
                    break;
        }    // Trying to get a handle to the system process
        hParentProc = OpenProcess(PROCESS_CREATE_PROCESS,TRUE,uSysProcId);
        if (!hParentProc)
        {
                    PrintWin32Error("Could not open system process",GetLastError());
            return -1;
        }    PASMJUMP NtCreateProcessHook = (PASMJUMP)
                                       GetProcAddress(
                                       GetModuleHandle(TEXT("ntdll.dll")),
                                       "NtCreateProcess");
        if (NtCreateProcessHook==NULL)
        {
            PrintWin32Error("Could not get procedure address",
    GetLastError());
            return -1;
        }    // Enable write acess to VM
        MEMORY_BASIC_INFORMATION mbi;
        VirtualQuery(NtCreateProcessHook,&mbi,
    sizeof(MEMORY_BASIC_INFORMATION));    DWORD dw;
        VirtualProtect(mbi.AllocationBase,mbi.RegionSize,
                       PAGE_EXECUTE_READWRITE,&dw);    // Redirect call to HackedNtCreateProcess :
        //
        // mov eax,HackedNtCreateProcess
        // jmp eax
        NtCreateProcessHook->mov_eax = 0xB8;
        NtCreateProcessHook->address = HackedNtCreateProcess;
        NtCreateProcessHook->jump_eax = 0xE0FF;    // Call modified CreateProcess
        PROCESS_INFORMATION pi;
        STARTUPINFO si;    ZeroMemory(&pi,sizeof (PROCESS_INFORMATION));
        ZeroMemory(&si,sizeof (STARTUPINFO));
        si.cb = sizeof(STARTUPINFO);    if (!CreateProcess(NULL,argv[2],
                           NULL, NULL,
                           FALSE,
                           0,NULL,NULL,
                           &si,
                           &pi))
        {
            PrintWin32Error("Could not create process",GetLastError());
            return -1;
        }    CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);    return 0;
    }
    BOOL SetPrivileges(HANDLE hprocess, LPTSTR privilege, BOOL bSwitch)
    {
        HANDLE           hToken;
        LUID             DebugValue;
        TOKEN_PRIVILEGES tkp;    if (!OpenProcessToken(hprocess,
                              TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
                              &hToken))
            goto err;    if (!LookupPrivilegeValue((LPTSTR) NULL,
                                  privilege,
                                  &DebugValue))
            goto err;    tkp.PrivilegeCount = 1;
        tkp.Privileges[0].Luid = DebugValue;    if (bSwitch)
            tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED |
                                           SE_PRIVILEGE_ENABLED_BY_DEFAULT
    |
                                           SE_PRIVILEGE_USED_FOR_ACCESS;
        else
            tkp.Privileges[0].Attributes = NULL;    AdjustTokenPrivileges(hToken,
                              FALSE,
                              &tkp,
                              sizeof(TOKEN_PRIVILEGES),
                              (PTOKEN_PRIVILEGES) NULL,
                              NULL);    if (GetLastError() != ERROR_SUCCESS)
           goto err;    return TRUE; err:
        return FALSE;
    }