本节课,我们讨论的主题是如何写出尽可能安全的应用程序。而要知道什么样的程序是安全的,就要先讨论程序会受到什么样的安全威胁,也就是常见的对应用程序的攻击手段,针对每种攻击手段,我们会给出提高程序安全性的防范建议。
要讨论的内容主要包括:
- 栈溢出攻击原理与防范
- 堆溢出攻击原理与防范
- 格式化字符串漏洞攻击与防范
24.1 应用程序安全概述
在互联网的世界里,安全是个永恒的话题,黑白两方的较量从来没有停止,在可预见的将来也将一直持续下去,而且,随着越来越多的商业活动转移到互联网上,安全问题也将受到越来越多的关注。
在大多数人的理解中,计算机安全与密码学和权限管理的关系比较大,而与常规的业务逻辑开发好像并没有太大的关系。实际上,应用程序执行过程中的任何一环都可能成为被攻击的目标。通过本节课的内容,读者们将会了解到,常规的业务逻辑缺陷是如何成为被攻击利用的目标,变成安全链条中薄弱的那一环的。
24.2 栈溢出攻击原理与防范
栈溢出是最常见、危害最大的软件漏洞类型之一,在互联网上传播的第一个蠕虫病毒“Morris 蠕虫”,就是用栈溢出漏洞实现的。
要理解栈溢出攻击的原理,需要对计算机程序中函数的调用和返回过程的底层细节有清晰的理解,尤其是这样一个问题:计算机是如何保存某个函数调用的下一条指令地址,实现函数执行完成之后跳回函数调用处,继续往下执行的?
我们都知道,函数的执行需要栈,大多数函数都有自己的栈帧,里面存放着当前函数内的局部变量、调用本函数之前的寄存器值等信息。以使用最广泛的 x86 CPU 为例,它有两个专用的寄存器