• 豆豆
    2019-12-23
    之前只是知道些简单的 SQL 注入方式以及防范措施,今天文末的盲注确实涨了知识,关于思考题自己做了如下的练习。

    首先盲注应该也是通过 web 端的输入来实现黑客的入侵目的的,那么黑客就可以通过观察页面的反应来动态修改自己的注入参数。比如一些提交输入框,当我们提交了参数之后页面反应正常那么就说明我们的猜测是正确的,否则继续猜。

    我们都知道 MySQL 内部有一个 information_schema 的库,里面都是数据裤的元信息,那么我们就可以利用这个库进行猜测,通过观察页面的反应来验证自己的猜测是否正确。

    第一步我们要知道数据的名字,那么就先猜测其长度。以下我们会用到 DATABASE(), LENGTH(), SUBSTRING(), ASCII() 四个内置函数。

    1. 确定数据库长度

    SELECT name FROM user WHERE id = 1 AND (SELECT LENGTH(DATABASE()) = 4);

    得到数据库长度之后猜测数据库名字的每个字母。

    2. 确定数据库名字 通过 ASCII 码方式

    SELECT name FROM user WHERE id = 1 AND (SELECT ASCII(SUBSTRING(DATABASE(), 1, 1)) < 128);

    根据 ASCII 码猜测是可以使用二分法来猜测。假设的到的结果是 test。

    得到数据库名字之后,猜测 user 表有多少个列。

    3. 获取该表有多少列

    SELECT name FROM user WHERE id = 1 AND ((SELECT COUNT(*) FROM information_schema.COLUMNS WHERE table_name = 'user' AND TABLE_SCHEMA = 'test') = 3);

    获取到列的多少列之后,就可以获取到每一列的长度了。

    4. 获取列长
    SELECT name FROM user WHERE id = 1 AND ((SELECT LENGTH(column_name) FROM information_schema.COLUMNS WHERE table_name = 'user' AND TABLE_SCHEMA = 'test' LIMIT 0, 1) = 2);


    最后,获取每一列的具体值。

    5. 获取列名,同样是使用 ASCII 码方式
    SELECT name FROM user WHERE id = 1 AND ((SELECT ASCII(SUBSTRING(column_name, 1, 1)) FROM information_schema.COLUMNS WHERE table_name = 'user' AND TABLE_SCHEMA = 'test' LIMIT 0, 1) < 120)

    为了故事的顺利发展这里我假设我们已知表名 user,但是我们可以根据同样的逻辑从 information_schema.TABLES 表中获取 test 库的所有表信息。

    最后,我感觉这个方式有点傻啊,因为它依赖一些很特定的条件,比如后端没有做 SQL 注入的防护,而且还必须结合前端页面的反应。
    展开

    作者回复: 赞,是这么个原理。

    
     11
  • sober
    2019-12-24
    希望老师能抽出一节讲讲登录实战,想真正了解一下整个登录如何应用加密,谢谢老师了

    作者回复: 这块在前面的加密和认证应该有涉及,还有哪些问题,可以具体留言沟通一下。

    
     1
  • 小晏子
    2019-12-23
    研究了下盲注的文章,长见识了,以前只是大概知道sql注入,知道最简单的方式,盲注这种方法还是第一次接触,针对这个思考题,可以按如下方式获取其他字段,思路如下,可以写脚本实现,还有前提是能够进行盲注,
    1. 先判断字段的第一个字符是否在a-z中,如下所示,

    select Username from Users where UserId = 1 and 1 = (select 1 from information_schema.columns WHERE table_name='Users’ and COLUMN_NAME REGEXP '^[a-z]')
    如果结果显示Username那就说明字段的第一个字符在a到z中,

    2. 使用二分查找法在a到z之间查找第一个字符,如下语句,

    select Username from Users where UserId = 1 and 1 = (select 1 from information_schema.columns WHERE table_name='Users’ and COLUMN_NAME REGEXP '^a[a-z]')

    如果能显示Username,那么就说明a是第一个字符,再依次去查第二个字符,反之,换一个字符再试。

    3. 以此类推,可以找到所有的字段名。

    顺便说下,字段名中可能包含其他字符,如 _ 等,可以在正则表达式中同样去匹配。

    展开

    作者回复: 赞~

    
     1
  • felix
    2020-01-13
    如果是string,还是解决不了第一个password或的情况?

    作者回复: 如果是字符串拼接然后直接执行sql,那就会被注入。

    
    
  • 律飛
    2020-01-02
    作为编程小白而言,学习难度有点大哦🙄。多看了好几篇盲注的文章,仍然是晕头转向的。豆豆已经提供了很好的答案。不过我还是来说说我的理解,不足之处请老师批评指正。

    盲注其实就是结合SQL最基本的两种注入方式,不断去猜测并验证数据库可能的信息,最终获得答案的过程。这需要注入者简单的基础和丰富的经验,以及长时间频繁地跟数据库交互。

    对于这种攻击,开发者采用PreparedStatment,存储过程,验证输入等方法就可以防范攻击。

    请教老师:对于输入内容验证是不是还可以通过长度进行控制?对于盲注是不是可以通过单位时间内某个id跟数据库连接次数进行限制和预警?如果想动手试验,如何避免触碰红线?
    展开

    作者回复: 1、可以,就是有点弱。如果你限制只能一个字符的话,可能还行。
    2、可以
    3、自己搭环境。网上有开源的渗透测试环境,比如WebGoat,可以自己搭一个玩。

    
    
  • 小老鼠
    2019-12-31
    可介绍下sqlmap吗?

    作者回复: sqlmap是自动化进行sql注入的工具,这个专栏注重甲方安全防御,所以攻击只介绍原理,不会过多去涉及攻击的各种细节。这方面感兴趣的话,可以自学一下,有问题欢迎留言沟通。

    
    
  • 小老鼠
    2019-12-31
    现在SQL注入不常见了吧,现在的开发框架都可避免SQL注入了吧。比如基于python的Django。

    作者回复: 如果使用了orm的话,确实不会出现。但如果还是自己写sql的话,其实还是很普遍的。

     1
    
  • leslie
    2019-12-30
    思考题的处理方式:最简单就是用存储过程;尤其如果开发语言是.net的话。sql注入问题的爆发应当是在2008-2009年左右,sql server当时的主流版本在2005;记得当时就是由于注入的爆发,导致当时大量的数据库代码从直接写改成了调用存储过程。
    
    
  • Zhen
    2019-12-23
    了解了一下盲注,比较有意思,根据你SQL注入的攻击语句返回TRUE或者FALSE,可被用来一点点猜测获取数据库schema。 比如:如果 http://newspaper.com/items.php?id=2 and 1=2   返回FALSE;http://newspaper.com/items.php?id=2 and 1=1 返回正确,就说明后面输入的语句被服务器执行了   而且存在一个数字型的注入;那我们现在就可以开始盲注,判断它目前使用的数据库、版本、一点点猜测数据库内容。

    另外有个很初级的问题想请教一下,SQL注入是不是所有SQL数据库固有的问题?为什么数据库本身不能自我完善做到输入参数的过滤和保护,而是要Java应用程序来通过PreparedStatement来做?
    展开

    作者回复: 数据库的任务就是执行SQL,在SQL注入的过程中,JAVA提交给数据库的,就是一条完整的SQL语句。因此,从数据库的角度,是没有任何问题的。

    
    
  • Cy23
    2019-12-23
    注册的时候看input的name都有什么,基本上就了解个大概有什么字段,然后尝试猜常用的字段,
    或者查询显示的语句里注入查询表中所有字段名,然后替换字段名到显示输出的地方查看,
    突然想起原来有个资源下载的网站,原来是免费的,后来收费了,有天无意将页面上下载所需要的分值改为负数,结果下载--为正给我加分了,然后尝试修改分值大小,结果我给自己充满了,我把这个漏洞告诉给站长,站长为了表示感谢奖励我1000分,然后我发现,我那999999999变成了1000。

    作者回复: 这是典型的应用逻辑的漏洞。这种数据,必须以后台数据为准,不能拿前端的数据去修改任何后台的数据。

     1
    
  • rocedu
    2019-12-23
    要是有个课题程配套虚拟机就更好了

    作者回复: 你好,感谢你的留言。本课题的主要目的还是让大家懂得如何避免漏洞,所以只以最简单的漏洞利用原理进行讲解,实操攻击不是必须的~

    
    
  • ban
    2019-12-23
    现在应该很多大部分开发都使用 PreparedStatement 了吧

    作者回复: 我也希望是这样的。

    
    
我们在线,来聊聊吧