5.6 人类思维缓冲区溢出
杯子的容积是有限的,将10盎司的液体往8盎司的杯子里倒,会发生什么?当然是液体溢出,流得到处都是。如果强行向容器中倒入超过其容积的液体,只会使杯子在压力作用下破碎。
同样的原理也适用于计算机程序。设想一个小程序,它只有一个功能和两个字段:用户名和密码。
当程序运行时,会有一个小窗口,你在用户名字段处输入“admin”,在密码字段处输入“password”,然后一个小的消息框会弹出提示“OK”,表示一切正常。
开发人员为用户名字段分配了一定数量的内存空间,足以保存几个“admin”的字符串长度。如果你在该字段中输入20个“A”然后点击确认键,会怎么样呢?
程序会崩溃并弹出错误提示窗口。为什么呢?因为输入的字符比分配的内存空间长,并且没有正确的错误处理程序来抛出异常,所以程序崩溃了。
软件黑客的目的就是找到能够引起程序崩溃的地址,并在该地址插入恶意代码。通过控制执行过程,黑客可以让程序“执行”他想要的任何程序。他能够在程序的内存空间中注入任何类型的命令,因为他有完全的掌控权。作为渗透测试人员,没有什么比让程序按照其意愿执行更令人兴奋的事情了。
人类的思维也可以被看做一系列运行的“软件”。随着时间的累积,渐渐地你形成自己特有的“软件包”,建立自己的指令集、缓冲区和内存长度。
在将这些应用到人类思维之前,有必要讲解下几个技术术语。缓冲区是一个空间区域,其中可以发生一些事或用来存储数据。在前面“登录程序”的示例中,密码字段有一个缓冲区,大小就是允许存放的字符数。如果输入的字符数比缓冲区大,程序员就应该告诉程序如何处理更大的数据集。
如果没有做处理,计算机就会崩溃,程序也就关闭了。通常,后台的情况是这样的:程序不知道该如何处理所有的数据,从而溢出了分配的内存空间,程序直接崩溃并退出。此谓缓冲区溢出。
人类思维的运行模式亦如此。我们为特定数据集分配了空间,如果特定的数据集不能放入申请的空间,会发生什么呢?不像计算机,大脑不会崩溃,但是会出现短暂的空档期,这个时候就可以植入命令,通过额外的数据告诉大脑该如何做。
人类思维缓冲区溢出基本上也是同样的道理。我们的目的是识别出运行的“程序”,并向程序插入代码,使你能够植入命令,从根本上控制思维导向。
可以通过一个很简单的例子测试这个概念(如图5-16所示)。
因为本书是单色印刷的,所以我将彩色版本放到了www.social-engineer.org/resources/book/HumanBufferOverflow1.jpg上。
测试要点是这样,打开前面的网址,尽量快速地说出图片中单词的颜色,而不是读单词。
图5-16 人类思维缓冲区溢出实验一
这个游戏并非表面上那么简单。如果你成功通关,可以试试不断加快朗读速度。对于大多数人(如果不是所有人)来说,至少有一次你会习惯性地读出单词,而不是其颜色,或者你会发现自己在整个过程中都很挣扎。
为什么这个实验这么难呢?因为植入的命令。我们下意识地要读出这些单词而不是其颜色。这就是人类大脑连接的方式。大脑看到了颜色,但是首先会对单词的拼写作出反应。也就是说,思维中出现的是单词而不是其颜色。这个实验显示人类大脑中执行的代码可能会与人们想到或看到的相反。
5.6.1 设定最基本的原则
在一篇名为Modification of Audible and Visual Speech的论文(详见www.prometheus-inc.com/asi/multimedia1998/papers/covell.pdf)中,米歇尔·科维尔(Michele Covell)、马尔克姆·斯兰尼(Malcolm Slaney)、克里斯托弗·贝格勒(Cristoph Bregler)和玛格丽特·威斯考特(Margaret Withgott)4位研究员共同指出,科学家已证明人们在一分钟时间里只能说出150个单词,但在同样的时间里却能够思考500~600个单词。这就意味着大多数人在听你说话时大脑会快速思考。所以想通过提升语速来使听者脑部缓冲区溢出几乎是不可能的。
你还得明白人们在日常生活中是如何作决定的。人们所作出的大部分决定都是下意识的,如怎样开车上班、冲咖啡、刷牙及穿什么衣服等都没有经过真正的思考。
你有没有过这样的经历呢?开车上班,到了公司之后,却不记得经过了哪些广告牌、走的哪条路或者新闻中播报了什么交通事故。你处于下意识掌控的思维状态,不需要有意识地去考虑每个转弯,只要按照惯性开就可以了。
人们的大多数决定都是这样作出来的。有些科学家甚至相信在正式作出决定7秒之前,潜意识就已作出了决定,其后才在现实中反应出来。当人们最终有意识地作出决定时,他们的决定不仅依据听到的内容,决策过程还会涉及视觉、感觉和情感。
弄清楚人类工作及思考的方式是创建缓冲区溢出的最快方法,或者说是创建人类思维固有程序溢出的最快方法,弄清楚之后,你就可以植入命令了。
5.6.2 人性操作系统的模糊测试
在实际的软件攻击中,模糊测试(fuzzing)方法能够用来寻找可以重写的软件错误,使得恶意黑客获得实际的控制权。模糊测试中,黑客向程序发送不同长度的随机数据,以测试因不能处理数据导致程序崩溃的情况。这样黑客就有机可乘,从而嵌入恶意代码。
和程序的模糊测试一样,你必须明白人类思维对特定类型的数据是如何反应的。通过观察人们在面对不同决定和数据时的反应,就能够知道他们运行的“程序”如何。人类思维中的有些行为准则似乎是与生俱来的,每个人都会遵守。
例如,一栋大厦有内外两道门,你为一个陌生人开了第一道门,你猜接下来他会怎么做?他要么帮你打开接下来那扇门,要么等你进去才关第一道门。
在交通汇流处,你让一个完全不认识的人并到你前面,当你稍后想并道时,他也会不假思索地让你。为什么呢?
这里面的原因和预期定律有关,即人们通常会遵循一个预期。人们常常遵循他们感受到的别人的期望或要求来作决定。利用这个定律,你可以将恶意“数据”植入到对方的脑部程序,我们称之为预设。
先给目标一点甜头尝尝,接下来再提请求时就不大可能吃闭门羹。拿前文“开门”的简单例子来说,如果你给别人开了门,他极有可能至少会试图为你打开下一扇门。在提出要求之前,社会工程人员可以预先恭维目标或者提供一些他们认为有价值的信息。通过先给予,接下来有所请求就显得理所应当了。
下面的示例完美地诠释了“预设”。
“你认识我的邻居拉尔夫吗?他总是开着那辆绿色的福特雅仕。”
在这句话中,你预设了如下信息:
想要高效地运用预设方法,你要综合运用措辞、肢体语言和面部表情来问问题,从而让人觉得你所表述的是事实。这种方法最基本的一点便是穿透“防火墙”(理性状态),直入“系统最低层”(下意识状态)。最快的方式便是通过嵌入式指令注入你的“代码”,接下来会有进一步的阐述。
5.6.3 嵌入式指令的规则
一些行之有效的嵌入式指令基本原则如下。
市场营销中对嵌入式指令的运用很流行。
在真正的缓冲区溢出中,程序编写人员会使用填充字符技术,即通过填充一些字符的方式,在不影响程序正常运行的情况下,让恶意代码得以“进场”执行。社会工程人员也会在表述时加上类似填充的语句,让后面植入的命令不至于显得太突兀。举例如下。
以上这些表述均能创建一种情绪或思维,允许你在潜意识中植入代码。
关于嵌入式指令的例子有很多,这里仅列出几个供参考。
巧用引用或故事 大脑在处理故事与处理其他信息方面有着很大的差异。纵观历史长河中的名师巨匠,像亚里士多德、柏拉图、迦玛列及耶稣,他们都是用故事和实例来向听众传授知识的。为什么呢?
秘密就在于潜意识的思维将故事作为直接指令来处理。NLP的创始人之一班德勒曾告诫NLP实践人员要学会引用。他深知演讲者以故事和引用的方式去传达信息会更为有效。多读、多用引用,然后将指令嵌入其中,是对该技术的一种极致应用。
例如有一次,我需要让目标给我旧密码,以便将其“修改”成更加安全的密码。我伪装成技术支持人员,当然他们会询问为何需要修改密码。于是我采用了这样的方法:“Xavier研究公司近期的一项研究指出,在美国企业中74%的人使用较弱的密码。这就是我们推出这项强制要求在企业范围内更改密码计划的缘由。我会帮你更改密码,你把旧的Windows密码告诉我,我即刻就能改好。”通过引用研究机构的说辞,我的话变得更有分量。
善用否定 善用否定利用的是人们的逆反心理。当阻止目标过多关注一件事时,往往也能在其中嵌入指令。比如说,在告诉你“不要花太多时间练习使用嵌入式命令”时,我就嵌入了“练习使用嵌入式命令”这一指令。我会预设你将进行一定程度的练习,如果你比较固执的话,可能会说:“不要告诉我该做什么,我会按照自己的意愿练习。”
如果你告诉某人一件事不重要或不相关时,他会下意识地格外关注,这样他就能够确定这到底是否相关。就像前文的例子,有时采取否定的方式嵌入命令可以令目标别无他选,只能执行。
使听众想象 当你问听众“……会怎么做”、“当……时,你有何感想”这样的问题时,该方法就会奏效,因为对方必须经过联想才能作答。如果我问“当名利双收时,你会怎么做?”,要回答这个问题,听者自然会想象自己又有钱、又有权的状态。同理,如果问“当你熟练掌握嵌入式指令时,会怎么样?”,我是在迫使你想象变成专家时会有何感觉。这样说吧,假使我告诉你“不要去想红色的奶牛”,你得先在脑海中勾勒出一头红色奶牛的模样,然后再告诉自己不要去想它。你潜意识的思维会先把指令中的每个词语构想出来,再进行下一步的指令执行。
在读懂这个句子时,你在潜意识里已经勾勒出了句中描绘的情形。潜意识会直接处理该句子,而不会去管上下文到底在说些什么。另一个重要的方面就在于潜意识能够操控肢体语言、面部表情、语音语调还有手势,并将其与所表达的信息联系起来。也就是说,潜意识里的行为一旦被破译,加上嵌入式指令,你能做的只有服从。
值得一提的是,在嵌入指令时,语气一定要正常。如果过分强调某个单词,只会让目标觉得有古怪,从而吓坏他,嵌入指令这一目的也就归于失败了。就像软件缓冲区溢出一样,传达的信息必须与想要溢出的指令相匹配。