NTSockets – 使用 NtCreateFile 和 NtDeviceIoControlFile 系统调用通过 HTTP 下载文件

原文链接:https://www.x86matthew.com/view_post?id=ntsockets

这篇文章演示了如何仅使用 ntdll 导出来创建 TCP 套接字和传输/接收数据。

我们将使用的函数是NtCreateFile和NtDeviceIoControlFile。Winsock 库使用这些函数与 AFD 驱动程序进行通信,但我们将绕过 Winsock 并直接调用它们。这些函数也可以使用直接系统调用指令来调用,以增加对用户模式挂钩的隐蔽性,尽管在内核级别检测网络流量仍然很容易。为了演示这个概念,我创建了一个通过 HTTP 下载文件的工具。

我只对这个概念验证所需的内部 AFD 数据结构进行了逆向工程。我希望可以在其他地方找到有关 AFD 结构的更多信息。

为了创建一个套接字,我们调用NtCreateFile来打开\Device\Afd\Endpoint对象。套接字属性(地址族、协议类型等)是使用未记录的结构指定的,该结构作为“扩展属性”传递给NtCreateFile 。我已经硬编码这些属性来创建一个 IPv4 TCP 套接字:

现在我们有了一个有效的套接字句柄,我们可以使用NtDeviceIoControlFile与 AFD 驱动程序进行通信。我创建了以下处理 AFD 驱动程序消息的通用函数:

我们可以使用相应的dwIoControlCode值调用NTSockets_SocketDriverMsg来执行我们想要执行的操作 – 连接、发送、接收等。如果事件对象返回一个挂起的状态代码,则等待函数完成。 完成后,我们可以使用CloseHandle(或NtClose)关闭套接字:

我创建了以下函数库,这些函数库执行此概念验证所需的所有操作:

NTSockets_CreateTcpSocket – 创建 TCP 套接字(相当于socket())
NTSockets_ConvertIP – 将 IP 字符串转换为二进制地址(相当于to inet_addr () )
NTSockets_Swap16BitByteOrder – 将 16 位整数转换为/从网络字节顺序(相当于htons() / ntohs())
NTSockets_Connect – 连接到远程主机(相当于connect())
NTSockets_Send – 将数据发送到套接字(相当于发送()- 注意:在发送完所有字节后,该函数不会返回)
NTSockets_Recv – 从套接字接收请求的字节数(相当于recv() – 注意:在接收到所有字节之前,该函数不会返回)
NTSockets_CloseSocket – 关闭套接字(相当于closesocket() )

对于这个概念验证,我创建了一个非常简单的 HTTP 客户端来从远程 Web 服务器下载文件。这不支持 HTTPS 或 301/302 状态重定向等

。除此之外,我还创建了一个基本的 DNS 客户端来执行名称查找 – 这是因为我们不能使用gethostbyname()函数,因为这是温索克图书馆。DNS 服务器当前被硬编码为8.8.8.8,但如果愿意,您可以从注册表中读取默认 DNS 服务器。

完整代码如下:

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注