漏洞判断
凌晨两点,漏洞判断我盯着屏幕上一段十六进制的漏洞判断输出,后背发凉。漏洞判断
那是漏洞判断一个再普通不过的登录接口,参数校验齐全,漏洞判断逻辑看着也顺眼。漏洞判断可当我往用户名后面塞了半个中文字符,漏洞判断系统居然把数据库的漏洞判断报错原封不动吐了出来。那一刻我意识到,漏洞判断漏洞这东西,漏洞判断从来不会长成你预想的漏洞判断样子。
很多年以前,漏洞判断我刚入行,漏洞判断觉得漏洞就是漏洞判断代码写错了。后来发现,漏洞判断更常见的情况是代码写对了,但人想错了。比如某个支付系统,金额字段在前端做了加密,后端也验签,看似固若金汤。但攻击者根本不碰金额,他改的是商品数量——负数。一单买下来,系统倒贴钱。你觉得他利用了漏洞吗?不,他利用的是“数量必须是正数”这个隐含假设。
这让我想起一个老段子。银行金库的锁做得再复杂,劫匪只需要在早上九点跟着运钞车进去就行。安全人员盯着密码学、盯着注入、盯着越权,却往往忘了业务逻辑本身就是一个巨大的暗面。
判断一个漏洞是否成立,我自己的土办法是问三个问题。第一,这个行为的输入,是设计者预期内的吗?第二,如果预期外,系统有没有优雅地拒绝?第三,拒绝失败后,影响范围到底有多大?
这三个问题看着简单,实操起来全是大坑。
去年帮朋友审计一个社区团购系统,发现一个“优惠券叠加”的接口。开发小哥信誓旦旦说,每种券类型在数据库里都做了唯一索引,不可能重复领取。我试了试,确实不行。但当我注册了五个新账号,每个账号领一张新人券,再把五张券都绑定到同一个手机号上呢?系统懵了,它压根没想过有人会这么干。五张券叠起来,一单三块钱的菜,实付倒贴两块五。
你看,漏洞不是bug,漏洞是“预期”和“现实”之间的缝隙。
更操蛋的是,有些缝隙你永远填不完。因为攻击者永远在找你没想过的地方下脚。今天堵住了负数数量,明天他给你传个字符串“NaN”进去,后端一解析,直接跳过校验。后天你把类型检查做死了,他换了个思路,把整个请求体改成超大体积,把你服务端的内存撑爆。
有时候我会想,做安全的人像在修一座不断漏水的破船。你刚补好甲板,发现舱底在渗水;你去堵舱底,发现舷窗裂了。但这活儿的乐趣也在这儿——每一次判断漏洞,本质上都是在跟另一个人类的大脑博弈。他在猜你怎么想,你在猜他怎么猜。
判断一个漏洞,别急着看报错日志,先问问自己:如果我是个坏蛋,我会怎么让这个系统做它不该做的事?往往那个最别扭、最不合理的路径,就是漏洞藏着的地方。
就像那半个中文字符。其实它根本不是什么高深攻击,只是因为系统用了GBK编码,半个字符恰好把后面的单引号“吃”掉了。就这么简单。简单到让人想摔键盘,又让人忍不住笑出声。