avatartwo / ndss18_wycinwyc

64 stars 15 forks source link

Full simulation with Openocd error #4

Closed HotzFish closed 4 years ago

HotzFish commented 4 years ago

Hi, I use mode 3 for the full simulation. I've compiled stm32l1 and wycinwyz plugin. the error is this:

Traceback (most recent call last):
  File "nucleo_state_transfer.py", line 81, in <module>
    main()
  File "nucleo_state_transfer.py", line 32, in main
    avatar.init_targets()
  File "/home/dghost/.local/lib/python2.7/site-packages/avatar2/avatar2.py", line 210, in init_targets
    t[1].init()
  File "/home/dghost/.local/lib/python2.7/site-packages/avatar2/watchmen.py", line 78, in watchtrigger
    ret = func(self, *args, **kwargs)
  File "/home/dghost/.local/lib/python2.7/site-packages/avatar2/targets/openocd_target.py", line 49, in init
    ocd_connected = openocd.connect()
  File "/home/dghost/.local/lib/python2.7/site-packages/avatar2/protocols/openocd.py", line 109, in connect
    self.output_directory))
RuntimeError: Openocd errored! Please check /tmp/avatar/openocd_err.txt for details

and /tmp/avatar/openocd_err.txt:

Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
adapter speed: 300 kHz
adapter_nsrst_delay: 100
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
none separate
Info : Unable to match requested speed 300 kHz, using 240 kHz
Info : Unable to match requested speed 300 kHz, using 240 kHz
Info : clock speed 240 kHz
Error: open failed
in procedure 'init' 
in procedure 'ocd_bouncer'

I'm not sure where the problem is, Is there anything need to change in nucleo-l152re.cfg?

Also, I'm a little curious about openocd, It seems it can start a gdbserver and telnetd with stlink. But what's it for in this case? can I just not implement the Openocd Target? (It seems need telnet, so confused.)

THANKS A LOT!!!

HotzFish commented 4 years ago

Also when I remove OpenocdTarget , the error is follow:

Traceback (most recent call last):
  File "wycinwyc_avatar_helper.py", line 343, in <module>
    output_dir='/tmp/fuzzing', heap_object=True, stack_object=True)
  File "wycinwyc_avatar_helper.py", line 277, in start_avatar
    panda.load_plugin('wycinwyc', wycinwyc_args)
  File "/home/dghost/.local/lib/python2.7/site-packages/avatar2/targets/target.py", line 34, in check
    return func(self, *args, **kwargs)
  File "/home/dghost/.local/lib/python2.7/site-packages/avatar2/targets/panda_target.py", line 74, in load_plugin
    return self.protocols.monitor.execute_command('load_plugin', args_dict)
  File "/home/dghost/.local/lib/python2.7/site-packages/avatar2/protocols/qmp.py", line 45, in execute_command
    resp = self._telnet.read_until('\r\n'.encode('ascii'))
  File "/usr/lib/python2.7/telnetlib.py", line 294, in read_until
    return self._read_until_with_poll(match, timeout)
  File "/usr/lib/python2.7/telnetlib.py", line 329, in _read_until_with_poll
    self.fill_rawq()
  File "/usr/lib/python2.7/telnetlib.py", line 576, in fill_rawq
    buf = self.sock.recv(50)
socket.error: [Errno 104] Connection reset by peer

it seems panda.loadplugin need telnet support? don't understand

mariusmue commented 4 years ago

Hi @HotzFish.

I don't completely understand. The script you are encountering the error with, nucleo_state_transfer.py, is not part of the wycinwyc repository, but rather a generic avatar2-example. The openOCD error is: Error: open failed This can have the following reasons: 1) No Nucleo connected to your host 2) your normal user does not have the permissions to access/open the usbport

