ACTCMS是一款完全开源的程序,有UTF-8和GB2132两个编码版本,支持ACCESS和MSSQL两种数据库。

前言:

前两天在群闲聊的时候听群友有说遇到了个ACTCMS的系统,大家并在对ACTCMS多扯了几句,当时闲着无事便在网上搜索了下ACTCMS的漏洞信息。搜索结果针对之前版本的到是爆有注入漏洞,但对最新的3.0版貌似没有,于是就顺便去官网down了一个3.0的版本下来,抱着学习的目的对系统开始了漏洞的挖掘。

拿到程序本地搭建好后第一件事就是上后台寻找拿shell的办法,然后再看前台的注入。系统后台登陆验证的地方做的还不错,借鉴动易的方式加了个认证码,而且其认证码和认证码的开关都是直接写在配置文件当中的。这个估计是在之前版本爆了注入和后台cookie欺骗登陆漏洞和作者才加上的。

不过在后台管理系统中存在一些的弱点,主要针对取得webshell的方法,简略看了下后台系统的功能,发现取得webshell不是什么难事儿,而且方法还不止一种,我就随便测试了最简单的一种方法,在系统配置当中加上asp的上传类型,然后直接上传webshell。对于上传类型的设置整个系统当中有两处,一是网站基本设置当中的上传文件类型,这个主要是后台添加文章时候上传用的,另外一个则是用户组权限设置中的文件上传类型,这个是用于前台用户发表文章时候上传图片用的。

找到后台拿shell的办法后接下来就是看前台程序的注入了,因为针对ASP网站系统漏洞的挖掘首先还是要考虑注入。不过程序作者在变量顾虑还是非常严谨的,读了好长时间的代码我都没找出未过滤的变量,眼看前台动态的程序页都快让我给读完了,不过,就在快要接近尾声的时候让我在某处找到了一个没有过滤的变量,并且直接代入到SQL语句中,我们来看看代码!

漏洞之一、SQL注入

漏洞代码分析:

sub DelFriend()
        Dim TG_ID:TG_ID =Request("ID")         IF TG_ID = "" Then
            response.Write "请先选定好友"
            response.End
        End IF       
         TG_ID = Split(TG_ID,",")
         For I = LBound(TG_ID) To UBound(TG_ID)
                 Conn.execute("Delete from Friend_ACT   where U="& UserHS.UserID &"   and ID = "&TG_ID(i)&"")          Next
        set conn=nothing
        response.Redirect("?")
end sub

这个函数是在/user/Friend.asp文件中,函数是用于删除好友的,系统有用户互动的功能,会员与会员之间可以互相添加为好友,也可以删除好友。

从以上代码中可以看出,TG_ID变量值直接使用request获取,并且未做任何过滤就带入到SQL语句中了,这样漏洞变产生了。现在很多有经验的程序员大多数也往往会在删除记录的时候出现类似的问题。

针对这个漏洞的利用有一定局限性,可能对注入漏洞原理比较清楚的朋友可能会发现,对于ACCESS的数据库来说这个漏洞根本就没什么利用的,因为在漏洞产生的SQL语句中,并不是向数据库查询记录,而是删,页面中也不会输出任何SQL语句得到的内容。并且不管SQL语句是否正确,最终执行后的页面都是重定向到Friend.asp?,也就是说返回的页面都是一样的,这样我们也就不能根据页面情况来判断SQL语句的执行结果。

不过,若网站是使用MSSQL数据库的话,那这个漏洞就大有用处了,大家都知道在注入中MSSQL能构造的语句比ACCESS的腰强大得多,所以针对这个注入点来说应该是ACTCMS 3.0 SQL版的0day,下面我就以SQL版为例,具体说下利用方式。

对于SQL版的来说,很多朋友第一个想到的应该就是直接向数据库中添加个管理员账号或者更改管理员密码,不过网站后台系统登录的时候需要个认证码的,而认证码是无法从注入点得到的。所以说就算是有了后台管理账号密码,登录后台的几率也需要看人品。

向数据库中加管理账号密码也是可以的,不过这里需要注意下,加管理的SQL语句有点特别,因为在代码中对ID值的获取后有一段处理代码:TG_ID = Split(TG_ID,","),他的作用就是将获取到的值以逗号分隔成多个值,然后使用循环一个一个的删除数据库中的相应记录。例如在用户想批量删除他好友的时候,传送过来的只就是1,2,3,4,5,6,然后程序就分别去删除ID为1、2、3、4、5、6的记录,而不是去删除ID等于1,2,3,4,5,6的记录,所这里我们要向数据库中插入记录需要使用一下语句:Friend.asp?A=Del&ID=1;insert into Admin_Act (Admin_Name) values (enjoyhack);update Admin_Act set PassWord=225cdc811adfe8d4 where Admin_Name=enjoyhack;update Admin_Act set SuperTF=1 where Admin_Name=enjoyhack,插入管理后在后台登陆会报错,不过验证是通过了的,直接访问admin/f.asp页面即可。

上面说到的是利用注入点加管理账号的方法,但由于管理后台登陆的时候需要提供认证码,而且认证码是直接写在配置文件当中的,我们光利用注入点是无法得到,所以加管理员的方法并不是很实用,这里给大家提供一个更为合适的办法,就是利用注入点更新用户组权限配置数据,添加一个asp文件的上传类型,然后前台用户发布文章直接上传webshell。

但在更新用户组权限配置的时候需要注意一点,用户组权限当中所有的项目在数据库当中是存放在Group_Act的GroupSetting字段当中,每个项目之间使用^@$@^符号隔开,所以这里我们也不能使用常规的更新方式,例如;update Group set GroupSettiong=xxxxx where id=3这样的方式是不行的,这样一来不仅不能跟新上传类型,而且还使得整个用户组的权限全部混乱了,这里我们需要先将他原来的全部配置做个备份,然后我们再将配置更新成系统初始值加一个asp上传类型,见一下语句: