首页
社区
课程
招聘
[原创]便捷稳定的 Shellcode 生成框架(windows)
发表于: 2022-3-19 14:19 22751

[原创]便捷稳定的 Shellcode 生成框架(windows)

2022-3-19 14:19
22751

shellcode-factory
dwm-screen-shot

位置无关,在执行或注入前无需进行任何额外的处理。

简洁小巧,可以轻松的在不同的功能中实现通用的功能。

MessageBox演示

image

dwm截屏演示

https://user-images.githubusercontent.com/46841563/159622629-b337380b-7ca2-4f3a-b043-d278be75a08f.mp4

21年中旬朋友在windows的dwm进程中发现一段异常执行的 "恶意代码",
在使用ida进行简单分析后得出结论:“该代码在dwm中 hook 相关渲染函数,恶意截取用户桌面画面”。
这段代码的来源指向了一款曾在2017年爆火网络的多人射击游戏,我们猜测其目的为:“截取用户游戏画面以判断用户是否在作弊”。
该shellcode引起了我的兴趣,它大概有如下特点:
| data types | ranges |
| ------- | ------- |
| .api | 0x0000 - 0x1D00 |
| .text | 0x1D00 - 0x2100 |
| .data | 0x2100 - 0x5000 |

在这个shellcode中,存在一些只会被链接进exe的清单文件,我猜测:“该shellcode的开发者先使用编译器编译并链接了一个不带crt的exe
之后对该exe进行加壳,最后使用exe to shellcode类的工具生成该代码。”

类似的 shellcode 的生成过程似乎不是很可靠 (将无意义的清单文件留存在shellcode中与我们编写shellcode的目的相背离),好奇心驱使下,我搜寻了 windows 下 的 shellcode 编写方法,结果不如人意。
有的人使用dll to shellcode框架或工具
有的人直接在c++代码中写下两个“标记函数”,之后将两个“标记函数”地址之间的bytes复制出来。
下面是一些常见的框架:

Cobalt Strike 生成 shellcode

MSVC 配合 Get-PEHeader生成shellcode

Win PE系列之导出表解析与ShellCode的编写及应用

基于C++的shellcode框架

我的目标是建立一个可以满足如下条件的shellcode生成框架:

coff全称 通用对象文件格式(Common Object File Format),我们常用的PE(exe,dll,sys,lib,obj)文件都属于coff,但我们这里要说的,是lib。
当我们在VS中将编译目标设置为lib时,.lib文件其实是个.obj文件的文件包,其中包含了你编译的所有.obj文件(也就是我们c++源代码.cpp所编译后的文件)。

.obj是 coff的一种,obj文件中包含我们编写的源代码编译后的字节码,其中包含了极其详细的符号信息:每个函数的名称、函数的字节码、静态数据的字节码、重定位信息、等等。

其实我们要做的事情很简单,将所有bytes从obj中提取出来,对相对寻址进行重定位就可以生成我们要的shellcode

使用 SC_EXPORT 标志公开函数

使用 SC_EXPORT_DATA 公开全局变量 不要在 .h 中使用SC_EXPORT_DATA

使用内嵌函数 内嵌函数的具体规则请自己查询,

使用新标准的c++代码,包括但不限于初始化列表、Lamda表达式、模板函数

使用多个.cpp文件,这代表你可以将不同的代码写在不同的cpp中

使用字符串、全局变量、导出全局变量相对shellcode的偏移

使用面向对象与C++ STL模板

使用开源库xorstr ,加密常量字符串

不要使用全局初始化,因为shellcode不能进行 CRT init

无法直接调用 系统API(这将在本框架优化后解决),暂时的调用api方法是 使用lazy_importer

无法使用 __declspec(thread) Tls线程局部储存关键字(但可以使用windows apiTlsAlloc TlsSetValue TlsGetValue)来解决

异常 try catch (没啥用,请忽略)

SDL检查(没啥用,请忽略)

基本运行时检查(没啥用,请忽略)

对x86的支持,后面可能会通过硬编码插入来解决

修改api导入策略,摆脱lazy_importer,实现可以在payload中直接使用api函数和crt函数的方法。

实现链接时混淆和虚拟化,这样我们可以将shellcode-generator(链接生成器)作为服务器功能,将payload.lib储存于服务器,每次执行shellcode获取都会生成完全不同的代码。(这个比较困难)

// 确保你已经安装了VS2019或以上 Make sure u have installed Visual Studio 2019 or later version
// 打开PowerShell并进入一个为项目准备的文件夹,依次输入以下命令, Enter the following commands in PowerShell
 
> git clone https://github.com/lainswork/shellcode-factory.git
 
> cd shellcode-factory
 
