首页
社区
课程
招聘
[原创]再放一份驱动域名劫持的代码
发表于: 2014-2-6 22:07 14327

[原创]再放一份驱动域名劫持的代码

2014-2-6 22:07
14327
再放一份驱动域名劫持的代码

年后求个职:qq->*******[DeDf]

就是访问A.com转到b.com,当然如果改成访问A就丢包,那就变成拦截指定网站了。

过程比较曲折:
首先用抓包工具发现,访问某网站时,(如果本地没有该网站的DNS缓存)首先会发DNS查询包(UDP),然后会与该网站建立连接,然后,发http请求包。

观察包内容,需要把发出的包的目标改成我们的目标,然后把响应的包中我们改过的东西改回来,就是欺上瞒下。代码不多,重点是演示了如何获取TCP与UDP的接收到包的内容。仅适用于XP:

bin会将www.baidu.com劫持到ip138.com.如果加载该驱动前访问过baidu,请在cmd里执行ipconfig /flushdns.

#include <ntddk.h>
#include <tdikrnl.h>

typedef NTSTATUS (__stdcall *MJ) (IN PDEVICE_OBJECT DeviceObject, IN PIRP irp);

MJ mj_addr = NULL;  // IRP_MJ_INTERNAL_DEVICE_CONTROL

PDEVICE_OBJECT g_udp_DevObj = NULL;

PTDI_IND_RECEIVE_DATAGRAM original_udp_EventHandler = NULL;
PTDI_IND_RECEIVE          original_tcp_EventHandler = NULL;

NTSTATUS mj_handle(IN PDEVICE_OBJECT DeviceObject, IN PIRP irp);

NTSTATUS tdi_event_receive_datagram(
                                    IN PVOID TdiEventContext,
                                    IN LONG SourceAddressLength,
                                    IN PVOID SourceAddress,
                                    IN LONG OptionsLength,
                                    IN PVOID Options,
                                    IN ULONG ReceiveDatagramFlags,
                                    IN ULONG BytesIndicated,
                                    IN ULONG BytesAvailable,
                                    OUT ULONG *BytesTaken,
                                    IN PVOID Tsdu,
                                    OUT PIRP *IoRequestPacket);
NTSTATUS tdi_event_receive(
                           __in_opt PVOID TdiEventContext,
                           __in_opt CONNECTION_CONTEXT ConnectionContext,
                           __in ULONG ReceiveFlags,
                           __in ULONG BytesIndicated,
                           __in ULONG BytesAvailable,
                           __out ULONG *BytesTaken,
                           __in PVOID Tsdu,                   // pointer describing this TSDU, typically a lump of bytes
                           __out_opt PIRP *IoRequestPacket    // TdiReceive IRP if MORE_PROCESSING_REQUIRED.
                           );

NTSTATUS get_device_object(WCHAR *name, PDEVICE_OBJECT *devobj);

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING pRegistryString)
{
    NTSTATUS status;

    status = get_device_object(L"\\Device\\Udp", &g_udp_DevObj);
    if (status)
    {
        KdPrint(("[tdi_fw] DriverEntry: get_device_object(udp): 0x%x\n", status));
        return status;
    }

    mj_addr = g_udp_DevObj->DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL];
    InterlockedExchange(
        (ULONG*)&(g_udp_DevObj->DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL]),
        (ULONG)mj_handle);

    return status;
}

NTSTATUS mj_handle(IN PDEVICE_OBJECT DeviceObject, IN PIRP irp)
{
    PIO_STACK_LOCATION  pIrpSp = irp->Tail.Overlay.CurrentStackLocation;
    PVOID pData;

    switch (pIrpSp->MinorFunction)
    {
    case TDI_SEND:
        KdPrint(("=TDI_SEND!\n"));
        pData = MmGetSystemAddressForMdlSafe((irp->MdlAddress),NormalPagePriority);
        //_asm int 3
        if ( !memcmp(pData, "GET / HTTP", 10) )
        {
            ULONG i;
            for (i = 11; ; i++)
            {
                if ( *((char*)pData + i) == '\r' && *((char*)pData + i + 1) == '\n' )
                {
                    if ( *((char*)pData + i + 2) == '\r' && *((char*)pData + i + 3) == '\n' )
                        break;
                    if ( !memcmp((char*)pData + i + 2, "Host: www.baidu.com", 19) )
                        memcpy( (char*)pData + i + 2, "Host: www.ip138.com", 19 );
                }
            }
        }

        break;

    case TDI_RECEIVE:
        KdPrint(("=TDI_RECEIVE!\n"));
        //_asm int 3
        break;

    case TDI_SEND_DATAGRAM:
        {
//             PTDI_REQUEST_KERNEL_SENDDG param = (TDI_REQUEST_KERNEL_SENDDG*)(&pIrpSp->Parameters);
//             TA_ADDRESS *remote_addr = ((TRANSPORT_ADDRESS *)(param->SendDatagramInformation->RemoteAddress))->Address;
//             sockaddr_in *remote_saddr = (sockaddr_in*)(&remote_addr->AddressType);

            KdPrint(("=TDI_SEND_DATAGRAM!\n"));

            pData = MmGetSystemAddressForMdlSafe((irp->MdlAddress),NormalPagePriority);

            if ( *((PUSHORT)pData + 1) == 0x0001 )
            {
                KdPrint(("==DNS query!\n"));
                //_asm int 3
                if ( !memcmp((char*)pData + 17, "baidu", 5) )
                    memcpy( (char*)pData + 17, "ip138", 5 );
            }
        }
        break;

    case TDI_RECEIVE_DATAGRAM:
        KdPrint(("=TDI_RECEIVE_DATAGRAM!\n"));
        break;

    case TDI_SET_EVENT_HANDLER:
        {
            PTDI_REQUEST_KERNEL_SET_EVENT param = (TDI_REQUEST_KERNEL_SET_EVENT*)&(pIrpSp->Parameters);
            switch(param->EventType)
            {
            case TDI_EVENT_RECEIVE:
                KdPrint(("!!!==TDI_EVENT_RECEIVE!!!\n"));
                if (param->EventHandler)
                {
                    original_tcp_EventHandler = param->EventHandler;
                    InterlockedExchange((PULONG)¶m->EventHandler, (ULONG)tdi_event_receive);
                }
                break;

            case TDI_EVENT_CHAINED_RECEIVE:
                KdPrint(("!!!==TDI_EVENT_CHAINED_RECEIVE!!!\n"));
                break;

            case TDI_EVENT_RECEIVE_DATAGRAM:
                KdPrint(("!!!==TDI_EVENT_RECEIVE_DATAGRAM!!!\n"));
                if (param->EventHandler)
                {
                    original_udp_EventHandler = param->EventHandler;
                    InterlockedExchange((PULONG)¶m->EventHandler, (ULONG)tdi_event_receive_datagram);
                }
                break;

            case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM:
                KdPrint(("!!!==TDI_EVENT_CHAINED_RECEIVE_DATAGRAM!!!\n"));
                break;
            }
        }
        break;
    }
   
    return mj_addr(DeviceObject, irp);
}

