Skip to content

Commit

Permalink
Fixed bug causing the pipe connection attempt in MonoLoaderDLL from f…
Browse files Browse the repository at this point in the history
…ailing if the injector is run as admin
  • Loading branch information
AWilliams17 committed Aug 7, 2019
1 parent f32991c commit c1ca2e9
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 25 deletions.
Binary file modified MonoJabber/.vs/MonoJabber/v15/.suo
Binary file not shown.
Binary file modified MonoJabber/.vs/MonoJabber/v15/Browse.VC.db
Binary file not shown.
53 changes: 28 additions & 25 deletions MonoJabber/MonoJabber/MonoJabber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ uintptr_t GetMonoLoaderFuncAddress(const std::string &MONO_LOADER_DLL_PATH, cons
uintptr_t injectedLoaderBase = mProcessFunctions::mGetModuleAddress(INJECTEE_HANDLE, "MonoLoaderDLL.dll");
uintptr_t funcAddress = injectedLoaderBase + funcOffset;
FreeLibrary(loaderModule);

return funcAddress;
}

Expand All @@ -59,14 +60,30 @@ std::string GetMonoLoaderDLLPath() {
}

HANDLE CreatePipe(const std::string &PIPENAME) {
// Give access to everyone so that running as admin does not prevent the injected DLL
// in a non-admin application from connecting.
PSECURITY_DESCRIPTOR pSecurityDesc = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);

if (!pSecurityDesc ||
!InitializeSecurityDescriptor(pSecurityDesc, SECURITY_DESCRIPTOR_REVISION) ||
!SetSecurityDescriptorDacl(pSecurityDesc, TRUE, NULL, FALSE)) {

return NULL;
}

SECURITY_ATTRIBUTES securityAttributes;
securityAttributes.nLength = sizeof(securityAttributes);
securityAttributes.lpSecurityDescriptor = pSecurityDesc;
securityAttributes.bInheritHandle = FALSE;

HANDLE hPipe = ::CreateNamedPipe(PIPENAME.c_str(),
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
1,
4096,
4096,
1,
NULL);
&securityAttributes);

return hPipe;
}
Expand All @@ -77,6 +94,7 @@ LoaderArguments CreateArgsStruct(char* program_args[]) {
strcpy_s(loaderArgs.LOADER_NAMESPACE, program_args[3]);
strcpy_s(loaderArgs.LOADER_CLASSNAME, program_args[4]);
strcpy_s(loaderArgs.LOADER_METHODNAME, program_args[5]);

return loaderArgs;
}

Expand All @@ -103,13 +121,6 @@ bool IsTarget64Bit(const HANDLE &TARGET_PROCESS) {
}
}

std::string CreatePipeName() {
DWORD currentPID = ::GetCurrentProcessId();
std::string pipeName = "MLPIPE_" + std::to_string(currentPID);

return pipeName;
}

int main(int argc, char* argv[]) {
printf(" -=MonoJabber=-\n");

Expand All @@ -121,20 +132,14 @@ int main(int argc, char* argv[]) {
EndApplication();
}

// Doing this until I can fix https://github.com/AWilliams17/MonoJabber/issues/1
printf(
"~~Warning: If this application is run as an administrator, "
"it is possible that it will hang when waiting for the pipe to be connected to from the DLL.~~\n"
);

// Create the arguments struct
const char *targetProcess = argv[1];
const char *dllPath = argv[2];
std::string monoLoaderDLLPath = GetMonoLoaderDLLPath();
LoaderArguments lArgs = CreateArgsStruct(argv);

// Create the pipe name and put it in the argument struct
std::string pipeName = "\\\\.\\pipe\\" + CreatePipeName();
std::string pipeName = "\\\\.\\pipe\\MLPIPE_" + std::to_string(::GetCurrentProcessId());
strcpy_s(lArgs.MLPIPENAME, pipeName.c_str());

int injecteePID = mProcessFunctions::mGetPID(targetProcess);
Expand Down Expand Up @@ -191,35 +196,33 @@ int main(int argc, char* argv[]) {
}
printf("Paramater struct written to target.\n");

// Grab MonoLoaderDLL.dll's Inject method offset, add it to the target's base,
// call it with the param struct, then close the handle.
// Grab MonoLoaderDLL.dll's Inject method offset, add it to the target's base...
uintptr_t targetFunctionAddress = GetMonoLoaderFuncAddress(monoLoaderDLLPath, injecteeHandle);

// ...call it with the param struct
CreateRemoteThread(injecteeHandle, NULL, 0, (LPTHREAD_START_ROUTINE)(targetFunctionAddress), addressOfParams, 0, NULL);
if (!mProcessFunctions::mValidateHandle(injecteeHandle)) {
printf("Error: CreateRemoteThread call failed - Handle is invalid. Last error code: %i\n", GetLastError());
return 1;
EndApplication();
}
else {
printf("CreateRemoteThread call succeeded - Creating pipe to receive results.\n");
HANDLE hPipe = CreatePipe(pipeName);
char buffer[1024];
DWORD dwRead;
if (hPipe != INVALID_HANDLE_VALUE) {
if (hPipe == INVALID_HANDLE_VALUE || hPipe == NULL) {
printf("Error: CreateNamedPipe call failed - Handle is invalid. Last error code: %i\n", GetLastError());
printf("This means you won't be able to see any error message from the DLL - it'll fail silently.\n");
} else {
ConnectNamedPipe(hPipe, NULL); // Block until connection is made. TODO: Make asynchronous... Or atleast have a timeout.
while (ReadFile(hPipe, buffer, sizeof(buffer) - 1, &dwRead, NULL) != FALSE) {
printf("-Received result from MonoLoaderDLL-\n");
printf("MonoLoaderDLL says: %s\n", buffer);
}
} else {
printf("Error: CreateNamedPipe call failed - Handle is invalid. Last error code: %i\n", GetLastError());
printf("This means you won't be able to see any error message from the DLL - it'll fail silently.\n");
}
DisconnectNamedPipe(hPipe);
CloseHandle(hPipe);
}
CloseHandle(injecteeHandle);

printf("Done.\n");
return 0;
}
4 changes: 4 additions & 0 deletions MonoJabber/MonoJabber/MonoJabber.vcxproj.user
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@
<LocalDebuggerCommandArguments>"SCPSL.exe" "D:\Source\SCP-Exposed-Establishment\SCPEE\bin\\x64\Release\SCPEE.dll" "SCPEE.NotEvil" "EELoader" "Init"</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerCommandArguments>"SCPSL.exe" "D:\Source\SCP-Exposed-Establishment\SCPEE\bin\\x64\Release\SCPEE.dll" "SCPEE.NotEvil" "EELoader" "Init"</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>

0 comments on commit c1ca2e9

Please sign in to comment.