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

Created WASM module. #3

Merged
merged 6 commits into from Apr 1, 2021
Merged

Created WASM module. #3

merged 6 commits into from Apr 1, 2021

Conversation

Copy link
Contributor

@LogoiLab LogoiLab commented Mar 31, 2021

Edit: I have solved a lot of my listed problems and learned a lot from this. Read all of my comments for my progress/brain dump on solving this and see the success in the video of my last comment.

I have created the groundwork for a WASM module that also displays the modal. Without knowing more about how coinhive calls this WASM function (i.e. the javascript that loads and runs the WASM miner), there is not much else I can do from here. If you get me a copy or stub of the actual calling javascript I can finish this implementation.

Created in rust using:

An awesome guide on how to utilize Rust with WASM: https://rustwasm.github.io/docs/wasm-bindgen/introduction.html

@LogoiLab
Copy link
Contributor Author

@LogoiLab LogoiLab commented Mar 31, 2021

I must admit after reading the CoinHive code:

image

I am not proficient enough at JavaScript to understand just what this is doing. All I need to get this to work is know what the very first function called by the CoinHive script from the WASM module is named.

@LogoiLab
Copy link
Contributor Author

@LogoiLab LogoiLab commented Mar 31, 2021

Here is the WASM file I extracted from the CoinHive JS module, pulled into radare2 it looks to have been stripped of all function names:

coinhive.wasm.zip

This WASM file is a "last resort" only unpacked from a massive bin2dec array in the CoinHive JS when asking the server for a new WASM file fails.

it appears to use emscripten which is considered "old-school" in the WASM world. This will require changes to my implementation depending on how the CoinHive script loads the WASM module.

@LogoiLab
Copy link
Contributor Author

@LogoiLab LogoiLab commented Apr 1, 2021

I have found a function call: _cryptonight_create I should be able to intercept this call and use it run the custom WASM page modifier:
image
image

@LogoiLab
Copy link
Contributor Author

@LogoiLab LogoiLab commented Apr 1, 2021

After testing a compile, the binary has the necessary function and should override the _cryptonight_create() call:
image

You can download the WASM file to test it yourself here:
coinhive_modal.wasm.zip

I currently have no idea how to get the CoinHive script to pull in this WASM file. Testing is going to be interesting to say the least.

To compile this yourself you will need to:

  1. Install Rust, use rustup
  2. Install support for the correct target, in this case just run rustup target add wasm32-unknown-unknown
  3. Install wasm-pack by running cargo install wasm-pack
  4. If you intend to test also install simple-http-server: cargo install simple-http-server
  5. Change directory to the wasm folder of this project and run: wasm-pack --target web
  6. The coinhive_modal.wasm file will be located at pkg/coinhive_modal.wasm
  7. You will probably want to strip this file as it is huge. Use the Web Assembly Binary Toolkit wasm-strip utility. (This is available in most Linux package managers, they also have release binaries).

@LogoiLab
Copy link
Contributor Author

@LogoiLab LogoiLab commented Apr 1, 2021

A video of it functioning

2021-03-31.23-11-52.mp4

@LogoiLab
Copy link
Contributor Author

@LogoiLab LogoiLab commented Apr 1, 2021

@troyhunt troyhunt merged commit dbf6d2a into troyhunt:main Apr 1, 2021
@hackcasual
Copy link

@hackcasual hackcasual commented Apr 1, 2021

