I use advapi32.dll's logonuser method to access data over our network.
I know it change the thread's user to the information i give it, but i was wondering if there's a way to reverse it.
I want to access the data and then return to the local user credentials.
Some time ago I created a small impersonator class.
Basically you wrap your code to execute under another user simply inside a using block:
using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
{
...
<code that executes under the new context>
...
}
Worked very well for my projects.
You can call RevertToSelf.
That said, there is something to be said for spinning up a dedicated thread for the impersonation task, and terminating it when the impersonation work is complete. This will segregate the impersonation work so that if any callbacks or messages are processed on the main thread they will be performed in the context of the principal user rather than the impersonated user. In fact, the more I think about this the stronger I feel that a dedicated thread is the solution.
Related
Im trying to figure out how does Meterpreter execute cmd commands as System after impersonating the security context of that account (NT AUTHORITY\System) using the getsystem's technique 1: Service - Named Pipe Impersonation (In Memory/Admin).
For that, I've wrote a small C# code that creates a named pipe A , generates a new service B running as System and then forces the service B to write some data on A, which allows me to impersonate the client through the client impersonation funcionality for named pipes.
Now, once the impersonation is done, what I do have is a process whose primary token points to a local admin user (the user who is running the c# code, let's say its the user Administrator) and one thread of this process with an impersonation token that points to the System account. The activities executed by the thread that is impersonanting System obviously run under the security context of the impersonnated account, but if I want to execute a cmd command (let's say a trivial one like whoami) I need to spawn a new process in order to run cmd.exe. At that moment, the primary token for the new process is the primary token of my initial process and not the impersonation token from the thread impersonating System, therefore the output for the command whoami is Administrator instead of System.
I guess Meterpreter is not using CreateProcessAsUser since A) It only has an impersonation token, not a primary token (is there any way to turn an impersonation token into a primary token) and B) Some special privileges are required in order to use that function and I haved checked that none of the users of my computer have that privileges granted, despite that I have been able to elevate my privileges using this technique through Meterpreter.
So this leads me to the main question: How does Meterpreter execute cmd commands as System after using getsystem's technique 1?
After some (more) research, I think I got the answer for this question.
Although you need SE_INCREASE_QUOTA_NAME and SE_ASSIGNPRIMARYTOKEN_NAME in order to use CreateProcessAsUser (and noone of my user had granted that privileges), you can use the function CreateProcessWithTokenW which only requires SE_IMPERSONATE_NAME. I guess Meterpreter is using this one because this is actually a privilege that some of my users have granted and it seems a less restrictive function. I've been able to reproduces the getsystem behaviour using this API call through C#.
In the other hand, you can turn impersonation tokens into primary tokens (it also works in the other direction) by using DuplicateToken function.
I am working on an MVC web application which has to access files in various shared directories. Currently I am using this implementation of impersonation to access a directory, which works fine. My problem starts when I have to open multiple files from the same directory, since right now I initialize a new impersonator every time and I quickly reach the number of allowed connections to the target computer.
The code right now looks like:
// do stuff that does not require impersonation
using (Impersonation.LogonUser("domain", "username", "password", LogonType.NewCredentials))
{
// access **one** particular file
}
// continue doing stuff that does not require impersonation
However, if I use just one impersonation instance, I can access as many files as I want. This is though impractical for a web application, as I would have to run all my code under impersonation. Furthermore, different directories have different credentials (could also be located on different computers).
So my question is if it's possible to cache an impersonation, undo it for a while and re-enable it when I need to, so that I don't start a new one. Basically something like the following pseudo-code:
// do stuff that does not require impersonation
// get cached impersonation or create a new one
var imp = GetImpersonationFromStaticSharedCache("domain", "username", "password")
// access **one** particular file
// stop impersonation, but don't dispose it, so that I can re-use it later
imp.StopImpersonationForTheCurrentThread()
// continue doing stuff that does not require impersonation
How can I notify another application which is in different domain that current running application has crashed?
in the other words, Is it possible to negotiate two different applications in separate domain?
Thanks in advance.
You can use named pipes for this sort of IPC. For this, look into System.IO.Pipes namespace and excellent NamedsPipeServerStream & NamedPipeClientStream classes.
Note that you can use anonymous pipes only for inter process communications within the same domain, while you can use named pipes for IPC in separate domains (i.e. across PCs on the same intranet).
Yes it is possible. How well this is supported in .NET types will vary depending on how you are going to make the determination of "has crashed".
Basically the monitoring application needs to supply credentials suitable to access the system that should be running the monitored application. This is exactly what one would do to copy a file to/from another domain by starting with something like:
net use \\Fileserver1.domain2.com\IPC$ /user:DOMAIN\USER PASSWORD
or its API equaivalent.
If you use WMI (this is the obvious approach, it is easy to list the processes on a remote system with a query for Win32_Process) you can supply credentials (eg. with the scripting interface or in .NET).
You can use the AppDomain.UnhandledException event to signal the other AppDomain, possibly through a named Mutex. Since they're system-wide, you could create one called "MyAppHasCrashed" and lock it immediately. When you hit an unhandled exception, you release the mutex. On the other side, have a thread that waits on the mutex. Since it's initially blocked, the thread will sit waiting. When an exception occurs, the thread resumes and you can handle the crash.
Mutex crashed = new Mutex(true, "AppDomain1_Crashed");
...
private void AppDomain_UnhandledException(...)
{
// do whatever you want to log / alert the user
// then unlock the mutex
crashed.ReleaseMutex();
}
Then, on the other side:
void CrashWaitThread()
{
try {
crashed = Mutex.OpenExisting("AppDomain1_Crashed");
}
catch (WaitHandleCannotBeOpenedException)
{
// couldn't open the mutex
}
crashed.WaitOne();
// code to handle the crash here.
}
It's a bit of a hack, but it works nicely for both inter-domain and inter-process cases.
I am attempting to Impersonate an administrator account from a LocalSystem Service in order to get data from administrators HKEY CURRENT USER registry - in order to impersonate I am using the codeproject code found at the following site written by Uwe Keim: Impersonator
My source code is as follows:
using (new Impersonator("user", ".", "pass"))
{
RegistryKey rk = Registry.CurrentUser.OpenSubKey("Software\\CompanyName");
string sValue = rk.GetValue("Value", "").ToString();
rk2.Close();
}
My expectation was that sValue would be from the user/pass account (as I am impersonating it) but oddly enough it is still the sValue from the LocalSystem account where my service is runnning ...
Any clues on what I am doing wrong? Any help would be much appreciated.
Thanks,
I know this is an old thread but I recently came across the same issue (albeit from a C++ Windows service) and thought I'd share my findings, because many forums have asked the same question and none have left a satisfactory answer.
Basically, I've found two ways to approach this, though this is an answer more for C applications rather than .NET (I haven't tested with pinvoke but it may work).
Solution 1:
Instead of using RegOpenKey, use RegOpenCurrentUser() to get the key handle. Apparently, the reason RegOpenKey doesn't get the impersonated user's key is because HKEY_CURRENT_USER is cached in the running thread.
Solution 2:
RegDisablePredefinedCache(). This disables the cache mentioned above and lets subsequent calls to HKEY_CURRENT_USER be of the actual impersonated user. This is the solution I went with.
Hope this helps.
Everything I've read on the subject seems to indicate that impersonation should get you access to the HKEY_CurrentUser for the impersonated account. However, it could be a quirk in the .NET Registry implementation.
This is just a hunch, and an untested one at that, but have you considered using Registry.Users instead of Registry.CurrentUser?
You'll need to find the SID for the Administrator account, but you should be able to deduce that using Regedit
By default the HKEY_CURRENT_USER handle is cached on a process wide basis. So when you impersonate a user and then access the current user hive you will be accessing the hive of the user that started the process not the user being impersonated. This is true for all Win32 processes not just .Net. If you wish to disable this caching so that all current user calls go to the correct user hive under HKEY_USERS then you must call RegDisablePredefinedCache via pInvoke.
Be warned that if the user being impersonated has not had their profile loaded then any CurrentUser requests will be forwarded to the .DEFAULT user. So you may also need to call LoadUserProfile.
Disabling the handle caching will also cause a slight slowdown in all CurrentUser requests.
I'm guessing you're going to find that you're out of luck. It can't be done.
If applications were able to impersonate an Administrator account and write values to the Registry in Windows, it would present a huge security hole. My guess is that the Registry.CurrentUser property will ALWAYS reference the user running your application...whether or not you try impersonation or not.
EDIT
Turns out that I didn't read the implementation details of the Impersonator code you were using. Your problem could be something completely different.
Does your code refer to the Registry static class prior to your impersonation code being run? If so, that would be the problem. If you look at the Registry.CurrentUser property in Reflector, you'll see that it is set by the static constructor of the Registry object. Static constructors get called when the static object is first referenced.
In your case, if you're referencing the Registry object (whether it involves CurrentUser or not) the static constructor is being called which is setting CurrentUser to your original user...not the Impersonated account.
I am calling the SQL Server Reporting Services Webservice from inside an asp.net application. I need to fire off all the subscriptions for a given report. But I don't want the user to have to wait around for it to all happen, so I want to have all the webservice calls inside a separate thread, and return to the user straight away.
I am using code that looks something like this:
public static void FireAllAsync(string ReportPath)
{
Hashtable paramValues = new Hashtable();
ThreadPool.QueueUserWorkItem(new WaitCallback(FireAll), ReportPath);
}
public static void FireAll(object ReportPath)
{
ReportingService rs = new ReportingService();
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
Subscription[] SubList = rs.ListSubscriptions((string)ReportPath, null);
foreach (Subscription CurSub in SubList) {
rs.FireEvent(CurSub.EventType, CurSub.SubscriptionID);
}
}
Calling FireAll works fine, but trying to call FireAllAsync to use the Thread fails with a 401 error. I believe the problem with the credentials not getting passed through properly. ie this line of code here:
rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
I do not have a good understanding of how the credentials cache works, so I can't figure out why it doesn't like being in a separate thread.
I have tried grabbing the credentials in the outer function, and passing them through as an argument, but the same error occurs.
Does anyone have any ideas what may be happening?
When your primary thread is executing, it has an impersonation context prepared for it. In an authenticated scenario, IIS has authenticated the user, and then set the thread token - not the process token - for that user.
Because the thread token is set for the user, that thread can then act on behalf of the user (on the local box; acting on behalf of the user on another box requires delegation to be set up if Integrated Windows Authentication (NTLM/Kerberos) is used).
But, if you spin off a worker thread without any identity information, that worker thread will be spawned without its own token, so it'll use the process token.
If you can do what you need to do on the initial thread, you don't have a delegation problem, just a lack of the user token on the worker thread.
Threadpool threads will run as the process identity (NetworkService by default, so the computer account of the hosting machine, unless your App Pool is set to run as SomeUser, in which case all worker threads will run as SomeUser) - and if that user has access to whatever it is the initial user wants, all is good.
If not, 401sville.
There are web references that can help work around this, with various possible answers:
Link
http://aspalliance.com/articleViewer.aspx?aId=650&pId=2