首页
社区
课程
招聘
7
[原创]开源一个基于C++的shellcode框架
发表于: 2021-7-29 18:00 21461

[原创]开源一个基于C++的shellcode框架

2021-7-29 18:00
21461

前言

最近工作中要经常编写shellcode,纯手工汇编编写shellcode太麻烦,又没有找到一个比较灵活的shellcode生成器框架,因此便有自己动手写了一个简单的基于C++的框架。已经使用了一段时间并没有发现什么问题,现在将代码开源。

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
SC_MAIN_BEGIN()
{
    // *** Place function declaration here! ***
    UINT MyFunc(VOID);
 
    SC_IMPORT_API_BATCH_BEGIN();
    SC_IMPORT_API_BATCH("User32.dll", MessageBoxA);
    SC_IMPORT_API_BATCH("User32.dll", MessageBoxW);
    SC_IMPORT_API_BATCH("Kernel32.dll", ExitProcess);
    SC_IMPORT_API_BATCH_END();
 
    // *** Place code here! ***
    MessageBoxA(NULL, SC_PISTRINGA("Hello Ansi!"), SC_PISTRINGA("Hello!"), MB_OK);
    MessageBoxW(NULL, SC_PISTRINGW(L"Hello Unicode!"), SC_PISTRINGW(L"Hello!"), MB_OK);
 
    ExitProcess(MyFunc());
}
 
// *** Place function definition here! ***
SC_NOINLINE UINT MyFunc(VOID) { return 0; }
 
SC_MAIN_END()

上述代码的主要功能是调用两次MessageBox(一次用的是Ansi版本一次是Unicode版本)然后调用ExitProcess结束进程。可以看出来,使用该C++框架编写shellcode基本上除了前面的导入API代码后续代码就与常规C++没有区别了。考虑到从PE文件中手动提取shellcode也挺麻烦,因此增加了一个提取shellcode的python脚本,添加到了vs中的Post-Build Event中(代码仓库中的src目录下有配置好的vs2019项目),在编译成功后可自动提取shellcode到编译目录下(*.sh)。

编译环境

由于MSVC没有关闭SSE指令集的编译选项(使用SSE指令集会导致长字符串被存储到只读区段,然后在通过SSE指令集拷贝到栈中,如果有大佬知道怎么关闭SSE指令集希望一个指点一下),因此只能使用Clang编译器,所幸vs2019可以一键安装Clang编译器,还是比较方便的。有几个比较重要的编译选项一定要改,其余的看个人喜好,暂时未发现对生成的代码有较大影响:

  • /MT(d) /GS- /Gs1048576 -mno-sse
  • /O1(比O2生成的代码要小) /O2(RELEASE模式默认开启)

已知问题


[注意]看雪招聘,专注安全领域的专业人才平台!

最后于 2021-7-30 14:25 被windpiaoxue编辑 ,原因: 更新版本
收藏
免费 7
支持
分享
赞赏记录
参与人
雪币
留言
时间
東陽不列山
为你点赞!
2025-1-3 05:41
PLEBFE
为你点赞~
2022-7-30 07:06
mb_yzkjpdwg
为你点赞~
2021-9-8 12:50
Otoboku
为你点赞~
2021-8-20 16:44
wweifu
为你点赞~
2021-8-16 00:12
sinkay
为你点赞~
2021-8-2 18:31
欧阳休
为你点赞~
2021-8-2 18:03
最新回复 (15)
雪    币: 8715
活跃值: (8619)
能力值: ( LV13,RANK:570 )
在线值:
发帖
回帖
粉丝
2
支持开源~楼主666~
2021-7-29 21:40
0
雪    币: 15021
活跃值: (18236)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
3
MSF:终究是错付了
2021-7-29 23:24
1
雪    币: 914
活跃值: (2623)
能力值: ( LV5,RANK:68 )
在线值:
发帖
回帖
粉丝
4
已知问题
由于关闭了SSE指令集,导致无法进行浮点数运算。
可以调用函数(如代码中的MyFunc),但是无法获取函数指针。

那么设置回调,创建线程 就无法使用了吗?
2021-7-30 10:17
0
雪    币: 8511
活跃值: (5131)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
5
mark
2021-7-30 10:46
0
雪    币: 352
活跃值: (804)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
6
万剑归宗 已知问题 由于关闭了SSE指令集,导致无法进行浮点数运算。 可以调用函数(如代码中的MyFunc),但是无法获取函数指针。 那么设置回调,创建线程 就无法使用了吗?
x64下没问题,x86下目前有一个思路准备试试,如果可以用的话会更新上去。
2021-7-30 10:48
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
帮我改改火绒论坛上那个烂尾帖子呗
2021-7-30 12:00
0
雪    币: 352
活跃值: (804)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
8
已更新,支持动态获取函数指针
2021-8-2 11:24
0
雪    币: 29
活跃值: (24)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
mark
2021-8-2 17:28
0
雪    币: 48
活跃值: (2248)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
关闭sse  把o1改成od就可以了
2021-8-3 01:02
0
雪    币: 94
活跃值: (520)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11

改框架有个地方不太明白,就是对BYTE进行运算总会出错。例如

BYTE szTest[256]={0};//这里编译时会报错,说MEMSET不行

for (DWORD i=0;i<256;i++)

    szTest[i] ^= 0x71;//执行到这里总是出错退出

最后于 2023-5-25 15:02 被dico编辑 ,原因: 内容写错了
2023-5-24 15:47
0
雪    币: 94
活跃值: (520)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
另外,只要用到memcpy之类的API,总是会返回lld-link : error : undefined symbol: memcpy这样的编译错误。
2023-5-25 15:28
0
雪    币: 352
活跃值: (804)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
13
dico 另外,只要用到memcpy之类的API,总是会返回lld-link : error : undefined symbol: memcpy这样的编译错误。

BYTE szTest[256]={0}初始化的方式会被编译器转换成对memset的调用,memset和memcpy都是c标准库里的函数,不能在shellcode里使用

最后于 2023-9-9 18:01 被windpiaoxue编辑 ,原因:
2023-9-9 17:52
0
雪    币: 94
活跃值: (520)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
windpiaoxue dico 另外,只要用到memcpy之类的API,总是会返回lld-link : error : undefined symbol: memcpy ...
那请问我要对一个数组初始化赋值应该怎么做呢?
2023-10-9 11:33
0
雪    币: 29951
活跃值: (2792)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
15
写shellcode看来还是delphi好使,特别是涉及字符串。所有东西根本不用二次加工和提取和修复
2023-10-9 13:47
0
雪    币: 94
活跃值: (520)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
升级了VS后,编译居然出现了error : no member named 'index_sequence' in namespace 'std'这样的错误,以前都好好的。请问怎么解决呢?
2024-4-18 12:00
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册