从sql注入学sql
sql注入原理
数据库针对我们的输入会进行查询
一般来说,数据库的查询可以是:
SELECT * FROM users WHERE name = 'skulle'
那么如果我们输入
skulle' OR 1=1; #
对于数据库而言,就会有这样一条命令
SELECT * FROM users WHERE name = 'skulle' OR 1=1; #
但是显然,不会这么简单,因为这种方法大家都知道了,因此才有了绕过
从数据库思路考虑绕过
数据库为了防止sql注入会采取一些措施,下面列举一下
-
过滤特殊字符:过滤用户输入中的特殊字符,如` ' " ; () #等,避免这些字符影响SQL语句的解析。
这是最常用的,最简单的就是双写绕过,使用编码、注释符等绕过。例如:SELECT * FROM users WHERE name = '1'; # 中使用注释符绕过对单引号的过滤。
-
参数化查询:使用参数化查询语句或者预编译语句,并且参数只接受基本类型,不直接拼接用户输入到SQL语句中。
例如:stmt = "SELECT * FROM users WHERE name = ?" stmt_prepared = db.prepare(stmt) stmt_executed = stmt_prepared.execute(input_name) 可以尝试修改参数类型为字符串,或使用EXECUTE IMMEDIATE执行非参数化查询。例如:
stmt = "SELECT * FROM users WHERE name = ?" stmt_prepared = db.prepare(stmt) input_name = "1' OR 1=1;" # 将参数改为字符串 stmt_executed = stmt_prepared.execute(str(input_name)) -
限制数据库权限:不赋予用户过高的权限,避免执行Drop Table、Shutdown之类的危险操作。通常只赋予Select、Insert、Update的权限。
尝试当前用户可利用的所有权限,或通过读取数据字典获取高权限账户密码登录
-
显示友好错误信息:不要直接将数据库的报错信息显示到用户界面,以免泄露过多信息。
尝试不同的注入语句,或在报错位置插入注入语句导致报错并回显信息。 -
SQL注入检测:对用户输入的数据执行SQL注入检测,检测可能存在的注入语句或 payload 并拦截。
使用编码、注释及较为隐蔽的语法等来绕过检测。例如:
SELECT * FROM users WHERE name = char(49); # 使用CHAR()编码绕过
-
安全编码:对用户数据在存储和显示的过程中,避免直接使用,转义或编码来减小SQL注入的风险。例如:
name = request.get['name'] name = mysql.escape_string(name) # 转义特殊字符 <p><?php echo htmlspecialchars($name) ?></p> # HTML编码 对应的也使用解码函数来解码,再执行注入。例如:
SELECT * FROM users WHERE name = unhex('3D') OR 1 = 1; # 使用UNHEX()解码16进制 -
WAF:使用Web应用防火墙来检测和阻挡常见的SQL注入语句,以防止注入攻击发生。
-
其他: 使用存储过程而不是直接拼接SQL语句,对注入检测结果记录日志以便追踪等。
综上,数据库主要是通过过滤特殊字符、参数化查询、权限管理、显示友好错误信息等方法来防范SQL注入。同时开发人员也需要遵循安全编码规范,增强安全意识来减小注入风险。
sql注入思路
-
sql注入要先找可供用户输入的地方,进行payload,在这之后还要考虑回显,sqlmap也是个不错的选择,但是一般情况下都会拿sqlmap试试吧
-
常见的注入方式有:拼接SQL语句、非法字符控制符注入(如;'--)、宽字节注入等
-
注入的查询语句中,信息是通过
union select
来获取的,用于抓取表名、列名、数据等信息 -
常用的过滤与绕过方式:
- 使用过滤掉'--'等字符:可使用
#、/.../
等代替 - 过滤空格:使用
/**/
代替 - 过滤关键字:使用大小写混合、编码等绕过
- 使用whitelist过滤:or 1=1--+绕过
- 过滤非数字:使用unicode字符如
ffff
代替
学习mysql
-
SELECT - 从数据库表中获取数据
SELECT * FROM users; //获取users表所有数据 SELECT name, age FROM users; //获取users表的name和age字段 -
UNION - 合并两个查询结果
SELECT * FROM users WHERE name='john' UNION SELECT * FROM info; -
WHERE - 用于过滤记录
SELECT * FROM users WHERE age=30; //获取age=30的用户 SELECT * FROM users WHERE name LIKE '%mary%'; //获取名称包含mary的用户 -
OR - 获取满足任一条件的记录
SELECT * FROM users WHERE name='john' OR age=30; -
ORDER BY - 对查询结果排序
SELECT * FROM users ORDER BY age DESC; //根据age降序排序
sql注入判断
来判断注入类型和网站漏洞情况:
- OR 1=1# - 如果该输入可以登录成功,那么很可能是数值型的布尔盲注入。
- ' OR 1=1# - 如果该输入可以登录成功,那么可能是字符型的布尔盲注入。
- OR SLEEP(5)# - 如果页面响应被延迟5秒,那么存在基于时间的盲注入。
- UNION SELECT 1,2,3# - 如果该输入可以登录成功并在页面上显示1 2 3,那么可能存在联合查询注入。
- OR '1'='1'# - 在MySQL下,如果该输入可以登录成功,那么可能存在字符回显注入。
- OR 1=1/* - 如果页面显示出错信息中包含SQL关键词,那么可能存在报错注入。
- a' AND (SELECT * FROM users WHERE username='admin') - 如果可以登录成功,那么存在提取数据的注入,并且admin账户存在。
- a' AND (SELECT * FROM users LIMIT 0,1)# - 如果每次重新输入会显示不同的用户名,那么存在基于查询结构的数据遍历注入。
本文来自博客园,作者:逆世混沌,转载请注明原文链接:https://www.cnblogs.com/nish1hundun/p/17361820.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步