以下是一篇不完整的文章,主要记录了在审计过程中的一些记录,在面对这类复杂的代码审计的时候,一旦被打断或者过后重新复习都会花费巨大的代价,所以这次稍微记录了一下结构。
以下笔记适用于 Roundcube mail 1.4.4
|
|
在审计roundcube mail的代码过程中,我们可以把目标的重心放在program目录下,其中
include、lib、steps这三个目录分别包含了整个系统最核心的相关代码。
|
|
换言之,也就是说,除了steps以外的代码只包含类以及函数定义,并没有实际的调用代码,所以我们的目标关注点主要集中在入口点steps。
在弄明白roundcube的结构时,首先我们把目标放在路由入口处。
值得注意的是steps中的代码都是.inc结尾的,所以我们必须要从入口文件进入才能走到具体的代码部分。
首先我们要关注:
|
|
路由分配
in index.php line 100
|
|
这里通过task和action做路由表的分配。
|
|
直接指向
|
|
当然,这一切都建立在有权限的情况下,如果没有登陆,则会在
index.php line 217-251
|
|
跳回登录页面
相应的引入路由文件的代码如下

在引入每个路由文件之前,还会相应的先引入func.php。
在index.php中,除了基本的路由分配以外,还有一个重要的特性。
csrf check
in index.php line 254
|
|
跟到 program/include/rcmail.php line 961
|
|
然后跟入 program/lib/roundcube/rcube.php line 955
|
|
可以比较清晰的看到,check request只默认检查POST的token。
你必须保证session id有效,并且token与session中存取的相同
|
|
除此之外,ajax还支持把token写在header里
|
|
这个csrf check对安全性的提升是比较巨大的,可以完全防护csrf类漏洞,而且在一定程度上也保护了2次漏洞的发生(如1-click to xxx)
当然他对实际的漏洞没有防护帮助,这个token我们可以在后台的很多地方找到。
roundcube的MVC结构,出口函数为
|
|
跟随这个send函数,我们可以找到引入模板文件的位置
|
|
在602行parse主要完成引入模板的工作,跟入
|
|

从这里我们就可以看到模板被引入了,比较可惜的是,这里的模板名字无法控制,否则可以构造本地文件包含来攻击。
跟入到后面的_write函数可以看到对模板的编译以及替换
而具体到相关的模板对象编译,则到涉及到
|
|

在program/include/rcmail_output_html.php line 1472,涉及到外部object的变量会通过exechook取值,并暂时赋值为临时变量
|
|
在_write中 postrender 函数
|
|
相应的类变量被重新刷新回去
过滤函数
Roundcube在过滤函数上得思路比较清奇,主要集中在输出过滤上,在输入点或者过程储存上大多不会对数据做过多得处理。
数据的出口主要集中在
|
|
主要的过滤函数为
|
|
等这类函数,其中主要的过滤函数出口类似,我们这里主要看其中1个
|
|
然后跟入program/lib/roundcube/rcube_utils.php line 165
|
|
仔细观察不难发现,其实过滤的方向主要在单双引号的转义,尖括号的转义上。当然,这样的转义已经足够应对90%的情况了。