首页
社区
课程
招聘
[原创]win10 x64 r0枚举端口
发表于: 2020-1-20 17:19 12778

[原创]win10 x64 r0枚举端口

2020-1-20 17:19
12778

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。
NPI_MS_TCP_MODULEID

第一次查询时,只需要填写NSI_PARAM结构中的3,4,5三个域,查询成功ConnCount会得到TCP连接数,之后就是第二次查询,查询前需要分配内存。
NPI_MS_TCP_MODULEID
buffer大小需要在返回的连接数上加2

思路和r3发请求一致,效果:
demo
源码:

以上代码仅供参考!不做其他用途。

个人兴趣,想研究一下在r0枚举TCP/UDP端口,网上有代码是xp和win7的,试了一下不行,就简单研究了一下win10的,没啥技术含量,能逆出来相关结构体就行,实现了一个小demo,代码质量堪忧,不喜勿喷。
个人兴趣,想研究一下在r0枚举TCP/UDP端口,网上有代码是xp和win7的,试了一下不行,就简单研究了一下win10的,没啥技术含量,能逆出来相关结构体就行,实现了一个小demo,代码质量堪忧,不喜勿喷。
#define IOCTL_NSI_GETALLPARAM 0x12001B
#define IOCTL_NSI_GETALLPARAM 0x12001B
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,
};
#include <wdm.h>
#include <intrin.h>
 
VOID MyUnload(PDRIVER_OBJECT pDriverObject);
#define ntohs(s) \
    (((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;
 
#define IOCTL_NSI_GETALLPARAM 0x12001B
 
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,
        &param,0x70,
        &param,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,
        &param, 0x70,
        &param, 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(&param, 0x00, 0x70);
    param.UnknownParam3 = (ULONG_PTR)NPI_MS_UDP_MODULEID;
    param.UnknownParam4 = 0x1;
    param.UnknownParam5 = 0x100000001;
 
    pIrp = IoBuildDeviceIoControlRequest(
        IOCTL_NSI_GETALLPARAM,
        DevObj,
        &param, 0x70,
        &param, 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(&param, 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,
        &param, 0x70,
        &param, 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");
}
#include <wdm.h>
#include <intrin.h>
 
VOID MyUnload(PDRIVER_OBJECT pDriverObject);
#define ntohs(s) \
    (((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;
 
#define IOCTL_NSI_GETALLPARAM 0x12001B
 
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,
        &param,0x70,
        &param,0x70,
        FALSE,
        &Event,
        &StatusBlock
    );
 
    StackLocation = IoGetNextIrpStackLocation(pIrp);
    StackLocation->FileObject = FileObj;
    StackLocation->DeviceObject = DevObj;
    pIrp->RequestorMode = KernelMode;
 

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2021-1-31 20:16 被Oday小斯编辑 ,原因:
收藏
免费 1
支持
分享
最新回复 (7)
雪    币: 2157
活跃值: (12639)
能力值: ( LV12,RANK:312 )
在线值:
发帖
回帖
粉丝
2
 
最后于 2020-1-20 17:23 被一半人生编辑 ,原因:
2020-1-20 17:22
0
雪    币: 573
活跃值: (222)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
论坛有你更精彩,感谢分享
2020-1-20 21:23
0
雪    币: 441
活跃值: (1060)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
4
不错
2020-1-20 22:47
0
雪    币: 1485
活跃值: (1135)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
楼主试试拦截端口读写。某驱动暴力关机代码
mov ax,2001h
mov dx,1004h
out dx,ax
ret
2020-3-27 22:22
0
雪    币: 28
活跃值: (254)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
请问  如何获取IOCTL_NSI_GETALLPARAM
2021-1-27 22:32
0
雪    币: 1129
活跃值: (2761)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
doomday 请问 如何获取IOCTL_NSI_GETALLPARAM
ida看nsi.dll   NsiAllocateAndGetTable函数,调用NtDeviceIoControlFile的地方第六个参数就是。
2021-1-31 11:44
0
雪    币: 28
活跃值: (254)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
Oday小斯 ida看nsi.dll NsiAllocateAndGetTable函数,调用NtDeviceIoControlFile的地方第六个参数就是。
谢谢前辈
2021-1-31 17:35
0
游客
登录 | 注册 方可回帖
返回
//