一、说明
最近有朋友问有木有认识做.Net关于Windows防火墙开发的朋友,很是好奇,为啥子需要用.Net开发呢,为啥不用万能的python。然而在认识的同事和朋友中,并没有做.Net开发的(原因未知),就用python尝试一下吧
重点:
- 管理员权限运行
- netsh advfirewall firewall 了解一下(手动滑稽)
二、win32com通用
不懂Windows的com组件,只知道python可以用win32com库调用com相关接口,或者加载调用dll库,需要的包:
import pythoncom import win32com
1. win32com.client.gencache.EnsureDispatch
根据官方声明,调用上述函数会自动生成指定com组件的结构,例如用python运行一下代码:
win32com.client.gencache.EnsureDispatch('HNetCfg.FwMgr', 0)
则会在目录C:\Users\Administrator\AppData\Local\Temp\gen_py\3.6\
下生成一个py文件,其中:class INetFwPolicy2(DispatchBaseClass): CLSID = IID('{98325047-C671-4174-8D81-DEFCD3F03186}') coclass_clsid = None .... # 表示该组件的get方法 _prop_map_get_ = { "CurrentProfileTypes": (1, 2, (3, 0), (), "CurrentProfileTypes", None), "LocalPolicyModifyState": (15, 2, (3, 0), (), "LocalPolicyModifyState", None), # Method 'Rules' returns object of type 'INetFwRules' #Rules保存所有规则,其返回类型为'INetFwRules‘ "Rules": (7, 2, (9, 0), (), "Rules", '{9C4C6277-5027-441E-AFAE-CA1F542DA009}'), # Method 'ServiceRestriction' returns object of type 'INetFwServiceRestriction' "ServiceRestriction": (8, 2, (9, 0), (), "ServiceRestriction", '{8267BBE3-F890-491C-B7B6-2DB1EF0E5D2B}'), } _prop_map_put_ = { } ... class INetFwRules(DispatchBaseClass): CLSID = IID('{9C4C6277-5027-441E-AFAE-CA1F542DA009}') coclass_clsid = None ... _prop_map_get_ = { "Count": (1, 2, (3, 0), (), "Count", None), } _prop_map_put_ = { } def __iter__(self): "Return a Python iterator for this object" try: ob = self._oleobj_.InvokeTypes(-4,LCID,2,(13, 10),()) except pythoncom.error: raise TypeError("This object does not support enumeration") return win32com.client.util.Iterator(ob, '{AF230D27-BABA-4E42-ACED-F524F22CFCE2}')
注:关于'HNetCfg.FwMgr'的来源--https://www.2cto.com/kf/200904/37096.html
2. 文件说明和接口调用
INetFwPolicy2类为一个com组件,其提供get和set接口,每一项代表一个接口,get接口有:
"CurrentProfileTypes": (1, 2, (3, 0), (), "CurrentProfileTypes", None)
"LocalPolicyModifyState": (15, 2, (3, 0), (), "LocalPolicyModifyState", None)
"Rules": (7, 2, (9, 0), (), "Rules", '{9C4C6277-5027-441E-AFAE-CA1F542DA009}')
"ServiceRestriction": (8, 2, (9, 0), (), "ServiceRestriction", '{8267BBE3-F890-491C-B7B6-2DB1EF0E5D2B}')
需要特别注意,元组中最后一项表示该接口返回的类型对应的已注册的com类型,如果为None,如上述的
CurrentProfileTypes
接口,则可以打印出,一般为数字通过调用以下代码,来查看一下我们的防火墙规则:
fw = win32com.client.gencache.EnsureDispatch('HNetCfg.FwPolicy2', 0) print(fw.CurrentProfileTypes) rules = fw.Rules # 此处根据`Rules`的类型{9C4C6277-5027-441E-AFAE-CA1F542DA009}找到INetFwRules print(rules.Count) for rule in rules: print(rule)# rule的类型查找方法如上,INetFwRules为一个类迭代器,返回类型为{AF230D27-BABA-4E42-ACED-F524F22CFCE2} rule = `win32com.client.CastTo(rule, "INetFwRule3") print(rule.Name)
- 根据接口
Rules
的类型{9C4C6277-5027-441E-AFAE-CA1F542DA009}
找到类INetFwRules
INetFwRules
为一个类迭代器,返回类型为{AF230D27-BABA-4E42-ACED-F524F22CFCE2} INetFwRule
即为rule
的类型INetFwRule
中的get
和put
接口对防火墙规则的一个属性,通过设置属性来获取或设置防火墙INetFwRule
中的属性较少,我们可以用rule =win32com.client.CastTo(rule, "INetFwRule3")
将其转换为INetFwRule3
来查看更多属性
INetFwRule3
属性如下class INetFwRule(DispatchBaseClass): CLSID = IID('{AF230D27-BABA-4E42-ACED-F524F22CFCE2}') coclass_clsid = None _prop_map_get_ = { "Action": (18, 2, (3, 0), (), "Action", None), "ApplicationName": (3, 2, (8, 0), (), "ApplicationName", None), "Description": (2, 2, (8, 0), (), "Description", None), "Direction": (11, 2, (3, 0), (), "Direction", None), "EdgeTraversal": (17, 2, (11, 0), (), "EdgeTraversal", None), "Enabled": (14, 2, (11, 0), (), "Enabled", None), "Grouping": (15, 2, (8, 0), (), "Grouping", None), "IcmpTypesAndCodes": (10, 2, (8, 0), (), "IcmpTypesAndCodes", None), "InterfaceTypes": (13, 2, (8, 0), (), "InterfaceTypes", None), "Interfaces": (12, 2, (12, 0), (), "Interfaces", None), "LocalAddresses": (8, 2, (8, 0), (), "LocalAddresses", None), "LocalPorts": (6, 2, (8, 0), (), "LocalPorts", None), "Name": (1, 2, (8, 0), (), "Name", None), "Profiles": (16, 2, (3, 0), (), "Profiles", None), "Protocol": (5, 2, (3, 0), (), "Protocol", None), "RemoteAddresses": (9, 2, (8, 0), (), "RemoteAddresses", None), "RemotePorts": (7, 2, (8, 0), (), "RemotePorts", None), "serviceName": (4, 2, (8, 0), (), "serviceName", None), }
三、防火墙控制
上述内容中,我们介绍如何使用win32com组件生成py接口类,通过给定的接口查找我们的防火墙规则,以及各个组件属性、调用和返回值。下面将介绍规则属性:
items_name = { "Action":'操作', "ApplicationName":'程序', "Description":'描述', "Direction":'进站/出站', "EdgeTraversal":'边缘穿越', "EdgeTraversalOptions":'边缘穿越选项', "Enabled":'已启用', "Grouping":'组', "IcmpTypesAndCodes":'ICMP设置', "InterfaceTypes":'接口类型', "Interfaces":'接口', "LocalAddresses":'本地地址', "LocalAppPackageId":'应用程序包', "LocalPorts":'本地端口', "LocalUserAuthorizedList":'授权的本地计算机', "LocalUserOwner":'本地用户所有者', "Name":'名称', "Profiles":'配置文件', "Protocol":'协议', "RemoteAddresses":'远程地址', "RemoteMachineAuthorizedList":'授权的远程计算机', "RemotePorts":'远程端口', "RemoteUserAuthorizedList":'授权的远程用户', "SecureFlags":'安全', "serviceName":'服务名'}
防火墙规则请参考Windows文档(皮一下),接口文档
四、全量代码
# fw_rules.py
class rule:
items = {}
# 中英文转换
items_name = {
"Action":'操作',
"ApplicationName":'程序',
"Description":'描述',
"Direction":'进站/出站',
"EdgeTraversal":'边缘穿越',
"EdgeTraversalOptions":'边缘穿越选项',
"Enabled":'已启用',
"Grouping":'组',
"IcmpTypesAndCodes":'ICMP设置',
"InterfaceTypes":'接口类型',
"Interfaces":'接口',
"LocalAddresses":'本地地址',
"LocalAppPackageId":'应用程序包',
"LocalPorts":'本地端口',
"LocalUserAuthorizedList":'授权的本地计算机',
"LocalUserOwner":'本地用户所有者',
"Name":'名称',
"Profiles":'配置文件',
"Protocol":'协议',
"RemoteAddresses":'远程地址',
"RemoteMachineAuthorizedList":'授权的远程计算机',
"RemotePorts":'远程端口',
"RemoteUserAuthorizedList":'授权的远程用户',
"SecureFlags":'安全',
"serviceName":'服务名'}
items_shell = {
"Action": 'action',
"ApplicationName": 'program',
"Description": 'description',
"Direction": 'dir',
"EdgeTraversal": 'edge',
"EdgeTraversalOptions": '边缘穿越选项',
"Enabled": 'enable',
"Grouping": '组',
"IcmpTypesAndCodes": 'ICMP设置',
"InterfaceTypes": 'interfacetype',
"Interfaces": '接口',
"LocalAddresses": 'localip',
"LocalAppPackageId": '应用程序包',
"LocalPorts": 'localport',
"LocalUserAuthorizedList": '授权的本地计算机',
"LocalUserOwner": '本地用户所有者',
"Name": 'name',
"Profiles": 'profile',
"Protocol": 'protocol',
"RemoteAddresses": 'remoteip',
"RemoteMachineAuthorizedList": 'rmtcomputergrp',
"RemotePorts": 'remoteport',
"RemoteUserAuthorizedList": 'rmtusrgrp',
"SecureFlags": 'security',
"serviceName": 'service'
}
def __init__(self,index):
self.index = index
for i in self.items_name.keys():
self.items[i] = ''
def init_by_app(self, app_in):
for key in self.items_name.keys():
self.items[key] = " " + str(eval("app_in."+key))
print(self.items[key] )
def init_by_dict(self,dirc_con):
flag = False
for item_key in self.items_name.keys():
if self.items_name[item_key] in dirc_con.keys():
flag = True
self.items[item_key] = dirc_con[self.items_name[item_key]]
if not flag:
for key in dirc_con.keys():
self.items[key] = dirc_con[key]
def create_rule(self):
app = win32com.client.Dispatch('HNetCfg.FwRule')
res = []
# 注意赋值顺序
app.Action = int(self.items["Action"])
app.Description = self.items["Description"]
app.Direction = int(self.items["Direction"])
app.EdgeTraversal = self.items["EdgeTraversal"]
app.EdgeTraversalOptions = self.items["EdgeTraversalOptions"]
app.Enabled = self.items["Enabled"]
app.Grouping = self.items["Grouping"]
## app.IcmpTypesAndCodes = self.items["IcmpTypesAndCodes"]
app.InterfaceTypes = self.items["InterfaceTypes"]
## app.Interfaces = self.items["Interfaces"]
app.LocalAddresses = self.items["LocalAddresses"]
app.LocalAppPackageId = self.items["LocalAppPackageId"]
## app.LocalPorts = str(self.items["LocalPorts"]),
## app.LocalUserAuthorizedList = self.items["LocalUserAuthorizedList"]
app.LocalUserOwner = self.items["LocalUserOwner"]
app.Name = self.items["Name"]
app.Profiles = self.items["Profiles"]
app.Protocol = self.items["Protocol"]
app.RemoteAddresses = self.items["RemoteAddresses"]
## app.RemoteMachineAuthorizedList = self.items["RemoteMachineAuthorizedList"]
app.RemotePorts = self.items["RemotePorts"]
app.LocalPorts = self.items['LocalPorts']
## app.RemoteUserAuthorizedList = ''
app.SecureFlags = self.items["SecureFlags"]
# app.serviceName = "null"
# app.ApplicationName = "null"
return app
def __str__(self):
result = "="*10 + '\n序号 : ' + str(self.index) + '\n'
for key in self.items_name.keys():
result += self.items_name[key] + " : " + str(self.items[key]) +"\n"
return result
def add_rule(dict_value):
fw = win32com.client.gencache.EnsureDispatch('HNetCfg.FwPolicy2', 0)
apps = fw.Rules
print(apps.Count)
# app = win32com.client.Dispatch('HNetCfg.FwRule3')
rule_obj = rule(-1)
rule_obj.init_by_dict(dict_value)
app = rule_obj.create_rule()
apps.Add(app)
def del_rule(dict_value):
fw = win32com.client.gencache.EnsureDispatch('HNetCfg.FwPolicy2', 0)
apps = fw.Rules
print("before :", apps.Count)
rule_obj = rule(-1)
rule_obj.init_by_dict(dict_value)
for app in apps:
print(rule_obj.items['Name'] , str(app.Name))
print(rule_obj.items['LocalPorts'] , str(app.LocalPorts))
print(rule_obj.items['RemoteAddresses'] , str(app.RemoteAddresses))
if rule_obj.items['Name'] == str(app.Name) and rule_obj.items['LocalPorts'] == str(app.LocalPorts) and rule_obj.items['RemoteAddresses'] == str(app.RemoteAddresses):
# 只能根据Name删除,大概是个傻子哟
apps.Remove(str(app.Name))
# break
print("after :", apps.Count)
if __name__ == '__main__':
my_dict = {
'序号' : '2',
'操作' : '0',
'程序' : '',
'描述' : '',
'进站/出站' : '1',
'边缘穿越' : 'False',
'边缘穿越选项' : '0',
'已启用' : 'True',
'组' : '',
'ICMP设置' : '',
'接口类型' : 'All',
'接口' : 'None',
'本地地址' : '*',
'应用程序包' : '',
'本地端口' : '9876',
'授权的本地计算机' : '',
'本地用户所有者' : '',
'名称' : 'test_cmd',
'配置文件' : '2',
'协议' : '6',
'远程地址' : '114.115.250.41/255.255.255.255',
'授权的远程计算机' : '',
'远程端口' : '*',
'授权的远程用户' : '',
'安全' : '0',
'服务名' : ''
}
add_rule(my_dict)
del_rule(my_dict)
原创不易,不喜勿喷
https://www.jianshu.com/p/78e70e8e363d