<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Fuzzing on Karthik's Blog</title><link>http://kvcache.cc/tags/fuzzing/</link><description>Recent content in Fuzzing on Karthik's Blog</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Fri, 19 Jan 2024 00:00:00 +0000</lastBuildDate><atom:link href="http://kvcache.cc/tags/fuzzing/index.xml" rel="self" type="application/rss+xml"/><item><title>kAFL: Hardware-Assisted Feedback Fuzzing for OS Kernels</title><link>http://kvcache.cc/posts/kafl/</link><pubDate>Fri, 19 Jan 2024 00:00:00 +0000</pubDate><guid>http://kvcache.cc/posts/kafl/</guid><description>&lt;blockquote>
&lt;p>Paper: &lt;a href="https://nyx-fuzz.com/papers/kafl.pdf">kAFL&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;ul>
&lt;li>Feedback fuzzing of closed source kernel mode components&lt;/li>
&lt;li>Feedback using hardware capabilities
&lt;ul>
&lt;li>Intel PT
&lt;ul>
&lt;li>Q: What does it give?&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Challenges with kernel fuzzing
&lt;ul>
&lt;li>Lots of states&lt;/li>
&lt;li>Interrupts and threads&lt;/li>
&lt;li>No straightforward way to &amp;ldquo;invoke&amp;rdquo; the kernel&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Technical details
&lt;ul>
&lt;li>x86-64: Kernel and userspace is split into halves
&lt;ul>
&lt;li>Total virtual address space: 2^48
&lt;ul>
&lt;li>Why?&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Each get 2^47&lt;/li>
&lt;li>Switching from user to kernel on syscalls do not switch page table&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Intel Processor Trace
&lt;ul>
&lt;li>Three types
&lt;ul>
&lt;li>Taken-Not-Taken: For conditional jumps, tell if a branch is taken or not&lt;/li>
&lt;li>Target-IP: Indirect jumps, target IP&lt;/li>
&lt;li>Flow Update Packets: Interrupts and async events.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Filters can be added to these
&lt;ul>
&lt;li>IP range&lt;/li>
&lt;li>Privilege level / ring&lt;/li>
&lt;li>CR3 filter: Only when the cr3 value matches. Helps in filtering per process&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>System Design
&lt;ul>
&lt;li>Components
&lt;ul>
&lt;li>Host user space process: kAFL&lt;/li>
&lt;li>QEMU-PT + KVM-PT for getting the processor trace from guest&lt;/li>
&lt;li>Usermode agent in the target OS&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Setup:
&lt;ul>
&lt;li>Agent performs a hypercall to provide kernel panic handler&lt;/li>
&lt;li>Host patches this to get the feedback on crash
&lt;ul>
&lt;li>Instead of waiting for hte timeout&lt;/li>
&lt;li>Then CR3 is exchanged from agent to host
&lt;ul>
&lt;li>This is used to set the filter&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Then a shared memory address is exchanged where the agent expects the input for fuzzing&lt;/li>
&lt;li>Fuzzing loop starts&lt;/li>
&lt;li>While fuzzing is being performed, the QEMU-PT decodes the trace&lt;/li>
&lt;li>When the agent is done, it sends a hypercall (hc_finished).
&lt;ul>
&lt;li>On this VM-Exit, it stops tracing&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Fuzzing logic
&lt;ul>
&lt;li>This is the core and does similar to AFL&lt;/li>
&lt;li>Also runs fuzzing in parallel
&lt;ul>
&lt;li>Most fuzzing is not CPU bound, so this helps&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>User mode agent
&lt;ul>
&lt;li>Broken into loader and agent&lt;/li>
&lt;li>Agent lets you run arbitrary program, thus making it easier&lt;/li>
&lt;li>Also loader checks if the program crashed and so it can restart&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>KVM-PT
&lt;ul>
&lt;li>This helps in tracing virtual cpu instead of logical&lt;/li>
&lt;li>By enabling on vm-entry and disabling on vm-exit&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>QEMU-PT
&lt;ul>
&lt;li>QEMU-PT also filters the stream of executed addresses—based on previous knowledge of non-deterministic basic blocks—to prevent false-positive fuzzing results, and makes those available to the fuzzing logic as AFL-compatible bitmaps&lt;/li>
&lt;li>???&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Also cache the disassembly results to speed up populating the bitmap&lt;/li>
&lt;li>Stateful and non deterministic
&lt;ul>
&lt;li>Interrupts generate non-deterministic exections&lt;/li>
&lt;li>So the fuzzer runs the program multiple times and identifies such basic blocks&lt;/li>
&lt;li>Adds it to blacklist&lt;/li>
&lt;li>This is ignored when updating the coverage map&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Hypercalls
&lt;ul>
&lt;li>Accessible from ring3&lt;/li>
&lt;li>So add custom hypercalls that can help in fuzzing
&lt;ul>
&lt;li>Eg: crash, ask for input&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>KVM-PT
&lt;ul>
&lt;li>vCPU specific traces
&lt;ul>
&lt;li>MSR autoload feature lets you load MSRs on exit or entry&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Continuous tracing
&lt;ul>
&lt;li>Uses ToPA
&lt;ul>
&lt;li>Table of physical address&lt;/li>
&lt;li>Each address is associated with behavior on overflow
&lt;ul>
&lt;li>First -&amp;gt; interrupt&lt;/li>
&lt;li>Second -&amp;gt; Stop tracing
&lt;ul>
&lt;li>But keep it large enough for this to never happen&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>On overflow it triggers and results in vm switch&lt;/li>
&lt;li>Buffer is cleared and switched back to the VM&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>QEMU-PT
&lt;ul>
&lt;li>Userspace application to interact with KVM-PT&lt;/li>
&lt;li>When to start stop&lt;/li>
&lt;li>Also does the decoding the trace to generate a AFL map&lt;/li>
&lt;li>Our Intel PT software decoder acts like a just-in-time decoder, which means that code sections are only considered if they are executed according to the decoded trace data
&lt;ul>
&lt;li>???&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Discussion
&lt;ul>
&lt;li>OS specific code
&lt;ul>
&lt;li>Not a necessity but improves fuzzing (cr3 value, custom process to test kernel)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Kernel JIT
&lt;ul>
&lt;li>Out of scope&lt;/li>
&lt;li>But very interesting&lt;/li>
&lt;li>Intel PT does not give all the instruction pointers and need the executable to decode
&lt;ul>
&lt;li>Becomes tricky&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul></description></item></channel></rss>