This won't work, even without seeing a page that uses it. The functions imported by the modal wasm are

  (import "wbg" "__wbindgen_object_drop_ref" (func $wbg.__wbindgen_object_drop_ref (type $t5)))
  (import "wbg" "__wbg_instanceof_Window_9c4fd26090e1d029" (func $wbg.__wbg_instanceof_Window_9c4fd26090e1d029 (type $t3)))
  (import "wbg" "__wbg_document_249e9cf340780f93" (func $wbg.__wbg_document_249e9cf340780f93 (type $t3)))
  (import "wbg" "__wbg_body_0d97f334de622953" (func $wbg.__wbg_body_0d97f334de622953 (type $t3)))
  (import "wbg" "__wbg_createElement_ba61aad8af6be7f4" (func $wbg.__wbg_createElement_ba61aad8af6be7f4 (type $t2)))
  (import "wbg" "__wbg_setid_16518c90432c2f8e" (func $wbg.__wbg_setid_16518c90432c2f8e (type $t4)))
  (import "wbg" "__wbg_setclassName_5f8aa8af1f203c85" (func $wbg.__wbg_setclassName_5f8aa8af1f203c85 (type $t4)))
  (import "wbg" "__wbg_setinnerHTML_bd35babb04d64bb9" (func $wbg.__wbg_setinnerHTML_bd35babb04d64bb9 (type $t4)))
  (import "wbg" "__wbg_outerHTML_ab9cbd959fa5adc3" (func $wbg.__wbg_outerHTML_ab9cbd959fa5adc3 (type $t1)))
  (import "wbg" "__wbg_setAttribute_0b50656f1ccc45bf" (func $wbg.__wbg_setAttribute_0b50656f1ccc45bf (type $t9)))
  (import "wbg" "__wbg_settextContent_fa342bf9999ed3eb" (func $wbg.__wbg_settextContent_fa342bf9999ed3eb (type $t4)))
  (import "wbg" "__wbg_appendChild_6ae001e6d3556190" (func $wbg.__wbg_appendChild_6ae001e6d3556190 (type $t0)))
  (import "wbg" "__wbg_call_cb478d88f3068c91" (func $wbg.__wbg_call_cb478d88f3068c91 (type $t0)))
  (import "wbg" "__wbindgen_object_clone_ref" (func $wbg.__wbindgen_object_clone_ref (type $t3)))
  (import "wbg" "__wbg_newnoargs_3efc7bfa69a681f9" (func $wbg.__wbg_newnoargs_3efc7bfa69a681f9 (type $t0)))
  (import "wbg" "__wbg_self_05c54dcacb623b9a" (func $wbg.__wbg_self_05c54dcacb623b9a (type $t6)))
  (import "wbg" "__wbg_window_9777ce446d12989f" (func $wbg.__wbg_window_9777ce446d12989f (type $t6)))
  (import "wbg" "__wbg_globalThis_f0ca0bbb0149cf3d" (func $wbg.__wbg_globalThis_f0ca0bbb0149cf3d (type $t6)))
  (import "wbg" "__wbg_global_c3c8325ae8c7f1a9" (func $wbg.__wbg_global_c3c8325ae8c7f1a9 (type $t6)))
  (import "wbg" "__wbindgen_is_undefined" (func $wbg.__wbindgen_is_undefined (type $t3)))
  (import "wbg" "__wbindgen_debug_string" (func $wbg.__wbindgen_debug_string (type $t1)))
  (import "wbg" "__wbindgen_throw" (func $wbg.__wbindgen_throw (type $t1)))

These are functions that need to be provided by the page for this wasm to work, so without a way of also injecting JS, this will just cause a console error message.

The imports the existing wasm uses are

(import "env" "abort" (func $env.abort (type $t1)))
(import "env" "enlargeMemory" (func $env.enlargeMemory (type $t2)))
(import "env" "getTotalMemory" (func $env.getTotalMemory (type $t2)))
(import "env" "abortOnCannotGrowMemory" (func $env.abortOnCannotGrowMemory (type $t2)))
(import "env" "___setErrNo" (func $env.___setErrNo (type $t1)))
(import "env" "___syscall20" (func $env.___syscall20 (type $t3)))
(import "env" "_emscripten_memcpy_big" (func $env._emscripten_memcpy_big (type $t4)))
(import "env" "_ftime" (func $env._ftime (type $t5)))
(import "env" "_gmtime" (func $env._gmtime (type $t5)))

None of which seem to provide a way to access the DOM. On top of that I believe any page using this would only run the WASM inside a worker, which means we would need a way to use the postMessage interface to cause something to display

@troyhunt
Copy link
Owner

@troyhunt troyhunt commented Apr 2, 2021

I'm open to pull requests on this if anyone can find a better approach.

@LogoiLab
Copy link
Contributor Author

@LogoiLab LogoiLab commented Apr 4, 2021

Perhaps we could use the syscall20 import to do something interesting.

Edit: on second thought probably not:

int env$$__syscall20(int Which, WasmArray<int> VarArgs) {
TRACE_ENTRY();
(void)Which;
(void)VarArgs;

return trace(getpid());
}

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

Successfully merging this pull request may close these issues.

None yet

3 participants