Hi, I tried to reproduce the buffer overlow as shown in Everything Old is New Again: Binary Security of WebAssembly Fig. 5 a).
While doing that I ran in two different problems.
Firstly, when looking at the stack the number of characters put into the function vulnerable doesn't correspond to the characters copied.
When putting a string with 5 characters into the function everything seems to work as supposed.
5xC.png
With 12
12xC.png
or 16 characters it seems off.
16xC.png
Also, there will never be more then 12 bytes copied.
void vulnerable(char *input) {
char same_frame[8] = "BBBBBBBB"; // 8x B
char buffer[8];
save_stack("first");
strcpy(buffer, input);
save_stack("second");
printf("buffer: %s\n", buffer);
printf("same_frame: %s\n", same_frame);
}
void parent() {
char parent_frame[8] = "AAAAAAAA"; // 8x A
vulnerable("CCCCCCCCCCCC"); // 12x C
printf("parent_frame: %s\n", parent_frame);
}
excerpt from save_stack:
uint32 *bottom = (uint32 *) exec_env->wasm_stack.bottom;
uint32 *top = (uint32 *)exec_env->wasm_stack.top;
printf("Printing:\tBottom %p\tTop %p\n", (size_t *) bottom, (size_t *) top);
for (uint32* i = bottom; i < top; i++) {
fprintf(file, "%p\t\t%08x\n", i, *i);
}
And secondly, when executing the same example without the save_stack function with 12 characters in vulnerable I get the following output:
buffer: CCCCCCCCCCCC
same_frame: CCCC
parent_frame: AAAAAAA
and with 16 characters.
buffer: CCCCCCCCBBBBBBB
same_frame: BBBBBBB
parent_frame: AAAAAAA
Even though same_frame should just be even more overwritten?!
Does sombody know why these two things occur or has a working Buffer Overflow Example?
@Lasse Krähner Did you find any buffer overflow issue in WAMR? I tried to compile and run the source code with wasi-sdk, but the compiler reported undefined reference error for save_stack
, and if I removed calling this function, it generated wasm file successfully and iwasm output the same result with wasmtime, I think it is as expected.
For why it outputs like the above, I think it is somewhat related to wasm spec and the compiler, for example, some data is put in the wasm function's params and locals (like same_frame
pointer, buffer
pointer), some data is put in the linear memory (like "AAAAAAAAAA", "BBBBBBBB") and some is put in a shadow stack which resides in the linear memory (like struct parameter, and maybe 8 bytes of char buffer[8]
, not very sure). So maybe you need to look into the details to understand more.
@Wenyong Huang Thank you for your answer. I didn't find any new buffer overflows issues, yet.
Do you have further literature on how putting data in linear memory is working exactly and the shadow Stack?
Lasse Krähner said:
Wenyong Huang Thank you for your answer. I didn't find any new buffer overflows issues, yet.
Do you have further literature on how putting data in linear memory is working exactly and the shadow Stack?
Maybe you can refer to:
https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/doc/memory_tune.md
https://bytecodealliance.github.io/wamr.dev/blog/understand-the-wamr-heaps/
And output more details on the compiled wasm, e.g.
(1) Add more flags for wasi-sdk or clang when cimpiling C to wasm, for example:
-Wl,--emit-relocs -Wl,--export=__heap_base -Wl,--export=__data_end -Wl,--export=__stack_pointer
Note that the global __stack_pointer
is the stack pointer of the shadow stack.
(2) Dump details of wasm file with wabt objdump:
wasm-objdump -s -x -r -d xxx.wasm > xxx.log
Last updated: Dec 23 2024 at 12:05 UTC