-
Notifications
You must be signed in to change notification settings - Fork 143
Expand file tree
/
Copy pathclient.go
More file actions
180 lines (168 loc) · 11.2 KB
/
Copy pathclient.go
File metadata and controls
180 lines (168 loc) · 11.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// Copyright (C) 2022 Specter Ops, Inc.
//
// This file is part of AzureHound.
//
// AzureHound is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// AzureHound is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package client
//go:generate go run github.com/golang/mock/mockgen -destination=./mocks/client.go -package=mocks . AzureClient
import (
"context"
"fmt"
"encoding/json"
"github.com/bloodhoundad/azurehound/v2/client/config"
"github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/models/azure"
"github.com/go-logr/logr"
)
func NewClient(config config.Config, log logr.Logger) (AzureClient, error) {
if msgraph, err := rest.NewRestClient(config.GraphUrl(), config); err != nil {
return nil, err
} else if resourceManager, err := rest.NewRestClient(config.ResourceManagerUrl(), config); err != nil {
return nil, err
} else {
if config.JWT != "" {
if aud, err := rest.ParseAud(config.JWT); err != nil {
return nil, err
} else if aud == config.GraphUrl() {
return initClientViaGraph(msgraph, resourceManager, config.Tenant, log)
} else if aud == config.ResourceManagerUrl() {
if body, err := rest.ParseBody(config.JWT); err != nil {
return nil, err
} else {
return initClientViaRM(msgraph, resourceManager, body["tid"])
}
} else {
return nil, fmt.Errorf("error: invalid token audience")
}
} else {
return initClientViaGraph(msgraph, resourceManager, config.Tenant, log)
}
}
}
func initClientViaRM(msgraph, resourceManager rest.RestClient, tid interface{}) (AzureClient, error) {
client := &azureClient{
msgraph: msgraph,
resourceManager: resourceManager,
}
if result, err := client.GetAzureADTenants(context.Background(), true); err != nil {
return nil, err
} else {
for _, tenant := range result.Value {
if tenant.TenantId == tid.(string) {
client.tenant = tenant
break
}
}
return client, nil
}
}
func initClientViaGraph(msgraph, resourceManager rest.RestClient, tid string, log logr.Logger) (AzureClient, error) {
client := &azureClient{
msgraph: msgraph,
resourceManager: resourceManager,
}
if org, err := client.GetAzureADOrganization(context.Background(), nil); err != nil {
log.V(0).Error(err, "unable to get Azure AD organization. It is likely that your user don't have MS Graph API permissions. If you list non AAD objects (e.g., az-rm) this should be okay.")
if result, err := client.GetAzureADTenants(context.Background(), true); err != nil {
return nil, err
} else {
for _, tenant := range result.Value {
if tenant.TenantId == tid {
client.tenant = tenant
break
}
}
return client, nil
}
} else {
client.tenant = org.ToTenant()
return client, nil
}
}
type azureClient struct {
msgraph rest.RestClient
resourceManager rest.RestClient
tenant azure.Tenant
}
func (s azureClient) TenantInfo() azure.Tenant {
return s.tenant
}
type AzureClient interface {
GetAzureADApp(ctx context.Context, objectId string, selectCols []string) (*azure.Application, error)
GetAzureADApps(ctx context.Context, filter, search, orderBy, expand string, selectCols []string, top int32, count bool) (azure.ApplicationList, error)
GetAzureADDirectoryObject(ctx context.Context, objectId string) (json.RawMessage, error)
GetAzureADGroup(ctx context.Context, objectId string, selectCols []string) (*azure.Group, error)
GetAzureADGroupOwners(ctx context.Context, objectId string, filter string, search string, orderBy string, selectCols []string, top int32, count bool) (azure.DirectoryObjectList, error)
GetAzureADGroups(ctx context.Context, filter, search, orderBy, expand string, selectCols []string, top int32, count bool) (azure.GroupList, error)
GetAzureADOrganization(ctx context.Context, selectCols []string) (*azure.Organization, error)
GetAzureADRole(ctx context.Context, roleId string, selectCols []string) (*azure.Role, error)
GetAzureADRoleAssignment(ctx context.Context, objectId string, selectCols []string) (*azure.UnifiedRoleAssignment, error)
GetAzureADRoleAssignments(ctx context.Context, filter, search, orderBy, expand string, selectCols []string, top int32, count bool) (azure.UnifiedRoleAssignmentList, error)
GetAzureADRoles(ctx context.Context, filter, expand string) (azure.RoleList, error)
GetAzureADServicePrincipal(ctx context.Context, objectId string, selectCols []string) (*azure.ServicePrincipal, error)
GetAzureADServicePrincipalOwners(ctx context.Context, objectId string, filter string, search string, orderBy string, selectCols []string, top int32, count bool) (azure.DirectoryObjectList, error)
GetAzureADServicePrincipals(ctx context.Context, filter, search, orderBy, expand string, selectCols []string, top int32, count bool) (azure.ServicePrincipalList, error)
GetAzureADTenants(ctx context.Context, includeAllTenantCategories bool) (azure.TenantList, error)
GetAzureADUser(ctx context.Context, objectId string, selectCols []string) (*azure.User, error)
GetAzureADUsers(ctx context.Context, filter string, search string, orderBy string, selectCols []string, top int32, count bool) (azure.UserList, error)
GetAzureDevice(ctx context.Context, objectId string, selectCols []string) (*azure.Device, error)
GetAzureDevices(ctx context.Context, filter, search, orderBy, expand string, selectCols []string, top int32, count bool) (azure.DeviceList, error)
GetAzureKeyVault(ctx context.Context, subscriptionId, groupName, vaultName string) (*azure.KeyVault, error)
GetAzureKeyVaults(ctx context.Context, subscriptionId string, top int32) (azure.KeyVaultList, error)
GetAzureManagementGroup(ctx context.Context, groupId, filter, expand string, recurse bool) (*azure.ManagementGroup, error)
GetAzureManagementGroups(ctx context.Context) (azure.ManagementGroupList, error)
GetAzureResourceGroup(ctx context.Context, subscriptionId, groupName string) (*azure.ResourceGroup, error)
GetAzureResourceGroups(ctx context.Context, subscriptionId string, filter string, top int32) (azure.ResourceGroupList, error)
GetAzureSubscription(ctx context.Context, objectId string) (*azure.Subscription, error)
GetAzureSubscriptions(ctx context.Context) (azure.SubscriptionList, error)
GetAzureVirtualMachine(ctx context.Context, subscriptionId, groupName, vmName, expand string) (*azure.VirtualMachine, error)
GetAzureVirtualMachines(ctx context.Context, subscriptionId string, statusOnly bool) (azure.VirtualMachineList, error)
GetAzureStorageAccount(ctx context.Context, subscriptionId, groupName, saName, expand string) (*azure.StorageAccount, error)
GetAzureStorageAccounts(ctx context.Context, subscriptionId string) (azure.StorageAccountList, error)
GetResourceRoleAssignments(ctx context.Context, subscriptionId string, filter string, expand string) (azure.RoleAssignmentList, error)
GetRoleAssignmentsForResource(ctx context.Context, resourceId string, filter string) (azure.RoleAssignmentList, error)
ListAzureADAppMemberObjects(ctx context.Context, objectId string, securityEnabledOnly bool) <-chan azure.MemberObjectResult
ListAzureADAppOwners(ctx context.Context, objectId string, filter, search, orderBy string, selectCols []string) <-chan azure.AppOwnerResult
ListAzureADApps(ctx context.Context, filter, search, orderBy, expand string, selectCols []string) <-chan azure.ApplicationResult
ListAzureADGroupMembers(ctx context.Context, objectId string, filter, search, orderBy string, selectCols []string) <-chan azure.MemberObjectResult
ListAzureADGroupOwners(ctx context.Context, objectId string, filter, search, orderBy string, selectCols []string) <-chan azure.GroupOwnerResult
ListAzureADGroups(ctx context.Context, filter, search, orderBy, expand string, selectCols []string) <-chan azure.GroupResult
ListAzureADRoleAssignments(ctx context.Context, filter, search, orderBy, expand string, selectCols []string) <-chan azure.UnifiedRoleAssignmentResult
ListAzureADRoles(ctx context.Context, filter, expand string) <-chan azure.RoleResult
ListAzureADServicePrincipalOwners(ctx context.Context, objectId string, filter, search, orderBy string, selectCols []string) <-chan azure.ServicePrincipalOwnerResult
ListAzureADServicePrincipals(ctx context.Context, filter, search, orderBy, expand string, selectCols []string) <-chan azure.ServicePrincipalResult
ListAzureADTenants(ctx context.Context, includeAllTenantCategories bool) <-chan azure.TenantResult
ListAzureADUsers(ctx context.Context, filter string, search string, orderBy string, selectCols []string) <-chan azure.UserResult
ListAzureContainerRegistries(ctx context.Context, subscriptionId string) <-chan azure.ContainerRegistryResult
ListAzureWebApps(ctx context.Context, subscriptionId string) <-chan azure.WebAppResult
ListAzureManagedClusters(ctx context.Context, subscriptionId string, statusOnly bool) <-chan azure.ManagedClusterResult
ListAzureVMScaleSets(ctx context.Context, subscriptionId string, statusOnly bool) <-chan azure.VMScaleSetResult
ListAzureDeviceRegisteredOwners(ctx context.Context, objectId string, securityEnabledOnly bool) <-chan azure.DeviceRegisteredOwnerResult
ListAzureDevices(ctx context.Context, filter, search, orderBy, expand string, selectCols []string) <-chan azure.DeviceResult
ListAzureKeyVaults(ctx context.Context, subscriptionId string, top int32) <-chan azure.KeyVaultResult
ListAzureManagementGroupDescendants(ctx context.Context, groupId string) <-chan azure.DescendantInfoResult
ListAzureManagementGroups(ctx context.Context) <-chan azure.ManagementGroupResult
ListAzureResourceGroups(ctx context.Context, subscriptionId, filter string) <-chan azure.ResourceGroupResult
ListAzureSubscriptions(ctx context.Context) <-chan azure.SubscriptionResult
ListAzureVirtualMachines(ctx context.Context, subscriptionId string, statusOnly bool) <-chan azure.VirtualMachineResult
ListAzureStorageAccounts(ctx context.Context, subscriptionId string) <-chan azure.StorageAccountResult
ListAzureStorageContainers(ctx context.Context, subscriptionId string, resourceGroupName string, saName string, filter string, includeDeleted string, maxPageSize string) <-chan azure.StorageContainerResult
ListAzureAutomationAccounts(ctx context.Context, subscriptionId string) <-chan azure.AutomationAccountResult
ListAzureLogicApps(ctx context.Context, subscriptionId string, filter string, top int32) <-chan azure.LogicAppResult
ListAzureFunctionApps(ctx context.Context, subscriptionId string) <-chan azure.FunctionAppResult
ListResourceRoleAssignments(ctx context.Context, subscriptionId string, filter string, expand string) <-chan azure.RoleAssignmentResult
ListRoleAssignmentsForResource(ctx context.Context, resourceId string, filter string) <-chan azure.RoleAssignmentResult
ListAzureADAppRoleAssignments(ctx context.Context, servicePrincipal, filter, search, orderBy, expand string, selectCols []string) <-chan azure.AppRoleAssignmentResult
TenantInfo() azure.Tenant
}