0

I am security testing an embedded ARM linux 4.19.130 IoT device - without kernel source code or ability to change the kernel due to signing.

I have managed to get a root shell.

However, by the time this happens, there is a guardian.ko LKM which has an active kernel thread, restricting what I can do.

vermagic=4.19.130 SMP mod_unload ARMv7 p2v8

/dev/mem is available and I have a user space program to read/write to it, and can patch the running thread code.

However, probably due to caching and such technicalities, it doesn't affect the running kernel thread.

There is about 20 seconds for me to patch this thread before guardian.ko decides it is not happy with my presence and reboots. Disabling reboot isn't an option here due to other factors.

  • can't change the bootargs from the bootloader
  • even if I could preventing loading of the module, it exports functions needed by the system.
  • I do have dump of the firmware and can decrypt it.
  • unloading will cause a crash.

Memory protections seem to prevent me from changing things like kallsyms and the like from my own LKM (though I can insmod one) in traditional hooking fashion. The only way I've found is to write to /dev/mem - and this does test ok on another LKM which just prints some output when I cat a /proc device. If I change that printing code to invalid instructions it will crash when I cat the /proc file - so I know I am changing it's code.

I did try changing memory, and inserting my own LKM that has:

smp_mb();

flush_cache_all();

isb();

make memory changes with userspace program and then insert this module in the hopes it would affect the running kernel thread - but it continues as though I made no changes.

krpobes etc not available.

If it matters, the guardian.ko thread was crated with kthread_create_on_node(guardian_watcher_kthread, 0, -1, "Guardian watcher")

I am able to test my patches on my own guardian.ko and they work so not worried about if the changes I am making are valid. Memory changes to precompiled and also loaded modules is tricky due to the way they are loaded with resolved local anchors and such, but that isn't the problem here. Even if I write nonsense to it it doesn't affect how it runs.

Any suggestions? It may well be ARM specific, and somewhat obvious what approach to use to those more well versed in such things.

I am considering trying to terminate the thread from my own LKM, though not sure if that will work - and making it happen is problematic and the task_struct differs a lot from stock kernel so will take ages to figure it out.

I could ask the vendor for the kernel source and config under GPL, but they don't have a history of honoring that :(

New contributor
user46754 is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
2
  • Did you try to overwrite with nops the main guardian kernel thread loop?
    – w s
    Commented 2 days ago
  • I know what instructions to patch the guardian kernel thread loop with. Problem is finding a way to actually make the writes to the running kernel thread haven't been successful. So NOPs, other instructions or even just invalid 0xFFFFFFFFs have no effect.
    – user46754
    Commented 2 days ago

0

Browse other questions tagged or ask your own question.