美文网首页
python 控制Windows防火墙(FireWall)

python 控制Windows防火墙(FireWall)

作者: 手残达人 | 来源:发表于2018-12-11 15:04 被阅读0次

    一、说明

    最近有朋友问有木有认识做.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中的getput接口对防火墙规则的一个属性,通过设置属性来获取或设置防火墙
    • 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

    相关文章

      网友评论

          本文标题:python 控制Windows防火墙(FireWall)

          本文链接:https://www.haomeiwen.com/subject/odorhqtx.html