Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

find 3 reproducible attacks on WASM programs #7

Closed
monperrus opened this issue Aug 30, 2019 · 21 comments
Closed

find 3 reproducible attacks on WASM programs #7

monperrus opened this issue Aug 30, 2019 · 21 comments
Assignees

Comments

@monperrus
Copy link
Collaborator

to support an experimental similar to Alexander's

@Jacarte Jacarte self-assigned this Sep 2, 2019
@Jacarte
Copy link
Collaborator

Jacarte commented Sep 5, 2019

@Jacarte
Copy link
Collaborator

Jacarte commented Sep 13, 2019

Added two reproducible vulnerabilities in vulnerable_programs folder. Based on https://www.forcepoint.com/sites/default/files/resources/files/report-web-assembly-memory-safety-en.pdf descriptions

Exploit description are inside c code as comments.

To create the wasm file run compile.sh <script>. This script will compile the c code to a wasm binary, a.out.wasm. To compile the c code the emsdk is needed. To launch the exploit with node, remove comment fot specific exploit code in exploit.js and then, run node exploit.js.

@monperrus
Copy link
Collaborator Author

Cool! What's the recommended way to install emsdk on Linux?

@Jacarte
Copy link
Collaborator

Jacarte commented Sep 16, 2019

Well, theoretically you just need to follow steps. There is a description for Linux installation.

@monperrus
Copy link
Collaborator Author

Thanks it works, then I meet the error below, any idea

$ node exploit.js 
Assertion failed: Cannot call unknown function func_ptr_overwrite, make sure it is exported
Assertion failed: Cannot call unknown function func_ptr_overwrite, make sure it is exported
abort(Assertion failed: Cannot call unknown function func_ptr_overwrite, make sure it is exported) at Error
    at jsStackTrace (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:1809:17)
    at stackTrace (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:1826:16)
    at abort (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:2391:44)
    at assert (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:640:5)
    at getCFunc (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:647:3)
    at Object.ccall (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:678:14)
    at Object.binary.onRuntimeInitialized (slumps/vulnerable_programs/report-web-assembly-memory-safety/exploit.js:18:25)
    at doRun (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:2294:71)
    at run (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:2311:5)
    at runCaller (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:2260:19)
abort(Assertion failed: Cannot call unknown function func_ptr_overwrite, make sure it is exported) at Error
    at jsStackTrace (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:1809:17)
    at stackTrace (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:1826:16)
    at abort (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:2391:44)
    at assert (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:640:5)
    at getCFunc (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:647:3)
    at Object.ccall (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:678:14)
    at Object.binary.onRuntimeInitialized (slumps/vulnerable_programs/report-web-assembly-memory-safety/exploit.js:18:25)
    at doRun (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:2294:71)
    at run (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:2311:5)
    at runCaller (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:2260:19)

slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:130
      throw ex;
      ^
abort(abort(Assertion failed: Cannot call unknown function func_ptr_overwrite, make sure it is exported) at Error
    at jsStackTrace (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:1809:17)
    at stackTrace (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:1826:16)
    at abort (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:2391:44)
    at assert (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:640:5)
    at getCFunc (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:647:3)
    at Object.ccall (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:678:14)
    at Object.binary.onRuntimeInitialized (slumps/vulnerable_programs/report-web-assembly-memory-safety/exploit.js:18:25)
    at doRun (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:2294:71)
    at run (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:2311:5)
    at runCaller (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:2260:19)) at Error
    at jsStackTrace (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:1809:17)
    at stackTrace (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:1826:16)
    at process.abort (slumps/vulnerable_programs/report-web-assembly-memory-safety/a.out.js:2391:44)
    at process.emit (events.js:209:13)
    at processPromiseRejections (internal/process/promises.js:201:33)
    at processTicksAndRejections (internal/process/task_queues.js:86:32)

@Jacarte
Copy link
Collaborator

Jacarte commented Sep 16, 2019

Yep...@monperrus, sorry about that, not the best solution at all, the thing is that you need to change manually the code of the exploit file. Both examples are commented inside the exploit.js file. To trigger the redirection.c or integer_overflow.c cases, you need to uncomment one of them inside the code.

