首页
社区
课程
招聘
[原创][shellcode框架(一)] 认识shellcode,部署shellcode开放框架
发表于: 2017-3-24 15:27 14601

[原创][shellcode框架(一)] 认识shellcode,部署shellcode开放框架

2017-3-24 15:27
14601

[shellcode框架(二)] 完善shellcode框架

https://bbs.pediy.com/thread-216661.htm

[shellcode框架(三)] 修复shellcode框架的小bug

https://bbs.pediy.com/thread-216673.htm

[shellcode框架(四)] shellcode编程小技巧

https://bbs.pediy.com/thread-216674.htm

[shellcode框架(五)] 多文件shellcode框架

https://bbs.pediy.com/thread-217040.htm


   倾其所学,做此系列,希望初入此道者,莫走弯路 。

  认识shellcode 

  Shellcode实际是一段代码(也可以是填充数据),是用来发送到服务器利用特定漏洞的代码,一般可以获取权限。另外,Shellcode一般是作为数据发送给受攻击服务器的。 Shellcode是溢出程序和蠕虫病毒的核心,提到它自然就会和漏洞联想在一起,毕竟Shellcode只对没有打补丁的主机有用武之地。网络上数以万计带着漏洞顽强运行着的服务器给hacker和Vxer丰盛的晚餐。漏洞利用中最关键的是Shellcode的编写。由于漏洞发现者在漏洞发现之初并不会给出完整Shellcode,因此掌握Shellcode编写技术就显得尤为重要。(来自百科 http://baike.baidu.com/link?url=3YqpOe7gRddlo6xMoMwEYhtprTNBTtWdvNTuaVq5Xo8Nucd9Kb7DZj1_GmWX1DGb8MN2iGIiJ6jIBgsOKbLnJD58lp0m0_PECdGTXPXSqgW)

   

   shellcode编写考虑因素


⒈Shellcode的编写语言。
⒉Shellcode本身代码的重定位
⒊Shellcode中使用的API地址定位。
⒋Shellcode编码问题。

多态技术躲避IDS检测。

这些问题是百科上提出的,这也正是shellcode开发要解决的问题。其实还有很多问题要解决,这里我先不一一列举,在以后的开发中很多问题就会暴露出来,到时我们再来探讨暴露的问题,这样记忆更深刻。

这里我就此系列来简单的回答以上问题:

1. 语言,这里我们用c语言,开发环境使用vs(10),部分代码使用汇编内联到代码中(如,获取TEP、PEB特殊地址),c语言开发简单易懂,大大降低了入门的门槛;移植性好,配合vs做简单修改后可以直接生成arm、x64的shellcode ;vs的强大调试功能可以帮助我们发现其中的bug,从此告别OD。

2.重定位。

3.API地址定位,这里我们使用最流行的通过比对函数名hash来查找函数地址。其工作原理是将函数名计算成hash(DWORD),当遍历dll导出表时,将函数名先计算为hash再和shellcode中存放的hash比较来确定API,从而找到其地址。这里不直接在shellcode中存放函数名是为了减小shellcode的体积。

4.编码问题。

5. 躲避IDS检测,我们随便加上异或编码、解码功能、解压缩、加解密等等 就可以产生千差万别的shellcode;总有一款适合你。


部署shellcode c语言框架

这里我直接使用 TK教主的shellcode模板 https://github.com/tombkeeper/Shellcode_Template_in_C

下载解压后一共3个文件shellcode.c gethash.c str2intarr.c ;其中shellcode.c就是这个模板了,以后所有的工嗯那个都在这个基础上增加;gethash.c 将使用的函数名计算得到hash值,以供利用hash获取函数地址;str2intarr.c 这个主要是将字符串资源直接嵌入到shellcode中,以供shellcode使用(一般开发字符串资源会被编译器放在资源中打包如PE文件,而我们的shellcode不能将字符串放在其他地方,而必须存放在shellcode的空间内,以保证shellcode能准确的获取字符串地址)。

部署shellcode.c 

1.打开vs10,新建工程->选择 "visual c++" ->Win32 -> Win32 Console Application ;名称随意;Application options 选择 Empty project(空工程)。

2.将shellcode.c放在工程目录下,将shellcode.c拖入新工程。

3.右键shellcode.c文件 属性-> c/c++ -> Precompiled Headers(预编译头)->Percompliled Header(预编译头):选择 “Not Using Pricomplied Headers" ;因为shellcode.c是c文件所以不使用预编译头

4. 将工程设置为release模式 ;并将工程属性 c/c++ -> Optimization(优化)->Optimization(优化):选择为disabled 或 Minimize Size(/O1) (当调试使用disabled ;发布shellcode时使用O1)

5. 将 void __declspec(naked) StartSign (){} 注释掉

6. 将shellcode.c文件中的main函数改为如下

7. 关闭GS、 关闭DEP、

void main(void)
{
    DWORD ShellCodeSize;
    ShellCodeSize = (DWORD)EndSign - (DWORD)StartSign;
    ShellCodeToHex ( (BYTE *)ShellCode, ShellCodeSize, stdout );
    // ShellCode();
}
// 修改后
void main(void)
{
    DWORD ShellCodeSize;
    ShellCodeSize = (DWORD)EndSign - (DWORD)ShellCode;
    ShellCodeToHex ( (BYTE *)ShellCode, ShellCodeSize, stdout );
    getchar();
    ShellCode();
	
}


   这样就可以运行shellcode工程了。 

   在cmd下运行shellcode.exe还可以看到输出的shellcode 十六进制数组。

  直接运行就能弹出 calc.exe了吧!

BYTE ShellCode[] = {
    0x55,0x8B,0xEC,0x83,0xEC,0x14,0xC7,0x45,0xF8,0x63,0x61,0x6C,0x63,0xC7,0x45,0xFC,
    0x00,0x00,0x00,0x00,0xE8,0x67,0x00,0x00,0x00,0x89,0x45,0xEC,0x68,0xB9,0x6B,0xFF,
    0xCB,0x8B,0x45,0xEC,0x50,0xE8,0x06,0x01,0x00,0x00,0x83,0xC4,0x08,0x89,0x45,0xF4,
    0x68,0x13,0xB9,0xE6,0x25,0x8B,0x4D,0xEC,0x51,0xE8,0xF2,0x00,0x00,0x00,0x83,0xC4,
    0x08,0x89,0x45,0xF0,0x6A,0x01,0x8D,0x55,0xF8,0x52,0xFF,0x55,0xF0,0x6A,0x00,0xFF,
    0x55,0xF4,0x8B,0xE5,0x5D,0xC3,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,
    0x55,0x8B,0xEC,0x64,0xA1,0x18,0x00,0x00,0x00,0x5D,0xC3,0xCC,0xCC,0xCC,0xCC,0xCC,
    0x55,0x8B,0xEC,0xE8,0xE8,0xFF,0xFF,0xFF,0x8B,0x40,0x30,0x5D,0xC3,0xCC,0xCC,0xCC,
    0x55,0x8B,0xEC,0x83,0xEC,0x10,0xE8,0xE5,0xFF,0xFF,0xFF,0x89,0x45,0xF4,0x8B,0x45,
    0xF4,0x8B,0x48,0x0C,0x8B,0x51,0x1C,0x89,0x55,0xF8,0xC7,0x45,0xFC,0x00,0x00,0x00,
    0x00,0xEB,0x09,0x8B,0x45,0xFC,0x83,0xC0,0x01,0x89,0x45,0xFC,0x83,0x7D,0xFC,0x02,
    0x7D,0x26,0x8B,0x4D,0xF8,0x8B,0x11,0x83,0xEA,0x10,0x89,0x55,0xF0,0x8B,0x45,0xF0,
    0x8B,0x48,0x30,0x0F,0xB7,0x51,0x10,0x83,0xFA,0x2E,0x75,0x02,0xEB,0x0A,0x8B,0x45,
    0xF8,0x8B,0x08,0x89,0x4D,0xF8,0xEB,0xCB,0x8B,0x55,0xF0,0x8B,0x42,0x18,0x8B,0xE5,
    0x5D,0xC3,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,
    0x55,0x8B,0xEC,0x51,0xC7,0x45,0xFC,0x00,0x00,0x00,0x00,0x8B,0x45,0x08,0x0F,0xBE,
    0x08,0x85,0xC9,0x74,0x1F,0x8B,0x55,0xFC,0xC1,0xE2,0x05,0x03,0x55,0xFC,0x8B,0x45,
    0x08,0x0F,0xBE,0x08,0x03,0xD1,0x89,0x55,0xFC,0x8B,0x55,0x08,0x83,0xC2,0x01,0x89,
    0x55,0x08,0xEB,0xD7,0x8B,0x45,0xFC,0x8B,0xE5,0x5D,0xC3,0xCC,0xCC,0xCC,0xCC,0xCC,
    0x55,0x8B,0xEC,0x83,0xEC,0x24,0xC7,0x45,0xE8,0x00,0x00,0x00,0x00,0x8B,0x45,0x08,
    0x89,0x45,0xFC,0x8B,0x4D,0xFC,0x8B,0x55,0x08,0x03,0x51,0x3C,0x89,0x55,0xE4,0x8B,
    0x45,0xE4,0x8B,0x4D,0x08,0x03,0x48,0x78,0x89,0x4D,0xF0,0x8B,0x55,0xF0,0x8B,0x45,
    0x08,0x03,0x42,0x20,0x89,0x45,0xF4,0xC7,0x45,0xF8,0x00,0x00,0x00,0x00,0xEB,0x09,
    0x8B,0x4D,0xF8,0x83,0xC1,0x01,0x89,0x4D,0xF8,0x8B,0x55,0xF0,0x8B,0x45,0xF8,0x3B,
    0x42,0x18,0x73,0x30,0x8B,0x4D,0xF4,0x8B,0x55,0x08,0x03,0x11,0x89,0x55,0xE0,0x8B,
    0x45,0xE0,0x50,0xE8,0x58,0xFF,0xFF,0xFF,0x83,0xC4,0x04,0x3B,0x45,0x0C,0x75,0x09,
    0xC7,0x45,0xE8,0x01,0x00,0x00,0x00,0xEB,0x0B,0x8B,0x4D,0xF4,0x83,0xC1,0x04,0x89,
    0x4D,0xF4,0xEB,0xBC,0x83,0x7D,0xE8,0x00,0x74,0x2F,0x8B,0x55,0xF0,0x8B,0x45,0x08,
    0x03,0x42,0x24,0x8B,0x4D,0xF8,0x66,0x8B,0x14,0x48,0x66,0x89,0x55,0xDC,0x8B,0x45,
    0xF0,0x8B,0x4D,0x08,0x03,0x48,0x1C,0x0F,0xB7,0x55,0xDC,0x8B,0x45,0x08,0x03,0x04,
    0x91,0x89,0x45,0xEC,0x8B,0x45,0xEC,0xEB,0x02,0x33,0xC0,0x8B,0xE5,0x5D,0xC3,0xCC
};
DWORD ShellCodeSize = 496;

这是未优化(选项disabled)的输出结果,里面有很多cc;

BYTE ShellCode[] = {
    0x55,0x8B,0xEC,0x51,0x51,0x83,0x65,0xFC,0x00,0xC7,0x45,0xF8,0x63,0x61,0x6C,0x63,
    0x64,0xA1,0x18,0x00,0x00,0x00,0x8B,0x40,0x30,0x8B,0x40,0x0C,0x8B,0x40,0x1C,0x33,
    0xC9,0x8B,0x00,0x8B,0x50,0x20,0x66,0x83,0x7A,0x10,0x2E,0x74,0x06,0x41,0x83,0xF9,
    0x02,0x7C,0xEE,0x56,0x57,0x8B,0x78,0x08,0x68,0xB9,0x6B,0xFF,0xCB,0xE8,0x1F,0x00,
    0x00,0x00,0x8B,0xF0,0xC7,0x04,0x24,0x13,0xB9,0xE6,0x25,0xE8,0x11,0x00,0x00,0x00,
    0x59,0x6A,0x01,0x8D,0x4D,0xF8,0x51,0xFF,0xD0,0x6A,0x00,0xFF,0xD6,0x5F,0x5E,0xC9,
    0xC3,0x55,0x8B,0xEC,0x51,0x8B,0x47,0x3C,0x8B,0x44,0x38,0x78,0x83,0x65,0xFC,0x00,
    0x53,0x03,0xC7,0x56,0x8B,0x70,0x20,0x03,0xF7,0x83,0x78,0x18,0x00,0x76,0x2A,0x8B,
    0x0E,0x03,0xCF,0x33,0xDB,0xEB,0x09,0x6B,0xDB,0x21,0x0F,0xBE,0xD2,0x03,0xDA,0x41,
    0x8A,0x11,0x84,0xD2,0x75,0xF1,0x3B,0x5D,0x08,0x74,0x14,0x83,0xC6,0x04,0xFF,0x45,
    0xFC,0x8B,0x4D,0xFC,0x3B,0x48,0x18,0x72,0xD6,0x33,0xC0,0x5E,0x5B,0xC9,0xC3,0x8B,
    0x48,0x24,0x8B,0x55,0xFC,0x8B,0x40,0x1C,0x8D,0x0C,0x51,0x0F,0xB7,0x0C,0x39,0x8D,
    0x04,0x88,0x8B,0x04,0x38,0x03,0xC7,0xEB,0xE2
};
DWORD ShellCodeSize = 201;

优化O1开启后 只有201字节了。




[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 1
支持
分享
最新回复 (22)
雪    币: 459
活跃值: (657)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
2
谢谢分享,接着看续集。另外再开个msf框架使用的帖子就更好了。
2017-3-24 16:39
0
雪    币: 16726
活跃值: (3998)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢分享,学习一下~!
2017-3-24 20:31
0
雪    币: 983
活跃值: (722)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
学习下。
2017-3-27 13:24
0
雪    币: 117
活跃值: (1114)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
5. 将 void __declspec(naked) StartSign (){} 不掉, 这个什么意思?
2017-3-31 10:48
0
雪    币: 117
活跃值: (1114)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
没弹出calc,win10系统,放虚拟机XP下 win7下 也没有弹出。
2017-3-31 10:56
0
雪    币: 69
活跃值: (270)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
msf
7
hackbs 没弹出calc,win10系统,放虚拟机XP下 win7下 也没有弹出。
是不是开启了GS
2017-4-4 12:14
0
雪    币: 1380
活跃值: (116)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
8
1>Shellcode.obj  :  error  LNK2001:  无法解析的外部符号  __imp____acrt_iob_func
1>Shellcode.obj  :  error  LNK2001:  无法解析的外部符号  __imp____stdio_common_vfprintf
1>Shellcode.obj  :  error  LNK2001:  无法解析的外部符号  __imp__getchar
这是什么情况?
2017-4-4 16:57
0
雪    币: 69
活跃值: (270)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
msf
9
ixiaohuo 1>Shellcode.obj : error LNK2001: 无法解析的外部符号 __imp____acrt_iob_func 1>Shellcode.obj : error LNK ...
#include  <winsock2.h>
#include  <windows.h>
#include  <stdlib.h>
#include  <stdio.h>
#include  <fcntl.h>
2017-4-5 09:07
0
雪    币: 1380
活跃值: (116)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
10
msf #include #include #include #include #include
不行,我头文件都加了还是不可以,估计编译器编译的函数名出错了
2017-4-5 16:10
0
雪    币: 1140
活跃值: (102)
能力值: ( LV4,RANK:48 )
在线值:
发帖
回帖
粉丝
11
输出了shellcode,但是不启动calc,win10  64位,是为什么啊
2017-4-5 17:42
0
雪    币: 1140
活跃值: (102)
能力值: ( LV4,RANK:48 )
在线值:
发帖
回帖
粉丝
12
ixiaohuo 不行,我头文件都加了还是不可以,估计编译器编译的函数名出错了
我把  #pragma  comment(ENTRY,"main");注释掉就不报错了,否则跟你一样的问题
2017-4-5 17:43
0
雪    币: 1380
活跃值: (116)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
13
大只狼 我把 #pragma comment(ENTRY,"main");注释掉就不报错了,否则跟你一样的问题
谢谢,的确是这个问题
2017-4-5 21:17
0
雪    币: 1
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
dll的shellcode和exe的shellcode运行起来有什么区别吗。
2017-7-17 14:46
0
雪    币: 206
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
源码下不了,能传到百度网盘么
2017-7-23 00:00
0
雪    币: 34
活跃值: (76)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
没弹出calc,win7虚拟机没有弹出。
2017-12-25 22:01
0
雪    币: 13
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
改成  #pragma  comment(  linker,"/ENTRY:mainCRTStartup"  )(多字节工程)即可
2018-4-2 17:23
0
雪    币: 189
活跃值: (267)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
为什么会使用到如此复杂的写法 shellcode 实际上根本不需要单独写成二进制 文件 然后在申请内存拷贝进去运行 
其实我们只需要针对目标进程 是x86 还是x64 在自身写代码使用虚表函数 在重定位目标进程的虚表不就搞定了吗
2018-4-3 22:27
0
雪    币: 195
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
有用,mark
2018-4-4 09:57
0
雪    币: 123
活跃值: (316)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
用框架写shelk  code似乎不方便,汇编代码取出loadlibrary和getprocaddress地址,不就可以做任何事情了吗?hash加密也可以用汇编代码实现
2018-4-7 05:01
0
雪    币: 296
活跃值: (236)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
学习,mark
2018-4-21 18:01
0
雪    币: 259
活跃值: (70)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
感谢楼主
2018-4-21 20:52
0
雪    币: 123
活跃值: (316)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
ShellCodeSize = (DWORD)EndSign - (DWORD)ShellCode;
有时候获取负数,优化问题?

2020-5-3 10:59
0
游客
登录 | 注册 方可回帖
返回
//