计算机安全入门(1)

作者:陆麟
转载请征得作者同意.
2005.04.05



清明节, 公司有休息. 台湾把传统保持得真好. 泽及我这个在大陆上班的员工.
很久没有动手写了, 一直没有什么大篇幅的时间可写点文章. 今天再恢复写作.

看到了很多人, 一直在钻如何得到什么什么权限, 怎么怎么绕过系统安全机制. 谈论的这些内容却是十分肤浅. 普及一下安全的入门知识十分迫切. 这次普及的对象不是普通的用户, 而是PROGRAMMER们和系统分析员们.

那从什么地方开始呢? 要找个开始的切入点是个很大的问题. 那就从裸机开始谈巴.

我们所应用的PC, 能够执行指令序列. 先不考虑OS的概念, 我们假定要求做的是一个加法操作, 我们编写了一段代码, 计算2个数字的加法.

mov ax,2
mov bx,3
add ax,bx

就这么一个简单的过程, 我们仔细想一下, 我们必须有多少个部件正常运作才能够使得这个简单的操作正常运行起来.
1. 我们必须确定编译器能正确将上面的汇编语言编译成目标CPU的机器代码.
2. CPU必须能正确解码上面的指令并且执行,输出正确的结果.
这2条是远远不够的, 因为我们的指令存储在RAM中, RAM必须在CPU请求读取指令时返回正确的数据序列: b8 02 00 bb 03 00...
数据在输出时不是直接到达CPU的, 中间经过了北桥芯片.
这样一来, CPU,RAM,北桥芯片, 以及连接这3者的线路必须完整,并且没有缺陷.
扩大一点, 我们输入时候用的USB键盘, 输入时必须让我们实际键入的数据进入到内存. 而键盘是经过USB HUB, USB ROOT HUB, 南桥, 北桥,CPU,RAM. 这样, 键盘输入涉及的部分和连接线路必须是完整没有缺陷的.

只有上面所有的东西全部都没有缺陷, 一个简单的操作才得以完成.

讲了这么多是为了什么, 为了引发一个概念, TCB. Trusted Computer Base.

我们想象一下, 倘若RAM在写入时给的数据是 b8 02 00.... 当CPU要执行时, 经过北桥读到的是b8 03 00... 那么执行的代码将是mov ax,3. 操作数都错误了, 结果怎么可能正确? 这是个数据操作的例子. 如果是关键的授权认证比对过程中的跳转指令, 突然出现了问题, 那么岂不是出大问题. 授权通过的用户可能被提示密码错误, 而非授权用户可能会进入系统.

上面考虑了设备的临时故障. 假定一个恶意的芯片制造商, 已经知道你设计的代码的指令序列
X86指令:
cmp eax, 0
jz auth_pass
jmp auth_not_pass
,或者一个ARM9指令
cmp r0,0
bne auth_not_pass
b auth_pass
在加载代码时, 传送给CPU的代码变成
cmp eax,0
jmp auth_pass
jmp auth_pass
或者
cmp r0,0
b auth_pass
b auth_pass
这么一来, 你所设计的指令序列, 完全失去了效力.

我们看一下, 这个恶意的修改过程有几个地方可以发生: 1. RAM芯片,2. 北桥芯片, 3. CPU内部, 4. 主板, 扩大一点看,从数据输入开始, 键盘,USB HUB, USB HOST,南桥,北桥都可以做到这点. 在整个输入链条的任何一个节点, 插入一个可以修改数据的芯片,或者预先设计留有后门的芯片, 都可以达到同样的目的.

这个例子是十分现实的,因为我们的任何操作必须假定整个硬件链条上没有任何恶意的芯片去干这种事情.

现在, 设备经过了严格的检测, 并且确定了没有任何恶意的芯片, 并且数据和指令都可以按照操作者的意愿正常输入输出执行, 这个平台变成了最最基本的TCB. TCB是有边界的, 他的边界在于, 目前这台机器的所有组成部分, 以及你这个操作者. 一旦有人向里面插入了任何没有经过你这个操作者认证的硬件, 那个多出来的芯片就不属于TCB, 并且使得整个机器的TCB被破坏. 又或者机器没有任何硬件的变化, 但是人家对机器里面写入了任何的指令, 这个时候, 这台机器里面含有的指令就不属于TCB边界, 从而导致TCB破坏. 整个的机器都不可以被信任.

为什么人家写入了指令后就破坏了整个TCB呢? 那是因为你无法确定人家写入的代码是否提供了你正常操作的假象. 在你输入MOV AX,2时, 或许人家在后台偷偷运行的代码已经把指令改成了MOV AX,3.

就到目前本文所述的裸机而言,TCB的边界仅仅局限于此. 后文慢慢扩大TCB的概念. 待续...