I've heard that Windows ASLR is session-based: A DLL would be relocated only once in each session, subsequent linking to the same dll in the same session would reuse this cached relocation.
So I tried:
Write a small program to print the address of a DLL
Connect to the computer with RDP twice, each creates its' own session (confirmed by query session)
Call the program within different RDP sessions
What I expect:
Different addresses observed, since I'm in different sessions.
What actually happens:
The addresses are the same.
Why?
Related
We have a server that securely sends a key to the client via a custom login program. The key is subsequently used for encrypting further client requests. That key is kept on the client's disk, like a cookie, and is used by a program that might be started and stopped multiple times before the client decides to logout and cause the key to be obsolete (hence the key is saved on disk, because there may be long periods between login and logout when no program is running).
It would seem to be a bit more secure to keep the key only in memory instead of on disk (it's OK if a crash or restart loses the key and subsequently forces a new login).
On Windows, what's the best way to retain the key only in memory (ignoring that the memory might be virtual and paged to disk) between separate executions of a program?
One possible solution is to leave a trivial Windows service running on the client that accepts the key, retains it in the service's memory, and returns it upon request (or use an equivalent trivial DDE server that does the same thing). A non-.net solution is preferred.
Is there a standard Windows service usually running that already provides this ability?
Is there a better approach?
There are probably a couple of solutions you can try that does not involve a running process:
Store it in a volatile registry key (REG_OPTION_VOLATILE)
Store it in the global atom table. The key has to be stored as a string. You would probably require two atoms; one that stores the key and one used to locate the first atom so you can call GlobalGetAtomName. The second atom should have a known name like "YourAppName:S-UsersSidGoesHere" so you can call GlobalFindAtom.
If you decide to store it in a file in %temp% you could use TOKEN_STATISTICS.AuthenticationId as part of a key used to encrypt the real key. You could encrypt the file itself with EFS (FILE_ATTRIBUTE_ENCRYPTED)...
specifically i want to know if kernel32.dll load address can be different for two processes within the same session ?
I want to use createremote thread so just wanted to know if kernel32 load address in remote process can be different from the injecting process in any scenario ?
Kernel32.dll has the same base address on all processes to allow exactly what you'd like to do. Read: Why are certain DLLs required to be at the same base address system-wide?
System DLLs are loaded at random addresses (ASLRed) for security reasons so that a remote attacker can't guess where bits of code on your system are living in memory (i.e. remote attackers can't guess pointers on your computer).
This happens once per boot, and hence kernel32 will be loaded at the same address in all processes across your system.
I have a COM server LocalServer32 EXE started when a client application calls c_com_ptr::CreateInstance (using ATL wrappers.)
On Windows 7, when a second client application running under the same user account also calls c_com_ptr::CreateInstance, a second copy of the EXE is launched running under the same user account. I was under the impression, from a past life, that the second client would share the first EXE.
Is the LocalServer32 process shared, or not? When, or when not? Googling for an answer gives me a huge noise to signal ratio and I can't find the answer.
My CLSID registry key has the LocalServer32 value giving the EXE path, ProgID, Programmable (empty string), TypeLib (GUID), and a VersionIndependentProgId. I have an AppID key.
I do not want to run the EXE as a service, and I don't mind that the process is not shared. I just want to know the rules so I know what to expect (on Windows Server 2003 onwards.)
EDIT: Following Chris' answer below, I examined the CoRegisterClassObject call in my server. I'm using ATL, and I overrode MyServer::RegisterClassObjects to hook into the calling chain to CAtlExeModuleT::RegisterClassObjects and see that ATL is using CLSCTX_LOCAL_SERVER and REGCLS_MULTIPLEUSE.
Changing this to CLSCTX_LOCAL_SERVER and REGCLS_SINGLEUSE causes more processes to be started, depending on the number of COM objects created by the client, as expected.
Still, going back to REGCLS_MULTIPLEUSE, I get one COM server process per COM client process, each server process containing all of the COM objects for its client, as expected, except that if two COM clients are running under the same user account, they each get their own server which is not how I understood REGCLS_MULTIPLEUSE.
Could the difference be that the clients themselves are actually Windows services? (They are.) When a Windows service process running as a user account creates a COM object under REGCLS_MULTIPLEUSE, is this treated differently, causing the observed behavior? Why am I getting more than one process? (And just to clarify, I do not want my COM server to run as a Windows service, but the clients that use it do run as Windows services.)
Also, running the clients as either Local System, or Network Service, REGCLS_MULTIPLEUSE works as I would have expected: only a single COM server EXE process is started. The multiple processes are started when the COM clients are Windows services running under user accounts.
The routing of out-of-process activation requests is controlled by the registration of class objects with the COM Service Control Manager. If the SCM has a usable registered class object, that will be used to service the request. If it doesn't, it will start an exe process instance of the COM server to get one. Whether multiple activation requests are routed to a single COM server exe process therefore depends on the following factors at least (I'm not sure if this is a complete list):
the activation flags specified by the COM server when it calls CoRegisterClassObject to register with the SCM can cause future activation requests to result in a new exe process instance being started, the simplest and commonest case being the use of the flag REGCLS_SINGLEUSE, which allows the registered class object to be used for a single activation only.
Depending on how the class is registered, activation requests from different security contexts may be serviced by different COM server exe instances (it seems this won't apply in your scenario as your client applications run under the same security contexts).
How does this program access other processes memory? How can it write into the address space of another process? Wasn't it supposed to segfault or something?
A program with a system privilege level is capable of mapping physical addresses to its own virtual address.
Cheat O'Matic (and poke) maps the physical address of whatever program it is trying to scan into its own virtual space.
Once this is done, it scans all the bytes for the target value you enter. It isolates the correct memory address by asking the user to altering the address to known values and basically does a diff between the old and new memory to find the changes.
One way to do it is to inject a DLL (Google for 'Dll injection') into the address process that you want to spy on: that DLL is then inside the process and can do things with the process' memory. The spy process can use an Interprocess Communication method (pipes, sockets, anything) to talk with the DLL which it injected into the other process.
Injecting a DLL takes administrator priviledge (e.g. to set a relevent entry in the system registry).
I've developed a windows application that uses shared memory---that is---memory mapped files for interprocess communication. I have a windows service that does some processing and periodically writes data to the memory mapped file. I have a separate windows application that reads from the memory mapped file and displays the information. The application works as expected on Windows XP, XP Pro and Server 2003, but NOT on Vista.
I can see that the data being written to the memory mapped file is happening correctly by the windows service because I can open the file with a text editor and see the stored messages, but the "consumer" application can't read from the file. One interesting thing to note here, is that if I close the consumer application and restart it, it consumes the messages that were previously written to the memory mapped file.
Also, another strange thing is that I get the same behavior when I connect to the windows host using Remote Desktop and invoke/use the consumer application through remote desktop. However, if I invoke the Remote Desktop and connect to the target host's console session with the following command: mstsc -v:servername /F -console, everything works perfectly.
So that's why I think the problem is related to permissions. Can anyone comment on this?
EDIT:
The ACL that I'm using to create the memory mapped file and the Mutex objects that sychronize access is as follows:
TCHAR * szSD = TEXT("D:")
TEXT("(A;;RPWPCCDCLCSWRCWDWOGAFA;;;S-1-1-0)")
TEXT("(A;;GA;;;BG)")
TEXT("(A;;GA;;;AN)")
TEXT("(A;;GA;;;AU)")
TEXT("(A;;GA;;;LS)")
TEXT("(A;;GA;;;RD)")
TEXT("(A;;GA;;;WD)")
TEXT("(A;;GA;;;BA)");
I think this may be part of the issue.
So I found the solution to my problem:
On Windows XP, all named kernel objects such as mutex, semaphore and memory mapped objects are stored in the same namespace. So when different processes in different user sessions reference a particular object using it's name, they obtain a handle to that object. However, as a security precaution, Windows terminal services creates a separate namespace for kernel objects referenced from processes started in it's session. Windows Vista has this behavior built into it as well, so that's why my app didn't work correctly on Vista. To elaborate, I have a Windows service that runs in the null session and an application that runs in a user session, so my named objects were being created in separate namespaces.
The quick fix for this issue was to use the Global namespace by prepending "Global\" to each kernel object name that I used and that did the trick.
The prefix "Global\" may not work on shared memory. See "Impact of Session 0 Isolation on Services and Drivers in Windows Vista" for solution.
What access are you opening the shared memory section with? Try with FILE_MAP_ALL_ACCESS and work your way down. Also make sure you don't have a race condition between the producer and consumers - which one is creating the shared memory? Make sure ths is created before the other one tries to open it. One method is to create the section in the parent before you start the child process - if you are using a parent/child architecture.
Your child may need to run elevated on Vista in order to be allowed access to the shared memory. It may also be related to the window session your are using. Services run in session 0 (I think) while other apps (especially if you log in via remote desktop) may run in another session.
Have you tried moving the file to a different location. Try putting it in the 'Shared Documents' folder, this seems to be the most freely accessible folder in Vista.