快速业务通道

缓冲区溢出还是问题吗?C++/CLI安全编码

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-30
我们在此继续使用托管扩展(CLR)。

这是一个非常简单的程序,尽管为了支持Windows GUI,它显得稍微有点长。在17至20行,有几个有意思的变量,lpszPassword是一个由16个宽字符(32字节)组成的已初始化的静态变量,紧跟其后的是userP指针及两个无符号整形:userNameLen和userPasswordLen,之后,userP在33行初始化。这些变量的地址如下:

&lpszPassword = 0x0040911C
&userP = 0x0040913C
&userNameLen = 0x00409140
&userPasswordLen = 0x00409144

userP的值为0x00554D30,userNameLen的值为0x00000010,userPasswordLen的值为0xffffffff。如果我们查看lpszPassword地址的起始处内存,可以非常清楚地看到这些变量的初始值(见插3)。

代码段3:

0040911C 30 00 31 00 32 00 33 00 34 00 35 00 36 00 37 00
0040912C 38 00 39 00 61 00 62 00 63 00 64 00 65 00 00 00
0040913C 30 4d 55 00 10 00 00 00 ff ff ff ff 8a 00 07 02
0040914C c6 00 07 02 02 01 07 02 00 00 00 00 01 00 00 00

此程序中的漏洞是在118至123行中对SendDlgItemMessage的调用,EM_GETLINE消息指定了从编辑控件IDC_EDIT1获取一行文本--编辑控件在Login对话框中,并把它复制到定长缓冲区lpszPassword中。这个缓冲区只能容纳15个Unicode字符及一个结尾的null,如果输入了多于15个字符,就会发生缓冲区溢出;在此假设输入了20个字符,第17及18个字符将会覆盖掉userP,第19及20个字符将会覆盖掉userNameLen,结尾的null将会覆盖掉userPasswordLen。

假定userP与userNameLen两者都被覆盖,当userNameLen被赋给存储在userP+4(user结构内len的偏移地址)的地址时,在124行就会导致对内存的任意写入。通过把一个地址覆盖为控制权最终要传递到的地址,攻击者就能利用内存的任意写入,把控制权传给任意的代码。而在本例中,堆栈上的返回地址被覆盖了。

因为lpszGuestPassword变量是一个声明在GetPassword函数中的自动变量,我们也可以查看这个变量地址起始处的内存。假定lpszGuestPassword定位在0x002DEB9C,那么可在这个位置查看堆栈的内容。经由程序调试,可以确定0x004f3a99的返回码位于堆栈上的0x002DEBD0处(见插4)。

代码段4:

002DEB9C 4e 00 43 00 43 00 2d 00 31 00 37 00 30 00 31 00
002DEBAC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
002DEBBC 1e df b4 bd 00 00 00 00 50 15 40 00 64 ec 2d 00
002DEBCC ec eb 2d 00 99 3a 4f 00 05 27 00 01 00 00 00
002DEBDC b0 32 2f 00 84 ec 2d 00 da c4 fc 79 58 f1 2d 00

假定shellcode已被注入到程序中的0x00409028,那么接下来,攻击者可在Login对话框的密码输入栏中输入以下字符串:

"1234567812345678\xebcc\x002d\x9028\x0040"

在缓冲区溢出之后,数据段的内存显示见插5:

代码段5:

0040911C 31 00 32 00 33 00 34 00 35 00 36 00 37 00 38 00
0040912C 31 00 32 00 33 00 34 00 35 00 36 00 37 00 38 00
0040913C cc eb 2d 00 28 90 40 00 00 00 ff ff 8a 00 07 00
0040914C c6 00 07 02 02 01 07 02 00 00 00 00 01 00 00 00

棕色的字节表示userP的值在何处被堆栈上的返回代码地址所覆盖(负4),绿色的字节表示userNameLen的值在何处被shellcode的地址所覆盖。当124行的内存任意写入执行之后,堆栈现在如插6所示。

代码段6:

002DEB9C 4e 00 43 00 43 00 2d 00 31 00 37 00 30 00 31 00
002DEBAC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
002DEBBC 1e df b4 bd 00 00 00 00 50 15 40 00 64 ec 2d 00
002DEBCC ec eb 2d 00 28 90 40 00 0e 05 27 00 01 00 00 00
002DEBDC b0 32 2f 00 84 ec 2d 00 da c4 fc 79 58 f1 2d 00

红色表示的字节标出了堆

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号