zoukankan      html  css  js  c++  java
  • 15.01.23-sql的注入式攻击

    很多网站上有登录和忘记密码的链接,可能存在sql注入的隐患。在忘记密码(把密码发送到邮箱)那里测试。

    获取数据

    1.'的妙用。在邮箱栏输入emailaddress',如果返回服务器错误,则说明sql注入成功,sql语句执行那里发现了多余的',然后报错。

    2.确定能够注入的情况下,输入;--。例如,在邮箱栏输入xx' or 1=1;--。这样后台组装sql语句就会变成(其中的field1、field2和table是指代,是后台的未知名称,待求证,下同):

    select field1,field2 from table where email='xx' or 1=1;--';

    这里的or 1=1让where后面的条件变成true。后面的;--则结束前面的语句,把后面的';给注释掉。这样就成功的返回了数据。

    3.能注入的前提下,多次尝试获取一个有效的email。也可以在网站的客服或者联系页面,找到相关工作人员的邮箱,然后尝试是否有注册帐号。在邮箱栏输入测试的地址,返回密码已发送到相关邮箱(类似信息),则说明这个邮箱在数据库存在帐号。

    4.前提下,获取有效的field字段。多次尝试获取。一般的用户表会包含一些类似userID,password,cellphone,email,等字段。测试方法,在where语句那里输入x' and userID=10。执行sql后,如果返回服务器错误,则说明字段错误。如果返回邮箱不正确或其他消息,则说明字段是存在的。

    4.前提下,获取有效的table。这里也是多次尝试。一般用户数据表,不外乎users,members,emails,mails,等。测试方法,在where语句那里嵌套子查询。例如,在邮箱栏输入xx' and (select count(*) from testTable)>0;--。这样后台组装sql后,执行查询时,如果testTable不存在,则会返回服务器错误,如果存在,则为邮箱不正确或者发送密码成功。

    5.在3和4中获得了tableName和field的前提下,假设上面获取的有效table名称为users,有效字段为userID,psw,email。测试此table是不是当前邮箱查询相对应的table。方法,在where语句里面用table.field=''来判断是不是和From后面的表格是同一个。具体的where语句:xx' and users.email='xx';--。此时完整的sql语句为:

    select field1,field2 from table where email='xx' and users.email='xx';--';

    这里,如果当前查询的table不是users表的话,这条语句不能通过,也就是返回结果会服务器错误。这说明表格不一致。返回其他结果,则表格一致。

    修改数据表

    6.在获得了有效工作人员邮箱和表格名及表格的“部分”有效字段后,如果当前web程序有数据库的修改权限的话可以修改数据库。具体的,可以增删改。

    改:

    select field1,field2 from users where email='admin@email.com';
        update users set email='self@email.com' where email='admin@email.com';--';

    这样就成功的将工作人员的邮箱改成了自己可用的邮箱地址。虽然同时会发送一封密码的邮件给工作人员的邮箱,但是也同时有效修改了相关帐号对应的邮箱,这时再去点击忘记密码,输入自己的邮箱self@email.com时,就能成功的获得相关的账号密码数据了。

    删:

    select field1,field2 from users where email='admin@email.com';
    drop table users;--';

    呵呵,玩笑开大了,直接删除用户表了。

    增:

    select field1,field2 from users where email='admin@email.com';
    insert into users(email,userID,pwd) select 'xx',10,'test';--';

    这样直接无声无息的在后台数据表里面增加了一条数据。虽然这条数据可能不能用,数据库有些字段不能为null,或者数据信息不够,等都可能导致数据失效,不能登录和使用。不过如果前面已经成功获取了管理员的帐号密码,这里的数据也没有管理员账号好用。o(∩_∩)o ~ 

    补救措施

    过滤查询条件里面的特殊字符,类似'(单引号);(分号,结束符)--(两个中画线,注释符)/(转义符)等等,特殊处理一下。但是这里也是有陷阱的,有些sql服务器会自动处理这些特殊字符,会自己添加转义字符,这种情况,又会死得很惨了。

    第二种方法,比较稳妥的,避免自己合成的sql语句直接执行,用sqlparameters,参数传入。例如:(类似代码,类和函数都只是说明用,不具实际用)

    var parameter = txtEmail.Text;
    var sql = new sqlParameter("select xx from users where email=p0");
    ExecuteQuery(sql, parameter);
    
    //或者linq to sql
    var f = db.users.Where(x=>x.Email==parameter);
    
    //或者linq to sql2
    var f2 = from x in db.users 
             where x.Email == parameter
             select x;

    补充说明

    1. sql注入除了防',还得防int类型的,如果后台的sql是"select field1,field2 from table where ID=",此时前台输入"5 or 1=1",连单引号都可以省略了,更加直接的注入。

    2. 可以看出来,sql注入,都是在where的条件语句里面做手脚,前台传递给后来的就是where的匹配的对象,这是sql注入式攻击基本的原理。虽然我们可以在里面做更多的select,delete,drop,update和insert等。

    3. 待研究:xp_cmdshell的开启。07年以后的版本,默认此项关闭(在外围应用配置器里没有勾选)。如果没有开启,则不会出现以上的漏洞。

  • 相关阅读:
    使用递归输出某个目录下所有子目录和文件
    如何进行复杂度分析?
    什么是时间复杂度?什么是空间复杂度?
    什么是复杂度?为什么要进行复杂度分析?
    什么是递归?递归的优缺点是什么?
    Executor 如何使用?
    什么是spring boot?为什么要用?
    spring boot核心配置文件是什么?
    @Autowired的作用是什么?
    @RequestMapping的作用是什么?
  • 原文地址:https://www.cnblogs.com/icyJ/p/4243718.html
Copyright © 2011-2022 走看看