黑客为什么可以做到无需知道源码的情况下找出系统漏洞?
提问者估计是一个刚学会编程的菜鸟程序员,看见大段代码头就昏。问题很好,解答很难。
首先,为什么windows不开源还有那么多人研究呢,甚至比开源的Linux研究人员多的多?因为全世界运行windows的机器最多,大部分windows用户没有经过严格培训,只会使用鼠标键盘,Linux用户都要使用命令行,没几个用户是新手,开源的Linux也使得漏洞可以用最快的速度被修补,因为世界上有很多人在维护Linux。windows不开源,只能由微软负责维护和补丁更新。世界上有大把的程序员,但微软公司负责开发操作系统的人不超过五万(算上离职的也不会超过十万人),写操作系统内核的核心开发人员不超过1000人,你连写操作系统代码都不会只会写应用程序根本理解不了操作系统是如何运转的,要想入门还是先多看看操作系统的书吧,至少要理解操作系统是如何运行的,推荐先看看Linux的内核代码,有一定基础后再看《windows核心揭秘》。
其次,windows操作系统是用C/C++写的,很多程序员都使用高级语言写程序,对C和C++这些“中间语言”不熟悉不了解,不知道哪些函数容易溢出,使用哪些函数更安全或者可以替代不安全的函数。系统漏洞的精髓在于缓冲区溢出,缓冲区溢出说白了就是利用冯诺伊曼架构的缺陷——数据和代码存储在同一个设备内存中,让计算机错误的把数据当作代码来执行。在windows数据结构中有堆栈和堆都可以被溢出,在NT5.0之前的系统中根本没有防范机制,XPSP2引入了安全堆栈,在编译器中还有/GS选项,用于防止堆栈溢出,使得堆栈溢出非常困难,但并不是不可能,堆溢出仍然可以。
当熟练掌握了缓冲区溢出就可以对windows进行分析了,方法主要是“黑盒”与“白盒”。白盒就是当微软发布补丁之后用虚拟机分析补丁前后的代码级差别,找出漏洞,但是这些漏洞都是微软补丁过的,利用价值不大;黑盒分析则是在完全没有源码的情况下靠分析工具和人的经验来寻找漏洞,人的经验起决定作用,你必须知道程序员比较容易在哪些地方犯错误,包括使用不安全函数、边界检查不完整、竞争条件、SEH结构化异常错误处理和VEH向量化异常错误处理等操作系统内部的知识。黑盒分析找到的漏洞一般没有补丁,又称0day漏洞,据说这种漏洞在地下黑市上价值上万美元(任意代码可执行漏洞值这个价,其他的信息泄露或者提升权限价值就比较低了)。
当你能够找到windows的0day漏洞,特别是影响巨大的任意代码可执行漏洞的时候,你已经是站在程序员金字塔塔尖的一小群人了,找到漏洞之后就需要编写一小段shellcode来利用漏洞,这段代码条件非常苛刻,也许只针对特定的windowsSP版本有效,也许针对所有windows系统有效。对所有windows有效的shellcode一定是可移植的,换句话说shellcode必须能够通用化。可以把shellcode想象成一个侦察兵,一个先头空降部队,如何在茫茫黑夜中侦查操作系统防线的位置、火力点的分布情况,从哪里开始执行负载并且不会陷入操作系统的泥沼中淹死(这足可以写一本书来描述)shellcode只是一枚导弹的制导系统,它负载的炸药可能是一个在地上砸个坑的铅球,也可能是毁灭一座城市的核武器。
这也是最体现黑客技术水平的地方,同一个漏洞有的人编写的shellcode能实现通用化(具体要看漏洞的位置以及形成原因),有的人编写的根本不能运行或者极大影响系统速度。一般来说编写shellcode都使用汇编语言,极少数情况下还需要使用二进制代码。
当你掌握以上技能后,就将修炼终极绝技了,那就是无比困难的、一旦掌握就必将天下无敌的绝技——硬件漏洞,就比如intel最近的“融毁”和“幽灵”。如果说操作系统是计算机的灵魂,那CPU就是计算机的心脏。从层级上来说,一般程序员编写的应用程序运行在3级,操作系统运行在0级(最新情况是操作系统运行在-1级,0级运行虚拟机,intel叫vt-x技术,可以极大减少切换层级引起的系统开销)而CPU核心运行在-3级,拥有远超windows的权限,这才是计算机的终极命门,硬件漏洞通用性也无与伦比,因为桌面CPU就intel和amd能生产,CPU微代码不更新的话漏洞会一直存在(老式计算机只有更换CPU,而老机器更换CPU几乎不可能,因为主板不支持,需要更换主板代价太大得不偿失;三年内新式计算机可以更新UEFI微代码,也就是微软和intel提供的补丁)这就是撞击地球后足以毁灭世界的小行星级别的武器了。要找到这种级别漏洞光靠个人已经不可能,光需要的特殊硬件就不是个人买得起的,一般要大公司或者国家才能找到这种级别的漏洞。
最后,用三个我最喜欢的小例子来结尾吧。
1、当windows弹出著名的“程序引用了0x00000000地址,即将关闭”的错误提示的时候,普通程序员会顺从的点击确定关闭对话框,然后思考究竟是什么地方出了问题;聪明一些的程序员会利用windows内核转储来寻找问题的答案,不一定能解决问题;顶尖黑客则会用softice或者其他工具重现这个问题,必须把它解决,没准能写出shellcode。
2、impossible和i'm'possible从字母排列上都是一样的,但意思却是相反的,这就是缓冲区溢出的精髓,只添加了两个标点。impossible是单词,属于数据的范畴,I'm'possible是句子,属于代码的范畴,混淆数据与代码的界限,让计算机把数据当成代码执行,只需要缓冲区溢出两个标点而已。在计算机的世界中,复杂的、毫无规律的垃圾数据突然间组成了一幅美丽的图画,随着锁“卡嗒”一声,安全的大门缓缓打开,苦心经营的安全防线瞬间崩溃。
3、在电影《黑客帝国》中,普通的程序安安静静的运行在虚拟机中,少数像尼奥这样不安分的程序突破了虚拟机的安全机制,进入到了真实操作系统矩阵中,这时候操作系统的SEH异常错误处理机制史密斯登场了;后来尼奥发现矩阵也不是真实的操作系统,只不过是更高一级的虚拟机罢了(虚拟机嵌套),尼奥可以在矩阵中使用操作系统的特权指令消灭追杀来的乌贼机器人就证明了这一点;最后史密斯叛变,病毒几乎感染了操作系统的所有进程,尼奥牺牲自己帮助操作系统定位了史密斯的位置(病毒的PID),经过一轮内存杀毒和系统重启后,操作系统又回到了正常的状态。