Sleuth Kit Java Bindings (JNI)  4.11.0
Java bindings for using The Sleuth Kit
WindowsAccountUtils.java
Go to the documentation of this file.
1 /*
2  * Sleuth Kit Data Model
3  *
4  * Copyright 2021 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.datamodel;
20 
21 import com.google.common.collect.ImmutableMap;
22 import com.google.common.collect.ImmutableSet;
23 import java.util.HashMap;
24 import java.util.Map;
25 import java.util.Map.Entry;
26 import java.util.Optional;
27 import java.util.Set;
28 
37 final class WindowsAccountUtils {
38 
39  // Special Windows Accounts with short SIDS are given a special realm "address".
40  final static String SPECIAL_WINDOWS_REALM_ADDR = "SPECIAL_WINDOWS_ACCOUNTS";
41 
42  final static String SPECIAL_WINDOWS_BACK_UP_POSTFIX = ".bak";
43 
44 
45  // Windows uses SIDs for groups as well as users.
46  // We dont want to create "User" account for group SIDs.
47  // The lists here help us identify and weed out group SIDs when creating accounts.
48  private static final Set<String> GROUP_SIDS = ImmutableSet.of(
49  "S-1-0-0", // Null SID
50  "S-1-1-0", // Everyone
51  "S-1-2-0", // Local - anyone who has logged on locally
52  "S-1-2-1", // Console Logon
53 
54  "S-1-3-1", // Creator
55  "S-1-3-4", // Owner rights
56 
57  "S-1-5-1", // Dialup
58  "S-1-5-2", // Network
59  "S-1-5-3", // Batch
60  "S-1-5-4", // Interactive
61  "S-1-5-6", // Service
62  "S-1-5-7", // Anonymous
63  "S-1-5-9", // Enterprise Domain Controllers
64 
65  "S-1-5-11", // Authenticated Users
66  "S-1-5-12", // Restricted Code - not a group but not a user SID either
67  "S-1-5-13", // Terminal Server Users
68  "S-1-5-14", // Remote Interactive Logon
69 
70  "S-1-5-15", // This Organization
71 
72  "S-1-5-80-0", // All Services
73  "S-1-5-83-0", // NT Virtual Machine\Virtual Machines
74  "S-1-5-90-0" // Windows Manager\Windows Manager Group
75 
76  );
77 
78  // Any SIDs with the following prefixes are group SID and should be excluded.
79  private static final Set<String> GROUP_SID_PREFIX = ImmutableSet.of(
80  "S-1-5-32", // Builtin
81  "S-1-5-87" // Task ID prefix
82 
83  );
84 
85  // SIDS that begin with a domain SID prefix and have on of these
86  private static final String DOMAIN_SID_PREFIX = "S-1-5";
87  private static final Set<String> DOMAIN_GROUP_SID_SUFFIX = ImmutableSet.of(
88  "-512", // Domain Admins
89  "-513", // Domain Users
90 
91  "-514", // Domain Guests
92  "-515", // Domain Computers
93  "-516", // Domain Controllers
94  "-517", // Cert Publishers
95 
96  "-518", // Schema Admins
97  "-519", // Enterprise Admins
98  "-520", // Group Policy Creator Owners
99 
100  "-526", // Key Admins
101  "-527", // Enterprise Key Admins
102 
103  "-533", // RAS and IAS Servers
104 
105  // Windows 2008 and later
106  "-498", // Enterprise Read-only Domain Controllers
107  "-521", // Read-only Domain Controllers
108  "-571", // Allowed RODC Password Replication Group
109  "-572", // Denied RODC Password Replication Group
110 
111  // Windows 2012 and later
112  "-522" // Cloneable Domain Controllers
113  );
114 
115 
116 
117  // Some windows SID indicate special account.
118  // These should be handled differently from regular user accounts.
119  private static final Map<String, String> SPECIAL_SIDS_MAP = ImmutableMap.<String, String>builder()
120  .put("S-1-5-18", "Local System Account")
121  .put("S-1-5-19", "Local Service Account")
122  .put("S-1-5-20", "Network Service Account")
123  .build();
124 
125  private static final Map<String, String> SPECIAL_SID_PREFIXES_MAP = ImmutableMap.<String, String>builder()
126  .put("S-1-5-80", "Service Virtual Account")
127  .put("S-1-5-82", "IIS AppPool Virtual Account")
128  .put("S-1-5-83", "Virtual Machine Virtual Account")
129  .put("S-1-5-90", "Window Manager Virtual Account")
130  .put("S-1-5-94", "WinRM Virtual accountt")
131  .put("S-1-5-96", "Font Driver Host Virtual Account")
132  .build();
133 
141  static boolean isWindowsSpecialSid(String sid) {
142  String tempSID = stripWindowsBackupPostfix(sid);
143 
144  if (SPECIAL_SIDS_MAP.containsKey(tempSID)) {
145  return true;
146  }
147  for (String specialPrefix: SPECIAL_SID_PREFIXES_MAP.keySet()) {
148  if (tempSID.startsWith(specialPrefix)) {
149  return true;
150  }
151  }
152 
153  // All the prefixes in the range S-1-5-80 to S-1-5-111 are special
154  tempSID = tempSID.replaceFirst(DOMAIN_SID_PREFIX + "-", "");
155  String subAuthStr = tempSID.substring(0, tempSID.indexOf('-'));
156  Integer subAuth = Optional.ofNullable(subAuthStr).map(Integer::valueOf).orElse(0);
157  if (subAuth >= 80 && subAuth <= 111) {
158  return true;
159  }
160 
161 
162  return false;
163  }
164 
172  static String getWindowsSpecialSidName(String sid) {
173  String tempSID = stripWindowsBackupPostfix(sid);
174 
175  if (SPECIAL_SIDS_MAP.containsKey(tempSID)) {
176  return SPECIAL_SIDS_MAP.get(tempSID);
177  }
178  for (Entry<String, String> specialPrefixEntry: SPECIAL_SID_PREFIXES_MAP.entrySet()) {
179  if (tempSID.startsWith(specialPrefixEntry.getKey())) {
180  return specialPrefixEntry.getValue();
181  }
182  }
183  return "";
184  }
185 
195  static boolean isWindowsUserSid(String sid) {
196 
197  String tempSID = stripWindowsBackupPostfix(sid);
198 
199  if (GROUP_SIDS.contains(tempSID)) {
200  return false;
201  }
202 
203  for (String prefix: GROUP_SID_PREFIX) {
204  if (tempSID.startsWith(prefix)) {
205  return false;
206  }
207  }
208 
209  // check for domain groups - they have a domains specific identifier but have a fixed prefix and suffix
210  if (tempSID.startsWith(DOMAIN_SID_PREFIX)) {
211  for (String suffix : DOMAIN_GROUP_SID_SUFFIX) {
212  if (tempSID.endsWith(suffix)) {
213  return false;
214  }
215  }
216  }
217 
218  return true;
219 
220  }
221 
235  public static String getWindowsRealmAddress(String sid) throws TskCoreException {
236 
237  String realmAddr;
238  String tempSID = stripWindowsBackupPostfix(sid);
239 
240  // When copying realms into portable cases, the SID may already be set to the special windows string.
241  if (isWindowsSpecialSid(tempSID) || tempSID.equals(SPECIAL_WINDOWS_REALM_ADDR)) {
242  realmAddr = SPECIAL_WINDOWS_REALM_ADDR;
243  } else {
244  // regular SIDs should have at least 5 components: S-1-x-y-z
245  if (org.apache.commons.lang3.StringUtils.countMatches(tempSID, "-") < 4) {
246  throw new TskCoreException(String.format("Invalid SID %s for a host/domain", tempSID));
247  }
248  // get the sub authority SID
249  realmAddr = sid.substring(0, tempSID.lastIndexOf('-'));
250  }
251 
252  return realmAddr;
253  }
254 
263  private static String stripWindowsBackupPostfix(String sid) {
264  String tempSID = sid;
265 
266  if(tempSID.endsWith(SPECIAL_WINDOWS_BACK_UP_POSTFIX)) {
267  tempSID = tempSID.replace(SPECIAL_WINDOWS_BACK_UP_POSTFIX, "");
268  }
269 
270  return tempSID;
271  }
272 
273 }

Copyright © 2011-2021 Brian Carrier. (carrier -at- sleuthkit -dot- org)
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.