首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WinAPI CreateThread杀灭过程

WinAPI CreateThread杀灭过程
EN

Stack Overflow用户
提问于 2017-03-14 22:22:34
回答 1查看 1.1K关注 0票数 1

我试图编写一个执行任意外壳代码的C#函数。它似乎正在工作,只是当创建的线程退出时,整个进程就终止了。我不是自己想出这段代码的,而是主要从这个站点获得的:https://webstersprodigy.net/2012/08/31/av-evading-meterpreter-shell-from-a-net-service/

下面是执行外壳代码的函数:

代码语言:javascript
复制
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);
}

我使用以下示例对其进行了命名:

(注意-你可能不应该从互联网上随机运行外壳代码,这个例子是无害的,但你不应该相信我的话)

我用msfvenom生成了外壳代码-它只是弹出一个消息框。

代码语言:javascript
复制
rsh.ExecuteShellCode(@"d9eb9bd97424f431d2b27731c9648b71308b760c8b761c8b46088b7e208b36384f1875f35901d1ffe1608b6c24248b453c8b54287801ea8b4a188b5a2001ebe334498b348b01ee31ff31c0fcac84c07407c1cf0d01c7ebf43b7c242875e18b5a2401eb668b0c4b8b5a1c01eb8b048b01e88944241c61c3b20829d489e589c2688e4e0eec52e89fffffff894504bb7ed8e273871c2452e88effffff894508686c6c20416833322e64687573657230db885c240a89e656ff550489c250bba8a24dbc871c2452e85fffffff686f6b582031db885c240289e368732158206869656e64687920467268486f776431c9884c240e89e131d252535152ffd031c050ff5508");

while (true)
{
    Thread.Sleep(42);
}

如果需要代码将字符串转换为字节,则如下所示:

代码语言:javascript
复制
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;
}

我的想法:

我觉得有一些问题,我的程序的返回地址需要在whole代码中指定,因为外壳代码正在扼杀整个过程。我用msfvenom尝试了所有的"EXITFUNC“参数,包括SEH、Process和Thread.但没有运气。我的示例外壳代码有问题吗?在那里吗

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-15 02:45:45

CreateThread当然不是杀灭过程。这是您的外壳代码(x86)在末尾调用ExitProcess。所以过程就是退出。另外,你的外壳代码的第一个字节是垃圾-你需要修复它。如果您不想退出进程--您需要在结束时删除ExitProcess调用并正确返回。

此外,我还声称这个外壳代码搜索kernel32.dll的方式是不正确的。

所有shellcode代码所做的事情(除了第一个错误字节之外):

代码语言:javascript
复制
MessageBoxA(0, "Howdy Friends!", "ok", 0);ExitProcess(0);

如果有人修改它(删除ExitProcess、恢复寄存器和堆栈并返回)--我们可以得到下一个代码(c或c++)。

代码语言:javascript
复制
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的方式是不正确的:

代码语言:javascript
复制
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`
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42797671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档