I will change this mechanism :(

Exploit file content

    //============================== integer_overflow.c ===========================
    /* var result = binary.ccall('buffer_overread', 'None', ['number','number'],
    [256, 270]); */
    //=============================================================================

    //=============================== redirection.c ===================================
    /* var result = binary.ccall('func_ptr_overwrite', 'None', ['string'],
    ["AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6"]); */
    //==================================================================================

@Jacarte
Copy link
Collaborator

Jacarte commented Sep 16, 2019

Solved !!. There is a python script in the root folder. You must provide the exploit id as an argument, python3 exploit_generator.py <id>. If you don't provide one, the script will list the available ids. Then, the script will generate a exploit.js file with the correct triggering code. After successful python execution, run exploit.js.

@bbaudry
Copy link
Member

bbaudry commented Sep 17, 2019

That's great!
So, this means that we can try to break the attack through randomization, right?

@monperrus
Copy link
Collaborator Author

It works, thanks! How to see that the exploit is successful in the output?

integer_overflow
cache:INFO: generating system library: libcompiler_rt.bc... (this will be cached in "/home/martin/.emscripten_cache/asmjs/libcompiler_rt.bc" for subsequent builds)
cache:INFO:  - ok
cache:INFO: generating system library: libc-wasm.bc... (this will be cached in "/home/martin/.emscripten_cache/asmjs/libc-wasm.bc" for subsequent builds)
cache:INFO:  - ok
cache:INFO: generating system library: libdlmalloc.a... (this will be cached in "/home/martin/.emscripten_cache/asmjs/libdlmalloc.a" for subsequent builds)
cache:INFO:  - ok
cache:INFO: generating system library: libpthreads_stub.bc... (this will be cached in "/home/martin/.emscripten_cache/asmjs/libpthreads_stub.bc" for subsequent builds)
cache:INFO:  - ok
Execute the explit... node exploit.js


@Jacarte
Copy link
Collaborator

Jacarte commented Sep 17, 2019

It works, thanks! How to see that the exploit is successful in the output?

integer_overflow
cache:INFO: generating system library: libcompiler_rt.bc... (this will be cached in "/home/martin/.emscripten_cache/asmjs/libcompiler_rt.bc" for subsequent builds)
cache:INFO:  - ok
cache:INFO: generating system library: libc-wasm.bc... (this will be cached in "/home/martin/.emscripten_cache/asmjs/libc-wasm.bc" for subsequent builds)
cache:INFO:  - ok
cache:INFO: generating system library: libdlmalloc.a... (this will be cached in "/home/martin/.emscripten_cache/asmjs/libdlmalloc.a" for subsequent builds)
cache:INFO:  - ok
cache:INFO: generating system library: libpthreads_stub.bc... (this will be cached in "/home/martin/.emscripten_cache/asmjs/libpthreads_stub.bc" for subsequent builds)
cache:INFO:  - ok
Execute the explit... node exploit.js

There is a generated file, exploit.js. Run it with node: node exploit.js.

To see the content of wasm file (the textual representation), you can use https://github.com/wasmerio/vscode-wasm in VSCode

@Jacarte
Copy link
Collaborator

Jacarte commented Sep 17, 2019

That's great!
So, this means that we can try to break the attack through randomization, right?

Theoretically yes, but I want to shrink the generated code a little bit more, because, now, emcc compiler put a lot of complement code in it. Its not really pure. For example, the generated code for redirection example is transformed into a 177k lines wasm binary with several wrapped C-libraries, like stdlib and string. There is a way to only transform the declared C code in the file, but is not working calling the node engine after.

@Jacarte
Copy link
Collaborator

Jacarte commented Sep 19, 2019

Added two more reproducible vulnerabilities:

  • %n C string format bug: "Nowadays you typically only get information disclosure since many C compilers disallow the use of the %n modifier because of its security implications. The situation is the same with Wasm – it doesn’t appear to be possible to get arbitrary code execution, but information disclosure is indeed possible"

  • function pointer overwrite different signature: "Function signature check is not a water-proof way of mitigatin *against function pointer overwrites. For example, when the C (or other language) datatypes are converted to the corresponding Wasm datatypes, type confusion can occur, which can let us bypass the function signature check. For example, a C void pointer (void ) and an integer (int) both translate to the i32 datatype in Wasm. This issue is not limited to lower-level languages such as C ."

@Jacarte
Copy link
Collaborator

Jacarte commented Sep 26, 2019

@Jacarte
Copy link
Collaborator

Jacarte commented Oct 24, 2019

This can be closed, we got 4 reproducible "errors" and a new issue is open for crypto libraries attack examples.

@monperrus
Copy link
Collaborator Author

What's the URL in the repo containing the list of reproduced attacks?

@Jacarte
Copy link
Collaborator

Jacarte commented Oct 25, 2019

This is the original security report. But, I want to start the gh-pages for the repo, and it's not a bad idea to have a complete page for the vulnerabilities and a short explanation for each one.

List of available errors:

  • buffer overread vulnerability
  • function pointer hijack
  • function pointer hijack2
  • %n C string format bug

@monperrus
Copy link
Collaborator Author

monperrus commented Oct 25, 2019 via email

@Jacarte
Copy link
Collaborator

Jacarte commented Oct 31, 2019

to have a complete page for the vulnerabilities and a short explanation for each one.
Excellent, looking forward to it

Done !

Here is the gh-page of the repo

@monperrus
Copy link
Collaborator Author

monperrus commented Oct 31, 2019 via email

@Jacarte
Copy link
Collaborator

Jacarte commented Feb 7, 2020

Reformulated in #42

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants