二次sql注入

来源:互联网 发布:微信数据储存到sd卡里 编辑:程序博客网 时间:2024/05/17 08:14
这种注入方式一般是在如下情况出现时发生:为了预防SQL注入攻击,而将输入到应用程序中的某些数据进行了“转义(escape)”,但是这些数据却又在“未被转义(Unescaped)”的查询窗体中重复使用。
例如,这里我们更改登录处理页面(在前面“攻击系统”一节中介绍的那个页面)以回避单引号:

username = escape( Request.form("username") );
password = escape( Request.form("password") );
var rso = Server.CreateObject("ADODB.Recordset");
var sql = "select * from users where username = '" + username + "' and password = '" + password + "'";
rso.open( sql, cn );


这个转义(escape)函数如下所示:

function escape(str)
{
  var s = new string(str);
  var ret;
  var re = new RegExp("'","g");
  ret = s.replace(re,"''");
  return ret;
}


请留意Jscrīpt的“String”对象在实现“replace”方法时存在一个弱点是非常重要的--下面的代码仅仅替换单引号的第一个字符:

function badescape(str)
{
  var s = new string(str);
  var ret;
  ret = s.replace("'","''");
  return ret;
}


为了能够成功地进行二次SQL注入,现在的攻击者可能不会再使用我们这里用作示例的任何方法进行SQL注入。
但是,假设应用程序允许用户可以更改他们的口令,实现这种功能的代码大致如下所示:

username = escape(Request.form("username"));
oldpassword = escape(Request.form("oldpassword"));
newpassword = escape(Request.form("newpassword"));
var rso = Server.CreateObject("ADODB.Recordset");
var sql = "select * from users where username='" + username + "' and  password = '" + oldpassword + "'";
rso.open(sql, cn);
if (rso.EOF)
{
...


设置新密码的查询与如下代码可能有些相似:

sql = "update users set password = '" + newpassword + "' where username = '" + rso("username") + "'";


在该示例代码中,rso("username")是从“login”查询中检索到的用户名称。假定用户名称为admin'--,该查询语句实际上就是下面的查询:

update users set password = 'password' where username = 'admin'--'


因此,攻击者可以通过用户名admin'--进行注册的方法,随意设置系统管理员admin的密码。

这主要强调了自始至终都要坚持输入验证的重要性,哪怕是对系统已经使用过的数据,在查询中包含该数据以前,也要坚持对其进行输入验证。
0 0
原创粉丝点击