Topic created on: April 25, 2008 19:37 CDT by apridgen  .
Hi, I was wondering if anyone could help me overcome my woes with DLL Injection. I am having some problems getting the DLL Injected into the process of another user. The wayI am doing it now works for any processes I own or create, but when I try to do it for another user, it fails.
For example, I am an Administrator, and I am trying to inject code into another user's process space, lets say 'numnutz' who is a back-up operator. When I try OpenProcess on the calc.exe process that numnutz started, I get an "Access Denied" error. So, I try to adjust my token's privileges to "SeDebugPrivilege", and it completes successfully. However, when I try to OpenProcess on numnutz's process again, I get the same error.
I am following the standard DLL Injection technique (1.FindPid, 2.OpenProcess, ...), and it works on processes I own, so I am trying to figure out how to inject DLLs into processes I don't own. Thanks in advance for any help.
don't open a process, man! everything you need - you have in _your_ address space. all windows-related data is mapped on every gui-process (as well as any console application loads USER32.DLL). of course, Windows tries to protect this area from intrusion (R-E attributes), but... it can't stop us :)
so, it's possible to inject code into any gui process via your own address space. Twister wrote an article (in rus) about it: https://wasm.ru/article.php?article=window_inject, describing how to inject shell-code ( try to translate it, using Google or http://translation.paralink.com/). he uses SetThreadContext(). not good!
I know how to do this without any such functions and going to write my own article.
|
@nezumi
Thanks for the article link, it's very interesting.
However I believe the author uses OpenThread there, so I guess it doesn't really solve the case, since if OpenProcess fails, OpenThread will most likely fail too.
@apridgen
I don't know how to fix the OpenProcess issue. However I can suggest using another method of DLL injection - system hooks. As stated in the MSDN, setting a windows hook (SetWindowsHook) causes the DLL with hook code to be loaded into every process in the system. It's a noisy method I'm afraid.
If You find the solution for OpenProcess issue, please post it here too ok ? ;> Thx
|
GynvaelColdwind
the point is: address space of every GUI process (or console process loaded USER32.DLL) has mapped area with windows data, including call-backs and I found the way how to modify these callbacks directly without using OpenProcess/OpenThread/SetThreadContext APIs. it's easy, but too long to be described here, I'm going to write an article, just tested this trick under Server 2008 and everything is fine, however, all offsets were changed, so injection becomes more complicated and system-depended and I don't know (yet) how to handle with. currently, I use symbols, distributed by MS, but it's very ugly idea, nothing more that dirty work around.
my goal is: to inject shell-code into Admin process under user account. it's possible, but still ugly and system-depended. I try to find more elegant solution to publish it.
apridgen
> If You find the solution for OpenProcess issue,
> please post it here too ok ?
I just ripped follow out of MSDN (see "How to Obtain a Handle to Any Process with SeDebugPrivilege"). this is not my code, however, it works fine. if you're under admin it opens any process, if you're not under admin, well, SetPrivilege says error, but you sill can open your processes.
/* open any process under admin */
#include <windows.h>
#include <stdio.h>
BOOL SetPrivilege(HANDLE hToken, LPCTSTR Privilege,
BOOL bEnablePrivilege)
{
DWORD cbPrevious=sizeof(TOKEN_PRIVILEGES);
LUID luid;TOKEN_PRIVILEGES tp;
TOKEN_PRIVILEGES tpPrevious;
if(!LookupPrivilegeValue( NULL, Privilege, &luid ))
return FALSE;
tp.Privileges[0].Attributes=0;
tp.PrivilegeCount=1;tp.Privileges[0].Luid=luid;
AdjustTokenPrivileges(hToken,FALSE,&tp,
sizeof(TOKEN_PRIVILEGES),&tpPrevious,&cbPrevious);
if (GetLastError() != ERROR_SUCCESS) return FALSE;
tpPrevious.PrivilegeCount=1;
tpPrevious.Privileges[0].Luid=luid;
if(bEnablePrivilege)
tpPrevious.Privileges[0].Attributes
|= (SE_PRIVILEGE_ENABLED);
else
tpPrevious.Privileges[0].Attributes
^=(SE_PRIVILEGE_ENABLED &
tpPrevious.Privileges[0].Attributes);
AdjustTokenPrivileges(hToken, FALSE,
&tpPrevious, cbPrevious, NULL, NULL);
if (GetLastError() != ERROR_SUCCESS) return FALSE;
return TRUE;
}
main(int c, char **v)
{
HANDLE h, hToken;
if (c < 2) return printf("USAGE: %s PID\n",v[0]);
if(!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return -1;
if(!SetPrivilege(hToken, SE_DEBUG_NAME, TRUE))
printf("-ERR: SetPrivilege\n");
h = OpenProcess(PROCESS_ALL_ACCESS,0, atol(v[1]));
return printf("handle == %08X\n",h);
}
how to build:
$cl.exe openproc.c advapi32.lib
|
nezumi:
Thanks. I was not Zero'ing the memory before I set all my values on the TOKEN_PRIVILEGES (doh!). Now, when I try to do CreateRemoteThread, I am getting a bogus error of 8 ("Not enough storage..."). I am looking into how to get around this issue, and I dug up some info under the remarks for CreateRemoteThread on MSDN. There was some information about Terminal Services and how it is not possible to perform CreateRemoteThread across sessions. So, I think I need to first enumerate the user's session, and then CreateProcessToken with my process in the session of the target. I found some sample code, so I will try and get that working sometime this weekend.
Thanks for your help everyone.
I also checked out the article, and it looked pretty interesting. I have to go back and re-read it, because I was trying to get figure out the issue with the DLL Injection nonsense.
|
@nezumi
Thats very interesting! I'm looking forward to your article about your method ;>
|
This is my first post. So, hello everyone :)
Speaking on the subject. Take into consideration that if your process us running in another session the standard injection via CreateRemoteThread will fail starting from Vista and higher. On XP it works.
Under different sessions I mean if your process is a NT service running in session 0 and you are trying to inject into process running in session 1 (explorer.exe for example).
A little reversing on the subject showed that one can use RtlCreateUserThread on Vista and higher to make it work.
> GynvaelColdwind: @nezumi
> Thats very interesting! I\'m looking forward to your article about your method ;>
|
|
nezumi come on, we are all waiting for your article
|
Note: Registration is required to post to the forums.
|