再放一份驱动域名劫持的代码
年后求个职: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直播授课
上传的附件: