| | 1 | | using System; |
| | 2 | | using System.Collections.Generic; |
| | 3 | | using System.Linq; |
| | 4 | | using System.Runtime.InteropServices; |
| | 5 | | using SharpHoundRPC.Handles; |
| | 6 | |
|
| | 7 | | namespace SharpHoundRPC.NetAPINative |
| | 8 | | { |
| | 9 | | public static class NetAPIMethods |
| | 10 | | { |
| | 11 | | private const int NetWkstaUserEnumQueryLevel = 1; |
| | 12 | | private const int NetSessionEnumLevel = 10; |
| | 13 | | private const int NetWkstaGetInfoQueryLevel = 100; |
| | 14 | |
|
| | 15 | | [DllImport("netapi32.dll")] |
| | 16 | | internal static extern NetAPIEnums.NetAPIStatus NetApiBufferFree( |
| | 17 | | IntPtr buffer); |
| | 18 | |
|
| | 19 | | public static NetAPIResult<IEnumerable<NetWkstaUserEnumResults>> NetWkstaUserEnum(string computerName) |
| 0 | 20 | | { |
| 0 | 21 | | var resumeHandle = 0; |
| 0 | 22 | | var result = NetWkstaUserEnum(computerName, NetWkstaUserEnumQueryLevel, out var buffer, -1, |
| 0 | 23 | | out var entriesRead, out _, ref resumeHandle); |
| | 24 | |
|
| 0 | 25 | | if (result != NetAPIEnums.NetAPIStatus.Success && result != NetAPIEnums.NetAPIStatus.ErrorMoreData) |
| 0 | 26 | | return result; |
| | 27 | |
|
| 0 | 28 | | return NetAPIResult<IEnumerable<NetWkstaUserEnumResults>>.Ok(buffer |
| 0 | 29 | | .GetEnumerable<NetAPIStructs.WkstaUserInfo1>(entriesRead) |
| 0 | 30 | | .Select(x => new NetWkstaUserEnumResults(x.Username, x.LogonDomain))); |
| 0 | 31 | | } |
| | 32 | |
|
| | 33 | | [DllImport("netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] |
| | 34 | | private static extern NetAPIEnums.NetAPIStatus NetWkstaUserEnum( |
| | 35 | | string servername, |
| | 36 | | int level, |
| | 37 | | out NetAPIPointer buffer, |
| | 38 | | int preferredMaxLength, |
| | 39 | | out int entriesRead, |
| | 40 | | out int totalEntries, |
| | 41 | | ref int resumeHandle); |
| | 42 | |
|
| | 43 | | public static NetAPIResult<IEnumerable<NetSessionEnumResults>> NetSessionEnum(string computerName) |
| 0 | 44 | | { |
| 0 | 45 | | var resumeHandle = 0; |
| 0 | 46 | | var result = NetSessionEnum(computerName, null, null, NetSessionEnumLevel, out var buffer, -1, |
| 0 | 47 | | out var entriesRead, out _, ref resumeHandle); |
| | 48 | |
|
| 0 | 49 | | if (result != NetAPIEnums.NetAPIStatus.Success && result != NetAPIEnums.NetAPIStatus.ErrorMoreData) |
| 0 | 50 | | return result; |
| | 51 | |
|
| 0 | 52 | | return NetAPIResult<IEnumerable<NetSessionEnumResults>>.Ok(buffer |
| 0 | 53 | | .GetEnumerable<NetAPIStructs.SessionInfo10>(entriesRead) |
| 0 | 54 | | .Select(x => new NetSessionEnumResults(x.Username, x.CName))); |
| 0 | 55 | | } |
| | 56 | |
|
| | 57 | | [DllImport("NetAPI32.dll", SetLastError = true)] |
| | 58 | | private static extern NetAPIEnums.NetAPIStatus NetSessionEnum( |
| | 59 | | [MarshalAs(UnmanagedType.LPWStr)] string serverName, |
| | 60 | | [MarshalAs(UnmanagedType.LPWStr)] string uncClientName, |
| | 61 | | [MarshalAs(UnmanagedType.LPWStr)] string userName, |
| | 62 | | int level, |
| | 63 | | out NetAPIPointer buffer, |
| | 64 | | int preferredMaxLength, |
| | 65 | | out int entriesRead, |
| | 66 | | out int totalEntries, |
| | 67 | | ref int resumeHandle); |
| | 68 | |
|
| | 69 | | public static NetAPIResult<NetAPIStructs.WorkstationInfo100> NetWkstaGetInfo(string computerName) |
| 0 | 70 | | { |
| 0 | 71 | | var result = NetWkstaGetInfo(computerName, NetWkstaGetInfoQueryLevel, out var buffer); |
| | 72 | |
|
| 0 | 73 | | if (result != NetAPIEnums.NetAPIStatus.Success) return result; |
| | 74 | |
|
| 0 | 75 | | return buffer.GetData<NetAPIStructs.WorkstationInfo100>(); |
| 0 | 76 | | } |
| | 77 | |
|
| | 78 | | [DllImport("netapi32.dll", SetLastError = true)] |
| | 79 | | private static extern NetAPIEnums.NetAPIStatus NetWkstaGetInfo( |
| | 80 | | [MarshalAs(UnmanagedType.LPWStr)] string serverName, |
| | 81 | | uint level, |
| | 82 | | out NetAPIPointer bufPtr); |
| | 83 | |
|
| | 84 | | public static NetAPIResult<NetAPIStructs.DomainControllerInfo> DsGetDcName(string computerName, |
| | 85 | | string domainName, uint flags) |
| 1 | 86 | | { |
| 1 | 87 | | var result = DsGetDcName(computerName, domainName, null, null, flags, out var buffer); |
| 2 | 88 | | if (result != NetAPIEnums.NetAPIStatus.Success) return result; |
| | 89 | |
|
| 0 | 90 | | return buffer.GetData<NetAPIStructs.DomainControllerInfo>(); |
| 1 | 91 | | } |
| | 92 | |
|
| | 93 | | [DllImport("Netapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] |
| | 94 | | private static extern NetAPIEnums.NetAPIStatus DsGetDcName |
| | 95 | | ( |
| | 96 | | [MarshalAs(UnmanagedType.LPTStr)] string computerName, |
| | 97 | | [MarshalAs(UnmanagedType.LPTStr)] string domainName, |
| | 98 | | [In] NetAPIStructs.GuidClass domainGuid, |
| | 99 | | [MarshalAs(UnmanagedType.LPTStr)] string siteName, |
| | 100 | | uint flags, |
| | 101 | | out NetAPIPointer pDomainControllerInfo |
| | 102 | | ); |
| | 103 | | } |
| | 104 | | } |