Getting Hosts from Microsoft Intune MDM using Python. Today I want to talk about Microsoft Intune. It is a Mobile Device Management platform.
Well, I think that the importance of MDM systems has become much higher than it was before the days of covid-19. Simply because a lot more people now work remotely using corporate laptops. And if these people don’t connect to the corporate network using a VPN, you most likely won’t see any activity from their devices in Active Directory. This means that you will not understand whether the device is active or not. And it will be impossible to get the correct security metrics for these devices.
Mobile device management is a solution to this problem as it maintains a connection between the laptop and the cloud server. MDM can collect various parameters from hosts, but for me the most important parameter is the timestamp. I will not describe all the features of Microsoft Intune here. Simply because at this stage they are not very interesting to me. The task I needed to solve was how to get the timestamp of the last activity for all hosts in Microsoft Intune using the official API. And since this is poorly documented, I want to share it with you.
Let’s start with authentication. The thing is that Intune API can use the same authentication method that I already described in the Microsoft Defender for Endpoint article. So, you need to go to Microsoft Azure and create an application. Then you need to set the permission for this app. And then it will be possible to make a post request and receive an authentication token. I won’t go into details on how to set up an Azure application, just see the previous article on Microsoft Defender for Endpoint. The only difference is that you need to request the intune -> get_data_warehouse permission.
All the rest is the same.
import requests
def get_token():
body = {
"resource": "https://api.manage.microsoft.com/",
"client_id": azure_appId,
"client_secret": azure_appSecret,
"grant_type": "client_credentials"
}
response = requests.post("https://login.windows.net/" + azure_tenantId + "/oauth2/token", data=body)
return response.json()["access_token"]
And it’s weird because the folks at Microsoft didn’t mention in the manual that you can use this for authentication, just some weird stuff about oauth2. You might think that Microsoft, one of the most cutting edge tech companies, would have the best guides. But this is not the case. At least for the Intune API.
Then the idea is that you use an authentication token in the headers and make requests to get hosts. But you should get a URL that will be unique to your organization, the easiest way to do this is to go to Reports -> Data Warehouse in the GUI (https://endpoint.microsoft.com/).
The rest is trivial, you will need to make one request and maybe deal with pagination, as I showed in the example below.
def get_devices(auth_token):
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': "Bearer " + auth_token
}
skip = 0
top = 1000
results = list()
processing_machines_continue = True
while processing_machines_continue:
url = "https://XXXX.manage.microsoft.com/ReportingService/DataWarehouseFEService/devices?api-version=v1.0&$skip= " + str(
skip) + " &$top=" + str(top)
response = requests.get(url, headers=headers)
if response.json()['value'] != list():
results += response.json()['value']
skip += top
else:
processing_machines_continue = False
return results
Also I list the parameters that you can retrive using the API:
{'deviceKey': XXXX, 'deviceId': 'XXXX-XXXX-XXXX-XXXX-XXXX', 'deviceName': 'XXXX', 'deviceTypeKey': XXXX, 'deviceRegistrationStateKey': XXXX, 'ownerTypeKey': XXXX, 'enrolledDateTime': '2021-06-19T14:43:23.3597155Z', 'lastSyncDateTime': '2021-06-20T01:01:02.5280342Z', 'managementAgentKey': XXXX, 'managementStateKey': XXXX, 'azureADDeviceId': 'XXXX-XXXX-XXXX-XXXX-XXXX', 'azureADRegistered': True, 'deviceCategoryKey': None, 'deviceEnrollmentTypeKey': XXXX, 'complianceStateKey': None, 'osVersion': '10.0.19042.631', 'easDeviceId': 'XXXX', 'serialNumber': 'XXXX', 'userId': 'XXXX-XXXX-XXXX-XXXX-XXXX', 'rowLastModifiedDateTimeUTC': '2021-06-04T00:17:01.2070619Z', 'manufacturer': 'XXXX', 'model': 'XXXX', 'operatingSystem': 'Windows', 'isDeleted': False, 'androidSecurityPatchLevel': None, 'meid': None, 'isSupervised': 0, 'freeStorageSpaceInBytes': XXXX, 'totalStorageSpaceInBytes': XXXX, 'encryptionState': 0, 'subscriberCarrier': '', 'phoneNumber': None, 'imei': None, 'cellularTechnology': None, 'wiFiMacAddress': 'XXXX', 'ethernetMacAddress': 'XXXX', 'office365Version': None, 'windowsOsEdition': '48'}
Hi! My name is Alexander and I am a Vulnerability Management specialist. You can read more about me here. Currently, the best way to follow me is my Telegram channel @avleonovcom. I update it more often than this site. If you haven’t used Telegram yet, give it a try. It’s great. You can discuss my posts or ask questions at @avleonovchat.
А всех русскоязычных я приглашаю в ещё один телеграмм канал @avleonovrus, первым делом теперь пишу туда.
Hello, thanks you for this share,
I have a Inoic/cordova app which uses intune MDM, how can i do to retrieve the device data (imei, sn, upn etc.) ?
if you have any documentation, can you share it with me? thank you !
Hi Ibrahim! I haven’t tried to get this parameters yet. Don’t you see these parameters in DataWarehouseFEService/devices request output? And I only use the documentation publicly available on the site.
Thanks you for your answer,
My GET request https://XXX.manage.microsoft.com/ReportingService/DataWarehouseFEService/devices?api-version=v1.0 in Postman give an errors, can you have any idea please ? thanks !
{
“ErrorCode”: “Forbidden”,
“Message”: “{\r\n \”_version\”: 3,\r\n \”Message\”: \”An error has occurred – Operation ID (for customer support): 00000000-0000-0000-0000-000000000000 – Activity ID: 679XXXX-37c2-4ba3-90bf-xxx – Url: https://XXX.manage.microsoft.com/ReportingService/DataWarehouseFEService/devices?api-version=v1.0\”,\r\n \”CustomApiErrorPhrase\”: \”\”,\r\n \”RetryAfter\”: null,\r\n \”ErrorSourceService\”: \”\”,\r\n \”HttpHeaders\”: \”{\\\”WWW-Authenticate\\\”:\\\”Bearer realm=\\\\\\\”urn:intune:service,xxxxx73-f703-4a4e-85e4-58016xxxx3cfa7,fxxxx-59bf-4f0d-b1b2-0ef84ddfe3c7\\\\\\\”\\\”}\”\r\n}”,
“Target”: null,
“Details”: null,
“InnerError”: null,
“InstanceAnnotations”: []
}
Ibrahim, most likely you have a problem with Permissions granted for your app. Check them in portal.azure.com. Also, check that granted permissions have “Application” Type.
I added all permission but still the same problem.
DeviceManagementManagedDevices.Read.All type “application “and “delegue”
DeviceManagementManagedDevices.Read.All type ” application” and “delegue”
get_data_warehouse. type “apllication”
can i please contact you on google meet or Discord ? thank you.
Pingback: Vulnerability Management news and publications #2 | Alexander V. Leonov
Pingback: И тут было бы справедливо спросить: «А не ты ли, Александр, совсем недавно топил за эти самые облачные ИБ сервисы Microsoft, а теперь получаетс
Pingback: How to get Antivirus-related Data from Microsoft Defender for Endpoint using Intune and Graph API | Alexander V. Leonov