For 1, the fix would be acquiring and attaching a Nucleo STM32l152RE. For 2, you can either execute the script as root user (only recommended when using a dedicated analysis VM), creating udev rules for the STLink, or directly adding your user to the plugdev group (c.f. http://openocd.org/doc-release/README)

For your second question: avatar2 uses the qemu-monitor-protocol (in short, qmp), for some part of the communication with QEMU. (To be specific, as monitor protocol.) You can find its implementation here: https://github.com/avatartwo/avatar2/blob/master/avatar2/protocols/qmp.py As it is a text-based protocol, we use telnetlib to abstract away the low-level read/writes on the socket. However, your error is Connection reset by peer, so likely something else goes wrong and QEMU just shuts down. It may be worth investigating those files.

Cheers, Marius

HotzFish commented 4 years ago

Thanks for reply. Firstly I'm sorry about the first question. I mixed a little bit of avatar2-example code for testing. and it still init openocd target in mode 3. The second problem , It seems boofuzz 0.1.0's API has changed a little bit? the error besides the telnet error log may also be like:

Traceback (most recent call last):
  File "scripts/wycinwyc_fuzzer.py", line 389, in <module>
    main(**kwargs)
  File "scripts/wycinwyc_fuzzer.py", line 328, in main
    fuzzing_session.fuzz()
  File "/home/dghost/.local/lib/python2.7/site-packages/boofuzz/sessions.py", line 527, in fuzz
    self._main_fuzz_loop(self._iterate_protocol())
  File "/home/dghost/.local/lib/python2.7/site-packages/boofuzz/sessions.py", line 628, in _main_fuzz_loop
    self._fuzz_current_case(*fuzz_args)
  File "/home/dghost/.local/lib/python2.7/site-packages/boofuzz/sessions.py", line 1377, in _fuzz_current_case
    callback_data = self._callback_current_node(node=self.fuzz_node, edge=path[-1])
  File "/home/dghost/.local/lib/python2.7/site-packages/boofuzz/sessions.py", line 936, in _callback_current_node
    data = edge.callback(self.targets[0], self._fuzz_data_logger, session=self, node=node, edge=edge)
TypeError: select_file_cb() got multiple values for keyword argument 'session'

So , I fix the callback select_file_cb like this: def select_file_cb(target, my_logger, session, *args, **kwargs):

also the init session part I changed like this:

        csv_log = open('my_fuzz_results.csv', 'wb') 
        my_logger = [FuzzLoggerCsv(file_handle=csv_log)] 
        fuzzing_session = sessions.Session(target=target, 
                                       fuzz_loggers=my_logger,
                                       crash_threshold_element=300)#, restart_interval=50)
                                       #crash_threshold=300)

and then It seems all works fine.

Thanks again for this great project. Very useful!

mariusmue commented 4 years ago

Heya,

Thanks for the feedback, happy the project is useful for you! It seems you are right; originally, this repository did not fix the version of boofuzz, and only a commit later introduced it, c.f.: 66282d8c0f6319f676fb7db7a7bb5ed261eeeec7

However, this uses boofuzz 0.1.0, which was clearly released after the paper/code was published (https://pypi.org/project/boofuzz/0.1.0/)

As this repository is about reproducibility of the experiments in the paper, I went on and checked the original experiment setup - thankfully, we created pre-packed/ready-to-use vagrant boxes back then: https://app.vagrantup.com/avatar2 :)

Now, with commit 451cd3416cdcff4aa345dcb271c613f7da32bf79, the versions are fixed exactly to the ones in the vagrant box, which is known to replicate the experiment setup.

Thanks for reporting this issue!

HotzFish commented 4 years ago

Hi. the problem 2 (Connection reset by peer) still exist when I fuzz --format or some other option. the --heapobjects is ok. It seems because the plugin wycinwyc will read 'output_dir'/conf.json for panda setting. but it seems panda save the conf file as "panda_conf.json". So I copy panda_conf.json to conf.json", everything works fine now!

I'm not sure it's panda's update or something I changed cause this problem (My code is a little mess right now > <).

HotzFish commented 4 years ago

Also , I'm wonder for familiar OS like Linux , is there a way to read and write specific memory of a specific process using Panda?(write direct phy memory maybe?) I'm thinking whether it's practical to write a fuzzer like this, you just change the mutate data of that memory every time with Panda's replay capability.

Just a thought, hope to get some advice from you. thanks!!!

mariusmue commented 4 years ago

Heya, I think the name should be conf.json in any case, so I don't know exactly how to solve your first problem.

For the second question, panda has two different functions which you can use for writing memory which you can use from its callbacks:

int panda_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, int len, int is_write);
int panda_virtual_memory_rw(CPUState *env, target_ulong addr, uint8_t *buf, int len, int is_write);

(Taken from here: https://github.com/panda-re/panda/blob/master/panda/docs/manual.md#appendix-a-callback-list - I don't know if the API documented there is still up to date, but at least the capabilities are definitely there.)

For figuring out whether you are in a specific process, I think the panda way is to check the current ASID:

target_ulong panda_current_asid(CPUState *cpu);

However, I think more information about those APIs can be found over at the panda-re repository. :)

HotzFish commented 4 years ago

THANKS A LOT !!!