首页
论坛
课程
招聘
[原创]windows下shellcode提取模板的实现
2018-6-29 13:35 10757

[原创]windows下shellcode提取模板的实现

2018-6-29 13:35
10757

Windows下的Shellcode一般用于在极小的空间内完成一些基本而重要的工作

除此之外也有别的好处,比如说代码加密以及代码隐藏

编写shellcode比起正常的编写代码来说算是件较为费事的工作,基本上来说需要协调较多东西。模板的意义在于做到将正常代码复制到模板中就可以生成可以直接Call的shellcode。

因为用汇编撰写shellcode比较麻烦。如果用C语言来撰写,则比较好。特别,对于类似病毒这种,远线程注入这种,如果能够用C语言来写,会方便很多。

后来一段时间我都用C语言来写,避开全局变量的调用,一遍又一遍的写K32寻址去加载需要的函数。后来觉得如果以这样的方式去转化一两个函数的代码能应付得过来,但是如果是转化几千行的整个项目的代码,这样的做的话需要花费时间太多。

所以将提取shellcode的方法写成模板,并尽可能加上C++特征。


以下是需要提取的代码的入口:

//加载起始函数,跳转到入口函数
VOID _declspec(naked) mmLoaderSCStart()
{
	__asm	jmp Strat;
}

//WIN_H里面定义dll函数


//将需要转为shellcode的所有代码放在这个类中
class MyShelocde
{
	//API寻址声明
#include"WIN_H.h"
public:
	WIN_H win;

public:
	
#include"Tool.h"

	//代码项目中其他文件放在类中
#include"AddMld.h"

	
public:
	//模拟全局变量---这里是对项目全局变量的定义
	char s_runexe[260];
	char s_szopen[260];
	char RandCIDStr[MAX_PATH];

public:
	//关于全局变量初始化以及一些开始的操作
	MyShelocde()
	{
		
		memset(RandCIDStr, 0, 260);

		memset(s_runexe, 0, 260);
		memset(s_szopen, 0, 260);

		char runexe[] = { 'c', 'm', 'd', '.', 'e', 'x', 'e', '\0' };
		char szopen[] = { 'o', 'p', 'e', 'n', '\0' };
		memcpy(s_runexe, runexe, strlen(runexe));
		memcpy(s_szopen, szopen, strlen(szopen));
		
	};
	~MyShelocde()
	{
	};

	
public:

	//提取项目的main文件,StartSCode相当于项目的main函数
	void __stdcall StartSCode(char * URL)
	{
                //自己的代码就放在这里,可以看到模板下使用API与正常一样,通过宏实现了去K32寻址
		//打开一下CMD
		ShellExecute(NULL, s_szopen, s_runexe, 0, NULL, SW_SHOW);

		MessageBoxA(NULL, s_runexe, NULL, NULL);
	}

};

//sehllcode入口函数
void __stdcall Strat(char * URL)
{
	//由于需要模拟全局变量,所以使用类包裹下
	MyShelocde runclass;
	runclass.StartSCode(URL);
}

void __declspec(naked) mmLoaderSCEnd()
{
	__asm int 3;
}

其他看附件,代码结构还算清晰,暂时用模板提取了一个2000多行代码的小项目,总的来说还是挺爽的,项目本身shellcode保存为任意形式,启用他的exe去掉DEF保护后调用直接call