> devenv shellcode-factory.sln /build "Debug|x64" /Project shellcode-generator
 
> cd ./x64/Debug
 
> .\shellcode-generator
 
// 现在你得到了 ./x64/Debug/payload.hpp     Now, u get ./x64/Debug/payload.hpp
// 确保你已经安装了VS2019或以上 Make sure u have installed Visual Studio 2019 or later version
// 打开PowerShell并进入一个为项目准备的文件夹,依次输入以下命令, Enter the following commands in PowerShell
 
> git clone https://github.com/lainswork/shellcode-factory.git
 
> cd shellcode-factory
 
> devenv shellcode-factory.sln /build "Debug|x64" /Project shellcode-generator
 
> cd ./x64/Debug
 
> .\shellcode-generator
 
// 现在你得到了 ./x64/Debug/payload.hpp     Now, u get ./x64/Debug/payload.hpp
 
 
 
 
 
 
 
 
1.不要让我用二进制编辑器来手动提取bytes
2.它应该有扩展的可能性
3.生成的shellcode应该与位置无关,在使用时只需要进行: 映射-执行
4.要能使用全局变量(静态变量),因为我们可能使用静态字符串
5.尽可能的支持新的c++标准
1.不要让我用二进制编辑器来手动提取bytes
2.它应该有扩展的可能性
3.生成的shellcode应该与位置无关,在使用时只需要进行: 映射-执行
4.要能使用全局变量(静态变量),因为我们可能使用静态字符串
5.尽可能的支持新的c++标准
SC_EXPORT
DWORD ShellCodeEntryPoint(LPVOID lpParameter) {
    CHAR buf[256] = {0};
    LI_FN(sprintf)(buf, xorstr_( "函数%s 线程参数0x%p"), __FUNCDNAME__, lpParameter);
    LI_FN(MessageBoxA)(HWND(0), buf, xorstr_("来自shellcode的展示"), MB_OK);
    return 0;
}
 
SC_EXPORT
DWORD ShellCodeEntryPoint2(LPVOID lpParameter) {
    CHAR buf[256] = {0};
    LI_FN(sprintf)(buf, xorstr_("函数%s 线程参数0x%p"), __FUNCDNAME__, lpParameter);
    LI_FN(MessageBoxA)(HWND(0), buf, xorstr_("来自shellcode的展示"), MB_OK);
    return 0;
}
 