NTSTATUS get_device_object(WCHAR *name, PDEVICE_OBJECT *devobj)
{
    NTSTATUS status;
    UNICODE_STRING str;
    PFILE_OBJECT fileobj;

    RtlInitUnicodeString(&str, name);

    status = IoGetDeviceObjectPointer(&str, FILE_ALL_ACCESS, &fileobj, devobj);
    if (status == STATUS_SUCCESS)
        ObDereferenceObject(fileobj);

    return status;
}

NTSTATUS tdi_event_receive_datagram(
                                    IN PVOID TdiEventContext,
                                    IN LONG SourceAddressLength,
                                    IN PVOID SourceAddress,
                                    IN LONG OptionsLength,
                                    IN PVOID Options,
                                    IN ULONG ReceiveDatagramFlags,
                                    IN ULONG BytesIndicated,
                                    IN ULONG BytesAvailable,
                                    OUT ULONG *BytesTaken,
                                    IN PVOID Tsdu,
                                    OUT PIRP *IoRequestPacket)
{
    KdPrint(("tdi_event_receive_datagram()\n"));

    if ( *((PUSHORT)Tsdu + 1) == 0x8081 )
    {
        KdPrint(("===DNS reply!\n"));

        if ( !memcmp((char*)Tsdu + 17, "ip138", 5) )
            memcpy( (char*)Tsdu + 17, "baidu", 5 );
    }

    return original_udp_EventHandler(
        TdiEventContext,
        SourceAddressLength,
        SourceAddress,
        OptionsLength,
        Options,
        ReceiveDatagramFlags,
        BytesIndicated,
        BytesAvailable,
        BytesTaken,
        Tsdu,
        IoRequestPacket);
}

NTSTATUS tdi_event_receive(
                           __in_opt PVOID TdiEventContext,
                           __in_opt CONNECTION_CONTEXT ConnectionContext,
                           __in ULONG ReceiveFlags,
                           __in ULONG BytesIndicated,
                           __in ULONG BytesAvailable,
                           __out ULONG *BytesTaken,
                           __in PVOID Tsdu,                   // pointer describing this TSDU, typically a lump of bytes
                           __out_opt PIRP *IoRequestPacket    // TdiReceive IRP if MORE_PROCESSING_REQUIRED.
                           )
{
    KdPrint(("tdi_event_receive()\n"));

    return original_tcp_EventHandler(
        TdiEventContext,
        ConnectionContext,
        ReceiveFlags,
        BytesIndicated,
        BytesAvailable,
        BytesTaken,
        Tsdu,              // pointer describing this TSDU, typically a lump of bytes
        IoRequestPacket    // TdiReceive IRP if MORE_PROCESSING_REQUIRED.
        );
}

这是附件: DNS_Redirect.7z

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 1
支持
分享
最新回复 (6)
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
应用层都可以实现呀
2014-2-7 08:34
0
雪    币: 185
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
这份代码只是做了DNS的处理吧。 相当于修改了解析。

并没有改TCP层的交互。
2014-2-7 09:35
0
雪    币: 284
活跃值: (3619)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
4
额,看了一下确实是这样,疏忽了。。
2014-2-7 13:20
0
雪    币: 138
活跃值: (306)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
5
下次别放可以直接编译的代码,免得被利用.
2014-2-7 13:55
0
雪    币: 74
活跃值: (748)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
先mark再看,thinks for share
2014-2-8 08:41
0
雪    币: 90
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
这样人家不用域名,直接用IP就不成功了
2016-4-15 21:39
0
游客
登录 | 注册 方可回帖
返回
//