[c++] Problem mit CreateRemoteThread

06/19/2010 22:10 Gajanist#1
Hallo,
ich beschäftige mich zur Zeit ein wenig mit Code Injection / dll injection. Dazu habe ich folgendes Tutorial von dieser Seite durchgearbeitet:
[Only registered and activated users can see links. Click Here To Register...]

Das Problem ist jetzt, dass CreateRemoteThread NULL zurück gibt. Wenn ich GetLastError() aufrufe, bekomme ich den Error-Code 0, was bedeuten würde, dass die Funktion einwandfrei funktioniert. Ich bin echt ratlos an was das liegen könnte und ich hoffe mir kann jemand weiterhelfen.

Zusätliche Informationen:
Windows XP SP3
Visual C++ 2008 Express Edition
06/20/2010 17:02 MrSm!th#2
Du brauchst in 99% der Fälle mindestens Debug Privilegien ;)
Ein einfaches OpenProcess reicht nicht, meistens musst du spezielle Tokens ändern.

schau dir mal das hier an ;)
[Only registered and activated users can see links. Click Here To Register...]
06/20/2010 17:39 Gajanist#3
Quote:
Originally Posted by MrSm!th View Post
Du brauchst in 99% der Fälle mindestens Debug Privilegien ;)
Ein einfaches OpenProcess reicht nicht, meistens musst du spezielle Tokens ändern.
Die Debug-Privilegien hab ich, wird auch am Ende des Tutorials noch erklärt.
Alle verwendeten Funktionen bis auf CreateRemoteThread liefern auch ein gültiges Handle zurück.
06/20/2010 23:40 Bot_interesierter#4
Welche Rechte holst du dir bei OpenProcess? Du musst natürlich auch die PROCESS_CREATE_THREAD, PROCESS_QUERY_INFORMATION, PROCESS_VM_OPERATION, PROCESS_VM_WRITE, PROCESS_VM_READ Rechte anfordern damit CreateRemoteThread funktioniert.
Außerdem wäre es schön wenn du deinen Source Code posten würdest, dann kann man viel besser helfen, so müssen wir mehr oder weniger Raten was der Fehler ist, da du ja auch keine wirklich brauchbaren Error Messages hast.
06/21/2010 01:47 Gajanist#5
Bei OpenProcess habe ich seither PROCESS_ALL_ACCESS verwendet. Auch mit den Änderungen, die Bot_interesierter vorgeschlagen hat, hats leider nicht funktioniert.

Hier mein Source-Code:
Code:
const char Path[] = "C:\\Message Box.dll";

int main()
{
	PROCESSENTRY32 p32;
	DWORD processId = NULL;
	HANDLE hSnapshot;
	
	p32.dwSize = sizeof(p32);
	hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
	
	Process32First(hSnapshot,&p32);
	if(!strcmp("notepad.exe",p32.szExeFile))
	{
		processId = p32.th32ProcessID;
	}else
	{
		while(Process32Next(hSnapshot,&p32))
		{
			if(!strcmp("notepad.exe",p32.szExeFile))
			{
				processId = p32.th32ProcessID;
				break;
			}
		}
	}

	if(processId == NULL)
	{
		printf("Zielprozess wurde nicht gefunden\n");
		pause();
		return -1;
	}
	
	if(!insertDll(processId,Path))
	{
		printf("Dll konnte nicht injected werden!\n");
	}else
		printf("Dll injected!\n");
	pause();
	return 0;
}
Und ganz wichtig insertDll:

Code:
bool insertDll(DWORD procID, std::string dll)
{
    HMODULE hLocKernel32 = GetModuleHandle("kernel32.dll");
    FARPROC hLocLoadLibrary = GetProcAddress(hLocKernel32, "LoadLibraryA");
    
    HANDLE hToken;
    TOKEN_PRIVILEGES tkp;
    if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    {
        LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
        tkp.PrivilegeCount = 1;
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        AdjustTokenPrivileges(hToken, 0, &tkp, sizeof(tkp), NULL, NULL);
    }

    HANDLE hProc = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, procID);

    dll += '\0';
    LPVOID hRemoteMem = VirtualAllocEx(hProc, NULL, dll.size(), MEM_COMMIT, PAGE_READWRITE);

    DWORD numBytesWritten;
    WriteProcessMemory(hProc, hRemoteMem, dll.c_str(), dll.size(), &numBytesWritten);
    HANDLE hRemoteThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)hLocLoadLibrary, hRemoteMem, 0, NULL);

    bool res = false;
    if (hRemoteThread)
        res = (bool)WaitForSingleObject(hRemoteThread, INFINITE);
	else
	{
		DWORD err = GetLastError();
		LPVOID MsgBuf;
		FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
		NULL,err,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR) &MsgBuf,0, NULL );
		printf("%s",(LPSTR)MsgBuf);
	}
    VirtualFreeEx(hProc, hRemoteMem, dll.size(), MEM_RELEASE);

    CloseHandle(hProc);

    return res;
}
Wenn ich das Programm ausführe, kommen die beiden Fehlermeldungen

Der Vorgang wurde erfolgreich beendet. und Dll konnte nicht injected werden!

Die dll "Message Box.dll" ist die Dll aus dem Tutorial, dass ich in meinem ersten Post verlinkt habe. Könnte es vll. auch an der dll liegen und wenn ja, gibt es ne Möglichkeit zu testen, ob es mit der Dll überhaupt funktioniert?
06/21/2010 03:06 MrSm!th#6
Vielleicht hast du keine Rechte, die Tokens überhaupt zu ändern?
Woher weißt du, dass OpenProcessToken einen gültigen Handle zurückgibt, wenn du keine Error-Prüfungen machst?

