首页
社区
课程
招聘
[讨论]防火墙是如何监控由本机的数据包(包括发送到internet上和收到来自internet的)?
发表于: 2016-12-9 19:46 5953

[讨论]防火墙是如何监控由本机的数据包(包括发送到internet上和收到来自internet的)?

2016-12-9 19:46
5953
我的理解是:
一般网卡的驱动里,会有“发送缓冲区”和“接收缓冲区”。而系统一般的做法有2种:
1、中断方式
1)当接收中断标志被触发,操作系统会从“硬件网卡”的接收缓冲区(一般4kb左右)里将数据copy到操作系统里设定的接收缓冲区。
2)当发送中断标志被触发,“硬件网卡”会将“发送缓冲区”里的数据从网口发送出去

2、轮询(主要是接收功能,关闭网卡接收中断的响应)
1)网卡驱动会设置循环读取“硬件网卡”的接收缓冲区,并将里面的数据copy到预设的接收缓冲区

那对于防火墙,它是如何做到先于应用程序“获得”(实际是截取)数据?

[培训]科锐逆向工程师培训第53期2025年7月8日开班!

收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 244
活跃值: (454)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
网络驱动 TDI,WFP, NDIS。都可以《Windows内核安全与驱动开发》 又讲。或者看看wireshark源码
2016-12-9 20:03
0
雪    币: 74
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
......
我的疑惑:防火墙的切入点是在哪里?
2016-12-9 20:26
0
雪    币: 878
活跃值: (496)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
你说的应该是物理层和数据链路层的数据传输;
防火墙工作层次不同, 切入点也不同, 一般软件防火墙实现在网络层或其上层, 在数据到达应用程序中间安装过滤驱动进行数据包处理.
2016-12-9 21:18
0
雪    币: 74
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
我的意思是,假设:
1)操作系统的发送和接收的函数是:os_send() 和 os_recv()
2)应用程序的发送和接收的函数是:app_send() 和 app_recv()
3)防火墙的“截取”函数分别是:fire_send() 和 fire_recv()

没有防火墙的情况:
1)发送过程:app_send() -> os_send()
2)接收过程:app_recv()  <- os_recv()

存在防火墙的情况
1)发送过程:app_send() -> fire_send() -> os_send()
2)接收过程:app_recv() <- fire_recv() <- os_recv()

我的疑问:
fire_send() 和 fire_recv() 是如何实现的?我感觉防火墙是“劫持”了用户的应用程序(用户进程),它是如何做到的?
2016-12-9 21:31
0
雪    币: 145
活跃值: (40)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
防火墙是系统开放出来的接口,如果你是想做防火墙,那你去研究如何调用这些接口就好了,比如TDI Filter,NDIS Filter, wfp.基本上就是按他的接口规范来写代码,有数据了系统会调用你的"回调" ,这些机制都是系统自己实现的.

就像你想弹个信息框,那你就去调用MessageBox.但如果你想知道,msgbox为啥可以在屏幕上弹个框框出来,标题文字又是怎么画出来的,按钮又是怎么画出来的,系统是怎么操作显卡的..... 这些只能你自己去折腾,毕竟这是OS内部的事情...

你说的app_send - os_send ,在windows上大概流程就是Winsock - afd - tdi/wfp - ndis

每一层,系统都有提供过滤数据的能力,比如Winsock这一层,有个叫LSP的东西可以用来做防火墙,TDI这一层,有tdi Filter过滤驱动, ndis也有过滤驱动等等.

至于你说的切入点:
lsp,你需要调用系统的接口来安装你得lsp dll,你通过系统的接口来安装lsp,那系统在有数据的时候就知道需要调用你的各种回调.

TDI filter是个过滤驱动,附加到系统的TCP/UDP设备上,按照OS的设计,附加后,该设备的IRP就会经过你,你自然就能过滤到数据

WFP同样,也是系统提供的接口,你按照他的要求写代码...有网络事件,系统会自己过来调用你

LSP可以找到很多代码, 高版本系统微软是不建议使用的,但还是能用.
TDI防火墙有TDIFW,开源的, 同样, 微软也不推荐在高版本系统用, 在WIN7可以正常用, win10上会有些残废.
WFP也有开源代码WinDivert,微软自带的例子也有. WFP只能用在WIN7及以后的系统上.
NDIS微软也有自带的例子.

具体区别,去看看网上的资料.

敲了一堆, 发现这帖子是发在安卓版块的..所以你问的是安卓上的防火墙么?  那请无视....
2016-12-10 05:07
0
雪    币: 74
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
谢谢你的回复。
或许我再具体点,在存在防火墙的情况下,当我调用app_send()的时候,为何防火墙(更具代表性的应该是防病毒软件)会首先截获到,在它“审查”通过后才能最终调用os_send()发送数据?
防火墙是如何做到的?它调用了操作系统的哪些功能?
2016-12-10 09:51
0
雪    币: 878
活跃值: (496)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
上述回答就是针对你的问题的, 再解释也没用
2016-12-10 12:35
0
雪    币: 74
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
之前altmanx的回复确实是很详细,非常感谢。

但我想或者是我之前的表达不够清晰吧,那我换一种方式,如下:

假设:
1、我自己写了一个简单的操作系统(类linux的小kernel+简单的文件系统)。
2、现在我想再写一个简单的防火墙。
3、这个简单的操作系统里有一个应用程序,名字叫app

现在,对应用程序app我要进行如下操作:

第一种情况(没防火墙)
1、在命令行下运行该应用程序app
> app (回车)
2、操作系统os 调用fork()等一系列函数完成进程的创建及最终跳转到该app进程代码段的首址,完成程序的运行

