有些情况下,应用程序可能不会直接泄露任何数据,但可以根据它的行为准确推断出有用的信息。
在探查其他类型漏洞的过程中,我们已经遇到过许多以这种方式泄露信息的情况,如下所示。
注册功能允许在选择已经存在的用户名时根据出现的错误消息枚举出已注册的用户名。
搜索引擎允许推断出未获授权就可直接查看的编入索引的文档内容(请参阅第11章了解相关内容)。
在盲目SQL注入漏洞中,可以通过给一个现有的查询增加一个二进制条件,一次一位地提取信息(请参阅第9章了解相关内容)。
.NET中的“填充提示”攻击,在这种攻击中,攻击者可以通过向服务器发送一系列请求,并观察哪些请求在解密期间导致错误,从而解密任何字符串(请参阅第18章)。
另外,根据某种对攻击者有利的事实,如果应用程序执行不同操作所用的时间各不相同,那么,应用程序行为上的这种细微差异也会导致信息泄露。这种差异由以下原因造成。
许多复杂的大型应用程序需要从数据库、消息队列与大型主机等后端系统中提取数据。为提高性能,一些应用程序缓存频繁使用的信息。同样,一些应用程序采用一种延迟加载(lazy load)模式,仅在需要时加载对象和数据。在这种情况下,应用程序会从服务器的本地缓存中迅速提取出最近访问的数据,而从相关后端系统中相对缓慢地提取出其他数据。
电子银行应用程序常常以这种方式运作,与活动账户相比,访问一个休眠账户通常需要更长的时间;这时,技巧熟练的攻击者就可以利用这种行为枚举出其他用户最近访问的账户。
有些时候,应用程序处理某个特殊请求所花的时间取决于用户提交的数据是否有效。例如,如果向登录机制提交一个有效的用户名,应用程序就会执行各种数据库查询,获取账户信息并更新审计日志,同时执行需要进行大量计算的操作,根据保存的散列确认用户提交的密码。如果攻击者能够探测到这种时间差异,他就能利用它枚举有效的用户名。
一些应用程序可能会根据用户输入执行一项操作。如果用户提交的某个数据无效,就会造成超时。例如,如果某应用程序使用cookie保存一个前端负载均衡器(load balancer)之内的主机地址,攻击者就可以操纵这个地址,扫描组织内部网络中的Web服务器。如果提交的服务器地址不属于应用程序基础设施的范围,应用程序就会立即返回一个错误。如果提交一个不存在的地址,那么尝试连接这个地址就会造成超时,然后应用程序再返回与上一种情况相同的常规错误。攻击者可以利用Burp Intruder 结果表中的响应计时器进行这种测试。注意,默认情况下这些列隐藏不可见,但可通过Columns菜单显示。