Skip to content

Commit 732bb28

Browse files
authored
Allowing desired access to be passed to SAM and LSA handles (#124)
Allowing desired access to be passed to SAM and LSA handles
1 parent 84e7c72 commit 732bb28

File tree

5 files changed

+131
-23
lines changed

5 files changed

+131
-23
lines changed

src/main/java/com/rapid7/client/dcerpc/mserref/SystemErrorCode.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -999,7 +999,8 @@ public enum SystemErrorCode {
999999
STATUS_NO_SUCH_PRIVILEGE(0xC0000060),
10001000
STATUS_NO_SUCH_ALIAS(0xC0000151),
10011001
STATUS_NO_SUCH_GROUP(0xC0000066),
1002-
STATUS_NONE_MAPPED(0xC0000073);
1002+
STATUS_NONE_MAPPED(0xC0000073),
1003+
STATUS_NO_SUCH_DOMAIN(0xC00000DF);
10031004

10041005

10051006
private final int value;

src/main/java/com/rapid7/client/dcerpc/mslsad/LocalSecurityAuthorityService.java

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
* @see <a href= "https://msdn.microsoft.com/en-us/library/cc234420.aspx">[MS-LSAT]</a>
5656
*/
5757
public class LocalSecurityAuthorityService extends Service {
58-
private final static int MAXIMUM_ALLOWED = 33554432;
58+
public final static int MAXIMUM_ALLOWED = 33554432;
5959

6060
/**
6161
* Create a new {@link LocalSecurityAuthorityService} backed by the provided {@link RPCTransport}
@@ -67,14 +67,43 @@ public LocalSecurityAuthorityService(final RPCTransport transport) {
6767
}
6868

6969
/**
70-
* Open a new {@link PolicyHandle}.
70+
* Open a new {@link PolicyHandle} for the local machine.
71+
* Uses {@link LocalSecurityAuthorityService#MAXIMUM_ALLOWED} as the desired access.
7172
*
7273
* @return A new {@link PolicyHandle}.
7374
* @throws IOException Thrown if either a communication failure is encountered, or the call
7475
* returns an unsuccessful response.
7576
*/
7677
public PolicyHandle openPolicyHandle() throws IOException {
77-
final LsarOpenPolicy2Request request = new LsarOpenPolicy2Request(WChar.NullTerminated.of(""), MAXIMUM_ALLOWED);
78+
return openPolicyHandle(MAXIMUM_ALLOWED);
79+
}
80+
81+
/**
82+
* Open a new {@link PolicyHandle} for the local machine.
83+
*
84+
* @param desiredAccess The desired access for the handle.
85+
* @return A new {@link PolicyHandle}.
86+
* @throws IOException Thrown if either a communication failure is encountered, or the call
87+
* returns an unsuccessful response.
88+
*/
89+
public PolicyHandle openPolicyHandle(final int desiredAccess) throws IOException {
90+
return openPolicyHandle("", desiredAccess);
91+
}
92+
93+
/**
94+
* Open a new {@link PolicyHandle}.
95+
*
96+
* @param serverName The machine name of the host. Null or empty uses local.
97+
* @param desiredAccess The desired access for the handle.
98+
* @return A new {@link PolicyHandle}.
99+
* @throws IOException Thrown if either a communication failure is encountered, or the call
100+
* returns an unsuccessful response.
101+
*/
102+
public PolicyHandle openPolicyHandle(String serverName, final int desiredAccess) throws IOException {
103+
if (serverName == null)
104+
serverName = "";
105+
final LsarOpenPolicy2Request request =
106+
new LsarOpenPolicy2Request(WChar.NullTerminated.of(serverName), desiredAccess);
78107
return parsePolicyHandle(callExpectSuccess(request, "LsarOpenPolicy2").getHandle());
79108
}
80109

src/main/java/com/rapid7/client/dcerpc/mssamr/SecurityAccountManagerService.java

Lines changed: 92 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
import static com.rapid7.client.dcerpc.mserref.SystemErrorCode.ERROR_SUCCESS;
105105

106106
public class SecurityAccountManagerService extends Service {
107-
private final static int MAXIMUM_ALLOWED = 33554432;
107+
public final static int MAXIMUM_ALLOWED = 33554432;
108108

109109
/**
110110
* Create a new {@link SecurityAccountManagerService} backed by the provided {@link RPCTransport}
@@ -127,19 +127,33 @@ public ServerHandle openServer() throws IOException {
127127

128128
/**
129129
* Open a new {@link ServerHandle} using the provided NETBIOS name of the server.
130+
* Uses {@link SecurityAccountManagerService#MAXIMUM_ALLOWED} as desired access.
130131
* @param serverName NETBIOS name of the server. Most targets ignore this value so an empty string is suggested.
131132
* @return A new {@link ServerHandle} for the given server identified by serverName.
132133
* @throws IOException Thrown if either a communication failure is encountered, or the call
133134
* returns an unsuccessful response.
134135
*/
135-
public ServerHandle openServer(String serverName) throws IOException {
136+
public ServerHandle openServer(final String serverName) throws IOException {
137+
return openServer(serverName, MAXIMUM_ALLOWED);
138+
}
139+
140+
/**
141+
* Open a new {@link ServerHandle} using the provided NETBIOS name of the server.
142+
* @param serverName NETBIOS name of the server. Most targets ignore this value so an empty string is suggested.
143+
* @param desiredAccess The desired access represented as a bitmask.
144+
* @return A new {@link ServerHandle} for the given server identified by serverName.
145+
* @throws IOException Thrown if either a communication failure is encountered, or the call
146+
* returns an unsuccessful response.
147+
*/
148+
public ServerHandle openServer(final String serverName, final int desiredAccess) throws IOException {
136149
final SamrConnect2Request request =
137-
new SamrConnect2Request(parseWCharNT(serverName), MAXIMUM_ALLOWED);
150+
new SamrConnect2Request(parseWCharNT(serverName), desiredAccess);
138151
return parseServerHandle(callExpectSuccess(request, "SamrConnect2"));
139152
}
140153

141154
/**
142155
* Open a new {@link DomainHandle} against a valid domain identified by the provided {@link SID}.
156+
* Uses {@link SecurityAccountManagerService#MAXIMUM_ALLOWED} as desired access.
143157
* @param serverHandle A valid server handle obtained from {@link #openServer()}
144158
* @param domainId A valid {@link SID} which identifies the domain.
145159
* Use {@link #getDomainsForServer(ServerHandle)} if you need to discover them.
@@ -148,44 +162,100 @@ public ServerHandle openServer(String serverName) throws IOException {
148162
* returns an unsuccessful response.
149163
*/
150164
public DomainHandle openDomain(final ServerHandle serverHandle, final SID domainId) throws IOException {
165+
return openDomain(serverHandle, domainId, MAXIMUM_ALLOWED);
166+
}
167+
168+
/**
169+
* Open a new {@link DomainHandle} against a valid domain identified by the provided {@link SID}.
170+
* @param serverHandle A valid server handle obtained from {@link #openServer()}
171+
* @param domainId A valid {@link SID} which identifies the domain.
172+
* Use {@link #getDomainsForServer(ServerHandle)} if you need to discover them.
173+
* @param desiredAccess The desired access represented as a bitmask.
174+
* @return A new {@link DomainHandle} for the resolved domain.
175+
* @throws IOException Thrown if either a communication failure is encountered, or the call
176+
* returns an unsuccessful response.
177+
*/
178+
public DomainHandle openDomain(final ServerHandle serverHandle, final SID domainId, final int desiredAccess)
179+
throws IOException {
151180
final SamrOpenDomainRequest request =
152-
new SamrOpenDomainRequest(parseHandle(serverHandle), MAXIMUM_ALLOWED, parseSID(domainId));
181+
new SamrOpenDomainRequest(parseHandle(serverHandle), desiredAccess, parseSID(domainId));
153182
return parseDomainHandle(callExpectSuccess(request, "SamrOpenDomain"));
154183
}
155184

156185
/**
157186
* Open a new {@link GroupHandle} against a valid group identified by both the
158187
* provided {@link DomainHandle} and groupRID.
188+
* Uses {@link SecurityAccountManagerService#MAXIMUM_ALLOWED} as desired access.
159189
* @param domainHandle A valid domain handle obtained from {@link #openDomain(ServerHandle, SID)}.
160190
* @param groupRID A relative identifier for the group.
161191
* @return A new {@link GroupHandle} for the resolved group.
162192
* @throws IOException Thrown if either a communication failure is encountered, or the call
163193
* returns an unsuccessful response.
164194
*/
165195
public GroupHandle openGroup(final DomainHandle domainHandle, final long groupRID) throws IOException {
196+
return openGroup(domainHandle, groupRID, MAXIMUM_ALLOWED);
197+
}
198+
199+
/**
200+
* Open a new {@link GroupHandle} against a valid group identified by both the
201+
* provided {@link DomainHandle} and groupRID.
202+
* @param domainHandle A valid domain handle obtained from {@link #openDomain(ServerHandle, SID)}.
203+
* @param groupRID A relative identifier for the group.
204+
* @param desiredAccess The desired access represented as a bitmask.
205+
* @return A new {@link GroupHandle} for the resolved group.
206+
* @throws IOException Thrown if either a communication failure is encountered, or the call
207+
* returns an unsuccessful response.
208+
*/
209+
public GroupHandle openGroup(final DomainHandle domainHandle, final long groupRID, final int desiredAccess)
210+
throws IOException {
166211
final SamrOpenGroupRequest request =
167-
new SamrOpenGroupRequest(parseHandle(domainHandle), MAXIMUM_ALLOWED, groupRID);
212+
new SamrOpenGroupRequest(parseHandle(domainHandle), desiredAccess, groupRID);
168213
return parseGroupHandle(callExpectSuccess(request, "SamrOpenGroupRequest"));
169214
}
170215

171216
/**
172217
* Open a new {@link UserHandle} against a valid user identified by both the
173218
* provided {@link DomainHandle} and userRID.
219+
* Uses 0x2011B as desired access.
174220
* @param domainHandle A valid domain handle obtained from {@link #openDomain(ServerHandle, SID)}.
175221
* @param userRID A relative identifier for the group.
176222
* @return A new {@link UserHandle} for the resolved user.
177223
* @throws IOException Thrown if either a communication failure is encountered, or the call
178224
* returns an unsuccessful response.
179225
*/
180226
public UserHandle openUser(final DomainHandle domainHandle, final long userRID) throws IOException {
227+
// Generic rights: 0x00000000
228+
// Standard rights: 0x00020000
229+
// SAMR User specific rights: 0x0000011b
230+
// Samr User Access Get
231+
// - Groups: SAMR_USER_ACCESS_GET_GROUPS is SET
232+
// - Attributes: SAMR_USER_ACCESS_GET_ATTRIBUTES is SET
233+
// - Logoninfo: SAMR_USER_ACCESS_GET_LOGONINFO is SET
234+
// <NDR: unsigned long> [in] unsigned long DesiredAccess
235+
return openUser(domainHandle, userRID, 0x2011B);
236+
}
237+
238+
/**
239+
* Open a new {@link UserHandle} against a valid user identified by both the
240+
* provided {@link DomainHandle} and userRID.
241+
* @param domainHandle A valid domain handle obtained from {@link #openDomain(ServerHandle, SID)}.
242+
* @param userRID A relative identifier for the group.
243+
* @param desiredAccess The desired access represented as a bitmask.
244+
* @return A new {@link UserHandle} for the resolved user.
245+
* @throws IOException Thrown if either a communication failure is encountered, or the call
246+
* returns an unsuccessful response.
247+
*/
248+
public UserHandle openUser(final DomainHandle domainHandle, final long userRID, final int desiredAccess)
249+
throws IOException {
181250
final SamrOpenUserRequest request =
182-
new SamrOpenUserRequest(parseHandle(domainHandle), userRID);
251+
new SamrOpenUserRequest(parseHandle(domainHandle), desiredAccess, userRID);
183252
return parseUserHandle(callExpectSuccess(request, "SamrOpenUserRequest"));
184253
}
185254

186255
/**
187256
* Open a new {@link AliasHandle} against a valid user identified by both the
188257
* provided {@link DomainHandle} and aliasRID.
258+
* Uses 0x0002000C as desired access.
189259
* @param domainHandle A valid domain handle obtained from {@link #openDomain(ServerHandle, SID)}.
190260
* @param aliasRID A relative identifier for the group.
191261
* @return A new {@link AliasHandle} for the resolved alias.
@@ -197,8 +267,23 @@ public AliasHandle openAlias(final DomainHandle domainHandle, final long aliasRI
197267
// SAMR Alias specific rights: 0x0000000c
198268
// - SAMR_ALIAS_ACCESS_LOOKUP_INFO is SET(8)
199269
// - SAMR_ALIAS_ACCESS_GET_MEMBERS is SET(4)
270+
return openAlias(domainHandle, aliasRID, 0x0002000C);
271+
}
272+
273+
/**
274+
* Open a new {@link AliasHandle} against a valid user identified by both the
275+
* provided {@link DomainHandle} and aliasRID.
276+
* @param domainHandle A valid domain handle obtained from {@link #openDomain(ServerHandle, SID)}.
277+
* @param aliasRID A relative identifier for the group.
278+
* @param desiredAccess The desired access represented as a bitmask.
279+
* @return A new {@link AliasHandle} for the resolved alias.
280+
* @throws IOException Thrown if either a communication failure is encountered, or the call
281+
* returns an unsuccessful response.
282+
*/
283+
public AliasHandle openAlias(final DomainHandle domainHandle, final long aliasRID, int desiredAccess)
284+
throws IOException {
200285
final SamrOpenAliasRequest request =
201-
new SamrOpenAliasRequest(parseHandle(domainHandle), 0x0002000C, aliasRID);
286+
new SamrOpenAliasRequest(parseHandle(domainHandle), desiredAccess, aliasRID);
202287
return parseAliasHandle(callExpectSuccess(request, "SamrOpenAlias"));
203288
}
204289

src/main/java/com/rapid7/client/dcerpc/mssamr/messages/SamrOpenUserRequest.java

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,29 +47,22 @@ public class SamrOpenUserRequest extends RequestCall<HandleResponse> {
4747
// <NDR: fixed array> [in] SAMPR_HANDLE DomainHandle
4848
private final byte[] domainHandle;
4949
// <NDR: unsigned long> [in] unsigned long DesiredAccess
50-
// Static
50+
private final int desiredAccess;
5151
// <NDR: unsigned long> [in] unsigned long UserId
5252
private final long userId;
5353

54-
public SamrOpenUserRequest(byte[] domainHandle, long userId) {
54+
public SamrOpenUserRequest(final byte[] domainHandle, final int desiredAccess, final long userId) {
5555
super(OP_NUM);
5656
this.domainHandle = domainHandle;
57+
this.desiredAccess = desiredAccess;
5758
this.userId = userId;
5859
}
5960

6061
@Override
6162
public void marshal(PacketOutput packetOut) throws IOException {
6263
packetOut.write(this.domainHandle);
63-
// Generic rights: 0x00000000
64-
// Standard rights: 0x00020000
65-
// SAMR User specific rights: 0x0000011b
66-
// Samr User Access Get
67-
// - Groups: SAMR_USER_ACCESS_GET_GROUPS is SET
68-
// - Attributes: SAMR_USER_ACCESS_GET_ATTRIBUTES is SET
69-
// - Logoninfo: SAMR_USER_ACCESS_GET_LOGONINFO is SET
70-
// <NDR: unsigned long> [in] unsigned long DesiredAccess
7164
// Alignment: 4 - Already aligned, wrote 20 bytes above
72-
packetOut.writeInt(0x2011B);
65+
packetOut.writeInt(desiredAccess);
7366
// <NDR: unsigned long> [in] unsigned long UserId
7467
// Alignment: 4 - Already aligned
7568
packetOut.writeInt(this.userId);

src/test/java/com/rapid7/client/dcerpc/mssamr/messages/Test_SamrOpenUser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
public class Test_SamrOpenUser {
3232
// https://msdn.microsoft.com/en-us/library/cc980032.aspx
33-
private final SamrOpenUserRequest request = new SamrOpenUserRequest(new byte[20], 500); //ADMINISTRATOR(500)
33+
private final SamrOpenUserRequest request = new SamrOpenUserRequest(new byte[20], 0x2011B, 500); //ADMINISTRATOR(500)
3434

3535
@Test
3636
public void getOpNum() {

0 commit comments

Comments
 (0)