|
《漏洞原理图》 先看一张图。漏洞不是原理流程图,不是漏洞架构图,就是原理一张普通的网络拓扑。左边一台服务器,漏洞右边一个客户端,原理中间一条线。漏洞线上面写着一个数字:443。原理 这个数字代表端口。漏洞很多人扫一眼就过去了,原理觉得443就是漏洞HTTPS,加密的原理,安全的漏洞。但漏洞往往藏在“觉得”这两个字里。原理我见过一个真实案例,漏洞某公司内网一台测试服务器开了443,证书是自签的,密钥长度512位。运维觉得“反正内网,没人看”。结果一个实习生用openssl一行命令就把私钥爆破出来了。整个内网流量被解密,包括数据库密码。那张拓扑图上的443,不是安全标记,是入口。 漏洞原理图的核心不是画漏洞长什么样,而是画“信任”在哪里断掉。信任链断掉的地方,就是漏洞的根。 再看另一张图。这次是代码片段,不是网络图。一个登录接口,接收用户名和密码,拼成SQL语句去查数据库。代码里有一行注释:“参数已过滤,安全。”我盯着这行注释看了很久。过滤用的是str_replace,把单引号替换成空。但攻击者用双引号加反斜杠,或者用UTF-8宽字节,就能绕过。注释写“安全”的那一刻,开发者已经停止思考了。漏洞不是技术问题,是心理问题。原理图应该画出这个心理断点:从“我检查过了”到“我不再检查了”。 有人喜欢把漏洞原理图画成迷宫,说攻击路径复杂。我不这么看。真正的漏洞原理图只有三个节点:入口、信任边界、执行点。入口是数据进来的地方,信任边界是数据被当作代码或指令的地方,执行点是后果发生的地方。中间那些弯弯绕绕,是防御者自己加的戏。攻击者只看两点之间最短的那条线。 举个例子。一个文件上传功能。入口是上传表单,信任边界是服务器把文件名拼进系统命令,执行点是命令执行。原理图就三笔:一个箭头从表单指向文件名,一个箭头从文件名指向命令,一个箭头从命令指向结果。没了。什么内容检测、后缀白名单、MIME校验,都是后来补的虚线。虚线越多,说明原来的实线越危险。 我画过一张漏洞原理图,用红笔标了一个点,旁边写:“这里,开发者以为用户不会输入负数。”那是一个电商优惠券系统,输入负数数量,总价变成负的,下单后平台倒贴钱。漏洞原理图不需要画整个购物车流程,只需要画那个减法运算。减号左边是用户输入,右边是数据库里的价格。信任断在“用户输入是正数”这个假设上。假设一破,减法变加法,平台亏钱。 还有一类漏洞原理图,画的是时间。比如竞态条件。两个线程同时检查余额,都发现够,然后都扣款。原理图就是两条平行线,在“检查”和“扣款”之间有一个时间窗口。窗口越宽,漏洞越容易触发。有人把窗口画成一条缝,旁边写“0.1毫秒”。我觉得应该画成一道门,门开着的时候,攻击者可以塞进去无数个请求。时间不是缝隙,是通道。 最后说一句。漏洞原理图不是给老板看的,也不是给审计看的。是给那个写代码的人看的。他看完之后,应该能指着图上的某一个点说:“这里,我当时想错了。”如果他说不出来,那这张图就白画了。漏洞从来不是代码写错了,是人在某个瞬间停止了怀疑。原理图就是那个瞬间的截图。 |