WinAPI CreateThread 杀进程
WinAPI CreateThread killing process
我正在尝试编写一个执行任意 shellcode 的 C# 函数。它似乎工作正常,只是当创建的线程退出时,整个进程终止。这段代码不是我自己想出来的,而是主要从这个网站得到的:https://webstersprodigy.net/2012/08/31/av-evading-meterpreter-shell-from-a-net-service/
这里是执行shellcode的函数:
public void ExecuteShellCode(String code)
{
//pipe msfvenom raw to xxd -p -c 999999 (for example)
byte[] shellcode = StringToByteArray(code);
UInt32 funcAddr = VirtualAlloc(0, (UInt32)shellcode.Length, 0x1000, 0x40);
Marshal.Copy(shellcode, 0, (IntPtr)(funcAddr), shellcode.Length);
IntPtr hThread = IntPtr.Zero;
UInt32 threadId = 0;
hThread = CreateThread(0, 0, funcAddr, IntPtr.Zero, 0, ref threadId);
WaitForSingleObject(hThread, 0xFFFFFFFF);
}
我使用以下示例调用它:
(注意 - 你可能不应该 运行 来自互联网的随机 shellcode,这个例子是无害的,但你不应该相信我的话)
我用 msfvenom 生成了 shellcode - 它只是弹出一个消息框。
rsh.ExecuteShellCode(@"d9eb9bd97424f431d2b27731c9648b71308b760c8b761c8b46088b7e208b36384f1875f35901d1ffe1608b6c24248b453c8b54287801ea8b4a188b5a2001ebe334498b348b01ee31ff31c0fcac84c07407c1cf0d01c7ebf43b7c242875e18b5a2401eb668b0c4b8b5a1c01eb8b048b01e88944241c61c3b20829d489e589c2688e4e0eec52e89fffffff894504bb7ed8e273871c2452e88effffff894508686c6c20416833322e64687573657230db885c240a89e656ff550489c250bba8a24dbc871c2452e85fffffff686f6b582031db885c240289e368732158206869656e64687920467268486f776431c9884c240e89e131d252535152ffd031c050ff5508");
while (true)
{
Thread.Sleep(42);
}
如果您需要将字符串转换为字节的代码,请在此处:
private static byte[] StringToByteArray(String opcodes)
{
int NumberChars = opcodes.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(opcodes.Substring(i, 2), 16);
return bytes;
}
我的想法:
我觉得我的程序的 return 地址需要以某种方式在 shellcode 中指定,因为 shellcode 正在终止整个进程。我用 msfvenom 尝试了所有 "EXITFUNC" 参数,包括 SEH、进程和线程……但没有成功。我的示例 shellcode 有问题吗?有没有
CreateThread 当然不是杀进程。这是你的 shellcode (x86
) 最后调用 ExitProcess
。所以过程是退出。你的 shellcode 的第一个字节也是垃圾——你需要修复它。如果你不想退出进程 - 你需要在最后删除 ExitProcess
调用并更正 return。
我还声称这个 shellcode 搜索 kernel32.dll
的方式是不正确的。
你的 shellcode 所做的一切(除了第一个错误的字节):
MessageBoxA(0, "Howdy Friends!", "ok", 0);ExitProcess(0);
如果有人修改它(删除 ExitProcess
、恢复寄存器和堆栈以及 return)——我们可以获得下一个代码(c 或 c++)
static const char sc[] =
"60e80000000031d2b27031c9648b71308b760c8b761c8b46088b7e208b36384f1875f35901d1ffe1"
"608b6c24248b453c8b54287801ea8b4a188b5a2001ebe334498b348b01ee31ff31c0fcac84c07407"
"c1cf0d01c7ebf43b7c242875e18b5a2401eb668b0c4b8b5a1c01eb8b048b01e88944241c61c3b208"
"29d489e589c2688e4e0eec52e89fffffff894504bb7ed8e273871c2452e88effffff894508686c6c"
"20416833322e64687573657230db885c240a89e656ff550489c250bba8a24dbc871c2452e85fffff"
"ff686f6b582031db885c240289e368732158206869656e64687920467268486f776431c9884c240e"
"89e131d252535152ffd083c43c61c3";
if (PVOID pv = VirtualAlloc(0, (sizeof(sc) - 1) >> 1, MEM_COMMIT, PAGE_EXECUTE_READWRITE))
{
ULONG cb = (sizeof(sc) - 1) >> 1;
if (CryptStringToBinaryA(sc, sizeof(sc) - 1, CRYPT_STRING_HEX, (PBYTE)pv, &cb, 0, 0))
{
if (FlushInstructionCache(NtCurrentProcess(), pv, cb))
{
(FARPROC(pv))();
}
}
VirtualFree(pv, 0, MEM_RELEASE);
}
sellcode怎么搜索KERNEL32.DLL
当然不对:
PLIST_ENTRY InInitializationOrderModuleList = &RtlGetCurrentPeb()->Ldr->InInitializationOrderModuleList, entry = InInitializationOrderModuleList;
_LDR_DATA_TABLE_ENTRY* ldte;
do
{
entry = entry->Flink;
ldte = CONTAINING_RECORD(entry, _LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
} while (*RtlOffsetToPointer(ldte->BaseDllName.Buffer, 24)); // assume that this is `KERNEL32.DLL`
我正在尝试编写一个执行任意 shellcode 的 C# 函数。它似乎工作正常,只是当创建的线程退出时,整个进程终止。这段代码不是我自己想出来的,而是主要从这个网站得到的:https://webstersprodigy.net/2012/08/31/av-evading-meterpreter-shell-from-a-net-service/
这里是执行shellcode的函数:
public void ExecuteShellCode(String code)
{
//pipe msfvenom raw to xxd -p -c 999999 (for example)
byte[] shellcode = StringToByteArray(code);
UInt32 funcAddr = VirtualAlloc(0, (UInt32)shellcode.Length, 0x1000, 0x40);
Marshal.Copy(shellcode, 0, (IntPtr)(funcAddr), shellcode.Length);
IntPtr hThread = IntPtr.Zero;
UInt32 threadId = 0;
hThread = CreateThread(0, 0, funcAddr, IntPtr.Zero, 0, ref threadId);
WaitForSingleObject(hThread, 0xFFFFFFFF);
}
我使用以下示例调用它:
(注意 - 你可能不应该 运行 来自互联网的随机 shellcode,这个例子是无害的,但你不应该相信我的话)
我用 msfvenom 生成了 shellcode - 它只是弹出一个消息框。
rsh.ExecuteShellCode(@"d9eb9bd97424f431d2b27731c9648b71308b760c8b761c8b46088b7e208b36384f1875f35901d1ffe1608b6c24248b453c8b54287801ea8b4a188b5a2001ebe334498b348b01ee31ff31c0fcac84c07407c1cf0d01c7ebf43b7c242875e18b5a2401eb668b0c4b8b5a1c01eb8b048b01e88944241c61c3b20829d489e589c2688e4e0eec52e89fffffff894504bb7ed8e273871c2452e88effffff894508686c6c20416833322e64687573657230db885c240a89e656ff550489c250bba8a24dbc871c2452e85fffffff686f6b582031db885c240289e368732158206869656e64687920467268486f776431c9884c240e89e131d252535152ffd031c050ff5508");
while (true)
{
Thread.Sleep(42);
}
如果您需要将字符串转换为字节的代码,请在此处:
private static byte[] StringToByteArray(String opcodes)
{
int NumberChars = opcodes.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(opcodes.Substring(i, 2), 16);
return bytes;
}
我的想法:
我觉得我的程序的 return 地址需要以某种方式在 shellcode 中指定,因为 shellcode 正在终止整个进程。我用 msfvenom 尝试了所有 "EXITFUNC" 参数,包括 SEH、进程和线程……但没有成功。我的示例 shellcode 有问题吗?有没有
CreateThread 当然不是杀进程。这是你的 shellcode (x86
) 最后调用 ExitProcess
。所以过程是退出。你的 shellcode 的第一个字节也是垃圾——你需要修复它。如果你不想退出进程 - 你需要在最后删除 ExitProcess
调用并更正 return。
我还声称这个 shellcode 搜索 kernel32.dll
的方式是不正确的。
你的 shellcode 所做的一切(除了第一个错误的字节):
MessageBoxA(0, "Howdy Friends!", "ok", 0);ExitProcess(0);
如果有人修改它(删除 ExitProcess
、恢复寄存器和堆栈以及 return)——我们可以获得下一个代码(c 或 c++)
static const char sc[] =
"60e80000000031d2b27031c9648b71308b760c8b761c8b46088b7e208b36384f1875f35901d1ffe1"
"608b6c24248b453c8b54287801ea8b4a188b5a2001ebe334498b348b01ee31ff31c0fcac84c07407"
"c1cf0d01c7ebf43b7c242875e18b5a2401eb668b0c4b8b5a1c01eb8b048b01e88944241c61c3b208"
"29d489e589c2688e4e0eec52e89fffffff894504bb7ed8e273871c2452e88effffff894508686c6c"
"20416833322e64687573657230db885c240a89e656ff550489c250bba8a24dbc871c2452e85fffff"
"ff686f6b582031db885c240289e368732158206869656e64687920467268486f776431c9884c240e"
"89e131d252535152ffd083c43c61c3";
if (PVOID pv = VirtualAlloc(0, (sizeof(sc) - 1) >> 1, MEM_COMMIT, PAGE_EXECUTE_READWRITE))
{
ULONG cb = (sizeof(sc) - 1) >> 1;
if (CryptStringToBinaryA(sc, sizeof(sc) - 1, CRYPT_STRING_HEX, (PBYTE)pv, &cb, 0, 0))
{
if (FlushInstructionCache(NtCurrentProcess(), pv, cb))
{
(FARPROC(pv))();
}
}
VirtualFree(pv, 0, MEM_RELEASE);
}
sellcode怎么搜索KERNEL32.DLL
当然不对:
PLIST_ENTRY InInitializationOrderModuleList = &RtlGetCurrentPeb()->Ldr->InInitializationOrderModuleList, entry = InInitializationOrderModuleList;
_LDR_DATA_TABLE_ENTRY* ldte;
do
{
entry = entry->Flink;
ldte = CONTAINING_RECORD(entry, _LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
} while (*RtlOffsetToPointer(ldte->BaseDllName.Buffer, 24)); // assume that this is `KERNEL32.DLL`