这个工具专门用于寻找路由器中的安全漏洞( 二 )


文章插图
 
首先 , 我们看到querystring被定义为函数vuln的参数 , 并被get_querystring_value函数作为参数querystring使用 。除此之外 , 函数get_querystring_value还定义了一个参数name 。最后 , get_querystring_value函数定义了一个返回值 , 并用到了上面定义的两个参数 。
然后 , 通过下图我们可以看到 , 在调用sprintf函数时 , 还用到了name变量(函数get_querystring_value的返回值)和一个字符串echo %s >> /tmp/log 。这一次 , 情况略有不同 。因为我们知道sprintf函数的第一个参数是目标 , 所以 , 我们必须对command进行适当的定义 , 从而让它全面使用提供给spritnf函数的2个参数 , 而不是仅使用返回值 。生成的use-def关系如下所示:

这个工具专门用于寻找路由器中的安全漏洞

文章插图
 
使用相同的概念 , 通过这种分析方法可以为函数中的所有原子生成相应的use-def关系 。正如我们在上面看到的 , 这种关系可以被建模为一个图:“使用”用边表示 , “定义”用节点表示 。因此 , 我们可以将其转换为图分析问题 。
在污点分析术语中 , source点是程序中产生污点数据的地方 , 而sink点是污点数据可能到达也可能不到达的地方 。污点分析是确定来自source点的数据是否到达sink点 。在上面的例子中 , get_querystring_value函数是source点 , 因为它从用户输入中提取一些值 , 而system函数是sink点 。就本例来说 , 来自source点的数据确实到达了sink点 。
在我们的use-def图中 , 我们可以确定source点和sink点的定义(即节点) , 然后用一些启发式方法遍历该图 , 以确定source点的数据是否被sink点所使用 。如果是 , 那么我们就把source点标记为易受攻击的 , 并继续对其进行筛查 。
工具总结
总而言之 , 我们的工具首先利用angr的Reaching Definitions分析方法 , 生成一个由路由器固件中的函数的组成的use-def关系图 。然后 , 对该图进行相应的分析 , 以检测可能的安全漏洞 , 比如 , 如果(来自source点)用户输入到达一个危险的函数(即sink点) , 如system函数 , 我们就认为发现了一个潜在的安全漏洞 。
实际上 , 我们的工具与CodeQL或Joern等引擎的功能非常类似 , 只是我们的工具缺乏强大的查询界面而已 。
测试结果前面我们曾提到 , 使用符号执行的方法时 , 有时分析一个程序需要花费2个多小时 。但是 , 使用上面介绍的方法 , 分析同样的程序只需2分钟左右就能搞定了 。所以 , 这看起来的确是一个不错的工具 。在对该工具进行改进以消除假阳性并覆盖更多的假阴性后 , 我们在DLink和PROLiNK路由器上进行了测试 。
PROLiNK PRC2402M
使用该工具 , 我们立即发现了近20个命令注入漏洞 , 其中10个不需要身份验证 , 可以直接通过WAN接口进行访问 。我们马上向PROLiNK报告了这些漏洞 , 他们也很快做出了回应 。在这些漏洞被修复后 , 我们申请了相应的CVE编号 , 它们分别为CVE-2021-35400到CVE-2021-35409 。下面是一些易受攻击的代码片段 , 其中source点和sink点分别是:
?Source点:web_get
?Sink点:system, do_system, popen
这个工具专门用于寻找路由器中的安全漏洞

文章插图
 

这个工具专门用于寻找路由器中的安全漏洞

文章插图
 

这个工具专门用于寻找路由器中的安全漏洞

文章插图
 
硬编码的密码 , 还是后门?在这个过程中 , 我还发现了一些其他的安全漏洞 。似乎有一个硬编码的密码或后门密码 , 可以用来登录到路由器的管理面板:管理页面将用户提供的密码的md5哈希值发送到login.cgi进行验证 , 相应的伪代码如下所示:
这个工具专门用于寻找路由器中的安全漏洞

文章插图
 
然而 , 在它后面还有一段可疑的代码:
这个工具专门用于寻找路由器中的安全漏洞

文章插图


推荐阅读