Compiled rules can execute malicious code regardless of PARANOID_EXEC
A malicious compiled rule file could escape YARA's virtual machine and execute arbitrary code despite the added checks introduced by PARANOID_EXEC.
This is possible due to the design of the virtual machine, which stores and operates on pointers to YR_OBJECTs from the virtual stack, as well as the following bugs:
OP_COUNTcan be used to read a DWORD from any arbitrary address.- the VM scratch memory is uninitialized and could leak important addresses from the real stack.
These were assigned the following IDs, respectively:
- CVE-2018-19976
- CVE-2018-19975
- CVE-2018-19974
I more detailed explanation of your exploit would be helpful. I guess your idea is using OP_COUNT to read the objects canary and craft a fake object to execute arbitrary code, is that correct?
using
OP_COUNTto read the objects canary
Yes. My PoC uses a fake function object and then executes code using OP_CALL.
more detailed explanation of your exploit would be helpful.
I have written a technical write-up that delves into the VM architecture and explains said PoC. I can publish it shortly.
@plusvic the write-up is here: https://bnbdr.github.io/posts/extracheese/ the PoC is here: https://github.com/bnbdr/swisscheese
Very good job in finding and explaining this issue. You have done an impressive job in understanding YARA's internals. This commit should solve the problem with OP_COUNT: https://github.com/VirusTotal/yara/commit/6acc08d7329413f60e0976be017e18a581450d7a
Regarding the initialization of vmem, it's now fully explained in your write-up but I guess your point is that you can read values from the the uninitialized vmem that are return addresses left in the stack, and they can be used for determining the base address where the library was loaded. Is that what you meant?
Thanks.
...from the the uninitialized vmem that are return addresses left in the stack, and they can be used for determining the base address where the library was loaded
Yeah, among other things.
#1001 should solve this issue. @bnbdr, your feedback is welcomed.
@bnbdr would you mind reviewing https://github.com/VirusTotal/yara/pull/1061? The idea is storing the canary in a structure in the heap, instead of using a global variable, this way it should be harder to determine the canary's address, at least in theory. Your feedback will be appreciated.