Klick mal auf den Link, den ich geposted habe, da steht auch, wie man sich die Rechte zum Tokenändern holt ;)
Falls das auch nicht klappt, würde ich hinte jeden API Call auch eine Fehlerprüfung mit GetLastError machen.

Mich wundert allerdings auch, dass CreateRemoteThread bei dir NULL und trotzdem ERROR_SUCCESS zurückgibt.
06/21/2010 12:46 Gajanist#7
Quote:
Originally Posted by MrSm!th View Post
Vielleicht hast du keine Rechte, die Tokens überhaupt zu ändern?
Ich hab mir das Tutorial, das du gepostet hast, noch einmal genau durchgelesen, aber ich finde den Teil nicht den du meinst. Was meinst du also genau damit?

Quote:
Originally Posted by MrSm!th View Post
Woher weißt du, dass OpenProcessToken einen gültigen Handle zurückgibt, wenn du keine Error-Prüfungen machst?
OpenProcessToken gibt ja NULL zurück, wenn es fehlschlägt. In dem Code, den ich gepostet habe, habe ich zwar die else-Verzweigung vergessen, aber auch mit ändert es nichts. Das Handle ist wohl gültig.

Noch etwas:
Ich habe die exe und die Dll auf meinen anderen Rechner kopiert. Dort erhalte ich bzgl. CreateRemoteThread die Fehlermeldung "Zugriff verweigert". Ich weiß jetzt nicht, ob es daran liegt, dass auf dem Rechner Win7 läuft, aber vll. hilfts ja weiter.
06/21/2010 16:47 MrSm!th#8
Quote:
OpenProcessToken gibt ja NULL zurück, wenn es fehlschlägt. In dem Code, den ich gepostet habe, habe ich zwar die else-Verzweigung vergessen, aber auch mit ändert es nichts. Das Handle ist wohl gültig.
Quote:
Originally Posted by Gajanist View Post
Code:
bool insertDll(DWORD pr
    if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    {
        LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
        tkp.PrivilegeCount = 1;
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        AdjustTokenPrivileges(hToken, 0, &tkp, sizeof(tkp), NULL, NULL);
    }

    HANDLE hProc = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, procID);
Stimmt nicht; du gibst dir die Privilegien nicht, wenn OpenProcessToken NULL zurückgibt; das wars dann aber auch.
Der Prozess-Handle wird trotzdem geholt und du willst trotzdem einen RemoteThread erstellen.
Was nun, wenn OpenProcessToken fehlschlägt? - Du gibst dir nicht die nötigen Rechte, versuchst die Injection aber trotzdem ;)

Quote:
Die dll "Message Box.dll" ist die Dll aus dem Tutorial, dass ich in meinem ersten Post verlinkt habe. Könnte es vll. auch an der dll liegen und wenn ja, gibt es ne Möglichkeit zu testen, ob es mit der Dll überhaupt funktioniert?
Nein, dann würde LoadLibrary einen Fehler zurückgeben, aber nicht CreateRemoteThread...

Quote:
Originally Posted by Gajanist View Post
Ich hab mir das Tutorial, das du gepostet hast, noch einmal genau durchgelesen, aber ich finde den Teil nicht den du meinst. Was meinst du also genau damit?
Schau dir mal den Code an ;)
Die Funktion GetProcessHandleWithEnoughRights; die ruft Funktionen auf, die einem im Notfall die richtigen Rechte verschaffen.


Quote:
Noch etwas:
Ich habe die exe und die Dll auf meinen anderen Rechner kopiert. Dort erhalte ich bzgl. CreateRemoteThread die Fehlermeldung "Zugriff verweigert". Ich weiß jetzt nicht, ob es daran liegt, dass auf dem Rechner Win7 läuft, aber vll. hilfts ja weiter.
führst du es als admin aus?
06/21/2010 18:13 Gajanist#9
1) Also, ich habe meinen Code mal dergestalt erweitert, dass ich den Code
übernommen habe. Jetzt erhalte ich die Fehlermeldung, dass das Handle
ungültig ist.
Jedoch habe ich den Code trotz Google und Lesen des Tutorials noch nicht
so ganz verstanden. Was ist da genau anders?

2) Auch wenn ich die exe auf meinem zweiten Rechner als Admin ausführe
(Rechtsklick->Als Administrator ausführen), bleibt es dabei: "Zugriff
verweigert"
06/22/2010 21:09 MrSm!th#10
1)
Na siehst du, also liegt es wohl wirklich an irgendwelchen Zugriffen.
Darf ich fragen, in was du injecten willst?
Der Code gibt dir grob gesagt, die Rechte, bestimmte Rechte zu ändern.
Dann holst du dir Debug Privilegien.

2)
In was willst du injecten?
06/24/2010 09:57 Gajanist#11
Also, wie gesagt beschäftige ich mich noch nicht sehr lange mit Codeinjection - genau gesagt habe ich mir ein paar Tutorials durchgeschaut und finde dass das, welches ich im Ausgangspost verlinkt habe, ziemlich gut in die Materie einführt. Ich will eigentlich nur das Tutorial nachprogrammieren, d.h. die dll aus dem Tutorial in notepad.exe injecten. Allerdings bekomm ich den Code auch mit Debugrechten nicht zum laufen.
Die Dll ist ja im Anhang des Tutorials verlinkt. Ich habe sie nicht selbst programmiert, sondern verwende diese aus dem Tutorial.