├── MDE2TEAMS ├── requirements.txt ├── TEAMS │ └── send2teams.py ├── MDEAPI │ ├── list.py │ └── gettoken.py ├── README.MD └── app.py ├── CODE_OF_CONDUCT.md ├── MDEcli ├── global_obj │ └── read.py ├── mde_api_obj │ ├── list.py │ ├── gettoken.py │ └── actions.py ├── LICENSE.TXT ├── README.MD └── app.py ├── LICENSE ├── SUPPORT.md ├── README.md ├── SECURITY.md └── .gitignore /MDE2TEAMS/requirements.txt: -------------------------------------------------------------------------------- 1 | getpass4 2 | argparse 3 | pymsteams -------------------------------------------------------------------------------- /MDE2TEAMS/TEAMS/send2teams.py: -------------------------------------------------------------------------------- 1 | import pymsteams 2 | 3 | class Send2teams: 4 | def __init__(self, webhook, message): 5 | self.webhook = webhook 6 | self.message = message 7 | 8 | def send2teams(self): 9 | myTeamsMessage = pymsteams.connectorcard(f"{self.webhook}") 10 | myTeamsMessage.text(f"{self.message}") 11 | myTeamsMessage.send() -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /MDEcli/global_obj/read.py: -------------------------------------------------------------------------------- 1 | import csv 2 | 3 | class Csv: 4 | def __init__(self, filename): 5 | self.filename = filename 6 | 7 | def open(self): 8 | try: 9 | self.list_ids = [] 10 | with open (self.filename, 'r') as file: 11 | csv_read = csv.DictReader(file) 12 | for machineid in csv_read: 13 | self.list_ids.append(machineid['Device ID']) 14 | return self.list_ids 15 | except Exception as e: 16 | print(e) -------------------------------------------------------------------------------- /MDE2TEAMS/MDEAPI/list.py: -------------------------------------------------------------------------------- 1 | import json 2 | import urllib.request 3 | import urllib.parse 4 | 5 | class List: 6 | def __init__(self, token, url_construct): 7 | self.token = token 8 | self.url_construct = url_construct 9 | 10 | def list(self): 11 | url = f"https://api.securitycenter.microsoft.com/api/{self.url_construct}" 12 | headers = { 13 | 'Content-Type' : 'application/json', 14 | 'Accept' : 'application/json', 15 | 'Authorization' : "Bearer " + self.token 16 | } 17 | req = urllib.request.Request(url, headers=headers) 18 | response = urllib.request.urlopen(req) 19 | self.jsonResponse = json.loads(response.read()) 20 | return self.jsonResponse -------------------------------------------------------------------------------- /MDE2TEAMS/MDEAPI/gettoken.py: -------------------------------------------------------------------------------- 1 | import json 2 | import urllib.request 3 | import urllib.parse 4 | 5 | class GetToken: 6 | def __init__(self, tenantId, appId, appSecret): 7 | self.tenantId = tenantId 8 | self.appId = appId 9 | self.appSecret = appSecret 10 | 11 | def gettoken(self): 12 | 13 | url = "https://login.microsoftonline.com/%s/oauth2/token" % (self.tenantId) 14 | 15 | resourceAppIdUri = 'https://api.securitycenter.microsoft.com' 16 | 17 | body = { 18 | 'resource' : resourceAppIdUri, 19 | 'client_id' : self.appId, 20 | 'client_secret' : self.appSecret, 21 | 'grant_type' : 'client_credentials' 22 | } 23 | 24 | data = urllib.parse.urlencode(body).encode("utf-8") 25 | 26 | req = urllib.request.Request(url, data) 27 | response = urllib.request.urlopen(req) 28 | jsonResponse = json.loads(response.read()) 29 | self.aadToken = jsonResponse["access_token"] 30 | return self.aadToken -------------------------------------------------------------------------------- /MDEcli/mde_api_obj/list.py: -------------------------------------------------------------------------------- 1 | import json 2 | import urllib.request 3 | import urllib.parse 4 | 5 | class List: 6 | def __init__(self, token, url): 7 | self.token = token 8 | self.url = url 9 | 10 | def list(self): 11 | try: 12 | url = f"https://api.securitycenter.microsoft.com/api/{self.url}" 13 | headers = { 14 | 'Content-Type' : 'application/json', 15 | 'Accept' : 'application/json', 16 | 'Authorization' : "Bearer " + self.token 17 | } 18 | 19 | req = urllib.request.Request(url, headers=headers) 20 | response = urllib.request.urlopen(req) 21 | jsonResponse = json.loads(response.read()) 22 | listdict = jsonResponse['value'] 23 | for alert in listdict: 24 | print(f'\n###{self.url}###') 25 | for key,value in alert.items(): 26 | print(f'{key}: {value}') 27 | print('###END###\n') 28 | except Exception as e: 29 | print(e) -------------------------------------------------------------------------------- /MDEcli/mde_api_obj/gettoken.py: -------------------------------------------------------------------------------- 1 | import json 2 | import urllib.request 3 | import urllib.parse 4 | 5 | class GetToken: 6 | def __init__(self, tenantId, appId, appSecret): 7 | self.tenantId = tenantId 8 | self.appId = appId 9 | self.appSecret = appSecret 10 | 11 | def gettoken(self): 12 | try: 13 | url = "https://login.microsoftonline.com/%s/oauth2/token" % (self.tenantId) 14 | resourceAppIdUri = 'https://api.securitycenter.microsoft.com' 15 | body = { 16 | 'resource' : resourceAppIdUri, 17 | 'client_id' : self.appId, 18 | 'client_secret' : self.appSecret, 19 | 'grant_type' : 'client_credentials' 20 | } 21 | data = urllib.parse.urlencode(body).encode("utf-8") 22 | req = urllib.request.Request(url, data) 23 | response = urllib.request.urlopen(req) 24 | jsonResponse = json.loads(response.read()) 25 | self.aadToken = jsonResponse["access_token"] 26 | return self.aadToken 27 | except Exception as e: 28 | print(e) -------------------------------------------------------------------------------- /MDEcli/LICENSE.TXT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /SUPPORT.md: -------------------------------------------------------------------------------- 1 | # TODO: The maintainer of this repo has not yet edited this file 2 | 3 | **REPO OWNER**: Do you want Customer Service & Support (CSS) support for this product/project? 4 | 5 | - **No CSS support:** Fill out this template with information about how to file issues and get help. 6 | - **Yes CSS support:** Fill out an intake form at [aka.ms/spot](https://aka.ms/spot). CSS will work with/help you to determine next steps. More details also available at [aka.ms/onboardsupport](https://aka.ms/onboardsupport). 7 | - **Not sure?** Fill out a SPOT intake as though the answer were "Yes". CSS will help you decide. 8 | 9 | *Then remove this first heading from this SUPPORT.MD file before publishing your repo.* 10 | 11 | # Support 12 | 13 | ## How to file issues and get help 14 | 15 | This project uses GitHub Issues to track bugs and feature requests. Please search the existing 16 | issues before filing new issues to avoid duplicates. For new issues, file your bug or 17 | feature request as a new Issue. 18 | 19 | For help and questions about using this project, please **REPO MAINTAINER: INSERT INSTRUCTIONS HERE 20 | FOR HOW TO ENGAGE REPO OWNERS OR COMMUNITY FOR HELP. COULD BE A STACK OVERFLOW TAG OR OTHER 21 | CHANNEL. WHERE WILL YOU HELP PEOPLE?**. 22 | 23 | ## Microsoft Support Policy 24 | 25 | Support for this **PROJECT or PRODUCT** is limited to the resources listed above. 26 | -------------------------------------------------------------------------------- /MDEcli/mde_api_obj/actions.py: -------------------------------------------------------------------------------- 1 | import json 2 | import urllib.request 3 | import urllib.parse 4 | 5 | class Action: 6 | def __init__(self, token, id, comment, body2): 7 | self.token = token 8 | self.id = id 9 | self.comment = comment 10 | self.body2 = body2 11 | 12 | def offboard(self): 13 | try: 14 | url = f"https://api.securitycenter.microsoft.com/api/machines/{self.id}/offboard" 15 | headers = { 16 | 'Content-Type' : 'application/json', 17 | 'Accept' : 'application/json', 18 | 'Authorization' : "Bearer " + self.token 19 | } 20 | 21 | data = json.dumps({"Comment": self.comment}).encode("utf-8") 22 | 23 | req = urllib.request.Request(url, data, headers) 24 | response = urllib.request.urlopen(req) 25 | jsonResponse = json.loads(response.read()) 26 | print(f'{jsonResponse["computerDnsName"]} - Machine ID {jsonResponse["machineId"]} as been offboarded') 27 | except Exception as e: 28 | print(e) 29 | 30 | def scan(self): 31 | try: 32 | url = f"https://api.securitycenter.microsoft.com/api/machines/{self.id}/runAntiVirusScan" 33 | headers = { 34 | 'Content-Type' : 'application/json', 35 | 'Accept' : 'application/json', 36 | 'Authorization' : "Bearer " + self.token 37 | } 38 | 39 | data = json.dumps({"Comment": self.comment, "ScanType": self.body2}).encode("utf-8") 40 | #data = str(json.dumps(body)).encode("utf-8") 41 | 42 | req = urllib.request.Request(url, data, headers) 43 | response = urllib.request.urlopen(req) 44 | jsonResponse = json.loads(response.read()) 45 | print(f'{jsonResponse["computerDnsName"]} - Machine ID {jsonResponse["machineId"]} - {jsonResponse["type"]} ({jsonResponse["scope"]}) action started') 46 | except Exception as e: 47 | print(e) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_type: sample 3 | languages: 4 | - python 5 | products: 6 | - MDE API 7 | description: "Auxiliary tools and samples for Microsoft Defender ATP Cross-Platform" 8 | --- 9 | 10 | # Project 11 | 12 | Welcome to Python for Security, the repo that contains multiple examples on how to use python with our greatest security products and features. Be part of this changing community that aims to make organizations more secure by leveraging the power of python with Microsoft Azure Security Solutions. 13 | 14 | ## Contributing 15 | 16 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 17 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 18 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. 19 | 20 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide 21 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions 22 | provided by the bot. You will only need to do this once across all repos using our CLA. 23 | 24 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 25 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 26 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 27 | 28 | ## Trademarks 29 | 30 | This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft 31 | trademarks or logos is subject to and must follow 32 | [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). 33 | Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. 34 | Any use of third-party trademarks or logos are subject to those third-party's policies. 35 | -------------------------------------------------------------------------------- /MDE2TEAMS/README.MD: -------------------------------------------------------------------------------- 1 | # MDE2TEAMS # 2 | Simple Python connector for Microsoft Defender Endpoint (MDE) events and Teams Channel. 3 | 4 | # About 5 | The MDE2TEAMS will allow Customers to have all new events (alerts, vulnerabilities, Inventory, etc.) posted to one or more Teams Channel automatically, allowing for a much faster response using all capabilities of Microsoft Teams. This connector uses MDE API. 6 | 7 | # Installation 8 | REQUIRED: python3 9 | pipenv install -r requirements.txt 10 | 11 | If you decide to manually deploy, you'll need to install the follwing python3 libraries: 12 | - getpass4 13 | - argparse 14 | - pymsteams 15 | 16 | # Prerequistes 17 | When you run the app, you'll be required to provide the following info: 18 | - Tenant ID 19 | - App ID 20 | - App Secret 21 | - Webhook 22 | 23 | Tenant ID, App Id and App Secret you'll need to create a Application Registration in Azure - https://docs.microsoft.com/en-us/skype-sdk/trusted-application-api/docs/registrationinazureactivedirectory. Make sure you allow the proper permissions for WindowsDefenderATP and Microsoft Threat Protection 24 | 25 | You'll also need to create webhooks for each Teams Channel where you want to post new events. App Secret and Webhooks will not displat«y back to the user for security reasons 26 | 27 | # Help 28 | This application as a help menu for all the options: 29 | python app.py -h 30 | 31 | Help Output: 32 | usage: app.py [-h] {alerts,investigations,indicators,machines,machineactions,recommendations,Software,vulnerabilities} 33 | 34 | MDE4Teams = A tool to track MDE events in Teams 35 | 36 | positional arguments: 37 | {alerts,investigations,indicators,machines,machineactions,recommendations,Software,vulnerabilities} 38 | Select which notifications to List in Teams 39 | 40 | optional arguments: 41 | -h, --help show this help message and exit 42 | 43 | Original project created by Bruno Rodrigues - rodrigues.bruno@microsoft.com 44 | 45 | # Usage & Examples 46 | To Run the app (every argument will require to be run separate): 47 | - python app.py alerts 48 | - python app.py vulnerabilities 49 | 50 | # To-Do 51 | -------------------------------------------------------------------------------- /MDE2TEAMS/app.py: -------------------------------------------------------------------------------- 1 | import getpass 2 | import argparse 3 | import time 4 | from MDEAPI import gettoken 5 | from MDEAPI import list 6 | from TEAMS import send2teams 7 | 8 | #menu argparser 9 | parser = argparse.ArgumentParser(prog='app.py', description='MDE4Teams = A tool to track MDE events in Teams', epilog='Original project created by Bruno Rodrigues - rodrigues.bruno@microsoft.com') 10 | parser.add_argument('list', choices=['alerts', 'investigations', 'indicators', 'machines', 'machineactions', 'recommendations', 'Software', 'vulnerabilities'], help='Select which notifications to List in Teams') 11 | 12 | args = parser.parse_args() 13 | 14 | #Login token 15 | try: 16 | tenantid = input('Please enter your Tenant ID: ') 17 | appid = input('Please enter your Application ID: ') 18 | secret = getpass.getpass('Please enter your Application Secret:') 19 | webhook = getpass.getpass('Please enter your webhook from Teams: ') 20 | new_token = gettoken.GetToken(tenantid, appid, secret) 21 | new_token.gettoken() 22 | token = new_token.aadToken 23 | except Exception as e: 24 | print(e) 25 | 26 | #Lists with no body API 27 | # 28 | #First run 29 | try: 30 | new_baseline = list.List(token, f'{args.list}') 31 | new_baseline.list() 32 | baseline_list = new_baseline.jsonResponse['value'] 33 | except Exception as e: 34 | print(e) 35 | 36 | #infinite loop 37 | while True: 38 | try: 39 | new_events = list.List(token, f'{args.list}') 40 | new_events.list() 41 | events_list = new_events.jsonResponse['value'] 42 | if events_list == baseline_list: 43 | print(f'No new {args.list}') 44 | else: 45 | for dict in events_list: 46 | if dict not in baseline_list: 47 | new_teams_message = send2teams.Send2teams(webhook, dict) 48 | new_teams_message.send2teams() 49 | print('Message sent to Teams Channel') 50 | update_baseline = list.List(token, f'{args.list}') 51 | update_baseline.list() 52 | baseline_list = update_baseline.jsonResponse['value'] 53 | local_time = time.ctime() 54 | print(local_time) 55 | time.sleep(120) 56 | except Exception as e: 57 | print(e) -------------------------------------------------------------------------------- /MDEcli/README.MD: -------------------------------------------------------------------------------- 1 | # MDE CLI 2 | This sample code creates an easy way to interact with Microsoft Defedner for Endpoint through a cli. This can be ran from any OS as long it's running python 3.6 or above 3 | 4 | # Requirements and Instalation 5 | MDE CLI can be ran from any OS as long it's running python 3.6 or above. You'll be required to use pip 6 | 7 | ## Instalation 8 | No instalation required 9 | 10 | # Usage 11 | Usage is pretyy much straight forward and you can always use the help menu - python app.py "option" -"sub option" 12 | 13 | python app.py alerts -list 14 | python app.py actions -offboard 15 | 16 | ## Examples 17 | 18 | ### Help menu for Options - python app.py -h 19 | 20 | usage: app.py [-h] {alerts,investigations,indicators,machines,actions,recommendations,software,vulnerabilities} ... 21 | 22 | MDEcli = A tool manage MDE through CLI 23 | 24 | optional arguments: 25 | -h, --help show this help message and exit 26 | 27 | Available options: 28 | {alerts,investigations,indicators,machines,actions,recommendations,software,vulnerabilities} 29 | Choose one of the main options. MDEcli -