fuzzware-fuzzer / fuzzware

Fuzzware's main repository. Start here to install.
Apache License 2.0
306 stars 53 forks source link

Invalid instruction - ARM TrustZone Cortex-m33 #6

Open Servax314 opened 2 years ago

Servax314 commented 2 years ago

Target

The firmware I am trying to fuzz is compiled for the following targe : Manufacturer : STMicro Board : U-585i Architecture : cortex-m33 (+TrustZone)

Setup

Fuzzware has been installed locally using the install_local.sh script. On another virtualenv, I am using unicorn 2.0.0rc7 alongside afl++ 4.01c for testing purposes.

My config.yml file is at the end of the ticket.

Tests done

I compiled and tested the firmware on the board -> works as intended. I tried to emulate it with unicorn 2.0.7 with the architecture set as : uc=Uc(UC_ARCH_ARM, UC_MODE_THUMB | UC_MODE_MCLASS). It runs smoothly until it reaches peripheral accesses.

After reading the paper, I decided to use fuzzware's heuristic. When running the pipeline, I get a UC_ERR_INSN_INVALID error while executing Instr: 0xc00e1f4: vldr s0, [pc, #0x144]. This instruction is understood correctly by unicorn 2.0.0rc7, so I decided to test it with unicorn 1.0.3 (the version unicorn-fuzzware is based on, if I understood right) -> I also get the UC_ERR_INSN_INVALID error.

My question is : is this issue related to the version of unicorn used for fuzzware-unicorn ? If it is, would a fix require adding support for a more recent version of unicorn ?

config.yaml

include:
  - ./syms.yml

entry_point: 0x0c00907c
initial_sp: 0x30040000

memory_map:

  mmio:
    base_addr:  0x40000000
    size: 0x20000000
    permissions: rw-
  mmio_core:
    base_addr:  0xe0000000
    size: 0x100000
    permissions: rw-

  ram_ns:
    base_addr: 0x20000000
    permissions: rw-
    size: 0xc0000
  ram_s:
    base_addr: 0x30000000
    permissions: rw-
    size: 0xc0000  

  sbfu_flash:
    base_addr: 0x0c004000
    file: 'bin/Project.bin'
    permissions: r-x
    size: 0x00022000
    is_entry: True

  loader_flash:
    base_addr: 0x0C1FA000
    file: bin/loader.bin
    permissions: r-x
    size: 0x00006000

  data_s:
    base_addr: 0x0c026000
    file: bin/tfm_s_data_init.bin
    permissions: r-x
    size: 0x00002000

  app_s:
    base_addr: 0x0c028000
    file: bin/tfm_s_app_init.bin
    permissions: r-x
    size: 0x0002e000

  data_ns:
    base_addr: 0x0C0F6000
    file: bin/tfm_ns_data_init.bin
    permissions: r-x
    size: 0x00002000

  app_ns:
    base_addr: 0x0C056000
    file: bin/tfm_ns_app_init.bin
    permissions: r-x
    size: 0x000a0000

use_nvic: False
use_systick: False  

exit_at:
  addr: 0x0c00916a
Scepticz commented 2 years ago

Hello Servax314,

indeed, this is related the Unicorn version. Updating the Unicorn version should do the trick for the instruction decoding issue. We actually have somebody currently working on the port. It seems to be working already, but some testing is still going on. In case you are interested to collaborate on this, please let me know!

Regarding TrustZone, it depends on which features the firmware uses / requires. Our interrupt controller implementation (you can find it here) does not currently take into account TrustZone-related features. In case this makes the firmware unable to execute properly after the Unicorn version upgrade due to TrustZone feature, additional functionality here would be great to have as well.

Best, Tobi

Servax314 commented 2 years ago

I'd be happy to help on the port (or at least try to).

I also had a question about the way fuzzware deals with crypto peripherals (or any peripherals with complex internal logic). I do not get how any pre-existing model factors in internal logic for its output. For example, if the input of a crypto peripheral is an invalid signature, how would the model know to output "False"? I don't think the DSE is of any help here as it only analyze the resulting path of an output (context-less with regard to the input).

I assume a workaround would be to create a new model requiring a custom handler for its output. But would that also mean creating new rules to infer it with the DSE's result ?

If you want to take this discussion private, here is my email : n.servot@gmail.com

Servax314 commented 2 years ago

indeed, this is related the Unicorn version. Updating the Unicorn version should do the trick for the instruction decoding issue. We actually have somebody currently working on the port. It seems to be working already, but some testing is still going on. In case you are interested to collaborate on this, please let me know!

By the way Tobias, do you have the name of the corresponding branch? I wanted to check it out if possible.

Thanks

Scepticz commented 2 years ago

I already talked to the other person and he said he will get in touch. I will also further answer via email. :-)