SC_EXPORT
DWORD ShellCodeEntryPoint3(LPVOID lpParameter) {
    CHAR buf[256] = {0};
    LI_FN(sprintf)(buf,xorstr_( "函数%s 线程参数0x%p"), __FUNCDNAME__, lpParameter);
    LI_FN(MessageBoxA)(HWND(0), buf, xorstr_("来自shellcode的展示"), MB_OK);
    return 0;
}
SC_EXPORT
DWORD ShellCodeEntryPoint(LPVOID lpParameter) {
    CHAR buf[256] = {0};
    LI_FN(sprintf)(buf, xorstr_( "函数%s 线程参数0x%p"), __FUNCDNAME__, lpParameter);
    LI_FN(MessageBoxA)(HWND(0), buf, xorstr_("来自shellcode的展示"), MB_OK);
    return 0;

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2022-3-23 12:58 被lainswork编辑 ,原因:
收藏
免费 11
支持
分享
最新回复 (20)
雪    币: 12848
活跃值: (9167)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
2
草,到底谁是恶意代码
2022-3-20 21:45
1
雪    币: 4134
活跃值: (5847)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
3
hzqst 草,到底谁是恶意代码
大黄牛出没
2022-3-20 22:31
0
雪    币: 231
活跃值: (640)
能力值: ( LV4,RANK:41 )
在线值:
发帖
回帖
粉丝
4

我上个月写了个类似的,不过没有用coff,用的elf格式,在windows下clang生成obj文件(linux一样), 然后解析一下处理导入导出,函数等,重定位可以参考elf32/64的重定位,解决完后按照PE的格式写导入导出表,或者自己定义格式, 把加载器自己编译一下自己就可以形成加载shellcode了, 再带上新的文件就可以想怎么加载就怎么加载

这样可以支持全局变量,未知函数(类似脚本函数导入),IAT导入,导出
不支持异常。

和你的思路很像,不过我没有用lib,只考虑了coff,coff加载可以参考 https://github.com/serge1/COFFI
不过我也没有采用coff,没elf解析爽

重定位32位可以采用模拟加载地址为0x0, 然后计算一下形成类似PE的重定位表,加载的时候写入就可以了。


函数导出可以采用static和非static来分别导出,或者使用clang的属性来分辨

最后于 2022-3-21 09:29 被wx_卖女孩的小火柴_588616编辑 ,原因:
2022-3-21 09:28
1
雪    币: 4776
活跃值: (4474)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
这段恶意代码有签名吗?
2022-3-21 09:32
0
雪    币: 264
活跃值: (654)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
wx_卖女孩的小火柴_588616 我上个月写了个类似的,不过没有用coff,用的elf格式,在windows下clang生成obj文件(linux一样), 然后解析一下处理导入导出,函数等,重定位可以参考elf32/ ...
解析obj文件和解析lib文件是一样的,但解析lib相当于对obj的打包。之所以解析lib是因为方便后续加强为能链接多个lib的框架~~~ ,最终实现将带crt 的普通lib也链接进shellcode,最最后可以制造出一个完美的shellcode链接器以期实现对任何的不做特殊处理的C++代码进行链接。
32位下的重定位可能需要插入一些硬编码来完成。shellcode-factory的宗旨是在执行器执行时不需要做任何额外工作,包括重定位工作。否则就和写个pe链接器没区别了,那样还不如直接使用dll注入。
2022-3-22 14:54
0
雪    币: 264
活跃值: (654)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
木志本柯 这段恶意代码有签名吗?
你要把它加进黑名单数据库嘛?
2022-3-22 14:55
0
雪    币: 264
活跃值: (654)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
hzqst 草,到底谁是恶意代码
在不经用户同意下,将代码注入到系统关键进程,并截取用户屏幕画面。它不是恶意代码谁是恶意代码呢?
它的代码是可以看到你整个屏幕上的内容的,不止是游戏窗口。
不管你是看小视频、聊天、商业谈判、代码、还是不为人知的任何事,都会被一览无余~~~
2022-3-22 14:58
1
雪    币: 429
活跃值: (2272)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
9
善意注入,恶意截屏是吧
2022-3-22 15:26
1
雪    币: 264
活跃值: (654)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
劫局丶 善意注入,恶意截屏是吧
恶意注入恶意截屏
2022-3-22 18:29
0
雪    币: 264
活跃值: (654)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
劫局丶 善意注入,恶意截屏是吧

从去年开始,我在不作弊的情况下玩吃鸡会被不停封号,进游戏,几分钟后就会永久封禁。这种情况是随机出现的。但是毕竟PC上这么多开发工具,也不算是清白,也认了。最后帮我把网瘾戒掉了。
分析蓝洞截屏的时候发现吧,我发现照着蓝洞的反汇编代码写并不能完成截屏。最后我通过尝试其他版本PC发现,蓝洞的hook点是非全系统兼容的,个别版本的电脑不执行它的hook函数,就会封号。好家伙,合着蓝洞靠封号创收啊,RNM蓝洞,退钱!

最后于 2022-3-22 18:37 被lainswork编辑 ,原因:
2022-3-22 18:36
1
雪    币: 429
活跃值: (2272)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
12
lainswork 劫局丶 善意注入,恶意截屏是吧 从去年开始,我在不作弊的情况下玩吃鸡会被不停封号,进游戏,几分钟后就会永久封禁。这种情况是随机出现的。但是毕竟P ...
现在免费了,冲他
2022-3-23 13:26
0
雪    币: 2428
活跃值: (2597)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
这两个项目都很有意思啊,牛逼
2022-3-23 14:26
0
雪    币: 2745
活跃值: (1846)
能力值: ( LV12,RANK:298 )
在线值:
发帖
回帖
粉丝
14
mark
2022-3-24 16:52
0
雪    币: 457
活跃值: (2793)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
X86编译不过额。。。
2022-3-29 15:31
0
雪    币: 264
活跃值: (654)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
saloyun X86编译不过额。。。
X86不能用,看ReadMe.md里写的
2022-3-29 19:53
0
雪    币: 1555
活跃值: (3118)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
17
貌似Twitter某大牛最近刚推的。
2022-3-30 22:01
0
雪    币: 264
活跃值: (654)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
zhenwo 貌似Twitter某大牛最近刚推的。
发链接瞅瞅
2022-4-1 09:18
0
雪    币: 1555
活跃值: (3118)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
19
lainswork 发链接瞅瞅
ShellcodeTemplate - An Easily Modifiable Shellcode Template For Windows X64/X86  点进去看了下,内容不一样,当时只看了下Twitter的小标题。
2022-4-2 17:04
0
雪    币: 219
活跃值: (434)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
厉害, 雀氏厉害
2023-1-26 21:35
0
雪    币: 222
活跃值: (315)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
21
厉害, 雀氏厉害。大佬什么时候继续开发啊,我等不及了。呜呜呜呜呜
2023-9-8 16:37
0
游客
登录 | 注册 方可回帖
返回
//