0%

WebAssembly 安全研究总结

WebAssembly是什么

  WebAssembly(简称wasm) 是一种可移植、体积小、加载快并且能够在浏览器上运行的一种程序文件。其能够在JavaScript通过接口进行调用执行。开发者们一直都比较关心JS的运行速度问题,V8引擎在JS的运行速度方面做了巨大的优化,但是少数情况下我们进行大量本地运算的时候,仍然可能遇到性能瓶颈,这个时候webassembly的作用就凸现出来了。例如AutoCAD利用编译器将其沉淀了30多年的代码直接编译成WebAssembly,同时性能基于之前的普通Web应用得到了很大的提升。
  C/C++/Rust源代码可以被编译为WebAssembly文件,然后JS层就可以对其进行调用。WebAssembly文件中存储着字节码,位于JavaScript引擎中的WebAssembly虚拟机将会执行字节码。字节码的执行有两种方式,一种是在运行时边读取opcode边执行,另一种则是在执行前将整个WebAssembly JIT翻译为本地汇编代码,然后直接跳转到汇编代码执行。V8采用的是第二种方式。

阅读全文 »

菜单题,add功能有一个off by null,glibc为2.35

Glibc 2.25 会检查P->fd->bk == P && P->bk->fd == P && size == prev_size,可以将large bin申请回来后,利用原来残留在fd_nextsize,bk_nextsize的指针来作为fakechunk的fd和bk,那么只需要在fd_nextsize对应堆块的bk位置低字节覆盖指向P,同理bk_nextsize对应堆块的fd位置低字节覆盖指向P,由于add时会添加’\0’,因此覆盖最少为2字节,这会导致指针的第2字节固定为0,那么就需要构造堆风水使得fakechunk的地址以X0YY结尾,由于ASLR的原因,X可以出现为0的时候,成功率为1/16。
伪造好chunk以后,利用off by null修改下一个堆块的prev_in_use,然后释放后unlink构造overlap chunk,最后先申请到_IO_2_1_stdout_劫持,泄漏environ拿到栈地址,然后申请到栈上写ROP。

阅读全文 »

首先是GET_PARAMETER可以泄漏ELF地址

然后SET_PARAMETER可以设置好后面需要用到的flag标志

阅读全文 »

wasmtime的预编译程序,用IDA进行分析,找到字符串

在gdb中对字符串进行硬件读断点rwatch *addr,然后在一个函数断下,根据断下的函数一直向上找上层函数,最终发现这个地方很可能是主菜单逻辑

阅读全文 »

首先盲目测试一下,发现switch后进行delete,仍然可以show,可以用来进行地址泄漏
审计到此处时发现很奇怪,调试得知sub_4838是获取message的个数

添加超出0x64个message时,会发现终端多输出了一个”Delete”字符串,通过gdb调试发现多余0x64的message会被free,但是指针仍然被保存存在UAF,此时再去delete整个username,会释放掉username下的所有message,造成double free使得程序崩溃。
存在UAF,可以构造fastbin 的double free,通过message将目标地址连接到fastbin中时,偶然发现fastbin会被整理到tcache中,这样就更加方便申请到目标地址处了,直接打free_hook

阅读全文 »

patch在系统的Email软件中加入了一个so库,当Email中存在image/bmp图片时会调用so库中的函数进行图片解析,其中memcpy存在溢出

可以溢出覆盖pages变量和watermark函数指针,当代码执行到后面时就可以调用到watermark函数,并且可以控制参数0和1。由于开启了地址随机化,通过观察发现系统中的boot.oat文件有RX代码区,并且每次重启或者开机其地址都不变,因此可以利用其中的gadgets。

阅读全文 »

这是一个不错的题,非常适合学习js引擎的漏洞利用方法。
题目给了patch如下

1
2
3
4
5
6
7
8
9
10
11
12
13
diff --git a/njs/src/njs_typed_array.c b/njs1/src/njs_typed_array.c
index 9242159..bc9d10b 100644
--- a/njs/src/njs_typed_array.c
+++ b/njs1/src/njs_typed_array.c
@@ -2588,7 +2588,7 @@ njs_data_view_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
return NJS_ERROR;
}

- if (njs_slow_path((offset + size) > buffer->size)) {
+ if (njs_slow_path((offset + size) > buffer->size + 0x29)) {
njs_range_error(vm, "Invalid DataView length: %uL", size);
return NJS_ERROR;
}

很明显,这是制造了一个溢出漏洞,可以通过如下代码构造溢出

阅读全文 »

当mov的次数超过10时,会生成push immediate的指令,由于push指令在cpu解析执行时,最多为4字节,于是会导致immediate立即数中后4字节成为指令。

因此,我们可以将需要的一些指令放入立即数中,比如syscall,通过构造read继续输入数据,并将数据存放于当前片段的后方。我们可以将后续的shellcode从这个read中输入。
禁用了write,因此只能进行flag的盲注

阅读全文 »

insert的时候,如果id一样,会释放第二个节点,但是当这个被释放的节点是头部节点时,即users,其位于全局中存储的指针没有清空,造成UAF。

通过UAF控制name指针,然后再结合check功能就能完成数据泄漏。同样,我们可以通过控制left和right指针,可以实现往任意地址写入一个堆地址。

阅读全文 »

WebAssembly被用在浏览器、嵌入式、云计算等领域,它使用虚拟机和字节码技术,因此能够在多平台运行无需重新编译。之前也有许多有关WebAssembly的议题出现在BlackHat大会上,经过分析,它们大多是针对程序编译为WASM以后,这个程序的行为、漏洞能否利用等方面进行的研究。比如一个程序原本具有栈溢出,但是编译为WASM文件后运行,由于WASM的架构和运行方式,使得这个程序的栈溢出消失或者变得无法利用。而我们的研究,则是侧重于如何挖掘WASM运行时的漏洞以及如何对WASM虚拟机方面的漏洞进行利用,并总结出通用的漏洞挖掘方向和利用思路。

WebAssembly运行时的架构标准如图,首先通过parser对wasm文件进行解析,将它们解析为一个虚拟机实例,虚拟机用于两种堆栈,一个是pc堆栈,用于存储跟wasm虚拟机控制流有关的指令结构体或者函数指针等;另一个是sp堆栈,用于存储wasm程序中使用到的数据,比如变量、常量等。

阅读全文 »