第二种情况(有防火墙)
1、在命令行下运行该应用程序app
> app (回车)
2、防火墙“劫持”了该app进程。
这里,我的思路不是太清晰,但我的猜测是:当操作系统调用fork()的时候,应该是挂起了;转而调用防火墙的相应程序去“审查”该app进程。而要做到fork()的时候挂起,则应该是操作系统的作者去完成这个功能的,即操作系统的代码里应该在fork()函数里会有一个类似if的检查语句,当发现系统了安装了防火墙,则fork()挂起,转而跳转至防火墙对应的程序(该程序的地址应该是配置好的)
3、当防火墙完成“审查”后,返回fork()并继续执行后面的进程创建及代码执行

注:
1、以上的想法纯粹的猜想,而且不一定就在fork()里面做检测跳转
2、在windows和linux里面是怎样的,我不太清楚,想请教各位
3、之前altmanx的回复里有说明windows里大致是怎样,但似乎不够底层,即windows是在创建进程的函数了设置了防火墙检查程序的地址,还是......(没有冒犯的意思,只是我还未明白......)
2016-12-10 16:31
0
雪    币: 931
活跃值: (2630)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
这样讲吧,windows底层调用你可以看成一个链表,app_send(data)执行进入内核后,查找这个链表,先执行func1(data),再执行firewall(data),最后执行os_send(data),操作系统在执行到底层的时候会根据这个链表,依次执行,data在执行过程中,里面的数据可以在那个函数中随意修改,判断,拦截(变为NULL一类)。至于为什么会执行firewall,就是调用一个API,插入到这个链表中指定的位置。所以在调用os_send(data)前会调用这个firewall(data).
2016-12-10 17:30
0
雪    币: 145
活跃值: (40)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
简单说说windows上LSP"防火墙"的大概流程

首先要知道windows上进程使用网络的套路:
1.调用wsaStartup()初始化winsock
2.调用socket()创建用于通信的socket
3.根据你的程序用途,调用bind,connect或listen&accept
4.调用send/recv或wsaSend/wsaRecv发收数据

这些接口都在系统的ws2_32.dll中导出.

在安装LSP的时候, 需要调用系统的接口 WSCInstallProvider() "注册"你的DLL , 系统会将注册过的DLL信息,写进注册表.
同时,你的DLL需要按照微软的要求, 导出几个函数:
如, WSPConnect ,WSPSend , WSPRecv 等.

当进程加载ws2_32.dll的时候, 这个DLL内部,会去遍历注册表, 将你的DLL加载到当前进程, 然后当这个进程调用ws2_32.dll的send , recv等接口的时候, ws2_32.dll内部会去同步调用你的WSPSend,WSPRecv等, 系统会将收发的数据指针, 数据长度, socket句柄等信息,通过参数传递给你的WSPSend/Recv ,这个时候你就能过滤到数据了.

再说TDI 防火墙:

ws2_32.dll的send/recv,其实是通过CreateFile / DeviceIOControl对系统的AFD驱动做读写操作,AFD驱动又会将读写交给TDI.

TDI驱动里面存在几个"设备",如\device\tcp, \device\udp,如果你要做防火墙,那么你的驱动创建好自己的设备,然后调用ioattachdevice附加到\device\tcp,\device\udp,按照系统的设计,当一个设备产生IO的时候, 他会将读写请求(IRP)"转发"到附加到这个设备上的其他设备,这样你就可以得到读写信息了, tdi中收发数据对应的irp code 是 IRP_MJ_INTERNAL_DEVICE_CONTROL , 其中又可细分为TDI_CONNECT (对应进程的connect) , TDI_SEND (对应进程的send/wsasend)等.   至于说具体的处理, 比如TDI_SEND的时候, 怎么得到缓冲区,怎么得到长度,IRP又该怎么处理,设备该怎么附加,这些你要去了解windows驱动开发相关的内容.

这是一个大概的流程,核心都是系统自己实现的,至于为啥存在LSP,存在AFD,存在TDI,为啥附加到其他设备,你的设备就能够得到数据,为啥系统要这么设计,这不是三言两语解释的清的,就像你写一套程序,你会按照你的经验去设计程序组织结构,会采用自己觉得合适的设计模式.

另外windows上防火墙的实现,跟进程创建并没有什么太大关联,是在进程实际进行网络操作的时候,系统中的网络组件才会去"调用"你的防火墙.

其他平台肯定也有对应的防火墙接口,其内部实现,取决于OS是怎么设计的, 如果没有提供防火墙接口,那么就得采用hook的方式来实现,比如上面说的AFD,这个东西的确可以用来做防火墙,只是没有官方的文档支持.TDI除了过滤驱动,也可以用IRP hook等方式实现, hook的目的,也就是为了得到网络IO的相关信息,从而进行过滤.

你前面说的操作中断,操作缓冲区,其实更接近于网卡硬件驱动.系统提供给你的防火墙接口,并不需要你去干涉这些东西,比如上面的LSP,TDI防火墙流程中,不需要你去主动定时读取缓冲区,更不需要你去响应中断,而是有网络事件的时候,系统会主动"通知你",调用你的回调,系统之所以知道需要调用你 ,是因为你已经通过(WSCInstallProvider, ioattachdevice)等方式告诉系统你是个防火墙,需要过滤数据.

如果你是自己设计操作系统, 那你在网络IO流程中一个合适的环节 ,暴漏相关的接口就行, 至于具体哪个环节, 仁者见仁智者见智了.
2016-12-11 01:08
0
游客
登录 | 注册 方可回帖
返回