科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件缓冲区溢出还是问题吗?C++/CLI安全编码

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

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

C++/CLI是对C++的一个扩展,其对所有类型,包括标准C++类,都添加了对属性、事件、垃圾回收、及泛型的支持。

作者:谢启东编译 来源:天极开发 2007年11月12日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
假定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

  红色表示的字节标出了堆栈上的返回值在何处被地址值所覆盖,在这,并没有修改堆栈上的其他任何字节(包括"密探"),使得运行时的系统很难发现这次攻击。结果,控制权在GetPassword()函数返回时,传到了shellcode中。

  让我们再来回顾一下,首先,它演示了堆栈上的返回地址仍可被覆盖--甚至在打开缓冲区安全检查(/GS)的情况下,这些安全检查只会减轻声明在堆栈上的自动变量缓冲区溢出;其次,它也说明了一个在Visual Studio 2005环境中编译时毫无警告信息的程序并不是没有漏洞可言。例3就消除了这个缓冲区溢出,在发送消息之前,lpszPassword的第一个字设为以TCHAR表示的缓冲区大小,对Unicode文本而言,这表示字符数。第一个字中的大小被复制进来的字符数所覆盖,同样,对编辑控件来说,复制进来的字符串并不包含一个null结尾字符,返回值(所复制的TCHAR数)必须再设为以null结尾的字符串。

  例3:

LRESULT Retval;
*((WORD *)(&lpszPassword)) = (sizeof(lpszPassword)/sizeof(TCHAR))-1;
Retval = SendDlgItemMessage(hDlg, IDC_EDIT1, EM_GETLINE,
(WPARAM) 0, // line 0
(LPARAM) lpszPassword
);
lpszPassword[Retval]='\0';

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章