win10 x64
NtBuildNumber 17134
给\Device\Nsi
设备发送IOCTL_NSI_GETALLPARAM进行查询,r3分别有两个函数:GetTcpTable和GetUdpTable(位于Iphlpapi.dll里面),两个函数实现也是通过上述思路。
函数调用链:GetTcpTable/GetUdpTable --->(Iphlpapi.dll)GetTcpTableInternal/GetUdpTableInternal ---> (nsi.dll)NsiAllocateAndGetTable
在NsiAllocateAndGetTable中调用NtDeviceIoControlFile查询
该函数会查询两次,第一次获取连接数量,根据返回的连接数分配合适大小的内存,在第二查询时会将连接信息填充到buffer中,主要的内容就是对nsi.dll中NsiAllocateAndGetTable的逆向,并在r0实现。
首先是控制码,在我的电脑上是0x12001B
其次是传入NtDeviceIoControlFile的通用结构体buffer,0x70字节大小,下面是我的定义
查询TCP时需要传入3个buffer,查询UDP传入两个,并且相关硬编码有所差异,NPI_MODULEID由上层函数GetTcpTableInternal传入,可以在ida中直接提取,NPI_MS_TCP_MODULEID
查询TCP时,NPI_MODULEID为NPI_MS_TCP_MODULEID。
第一次查询时,只需要填写NSI_PARAM结构中的3,4,5三个域,查询成功ConnCount会得到TCP连接数,之后就是第二次查询,查询前需要分配内存。
buffer大小需要在返回的连接数上加2
思路和r3发请求一致,效果:
源码:
以上代码仅供参考!不做其他用途。
个人兴趣,想研究一下在r0枚举TCP
/
UDP端口,网上有代码是xp和win7的,试了一下不行,就简单研究了一下win10的,没啥技术含量,能逆出来相关结构体就行,实现了一个小demo,代码质量堪忧,不喜勿喷。
个人兴趣,想研究一下在r0枚举TCP
/
UDP端口,网上有代码是xp和win7的,试了一下不行,就简单研究了一下win10的,没啥技术含量,能逆出来相关结构体就行,实现了一个小demo,代码质量堪忧,不喜勿喷。
typedef struct _NSI_PARAM
{
ULONG_PTR UnknownParam1;
/
/
0
ULONG_PTR UnknownParam2;
/
/
0
ULONG_PTR UnknownParam3;
/
/
NPI_MODULEID指针
ULONG_PTR UnknownParam4;
/
/
硬编码
ULONG_PTR UnknownParam5;
/
/
硬编码
ULONG_PTR UnknownParam6;
/
/
结构体
1
数组指针
ULONG_PTR UnknownParam7;
/
/
结构体
1
大小
ULONG_PTR UnknownParam8;
/
/
0
ULONG_PTR UnknownParam9;
/
/
0
ULONG_PTR UnknownParam10;
/
/
结构体
2
数组指针
ULONG_PTR UnknownParam11;
/
/
结构体
2
大小
ULONG_PTR UnknownParam12;
/
/
结构体
3
数组指针
ULONG_PTR UnknownParam13;
/
/
结构体
3
数组指针
ULONG_PTR ConnCount;
/
/
连接数
}NSI_PARAM,
*
PNSI_PARAM;
typedef struct _NSI_PARAM
{
ULONG_PTR UnknownParam1;
/
/
0
ULONG_PTR UnknownParam2;
/
/
0
ULONG_PTR UnknownParam3;
/
/
NPI_MODULEID指针
ULONG_PTR UnknownParam4;
/
/
硬编码
ULONG_PTR UnknownParam5;
/
/
硬编码
ULONG_PTR UnknownParam6;
/
/
结构体
1
数组指针
ULONG_PTR UnknownParam7;
/
/
结构体
1
大小
ULONG_PTR UnknownParam8;
/
/
0
ULONG_PTR UnknownParam9;
/
/
0
ULONG_PTR UnknownParam10;
/
/
结构体
2
数组指针
ULONG_PTR UnknownParam11;
/
/
结构体
2
大小
ULONG_PTR UnknownParam12;
/
/
结构体
3
数组指针
ULONG_PTR UnknownParam13;
/
/
结构体
3
数组指针
ULONG_PTR ConnCount;
/
/
连接数
}NSI_PARAM,
*
PNSI_PARAM;
UCHAR NPI_MS_TCP_MODULEID[
24
]
=
{
0x18
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x03
,
0x4a
,
0x00
,
0xeb
,
0x1a
,
0x9b
,
0xd4
,
0x11
,
0x91
,
0x23
,
0x00
,
0x50
,
0x04
,
0x77
,
0x59
,
0xbc
,
};
UCHAR NPI_MS_TCP_MODULEID[
24
]
=
{
0x18
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x03
,
0x4a
,
0x00
,
0xeb
,
0x1a
,
0x9b
,
0xd4
,
0x11
,
0x91
,
0x23
,
0x00
,
0x50
,
0x04
,
0x77
,
0x59
,
0xbc
,
};
VOID MyUnload(PDRIVER_OBJECT pDriverObject);
(((s >>
8
) &
0x00FF
) | \
((s <<
8
) &
0xFF00
))
typedef struct _NSI_PARAM
{
ULONG_PTR UnknownParam1;
ULONG_PTR UnknownParam2;
ULONG_PTR UnknownParam3;
ULONG_PTR UnknownParam4;
ULONG_PTR UnknownParam5;
ULONG_PTR UnknownParam6;
ULONG_PTR UnknownParam7;
ULONG_PTR UnknownParam8;
ULONG_PTR UnknownParam9;
ULONG_PTR UnknownParam10;
ULONG_PTR UnknownParam11;
ULONG_PTR UnknownParam12;
ULONG_PTR UnknownParam13;
ULONG_PTR ConnCount;
}NSI_PARAM,
*
PNSI_PARAM;
typedef struct _INTERNAL_UDP_TABLE_ENTRY
{
USHORT Unknown1;
USHORT Port;
ULONG dwIP;
UCHAR Unknown2[
0x14
];
}INTERNAL_UDP_TABLE_ENTRY,
*
PINTERNAL_UDP_TABLE_ENTRY;
typedef struct _INTERNAL_TCP_TABLE_SUBENTRY
{
USHORT Unknown1;
USHORT Port;
ULONG dwIP;
UCHAR Unknown2[
20
];
}INTERNAL_TCP_TABLE_SUBENTRY,
*
PINTERNAL_TCP_TABLE_SUBENTRY;
typedef struct _NSI_STATUS_ENTRY
{
ULONG_PTR dwState;
ULONG_PTR Unknown1;
}NSI_STATUS_ENTRY,
*
PNSI_STATUS_ENTRY;
typedef struct _INTERNAL_TCP_TABLE_ENTRY
{
INTERNAL_TCP_TABLE_SUBENTRY localEntry;
INTERNAL_TCP_TABLE_SUBENTRY remoteEntry;
}INTERNAL_TCP_TABLE_ENTRY,
*
PINTERNAL_TCP_TABLE_ENTRY;
typedef struct _NSI_PROCESSID_INFO
{
ULONG dwUdpProId;
ULONG UnknownParam2;
ULONG UnknownParam3;
ULONG dwTcpProId;
ULONG UnknownParam5;
ULONG UnknownParam6;
ULONG UnknownParam7;
ULONG UnknownParam8;
}NSI_PROCESSID_INFO,
*
PNSI_PROCESSID_INFO;
extern
"C"
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
{
PIRP pIrp
=
NULL;
KEVENT Event;
NTSTATUS Statu;
IO_STATUS_BLOCK StatusBlock;
NSI_PARAM param
=
{
0
, };
PIO_STACK_LOCATION StackLocation
=
NULL;
UCHAR NPI_MS_TCP_MODULEID[
24
]
=
{
0x18
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x03
,
0x4a
,
0x00
,
0xeb
,
0x1a
,
0x9b
,
0xd4
,
0x11
,
0x91
,
0x23
,
0x00
,
0x50
,
0x04
,
0x77
,
0x59
,
0xbc
,
};
__debugbreak();
pDriverObject
-
>DriverUnload
=
MyUnload;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
UNICODE_STRING DeviceName;
RtlInitUnicodeString(&DeviceName, L
"\\Device\\Nsi"
);
PFILE_OBJECT FileObj;
PDEVICE_OBJECT DevObj;
Statu
=
IoGetDeviceObjectPointer(
&DeviceName,
FILE_ALL_ACCESS,
&FileObj, &DevObj
);
param.UnknownParam3
=
(ULONG_PTR)&NPI_MS_TCP_MODULEID;
param.UnknownParam4
=
0x3
;
/
/
udp
0x1
param.UnknownParam5
=
0x100000001
;
pIrp
=
IoBuildDeviceIoControlRequest(
IOCTL_NSI_GETALLPARAM,
DevObj,
¶m,
0x70
,
¶m,
0x70
,
FALSE,
&Event,
&StatusBlock
);
StackLocation
=
IoGetNextIrpStackLocation(pIrp);
StackLocation
-
>FileObject
=
FileObj;
StackLocation
-
>DeviceObject
=
DevObj;
pIrp
-
>RequestorMode
=
KernelMode;
Statu
=
IoCallDriver(DevObj, pIrp);
Statu
=
KeWaitForSingleObject(
&Event,
Executive,
KernelMode,
FALSE,
0
);
ULONG_PTR Count
=
param.ConnCount
+
2
;
PINTERNAL_TCP_TABLE_ENTRY pBuf1
=
(PINTERNAL_TCP_TABLE_ENTRY)ExAllocatePoolWithTag(NonPagedPool,
0x38
*
Count,
'MINL'
);
PNSI_STATUS_ENTRY pBuf2
=
(PNSI_STATUS_ENTRY)ExAllocatePoolWithTag(NonPagedPool,
0x10
*
Count,
'MINL'
);
PNSI_PROCESSID_INFO pBuf3
=
(PNSI_PROCESSID_INFO)ExAllocatePoolWithTag(NonPagedPool,
0x20
*
Count,
'MINL'
);
RtlZeroMemory(pBuf1,
0x38
*
Count);
RtlZeroMemory(pBuf2,
0x10
*
Count);
RtlZeroMemory(pBuf3,
0x20
*
Count);
param.UnknownParam3
=
(ULONG_PTR)&NPI_MS_TCP_MODULEID;
param.UnknownParam4
=
0x3
;
param.UnknownParam5
=
0x100000001
;
param.UnknownParam6
=
(ULONG_PTR)pBuf1;
param.UnknownParam7
=
0x38
;
param.UnknownParam10
=
(ULONG_PTR)pBuf2;
param.UnknownParam11
=
0x10
;
param.UnknownParam12
=
(ULONG_PTR)pBuf3;
param.UnknownParam13
=
0x20
;
param.ConnCount
=
Count
-
2
;
pIrp
=
IoBuildDeviceIoControlRequest(
IOCTL_NSI_GETALLPARAM,
DevObj,
¶m,
0x70
,
¶m,
0x70
,
FALSE,
&Event,
&StatusBlock
);
StackLocation
=
IoGetNextIrpStackLocation(pIrp);
StackLocation
-
>FileObject
=
FileObj;
StackLocation
-
>DeviceObject
=
DevObj;
pIrp
-
>RequestorMode
=
KernelMode;
Statu
=
IoCallDriver(DevObj, pIrp);
Statu
=
KeWaitForSingleObject(
&Event,
Executive,
KernelMode,
FALSE,
0
);
DbgPrint(
"TCP PORT"
);
for
(ULONG i
=
0
; i < param.ConnCount; i
+
+
)
{
DbgPrint(
"ip ---> %x\tport ---> %d pid ---> %d\n"
, pBuf1[i].localEntry.dwIP, ntohs(pBuf1[i].localEntry.Port), pBuf3[i].dwTcpProId);
}
UCHAR NPI_MS_UDP_MODULEID[
24
]
=
{
0x18
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x02
,
0x4a
,
0x00
,
0xeb
,
0x1a
,
0x9b
,
0xd4
,
0x11
,
0x91
,
0x23
,
0x00
,
0x50
,
0x04
,
0x77
,
0x59
,
0xbc
,
};
memset(¶m,
0x00
,
0x70
);
param.UnknownParam3
=
(ULONG_PTR)NPI_MS_UDP_MODULEID;
param.UnknownParam4
=
0x1
;
param.UnknownParam5
=
0x100000001
;
pIrp
=
IoBuildDeviceIoControlRequest(
IOCTL_NSI_GETALLPARAM,
DevObj,
¶m,
0x70
,
¶m,
0x70
,
FALSE,
&Event,
&StatusBlock
);
StackLocation
=
IoGetNextIrpStackLocation(pIrp);
Statu
=
IoCallDriver(DevObj, pIrp);
Statu
=
KeWaitForSingleObject(
&Event,
Executive,
KernelMode,
FALSE,
0
);
Count
=
param.ConnCount
+
2
;
PINTERNAL_UDP_TABLE_ENTRY pBuf4
=
(PINTERNAL_UDP_TABLE_ENTRY)ExAllocatePoolWithTag(NonPagedPool,
0x1c
*
Count,
'MINL'
);
PNSI_PROCESSID_INFO pBuf5
=
(PNSI_PROCESSID_INFO)ExAllocatePoolWithTag(NonPagedPool,
0x20
*
Count,
'MINL'
);
memset(¶m,
0x00
,
0x70
);
param.UnknownParam3
=
(ULONG_PTR)NPI_MS_UDP_MODULEID;
param.UnknownParam4
=
0x1
;
param.UnknownParam5
=
0x100000001
;
param.UnknownParam6
=
(ULONG_PTR)pBuf4;
param.UnknownParam7
=
0x1c
;
param.UnknownParam12
=
(ULONG_PTR)pBuf5;
param.UnknownParam13
=
0x20
;
param.ConnCount
=
Count
-
2
;
pIrp
=
IoBuildDeviceIoControlRequest(
IOCTL_NSI_GETALLPARAM,
DevObj,
¶m,
0x70
,
¶m,
0x70
,
FALSE,
&Event,
&StatusBlock
);
StackLocation
=
IoGetNextIrpStackLocation(pIrp);
Statu
=
IoCallDriver(DevObj, pIrp);
Statu
=
KeWaitForSingleObject(
&Event,
Executive,
KernelMode,
FALSE,
0
);
DbgPrint(
"UDP PORT"
);
for
(ULONG i
=
0
; i < param.ConnCount; i
+
+
)
{
DbgPrint(
"ip ---> %x\tport ---> %d\tpid ---> %d\n"
, pBuf4[i].dwIP, ntohs(pBuf4[i].Port), pBuf5[i].dwUdpProId);
}
ExFreePool(pBuf1);
ExFreePool(pBuf2);
ExFreePool(pBuf3);
ExFreePool(pBuf4);
ExFreePool(pBuf5);
ObDereferenceObject(FileObj);
return
STATUS_SUCCESS;
}
VOID MyUnload(PDRIVER_OBJECT pDriverObject)
{
DbgPrint(
"Unload!\n"
);
}
VOID MyUnload(PDRIVER_OBJECT pDriverObject);
(((s >>
8
) &
0x00FF
) | \
((s <<
8
) &
0xFF00
))
typedef struct _NSI_PARAM
{
ULONG_PTR UnknownParam1;
ULONG_PTR UnknownParam2;
ULONG_PTR UnknownParam3;
ULONG_PTR UnknownParam4;
ULONG_PTR UnknownParam5;
ULONG_PTR UnknownParam6;
ULONG_PTR UnknownParam7;
ULONG_PTR UnknownParam8;
ULONG_PTR UnknownParam9;
ULONG_PTR UnknownParam10;
ULONG_PTR UnknownParam11;
ULONG_PTR UnknownParam12;
ULONG_PTR UnknownParam13;
ULONG_PTR ConnCount;
}NSI_PARAM,
*
PNSI_PARAM;
typedef struct _INTERNAL_UDP_TABLE_ENTRY
{
USHORT Unknown1;
USHORT Port;
ULONG dwIP;
UCHAR Unknown2[
0x14
];
}INTERNAL_UDP_TABLE_ENTRY,
*
PINTERNAL_UDP_TABLE_ENTRY;
typedef struct _INTERNAL_TCP_TABLE_SUBENTRY
{
USHORT Unknown1;
USHORT Port;
ULONG dwIP;
UCHAR Unknown2[
20
];
}INTERNAL_TCP_TABLE_SUBENTRY,
*
PINTERNAL_TCP_TABLE_SUBENTRY;
typedef struct _NSI_STATUS_ENTRY
{
ULONG_PTR dwState;
ULONG_PTR Unknown1;
}NSI_STATUS_ENTRY,
*
PNSI_STATUS_ENTRY;
typedef struct _INTERNAL_TCP_TABLE_ENTRY
{
INTERNAL_TCP_TABLE_SUBENTRY localEntry;
INTERNAL_TCP_TABLE_SUBENTRY remoteEntry;
}INTERNAL_TCP_TABLE_ENTRY,
*
PINTERNAL_TCP_TABLE_ENTRY;
typedef struct _NSI_PROCESSID_INFO
{
ULONG dwUdpProId;
ULONG UnknownParam2;
ULONG UnknownParam3;
ULONG dwTcpProId;
ULONG UnknownParam5;
ULONG UnknownParam6;
ULONG UnknownParam7;
ULONG UnknownParam8;
}NSI_PROCESSID_INFO,
*
PNSI_PROCESSID_INFO;
extern
"C"
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
{
PIRP pIrp
=
NULL;
KEVENT Event;
NTSTATUS Statu;
IO_STATUS_BLOCK StatusBlock;
NSI_PARAM param
=
{
0
, };
PIO_STACK_LOCATION StackLocation
=
NULL;
UCHAR NPI_MS_TCP_MODULEID[
24
]
=
{
0x18
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x03
,
0x4a
,
0x00
,
0xeb
,
0x1a
,
0x9b
,
0xd4
,
0x11
,
0x91
,
0x23
,
0x00
,
0x50
,
0x04
,
0x77
,
0x59
,
0xbc
,
};
__debugbreak();
pDriverObject
-
>DriverUnload
=
MyUnload;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
UNICODE_STRING DeviceName;
RtlInitUnicodeString(&DeviceName, L
"\\Device\\Nsi"
);
PFILE_OBJECT FileObj;
PDEVICE_OBJECT DevObj;
Statu
=
IoGetDeviceObjectPointer(
&DeviceName,
FILE_ALL_ACCESS,
&FileObj, &DevObj
);
param.UnknownParam3
=
(ULONG_PTR)&NPI_MS_TCP_MODULEID;
param.UnknownParam4
=
0x3
;
/
/
udp
0x1
param.UnknownParam5
=
0x100000001
;
pIrp
=
IoBuildDeviceIoControlRequest(
IOCTL_NSI_GETALLPARAM,
DevObj,
¶m,
0x70
,
¶m,
0x70
,
FALSE,
&Event,
&StatusBlock
);
StackLocation
=
IoGetNextIrpStackLocation(pIrp);
StackLocation
-
>FileObject
=
FileObj;
StackLocation
-
>DeviceObject
=
DevObj;
pIrp
-
>RequestorMode
=
KernelMode;
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2021-1-31 20:16
被Oday小斯编辑
,原因: