Example #1
0
def mitre():
    """Urls might change, for proper urls see https://github.com/swimlane/pyattck"""
    try:
        from pyattck import Attck
    except ImportError:
        print(
            "Missed dependency: install pyattck library, see requirements for proper version"
        )
        return

    mitre = Attck(
        nested_subtechniques=True,
        save_config=False,
        use_config=False,
        config_file_path=os.path.join(CUCKOO_ROOT, "data", "mitre",
                                      "config.yml"),
        data_path=os.path.join(CUCKOO_ROOT, "data", "mitre"),
        enterprise_attck_json=
        "https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json",
        pre_attck_json=
        "https://raw.githubusercontent.com/mitre/cti/master/pre-attack/pre-attack.json",
        mobile_attck_json=
        "https://raw.githubusercontent.com/mitre/cti/master/mobile-attack/mobile-attack.json",
        nist_controls_json=
        "https://raw.githubusercontent.com/center-for-threat-informed-defense/attack-control-framework-mappings/master/frameworks/ATT%26CK-v9.0/nist800-53-r4/stix/nist800-53-r4-controls.json",
        generated_attck_json=
        "https://swimlane-pyattck.s3.us-west-2.amazonaws.com/generated_attck_data.json",
        generated_nist_json=
        "https://swimlane-pyattck.s3.us-west-2.amazonaws.com/attck_to_nist_controls.json",
    )

    print("[+] Updating MITRE datasets")
    mitre.update()
Example #2
0
def test_passed_kwargs():
      from pyattck import Attck, Configuration
      attck = Attck()
      assert Configuration.requests_kwargs == {}
      args = {
          'verify': False,
          'proxies': {
              'http': 'http://10.10.1.10:3128',
              'https': 'http://10.10.1.10:1080',
          }
      }
      attck = Attck(**args)
      assert Configuration.requests_kwargs == args
Example #3
0
def test_attck_attribute_is_list(target_attribute):
    from pyattck import Attck
    path = os.path.join(os.path.dirname(os.path.dirname(__file__)),
                        'fixtures')  #, 'generated_attck_data' + '.json')
    attck = Attck(data_path=path)
    ics = getattr(attck, 'ics')
    assert isinstance(getattr(ics, target_attribute), list)
Example #4
0
def test_preattck_attck_attribute_is_list(target_attribute):
    from pyattck import Attck
    path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'fixtures',
                        'generated_attck_data' + '.json')
    attck = Attck()
    preattack = getattr(attck, 'preattack')
    assert isinstance(getattr(preattack, target_attribute), list)
Example #5
0
def test_default_config(attck_configuration):
      from pyattck import Attck, Configuration
      attck = Attck()
      for key,val in default_config_data.items():
          if hasattr(Configuration, key):
              setattr(Configuration, key, val)
      assert attck_configuration.config_data == default_config_data
Example #6
0
def test_attck_attribute_is_list(target_attribute):
    from pyattck import Attck
    path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'fixtures',
                        'generated_attck_data' + '.json')
    attck = Attck(dataset_json=path)
    enterprise = getattr(attck, 'enterprise')
    assert isinstance(getattr(enterprise, target_attribute), list)
Example #7
0
def test_nested_subtechniques():
      from pyattck import Attck
      attck = Attck(nested_subtechniques=False)
      count = 0
      for technique in attck.enterprise.techniques:
          if technique.subtechnique:
              count += 1
      assert count >= 360
Example #8
0
def test_config_dataset_json_path_default_value():
    from pyattck import Attck
    Attck()
    
    config = None
    with open(os.path.abspath(os.path.join(expanduser('~'), 'pyattck', 'config' + '.yml'))) as f:
        config = yaml.load(f, Loader=yaml.FullLoader)
    assert config['enterprise_attck_dataset'] == os.path.abspath(os.path.join(expanduser('~'), 'pyattck', 'enterprise_attck_dataset' + '.json'))
Example #9
0
def test_all_preattck_attck_objects_have_standard_properties(
        target_attribute, target_properties):
    from pyattck import Attck
    path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'fixtures',
                        'generated_attck_data' + '.json')
    attck = Attck()
    preattack = getattr(attck, 'preattack')
    for attribute in getattr(preattack, target_attribute):
        assert getattr(attribute, target_properties)
Example #10
0
def test_all_attck_objects_have_standard_properties(target_attribute,
                                                    target_properties):
    from pyattck import Attck
    path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'fixtures',
                        'generated_attck_data' + '.json')
    attck = Attck(dataset_json=path)
    enterprise = getattr(attck, 'enterprise')
    for attribute in getattr(enterprise, target_attribute):
        assert getattr(attribute, target_properties)
Example #11
0
def test_all_attck_objects_have_standard_properties_deprecated(target_attribute,target_properties):
    from pyattck import Attck
    path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'fixtures', 'generated_attck_data' + '.json')
    attck = Attck(dataset_json=path)
    return_list = []
    for attribute in getattr(attck,target_attribute):
        if hasattr(attribute, target_properties):
            return_list.append(getattr(attribute,target_properties))
    if len(return_list) >= 1:
        assert True
Example #12
0
def test_config_enterprise_attck_dataset_json_path_provided_value(tmpdir):
    from pyattck import Attck
    config_path = os.path.abspath(os.path.join(expanduser('~'), 'pyattck', 'config' + '.yml'))
    path = tmpdir.mkdir('pyattck').join('enterprise_attck_dataset.json')
    Attck(dataset_json=os.path.abspath(str(path)))
    
    config = None
    with open(config_path) as f:
        config = yaml.load(f, Loader=yaml.FullLoader)
    assert config['enterprise_attck_dataset'] == os.path.abspath(str(path))
def test_config_attck_json_path_default_value():
    from pyattck import Attck
    Attck()

    config_path = os.path.abspath(
        os.path.join(expanduser('~'), 'pyattck', 'config' + '.yml'))
    config = None
    with open(config_path) as f:
        config = yaml.load(f, Loader=yaml.FullLoader)
    assert os.path.join(config.get('data_path'),
                        config['enterprise'].get('filename')) == os.path.join(
                            config.get('data_path'),
                            'enterprise_attck' + '.json')
def test_config_attck_json_path_provided_value(tmpdir):
    from pyattck import Attck
    config_path = os.path.abspath(
        os.path.join(expanduser('~'), 'pyattck', 'config' + '.yml'))
    path = tmpdir.mkdir('pyattck')
    Attck(data_path=str(path))

    config = None
    with open(config_path) as f:
        config = yaml.load(f, Loader=yaml.FullLoader)
    assert os.path.join(config.get('data_path'),
                        config['enterprise'].get('filename')) == os.path.join(
                            config.get('data_path'),
                            'enterprise_attck' + '.json')
Example #15
0
def mitre_techniques() -> Dict[Text, Text]:
    """
    Get list of all MITRE ATT&CK techniques and return map combined with
    both technique IDs and (lowercased) name as key an name as value
    """

    attack = Attck()
    techniques = {}

    for technique in attack.enterprise.techniques:
        techniques[technique.id] = technique.name
        techniques[technique.name.lower()] = technique.name

    return techniques
Example #16
0
def main() -> None:
    """Main function"""

    # Look for default ini file in "/etc/actworkers.ini" and ~/config/actworkers/actworkers.ini
    # (or replace .config with $XDG_CONFIG_DIR if set)
    args = cli.handle_args(parseargs())

    actapi = worker.init_act(args)

    proxies = ({
        "http": args.proxy_string,
        "https": args.proxy_string
    } if args.proxy_string else None)

    attack = Attck(proxies=proxies)

    types = [args.type] if args.type else MITRE_TYPES

    for mitre_type in types:
        if mitre_type not in MITRE_TYPES:
            error("Unknown mitre type: {}. Valid types: {}".format(
                mitre_type, ",".join(MITRE_TYPES)))
            sys.exit(2)

        cache = notify_cache(args.notifycache)

        model = getattr(attack, mitre_type)

        techniques_notify = add_techniques(actapi, model, args.output_format)
        groups_notify = add_groups(actapi, model, args.output_format)
        software_notify = add_software(actapi, model, args.output_format)

        # filter revoked objects from those allready notified
        notify = [
            notify
            for notify in techniques_notify + groups_notify + software_notify
            if notify.id not in cache
        ]

        if notify:
            notified = send_notification(notify, args.smtphost, args.sender,
                                         args.recipient, mitre_type)

            for object_id in notified:
                # Add object to cache, so we will not be notified on the same object on the next run
                add_to_cache(args.notifycache, object_id)
Example #17
0
def attck_fixture():
    from pyattck import Attck
    yield Attck(
        use_config=False,
        save_config=False,
        enterprise_attck_json=
        "https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json",
        pre_attck_json=
        "https://raw.githubusercontent.com/mitre/cti/master/pre-attack/pre-attack.json",
        mobile_attck_json=
        "https://raw.githubusercontent.com/mitre/cti/master/mobile-attack/mobile-attack.json",
        nist_controls_json=
        "https://raw.githubusercontent.com/center-for-threat-informed-defense/attack-control-framework-mappings/main/frameworks/attack_10_1/nist800_53_r4/stix/nist800-53-r4-controls.json",
        generated_attck_json=
        "https://github.com/swimlane/pyattck/blob/master/generated_attck_data.json?raw=True",
        generated_nist_json=
        "https://github.com/swimlane/pyattck/blob/master/attck_to_nist_controls.json?raw=True"
    )
