SQL注入:二次注入

SQL注入系列文章:

初识SQL注入-CSDN博客

SQL注入:联合查询的三个绕过技巧-CSDN博客

SQL注入:报错注入-CSDN博客

SQL注入:盲注-CSDN博客

目录

什么是二次注入?

二次注入演示

1、可以注册新用户

2、可以登录->修改密码

3、可以忘记密码

[WEB|\[CISCN2019 华北赛区 Day1 Web5 CyberPun](#[WEB|[CISCN2019 华北赛区 Day1 Web5 ] CyberPun)

利用文件包含漏洞来读取源码

二次注入


前面和大家分享了SQL注入中的,联合查询,报错注入,盲注,还有一个非常好用的SQL注入技巧就是二次注入,那么再本篇,我会和搭建通过复习+练习的方式来一起学习一下SQL注入的二次注入,那么现在我们开始ヾ(◍°∇°◍)ノ゙

这里演示的靶场还是sqli-labs

什么是二次注入?

当用户提交的恶意数据被存入数据库后,应用程序再把它读取出来用于生成新的SQL语句时,如果没有相应的安全措施,是有可能发生SQL注入的,这种注入就叫做二次注入,也叫做存储型SQL注入,下面来演示一下二次注入

二次注入演示

靶场对应的二次注入关卡是第24关,那么我们来到24关

从页面可以看到这一关是一个页面非常丰富的一关

最后分析可以得到本关我们都可以做以下动作:

1、可以注册新用户

可以看到已经注册成功了

2、可以登录->修改密码

可以看到密码也是可以修改成功的

3、可以忘记密码

可以看到作为一个安全工作者,面对忘记密码这种事情,它建议我们去hack

那么现在我们应该怎么利用这些点来进行SQL二次注入呢?

这既然是SQL注入的靶场,我想肯定需要网数据库的方面来想,比如说像前面那样闭合掉用户名,然后注释后面的其他语句,实现无密码登录,那么那些地方都会用到sql语句的查询呢,应该是登录和注册,修改密码,都会用到数据库语句查询,那可以在登录的地方测试一下:

但是从结果看出,并没有成功

注:因为这里是POST的方式传参,因此不能使用--+来进行注释,而是要用#

现在来看看后端的代码

php 复制代码
function sqllogin(){

   $username = mysql_real_escape_string($_POST["login_user"]);  //过滤了单双引号
   $password = mysql_real_escape_string($_POST["login_password"]);//过滤了单双引号
   $sql = "SELECT * FROM users WHERE username='$username' and password='$password'";
//$sql = "SELECT COUNT(*) FROM users WHERE username='$username' and password='$password'";
   $res = mysql_query($sql) or die('You tried to be real smart, Try harder!!!! :( ');
   $row = mysql_fetch_row($res);
	//print_r($row) ;
   if ($row[1]) {
			return $row[1];
   } else {
      		return 0;
   }

}

可以看出,后端代码对我们输入的登录用户名和密码进行了过滤,因此无法注入

再来看看其他文件页面的后端代码是否有可以利用的点呢?

这里发现注册页面中,对于用户名和密码,并没有什么限制,因此我们可以尝试在这里直接传入一个user001'#的用户名和密码,试试看:

可以看到注册成功了

我们可以再看看数据库,是否有该记录:

可以看到是有的

但是还有一个问题就是在登录时,我们却无法输入'这应该怎么办呢?

这里龙哥告诉我们了一个办法,我们先使用user001'#账号和密码来尝试登录一下

这里居然登录成功了,然后修改密码,这里的原本密码是可以随便写的

发现居然修改成功了,现在我们使用现在的密码来尝试登录一下user001用户

这里居然就成功登录了。

这里我们居然在不知道用户的原本密码下,直接修改了该用户的密码

这里龙哥告诉了我们原因:这里因为我们注册了一个新用户,但是修改密码时却使用的是一个已存在的用户,并且无密码的用户(因为我们的用户名中有一个注释符,将后面的密码查询判断语句注释掉了),所以我们可以修改密码成功

那为什么转义符并没有将我们用户名中的'和#转义呢:因为我们在从数据库中拿出该用户名时没有对'和#进行转义,导致将密码的检测注释了,虽然看似后端代码将我们输入的'进行了转义,但是当将输入的数据存储到数据库中时,会将'加上存储的,这样就实现了二次注入

WEB|\[CISCN2019 华北赛区 Day1 Web5 CyberPun

现在相信大家已经对二次注入有了一些了解了吧,那么下面我们再来在一个靶机例题中实践一下:

这里会使用一个在线靶场:BUUCTF在线评测 (buuoj.cn)

然后找到这个题目,启动靶机

进入靶机后就可以看到下面这个页面:

一般这种网站我们在不知道源码的情况下很难得到什么有用的信息,因此我们可以使用dirsearch来扫描一下是否有网页源码

可以看到什么东西都没有扫出来,那么现在就只能自己找了,我们先俩看看网页前端页面有没有什么可以用的信息

可以看到这里有一个file,那么说明可以利用这个file来搞事情,使用file来读取源码

利用文件包含漏洞来读取源码

payload:

php 复制代码
http://89dbaea5-2b4c-4aa5-b781-272ca2172d0c.node4.buuoj.cn:81/index.php?file=php://filter/convert.base64-encode/resource=index.php

可以看到使用这种方式确实可以读取出源码,只是源码是base64编码过的

我们可以使用base64工具来进行解码:

这样就成功的拿到了该页面的前后端源码:

php 复制代码
<?php

ini_set('open_basedir', '/var/www/html/');

// $file = $_GET["file"];
$file = (isset($_GET['file']) ? $_GET['file'] : null);
if (isset($file)){
    if (preg_match("/phar|zip|bzip2|zlib|data|input|%00/i",$file)) {
        echo('no way!');
        exit;
    }
    @include($file);
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>index</title>
<base href="./">
<meta charset="utf-8" />

<link href="assets/css/bootstrap.css" rel="stylesheet">
<link href="assets/css/custom-animations.css" rel="stylesheet">
<link href="assets/css/style.css" rel="stylesheet">

</head>
<body>
<div id="h">
	<div class="container">
        <h2>2077发售了,不来份实体典藏版吗?</h2>
        <img class="logo" src="./assets/img/logo-en.png"><!--LOGOLOGOLOGOLOGO-->
        <div class="row">
			<div class="col-md-8 col-md-offset-2 centered">
                <h3>提交订单</h3>
                <form role="form" action="./confirm.php" method="post" enctype="application/x-www-urlencoded">
                    <p>
                    <h3>姓名:</h3>
                    <input type="text" class="subscribe-input" name="user_name">
                    <h3>电话:</h3>
                    <input type="text" class="subscribe-input" name="phone">
                    <h3>地址:</h3>
                    <input type="text" class="subscribe-input" name="address">
                    </p>
                    <button class='btn btn-lg  btn-sub btn-white' type="submit">我正是送钱之人</button>
                </form>
            </div>
        </div>
    </div>
</div>

<div id="f">
    <div class="container">
		<div class="row">
            <h2 class="mb">订单管理</h2>
            <a href="./search.php">
                <button class="btn btn-lg btn-register btn-white" >我要查订单</button>
            </a>
            <a href="./change.php">
                <button class="btn btn-lg btn-register btn-white" >我要修改收货地址</button>
            </a>
            <a href="./delete.php">
                <button class="btn btn-lg btn-register btn-white" >我不想要了</button>
            </a>
		</div>
	</div>
</div>

<script src="assets/js/jquery.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="assets/js/retina-1.1.0.js"></script>
<script src="assets/js/jquery.unveilEffects.js"></script>
</body>
</html>
<!--?file=?-->

注:使用这种方法我们可以拿到每个页面的源码

二次注入

分析了各个页面的代码后,发现修改订单页面是存在二次注入的,因此我们可以先创建一个订单

php 复制代码
$pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';
    $user_name = $_POST["user_name"];
    $address = addslashes($_POST["address"]);
    $phone = $_POST["phone"];
    if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){
        $msg = 'no sql inject!';
    }else{
        $sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";
        $fetch = $db->query($sql);
    }

更新页面address使用的是addslashes,存在二次注入漏洞

addslashes() 函数返回在预定义字符之前添加反斜杠的字符串 预定义字符是:单引号(')、双引号(")、反斜杠(\)、NULL

这里addslashes将单引号(')转义为',但是进入数据库中单个 \ 是会被去除,所以存储到数据还是单引号('),更新时会被拼接到sql语句中:

php 复制代码
' ,`address`=database()#'

提交订单

修改地址:

查询订单:

然后就可以看到这里就成功的将数据库的名称注入出来了

这里还可以利用报错注入来注入:

ayload:

php 复制代码
1' and  updatexml(1,concat(0x7e,(select database()),0x7e),1)#

提交订单:

修改订单:

可以看到这里也是成功的注入出了数据库名称,然后就可以使用同样的方法分别注入出数据库名、表名、列名,然后查询数据

到此,关于SQL注入的二次注入的基本知识和实验演示就到此完毕了,还是一样,知识本篇结束了,SQL注入的知识和技巧还没有结束,后面还会和大家分享更多的关于SQL注入的技巧和实验,我们后面再见(^▽^)

相关推荐
全云在线allcloudonline1 小时前
等保服务公司能提供什么?广东创云科技一站式等保流程解析
网络安全·等保·企业服务
山东科恩光电1 小时前
如何通过穆柯隐卫MZS-01确保生产安全与人员保护?
安全
三言老师1 小时前
CentOS7.9:Redis‑Cluster集群部署结构化实战教程
linux·运维·服务器·数据库
旺仔学长 哈哈2 小时前
Spring Boot 智能停车场管理系统---附源码+数据库文档
数据库·spring boot·后端·智能停车场
ClickHouseDB2 小时前
ClickHouse托管Postgres:OLTP+OLAP,新能力解锁最佳数据平台
java·前端·数据库
数智化管理手记3 小时前
主数据重复、错漏频发?一站式主数据管理平台如何落地?
大数据·运维·数据库·人工智能·数据挖掘
吴声子夜歌3 小时前
MongoDB 4.2——选择片键
数据库·mongodb
天天进步一点点3 小时前
QSqlQuery删除sqlite数据库执行drop数据表报错database table is locked unable to fetch row问题
数据库·oracle·sqlite
音视频工程实战3 小时前
PromptQL 新手入门与实战指南
数据库·sql·算法
清川渡水4 小时前
NL2SQL 的正确打开方式:从「AI 猜 SQL」到「置信度闭环」的工程化落地
数据库·人工智能·sql