void main()
	{
		char shelname[] = "123.bin";

		DWORD filelen = GetFileSizeLen(shelname);
		char *filebuf = new char[filelen];
		ReadFileData(shelname, filebuf);

		char URL[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

		typedef void(WINAPI* fnFun)(
			char*
			);
		fnFun Shellcode = (fnFun)(filebuf);
		Shellcode(URL);
	}

模板极大方便了提取shellcode的工作,并且能够支持全局变量。这样实现了转化甚至于一整个项目的代码,作用的话,依旧是代码加密以及隐藏,以及非常灵活的调用。


编写这个模板的缘故在于,需要做一个应用,客户端本身仅仅是与服务器交互的通讯模块,功能模块全部由shellcode构成,由服务器发送至客户端执行,并且如此的话客户端也需要与服务器连线才能发挥作用否则客户端本身无任何特别的代码,如此操作中间没有多余文件产生,仅仅是服务器与客户端的数据交流。

这样的设想需要编写的shellcode的量就比较大,所以没有合适的方法基本不能完成这样的工作。


附件中 doc是引用的学习文档,由此文档启发从而编写出来的。
更多是想抛砖引入玉,获得更多的建议以便更好地学习。



看雪侠者千人榜,看看你上榜了吗?

上传的附件:
收藏
点赞1
打赏
分享
打赏 + 1.00
打赏次数 1 金额 + 1.00
 
赞赏  junkboy   +1.00 2018/06/29
最新回复 (20)
雪    币: 153
活跃值: 活跃值 (421)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
fengyunabc 活跃值 1 2018-6-29 13:48
2
0
感谢分享!
雪    币: 378
活跃值: 活跃值 (12)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
ISSACASSI 活跃值 2018-6-29 14:04
3
0
感兴趣的小伙伴加群讨论讨论~~183746493~~路漫漫其修远兮
雪    币: 309
活跃值: 活跃值 (66)
能力值: ( LV7,RANK:140 )
在线值:
发帖
回帖
粉丝
yeyeshun 活跃值 2 2018-6-29 14:51
4
0
使用类进行包裹模拟全局变量,这样做是否可以避免重定位?我看你代码里似乎不需要做重定位修正
雪    币: 378
活跃值: 活跃值 (12)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
ISSACASSI 活跃值 2018-6-29 14:57
5
0
yeyeshun 使用类进行包裹模拟全局变量,这样做是否可以避免重定位?我看你代码里似乎不需要做重定位修正
不需要~都是属于类变量啊~总得算下来还是局部变量~只不过将整个需要提取的项目包裹在一个类里,把这个类看做项目文件就好哈哈哈~
雪    币: 50
活跃值: 活跃值 (34)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
return 活跃值 2018-6-29 15:52
6
0
感谢分享!
雪    币: 58
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zaimongli 活跃值 2018-6-29 17:32
7
0
学习了,居然忘了还有这种方法去除全局变量导致的重定位.
在类中,是这样访问类的变量的.
首先是,将类指针给ecx
然后,通过ecx加变量偏移,进行寻址,...
最后于 2018-6-29 17:33 被zaimongli编辑 ,原因: ..
雪    币: 11
活跃值: 活跃值 (152)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
猪会被杀掉 活跃值 1 2018-6-29 18:40
8
0
先顶一下,厉害。
说下建议
这个太复杂,看我写那个注入的例子,直接编译为exe,然后使用7z模板的右键解压功能直接提取出来的exe区段就是shellcode。
最后于 2018-6-29 18:43 被猪会被杀掉编辑 ,原因:
雪    币: 378
活跃值: 活跃值 (12)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
ISSACASSI 活跃值 2018-6-29 20:48
9
0
猪会被杀掉 先顶一下,厉害。说下建议这个太复杂,看我写那个注入的例子,直接编译为exe,然后使用7z模板的右键解压功能直接提取出来的exe区段就是shellcode。
好的大佬~我去研究研究
雪    币: 38
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
cjkillyes 活跃值 2018-7-5 23:45
10
0
感谢分享!我去研究研究 哈哈哈
雪    币: 57
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zyla 活跃值 2018-7-20 09:48
11
0
普通代码shellcode化并不是只有全局变量这个坑...
1.字符串,需要处理
2.switch 需要改成 if else 结构,有些代码写的太骚,根本没法改
3.结构体不能用 struct a = { 0 } 这样的方式初始化(里面不能是0)
4.其他待发现的...
雪    币: 378
活跃值: 活跃值 (12)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
ISSACASSI 活跃值 2018-7-22 18:03
12
0
zyla 普通代码shellcode化并不是只有全局变量这个坑... 1.字符串,需要处理 2.switch 需要改成 if else 结构,有些代码写的太骚,根本没法改 3.结构体不能用 struct ...
我后期再改进改进,shellcode与C++的结合,路数还是不少,自己用自己模板都发现好多坑
雪    币: 67
活跃值: 活跃值 (23)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
msf 活跃值 2018-9-6 09:07
13
0
我一直在用c直接dump shellcode ,全局变量我利用了peb中的某个不常用的位置存放全局变量列表;
雪    币: 67
活跃值: 活跃值 (23)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
msf 活跃值 2018-9-6 09:18
14
0
看你的代码取shellcode大小直接用 (int)mmLoaderSCEnd - (int)mmLoaderSCStart; 你能保证项目大时,mmLoaderSCEnd就绝对位于类的最下面位置(最高位置),mmLoaderSCStart位于类最上(最低位置)吗? 这中间会不会有其他无关代码;像创建线程这种要获取绝对地址的操作如何解决;
雪    币: 153
活跃值: 活跃值 (421)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
fengyunabc 活跃值 1 2018-9-6 10:55
15
0
楼上点出的问题在实际应用中我也遇见了。
雪    币: 378
活跃值: 活跃值 (12)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
ISSACASSI 活跃值 2018-9-8 01:54
16
0
msf 看你的代码取shellcode大小直接用 (int)mmLoaderSCEnd - (int)mmLoaderSCStart; 你能保证项目大时,mmLoaderSCEnd就绝对位于类的最下面位置(最 ...
不会……我最大的弄了26kb的shellcode……我觉得够大了
雪    币: 67
活跃值: 活跃值 (23)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
msf 活跃值 2018-9-11 09:16
17
0
告诉你些经验:
1. 放弃使用内敛汇编,可以直接利用编译器 将shellcode在x86和x64之间快速切换生成,(实在没办法的地方可以领_WIN64宏来区分加入汇编)
2. 可以利用vs /MAP":map.txt" /ORDER:@"funs.txt"  的办法将 所需的函数紧密的链接到文件中(内存中也紧密排列)这样就可以准确的获取shellcode起始位置和大小。
雪    币: 46
活跃值: 活跃值 (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
seaworlds 活跃值 2019-5-29 09:15
18
0
在吗?为什么winhttp库在debug下调用获取地址成功,但是在RUN_EXE模式下有的函数能提取成功,有的失败?
最后于 2019-6-5 09:51 被seaworlds编辑 ,原因:
雪    币: 213
活跃值: 活跃值 (50)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
shuaiaimei 活跃值 2019-6-28 02:46
19
0
猪会被杀掉 先顶一下,厉害。说下建议这个太复杂,看我写那个注入的例子,直接编译为exe,然后使用7z模板的右键解压功能直接提取出来的exe区段就是shellcode。
找不到你的注入例子,给个连接
雪    币: 102
活跃值: 活跃值 (185)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lhb天羽 活跃值 2019-9-9 14:21
20
0
mark一下
雪    币: 4294
活跃值: 活跃值 (346)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
如斯咩咩咩 活跃值 2020-4-13 22:19
21
0
最近学这个,mark一下
游客
登录 | 注册 方可回帖
返回