Example #18
0
def test_setting_json_locations(target_attribute):
      from pyattck import Attck, Configuration

      enterprise_temp_value = get_random_file_or_url()
      pre_attck_temp_value = get_random_file_or_url()
      mobile_temp_value = get_random_file_or_url()
      ics_temp_value = get_random_file_or_url()
      nist_controls_temp_value = get_random_file_or_url()
      generated_attck_temp_value = get_random_file_or_url()
      generated_nist_temp_value = get_random_file_or_url()

      attck = Attck(
        enterprise_attck_json=enterprise_temp_value
      )
      assert Configuration.enterprise_attck_json == enterprise_temp_value

      attck = Attck(
        pre_attck_json=pre_attck_temp_value
      )
      assert Configuration.pre_attck_json == pre_attck_temp_value

      attck = Attck(
        mobile_attck_json=mobile_temp_value
      )
      assert Configuration.mobile_attck_json == mobile_temp_value

      attck = Attck(
        ics_attck_json=ics_temp_value
      )
      assert Configuration.ics_attck_json == ics_temp_value

      attck = Attck(
        nist_controls_json=nist_controls_temp_value
      )
      assert Configuration.nist_controls_json == nist_controls_temp_value

      attck = Attck(
        generated_attck_json=generated_attck_temp_value
      )
      assert Configuration.generated_attck_json == generated_attck_temp_value

      attck = Attck(
        generated_nist_json=generated_nist_temp_value
      )
      assert Configuration.generated_nist_json == generated_nist_temp_value
Example #19
0
from pyattck import Attck

attack = Attck()

# Examples of MITRE Enterprise ATT&CK using nested subtechniques

for actor in attack.enterprise.actors:
    print(actor.id)
    print(actor.name)

    # accessing malware used by an actor or group
    for malware in actor.malwares:
        print(malware.id)
        print(malware.name)

    # accessing tools used by an actor or group
    for tool in actor.tools:
        print(tool.id)
        print(tool.name)

    # accessing techniques used by an actor or group
    for technique in actor.techniques:
        print(technique.id)
        print(technique.name)
        # you can also access generated data sets on aa technique
        print(technique.command_list)
        print(technique.commands)
        print(technique.queries)
        print(technique.datasets)
        print(technique.possible_detections)
        # You can access subtechniques nested under techniques by default
Example #20
0
import pandas as pd
import matplotlib.pyplot as plt
from pyattck import Attck

attack = Attck()
attack.update(enterprise=True)

techniques = []
data_sources = []

for technique in attack.enterprise.techniques:
    if technique.data_source:
        for data_source in technique.data_source:
            techniques.append(technique.name)
            data_sources.append(data_source)

data = {
    'technique': techniques,
    'data_source': data_sources
}

t2d = pd.DataFrame(data, columns=['technique', 'data_source'])

t2d.head(20)

# Look at the frequency of the data sources
dataFrequency = t2d['data_source'].value_counts()
dataFrequency.head(20)
plt.bar(dataFrequency.index, dataFrequency.values)
plt.xticks(dataFrequency.index, dataFrequency.index, rotation=90)
Example #21
0
def test_config_alternate_location(tmpdir):
    config_path = str(tmpdir.mkdir('pyattck').join('config.yml'))
    from pyattck import Attck
    Attck(config_path=config_path)
    
    assert len(tmpdir.listdir()) == 1
Example #22
0
def test_config_in_default_location():
    from pyattck import Attck
    Attck()

    assert os.path.isfile(os.path.join(expanduser('~'), 'pyattck', 'config' + '.yml'))
Example #23
0
def test_configuration_save_config(attck_configuration):
    from pyattck import Attck
    attck = Attck(save_config=True)
    assert attck_configuration.save_config == True
    assert isinstance(attck_configuration.config_data, dict)
    assert os.path.abspath(os.path.expanduser(os.path.expandvars(attck_configuration.data_path))) == attck_configuration.config_data.get('data_path')
Example #24
0
def test_default_configuration_settings_jsons(attck_configuration, target_attribute):
    from pyattck import Attck, Configuration
    attck = Attck()
    assert getattr(Configuration, target_attribute) == default_config_data[target_attribute]
Example #25
0
def main(args=None):
    attck = Attck()
    fire.Fire(attck)
Example #26
0
class AttckDocs(object):

    _attck = Attck(nested_subtechniques=False)
Example #27
0
from pyattck import Attck

attack = Attck(nested_subtechniques=False)

# Examples of MITRE Enterprise ATT&CK using nested subtechniques


for actor in attack.enterprise.actors:
    print(actor.id)
    print(actor.name)

    # accessing malware used by an actor or group
    for malware in actor.malwares:
        print(malware.id)
        print(malware.name)

    # accessing tools used by an actor or group
    for tool in actor.tools:
        print(tool.id)
        print(tool.name)

    # accessing techniques used by an actor or group
    for technique in actor.techniques:
        print(technique.id)
        print(technique.name)
        print(technique.data_sources)
        # you can also access generated data sets on aa technique
        print(technique.command_list)
        print(technique.commands)
        print(technique.queries)
        print(technique.datasets)
Example #28
0
def attck_fixture_nested_subtechniques_false():
    from pyattck import Attck
    return Attck(nested_subtechniques=False)
Example #29
0
class AttckDocs(object):

    _attck = Attck()
Example #30
0
def attck_fixture():
    from pyattck import Attck
    return Attck()