{"@attributes":{"version":"2.0"},"channel":{"title":"The Shadow File","link":"https:\/\/shadowfile.inode.link\/","description":"Recent content on The Shadow File","generator":"Hugo","language":"en","lastBuildDate":"Sat, 29 Aug 2026 09:47:42 -1000","item":[{"title":"The Second Derivative: Why No One Understands the AI Boom - Translation","link":"https:\/\/shadowfile.inode.link\/blog\/2026\/08\/the-second-derivative-why-no-one-understands-the-ai-boom-translation\/","pubDate":"Sat, 29 Aug 2026 09:47:42 -1000","guid":"https:\/\/shadowfile.inode.link\/blog\/2026\/08\/the-second-derivative-why-no-one-understands-the-ai-boom-translation\/","description":"<p>Several weeks ago Jeff Moss, founder of DEF CON, reposted a link to this article into my Mastodon timeline: <a href=\"https:\/\/www.groundbrkr.com\/p\/the-second-derivative-why-no-one\" target=\"_blank\">The Second Derivative: Why No One Understands the AI Boom<\/a>.<\/p>\n\n<blockquote class=\"mastodon-embed\" data-embed-url=\"https:\/\/techpolicy.social\/@joebeone\/117011231660728017\/embed\" style=\"background: #FCF8FF; border-radius: 8px; border: 1px solid #C9C4DA; margin: 0; max-width: 540px; min-width: 270px; overflow: hidden; padding: 0;\"> <a href=\"https:\/\/techpolicy.social\/@joebeone\/117011231660728017\" target=\"_blank\" style=\"align-items: center; color: #1C1A25; display: flex; flex-direction: column; font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', Roboto, sans-serif; font-size: 14px; justify-content: center; letter-spacing: 0.25px; line-height: 20px; padding: 24px; text-decoration: none;\"> <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" xmlns:xlink=\"http:\/\/www.w3.org\/1999\/xlink\" width=\"32\" height=\"32\" viewBox=\"0 0 79 75\"><path d=\"M63 45.3v-20c0-4.1-1-7.3-3.2-9.7-2.1-2.4-5-3.7-8.5-3.7-4.1 0-7.2 1.6-9.3 4.7l-2 3.3-2-3.3c-2-3.1-5.1-4.7-9.2-4.7-3.5 0-6.4 1.3-8.6 3.7-2.1 2.4-3.1 5.6-3.1 9.7v20h8V25.9c0-4.1 1.7-6.2 5.2-6.2 3.8 0 5.8 2.5 5.8 7.4V37.7H44V27.1c0-4.9 1.9-7.4 5.8-7.4 3.5 0 5.2 2.1 5.2 6.2V45.3h8ZM74.7 16.6c.6 6 .1 15.7.1 17.3 0 .5-.1 4.8-.1 5.3-.7 11.5-8 16-15.6 17.5-.1 0-.2 0-.3 0-4.9 1-10 1.2-14.9 1.4-1.2 0-2.4 0-3.6 0-4.8 0-9.7-.6-14.4-1.7-.1 0-.1 0-.1 0s-.1 0-.1 0 0 .1 0 .1 0 0 0 0c.1 1.6.4 3.1 1 4.5.6 1.7 2.9 5.7 11.4 5.7 5 0 9.9-.6 14.8-1.7 0 0 0 0 0 0 .1 0 .1 0 .1 0 0 .1 0 .1 0 .1.1 0 .1 0 .1.1v5.6s0 .1-.1.1c0 0 0 0 0 .1-1.6 1.1-3.7 1.7-5.6 2.3-.8.3-1.6.5-2.4.7-7.5 1.7-15.4 1.3-22.7-1.2-6.8-2.4-13.8-8.2-15.5-15.2-.9-3.8-1.6-7.6-1.9-11.5-.6-5.8-.6-11.7-.8-17.5C3.9 24.5 4 20 4.9 16 6.7 7.9 14.1 2.2 22.3 1c1.4-.2 4.1-1 16.5-1h.1C51.4 0 56.7.8 58.1 1c8.4 1.2 15.5 7.5 16.6 15.6Z\" fill=\"currentColor\"\/><\/svg> <div style=\"color: #787588; margin-top: 16px;\">Post by @joebeone@techpolicy.social<\/div> <div style=\"font-weight: 500;\">View on Mastodon<\/div> <\/a> <\/blockquote> <script data-allowed-prefixes=\"https:\/\/techpolicy.social\/\" async src=\"https:\/\/techpolicy.social\/embed.js\"><\/script>\n<br>\n\n<p>It&rsquo;s an incredibly detailed explanation of the economics of the AI boom and how they relate to previous bubbles. Anyone trying to understand this boom and what the Minsky Moment looks like or when it might happen should give it a read.<\/p>"},{"title":"Forrester Research Note - Mythos 10 Consequences - Finance Translation","link":"https:\/\/shadowfile.inode.link\/blog\/2026\/04\/forrester-research-note-mythos-10-consequences-finance-translation\/","pubDate":"Sun, 26 Apr 2026 21:04:20 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2026\/04\/forrester-research-note-mythos-10-consequences-finance-translation\/","description":"<p>A few weeks ago Forrester Research, who would not normally be on my radar, posted a very concise &ldquo;Project Glasswing: The 10 Consequences Nobody\u2019s Writing About Yet.&rdquo; Short version: the infosec industry is about to be turned upside down over the next 2\u20135 years, and in many ways the transition is well underway.<\/p>\n<p>This is one of the most important things I&rsquo;ve read this year, and it exists at the intersection of infosec, artificial intelligence, and business &amp; economics. I feel like people in our industry are snoozing on this.<\/p>"},{"title":"Revisiting Pegasus on iOS9","link":"https:\/\/shadowfile.inode.link\/blog\/2022\/07\/revisiting-pegasus-on-ios9\/","pubDate":"Sat, 02 Jul 2022 13:50:48 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2022\/07\/revisiting-pegasus-on-ios9\/","description":"<p>What follows is a writeup of the kernel bugs NSO Group&rsquo;s Pegasus spyware exploited in iOS 9, specifically versions 9.3.4 and earlier. The spyware was discovered and the vulnerabilities patched roughly six years ago.<\/p>\n<p>Why now? Well, &ldquo;now&rdquo; isn&rsquo;t exactly the right word; I wrote this up just over four years ago. At the time, my intent wasn&rsquo;t to publish. Rather it was to better understand the practical aspects of exploiting kernel bugs in XNU, iOS&rsquo;s and macOS&rsquo;s kernel. As I explain in the writeup, there&rsquo;s often a lot of discussion of bugs themselves, and sometimes some superficial discussion of their exploitability. But there&rsquo;s rarely a soup-to-nuts discussion along the lines of &ldquo;What do these bugs actually get you? What does exploiting kernel bugs on iOS <em>actually<\/em> look like, and what do you next, having exploited them?&rdquo;. I wanted to understand <em>those aspects<\/em> of kernel exploitation, so I went through the exercise of exploiting the bugs myself, in as similar a manner as possible to what Pegasus did. I wanted to understand the challenges of:<\/p>"},{"title":"Source Level Debugging the XNU Kernel","link":"https:\/\/shadowfile.inode.link\/blog\/2018\/10\/source-level-debugging-the-xnu-kernel\/","pubDate":"Wed, 24 Oct 2018 19:50:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2018\/10\/source-level-debugging-the-xnu-kernel\/","description":"<p>Whether you&rsquo;re developing a kernel extension, doing vulnerability research, or you have some other need to spelunk into the macOS\/iOS kernel, XNU, sometimes you need to attach a debugger. And when you do that, doing it with source code is really nice when possible. <a href=\"https:\/\/twitter.com\/damiendeville\" target=\"_blank\">Damien DeVille<\/a>, <a href=\"https:\/\/twitter.com\/snare\" target=\"_blank\">Snare<\/a> and probably others have written about this process. Here are some of their articles:<\/p>\n<ul>\n<li><a href=\"http:\/\/ho.ax\/posts\/2012\/02\/debugging-the-mac-os-x-kernel-with-vmware-and-gdb\/\" target=\"_blank\">Debugging the Mac OS X kernel with VMware and GDB<\/a><\/li>\n<li><a href=\"http:\/\/ho.ax\/posts\/2012\/02\/vmware-hardware-debugging\/\" target=\"_blank\">VMware debugging II: &ldquo;Hardware&rdquo; debugging<\/a><\/li>\n<li><a href=\"http:\/\/ddeville.me\/2015\/08\/using-the-vmware-fusion-gdb-stub-for-kernel-debugging-with-lldb\" target=\"_blank\">Using the VMware Fusion GDB stub for kernel debugging with LLDB<\/a><\/li>\n<\/ul>\n<p>Things have evolved a bit. And while you can probably work it all out from the combined previous work, there are some things that aren&rsquo;t addressed. So let&rsquo;s go through it here, from scratch.<\/p>"},{"title":"Autogenerating defaults(1) Commands","link":"https:\/\/shadowfile.inode.link\/blog\/2018\/08\/autogenerating-defaults1-commands\/","pubDate":"Tue, 28 Aug 2018 13:00:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2018\/08\/autogenerating-defaults1-commands\/","description":"<p>In <a href=\"https:\/\/shadowfile.inode.link\/blog\/2018\/06\/advanced-defaults1-usage\/\">previous<\/a> posts, I described some advanced uses of the macOS <code>defaults(1)<\/code> command, including adding arbitrarily complex data structures to defaults dictionaries. I also <a href=\"https:\/\/shadowfile.inode.link\/blog\/2018\/08\/defaults-non-obvious-locations\/\">described<\/a> less than obvious locations where system and applicaton preferences get recorded. Those were all background for this article.<\/p>\n<p>It can be difficult know what plist file on disk stores a given setting, or exactly what the key (and corresponding value in that dictionary) are for a setting. In this post I&rsquo;ll describe a tool I&rsquo;ve written for detecting what file on disk is changed and exactly what the change was.<\/p>"},{"title":"Defaults Non-obvious Locations","link":"https:\/\/shadowfile.inode.link\/blog\/2018\/08\/defaults-non-obvious-locations\/","pubDate":"Sat, 18 Aug 2018 14:37:00 -0800","guid":"https:\/\/shadowfile.inode.link\/blog\/2018\/08\/defaults-non-obvious-locations\/","description":"<p>I wrote a tool that sniffs changes to macOS defaults as they change and autogenerates the <code>defaults<\/code> incantation to set those preferences. I have a post in the wings about this. For that to be useful, though, I need to establish a bit more groundwork about defaults. In particular, the various locations where the backing plist files can exist. Most are intuitive, but many are not.<\/p>\n<p>Here&rsquo;s a rundown of places where <code>defaults<\/code> plist files can exist if they&rsquo;re not in <code>~\/Library\/Preferences<\/code> or <code>\/Library\/Preferences<\/code>.<\/p>"},{"title":"Advanced defaults(1) Usage","link":"https:\/\/shadowfile.inode.link\/blog\/2018\/06\/advanced-defaults1-usage\/","pubDate":"Sat, 16 Jun 2018 12:34:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2018\/06\/advanced-defaults1-usage\/","description":"<p>Want to change Finder&rsquo;s preferred view to column view from the command line? There&rsquo;s a <code>defaults<\/code> command for that. Want to alter trackpad behavior from a shell script? Yep, <code>defaults<\/code> can do it.<\/p>\n<p>Lots of (most?) macOS and iOS settings manifest in the defaults subsystem (see Apple&rsquo;s <a href=\"https:\/\/developer.apple.com\/library\/content\/documentation\/CoreFoundation\/Conceptual\/CFPreferences\/CFPreferences.html\" target=\"_blank\">Preferences Programming Topics for Core Foundation<\/a> and <a href=\"https:\/\/developer.apple.com\/documentation\/foundation\/userdefaults\" target=\"_blank\">UserDefaults<\/a>). What this means for you, the macOS user, is many of these settings exist somewhere on disk in the form of <code>.plist<\/code> files. You can find them in <code>\/Library\/Preferences<\/code>, <code>~\/Library\/Preferences<\/code>, among other places.<\/p>"},{"title":"Broken, Abandoned, and Forgotten Code, Part 14","link":"https:\/\/shadowfile.inode.link\/blog\/2015\/11\/broken-abandoned-and-forgotten-code-part-14\/","pubDate":"Thu, 05 Nov 2015 08:30:00 -0800","guid":"https:\/\/shadowfile.inode.link\/blog\/2015\/11\/broken-abandoned-and-forgotten-code-part-14\/","description":"<p>In the previous\n<a href=\"http:\/\/shadow-file.blogspot.com\/2015\/10\/abandoned-part-13.html\" target=\"_blank\">post<\/a>,\nwe walked through building a stage 1 firmware image that can be flashed\nto the Netgear R6200 by exploiting the hidden <code>SetFirmware<\/code> SOAP action\nin <code>upnpd<\/code>. Due to an undersized memory allocation, we aren&rsquo;t able to\nflash a full sized image using this exploit. Whereas a stock firmware is\nnearly 9MB, the buffer <code>upnpd<\/code> base64 decodes into is 4MB, leading to a\ncrash. As a result we have to load our trojanized firmware in two\nstages.<\/p>"},{"title":"Broken, Abandoned, and Forgotten Code, Part 13","link":"https:\/\/shadowfile.inode.link\/blog\/2015\/10\/broken-abandoned-and-forgotten-code-part-13\/","pubDate":"Thu, 08 Oct 2015 08:30:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2015\/10\/broken-abandoned-and-forgotten-code-part-13\/","description":"<p>In the\n<a href=\"http:\/\/shadow-file.blogspot.com\/2015\/04\/abandoned-part-01.html\" target=\"_blank\">first<\/a>\ntwelve parts of this\n<a href=\"http:\/\/shadow-file.blogspot.com\/2015\/06\/abandoned-intermission.html\" target=\"_blank\">series<\/a>,\nwe identified an unauthenticated firmware update feature in the Netgear\nR6200 wireless router. Unfortunately, this feature was broken and only\npartially implemented, making exploitation less that straightforward. We\nreverse engineered the timing requirements and structure of the SOAP\nrequest required to exploit this vulnerability. We also reverse\nengineered the firmware image format, including its undocumented\nfirmware header.<\/p>\n<p>As of the previous\n<a href=\"http:\/\/shadow-file.blogspot.com\/2015\/09\/abandoned-part-12.html\" target=\"_blank\">part<\/a>,\nthe exploitation phase is complete, which is to say we are able to have\nthe Netgear UPnP daemon overwrite the firmware on flash storage with\narbitrary data of our choosing. We are able to do this without\nauthentication.<\/p>"},{"title":"Broken, Abandoned, and Forgotten Code, Part 12","link":"https:\/\/shadowfile.inode.link\/blog\/2015\/09\/broken-abandoned-and-forgotten-code-part-12\/","pubDate":"Thu, 17 Sep 2015 08:30:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2015\/09\/broken-abandoned-and-forgotten-code-part-12\/","description":"<p>In the previous\n<a href=\"http:\/\/shadow-file.blogspot.com\/2015\/07\/abandoned-part-11.html\" target=\"_blank\">part<\/a>,\nI described how to strip out all but the most essential services and\nlibraries in the stock firmware in order to get the firmware image down\nto under 4MB. This avoids crashing <code>upnpd<\/code>, which allocates less than\nhalf enough memory to base64 decode a stock-sized firmware image.<\/p>\n<p>In this part, we&rsquo;ll walk through a crasher you might encounter (or might\nnot, depending how you formatted your ambit header) and how to sidestep\nit.<\/p>"},{"title":"Broken, Abandoned, and Forgotten Code, Part 11","link":"https:\/\/shadowfile.inode.link\/blog\/2015\/07\/broken-abandoned-and-forgotten-code-part-11\/","pubDate":"Thu, 16 Jul 2015 08:00:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2015\/07\/broken-abandoned-and-forgotten-code-part-11\/","description":"<p>In the previous part, we moved away from emulation to working with\nphysical hardware. We identified a UART header inside the Netgear R6200\nthat can be used for console access. I demonstrated how to access the\nCFE bootloader&rsquo;s recovery mode to reflash a working firmware over TFTP.\nThis makes it possible to iteratively modify and test firmware images\nthat will be used in the <code>SetFirmware<\/code> UPnP exploit.<\/p>\n<p>In this part, I&rsquo;ll talk about regenerating the filesystem portion of the\nfirmware image. I&rsquo;ll also walk through shrinking the filesystem in order\nto avoid crashing <code>upnpd<\/code>.<\/p>"},{"title":"Broken, Abandoned, and Forgotten Code, Part 10","link":"https:\/\/shadowfile.inode.link\/blog\/2015\/07\/broken-abandoned-and-forgotten-code-part-10\/","pubDate":"Thu, 09 Jul 2015 08:11:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2015\/07\/broken-abandoned-and-forgotten-code-part-10\/","description":"<h3 id=\"debugging-and-de-bricking-the-netgear-r6200-via-uart\">Debugging and De-bricking the Netgear R6200 via UART<\/h3>\n<p><em>Update: I forgot to credit my former colleague, Tim\n(<a href=\"https:\/\/twitter.com\/bjt2n3904\" target=\"_blank\">@bjt2n3904<\/a>), for helping me locate the\nUART header. This project would have been way more challenging without\nthe serial connection. It would have involved desoldering the flash\nmemory chip, probably replacing it with a ZIF socket, and then removing\nand reprogramming the chip for each iteration of testing.<\/em><\/p>\n<p>In the previous\n<a href=\"http:\/\/shadow-file.blogspot.com\/2015\/06\/abandoned-part-09.html\" target=\"_blank\">installment<\/a>,\nwe filled out the ambit firmware header just enough to satisfy Netgear&rsquo;s\nbroken UPnP server. We also patched out several <code>ioctl()<\/code> calls in\n<code>upnpd<\/code> in order to test the <code>SetFirmware<\/code> exploit in emulation.<\/p>"},{"title":"Broken, Abandoned, and Forgotten Code, Part 9","link":"https:\/\/shadowfile.inode.link\/blog\/2015\/06\/broken-abandoned-and-forgotten-code-part-9\/","pubDate":"Thu, 25 Jun 2015 08:30:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2015\/06\/broken-abandoned-and-forgotten-code-part-9\/","description":"<p>In the <a href=\"http:\/\/shadow-file.blogspot.com\/2015\/06\/abandoned-part-08.html\" target=\"_blank\">previous\npart<\/a>,\nwe switched gears back to the Netgear R6200 <code>upnpd<\/code> after spending some\ntime analyzing <code>httpd<\/code>. The HTTP daemon provided an understanding of how\nthe firmware header is <em>supposed<\/em> to be constructed. We found a header\nparsing function in <code>upnpd<\/code> that was similar to its <code>httpd<\/code> counterpart.\nSo similar that it has the same <code>memcpy()<\/code> buffer overflow. This\noverflow was more interesting this time around, as it did not require\nauthentication. Additionally, we discovered a reference to the &ldquo;Ambit\nimage&rdquo; via an error message string. Presumably an ambit image is a\nfirmware format analogous to TRX. In this case, however, the ambit image\nencapsulates a TRX image.<\/p>"},{"title":"Broken, Abandoned, and Forgotten Code, Part 8","link":"https:\/\/shadowfile.inode.link\/blog\/2015\/06\/broken-abandoned-and-forgotten-code-part-8\/","pubDate":"Thu, 18 Jun 2015 08:30:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2015\/06\/broken-abandoned-and-forgotten-code-part-8\/","description":"<p>In the\n<a href=\"http:\/\/shadow-file.blogspot.com\/2015\/05\/abandoned-part-05.html\" target=\"_blank\">previous<\/a>\n<a href=\"http:\/\/shadow-file.blogspot.com\/2015\/05\/abandoned-part-06.html\" target=\"_blank\">few<\/a>\n<a href=\"http:\/\/shadow-file.blogspot.com\/2015\/06\/abandoned-part-07.html\" target=\"_blank\">posts<\/a>,\nwe spent time reversing how the Netgear R6200&rsquo;s HTTP daemon parses a\nfirmware header before writing the firmware image to flash. The goal was\nto work out how the 58-byte firmware header is constructed and how to\ngenerate a new one that can replace the header in a stock firmware. In\nthe end we identified the purpose of all but 4 bytes. The regenerated\nheader plus the original TRX firmware image allowed the HTTP daemon,\nrunning in emulation, to reach the stage where it would start writing\ndata to the <code>\/dev\/mtd1<\/code> flash partition. Considering this a win, we&rsquo;ll\nnow circle back to analyzing <code>upnpd<\/code>.<\/p>"},{"title":"Broken, Abandoned, and Forgotten Code, Intermission","link":"https:\/\/shadowfile.inode.link\/blog\/2015\/06\/broken-abandoned-and-forgotten-code-intermission\/","pubDate":"Mon, 08 Jun 2015 06:31:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2015\/06\/broken-abandoned-and-forgotten-code-intermission\/","description":"<p>We&rsquo;re about halfway through the <a href=\"http:\/\/shadow-file.blogspot.com\/2015\/04\/broken-abandoned-and-forgotten-code_22.html\" target=\"_blank\">Broken,\nAbandoned<\/a>\nseries, so this is a good time to pause for a minute and take stock. At\nthis point, things have gotten pretty technical; if you&rsquo;ve only joined\nrecently, you may be wondering what this series is about. I want to take\na moment to summarize where we&rsquo;ve been and where we can expect to go\nfrom here.<\/p>\n<h3 id=\"overview\">Overview<\/h3>\n<p>This series, entitled <em>Broken, Abandoned, and Forgotten Code<\/em>, is about\nan unauthenticated firmware update mechanism in the Netgear R6200\nwireless router&rsquo;s UPnP service. Bypassing authentication and updating\nthe firmware would be moderately interesting by itself. What makes this\nparticularly interesting, however, is this capability appears only\npartially implemented. It&rsquo;s not quite dead code; more like zombie code.\nIt&rsquo;s wired up just enough to <em>kind of<\/em>\u00a0work. There are many artifacts of\nincomplete implementation that stand in the way of straightforward\nexploitation.<\/p>"},{"title":"Broken, Abandoned, and Forgotten Code, Part 7","link":"https:\/\/shadowfile.inode.link\/blog\/2015\/06\/broken-abandoned-and-forgotten-code-part-7\/","pubDate":"Thu, 04 Jun 2015 10:37:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2015\/06\/broken-abandoned-and-forgotten-code-part-7\/","description":"<p>In the <a href=\"http:\/\/shadow-file.blogspot.com\/2015\/05\/abandoned-part-06.html\" target=\"_blank\">previous\npost<\/a>, I\nfinished discussing the <code>abCheckBoardID()<\/code> function. I called attention\nto a checksum in the header generated by an unknown algorithm. I\nprovided a python implementation of that algorithm ported from IDA\ndisassembly. In total, I identified four fields parsed by this function,\naccounting for 30 bytes of the 58 byte header.<\/p>\n<p>In this part I&rsquo;ll give an overview of the remaining functions that parse\nand validate the firmware header. By the end we will be able to generate\na header that allows the firmware to be programmed to flash memory. I\nwon&rsquo;t discuss each header field in quite as much detail as I did\npreviously, but if you&rsquo;ve made it this far, it shouldn&rsquo;t be too hard to\nunderstand how each field is used.<\/p>"},{"title":"Broken, Abandoned, and Forgotten Code, Part 6","link":"https:\/\/shadowfile.inode.link\/blog\/2015\/05\/broken-abandoned-and-forgotten-code-part-6\/","pubDate":"Thu, 28 May 2015 08:26:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2015\/05\/broken-abandoned-and-forgotten-code-part-6\/","description":"<p><strong>Note:<\/strong>\u00a0<em>It is assumed that the reader is debugging the processes\ndescribed in this and the next several posts using emulation and IDA\nPro. Those topics are outside the scope of this series and are covered\nin detail\n<a href=\"http:\/\/shadow-file.blogspot.com\/2015\/01\/dynamically-analyzing-wifi-routers-upnp.html\" target=\"_blank\">here<\/a>\nand\n<a href=\"http:\/\/shadow-file.blogspot.com\/2015\/01\/patching-emulating-and-debugging.html\" target=\"_blank\">here<\/a>.<\/em><\/p>\n<p>In the <a href=\"http:\/\/shadow-file.blogspot.com\/2015\/05\/abandoned-part-05.html\" target=\"_blank\">previous\npost<\/a>,\nwe switched gears and started looking at the web server for the Netgear\n\u00a0R6200. That&rsquo;s because the HTTP daemon&rsquo;s code for upgrading the firmware\nis less broken and easier to analyze. We also analyzed a stock firmware\nimage downloaded from Netgear to see how it is composed. Craig Heffner&rsquo;s\nbinwalk identified three parts, a TRX header at offset 58, followed by a\ncompressed Linux kernel, followed by a squashfs filesystem. All of those\nparts are well understood, which only leaves the first 58 bytes to\nanalyze.<\/p>"},{"title":"Broken, Abandoned, and Forgotten Code, Part 5","link":"https:\/\/shadowfile.inode.link\/blog\/2015\/05\/broken-abandoned-and-forgotten-code-part-5\/","pubDate":"Thu, 21 May 2015 09:30:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2015\/05\/broken-abandoned-and-forgotten-code-part-5\/","description":"<p>In\n<a href=\"http:\/\/shadow-file.blogspot.com\/2015\/04\/abandoned-part-01.html\" target=\"_blank\">previous<\/a>\n<a href=\"http:\/\/shadow-file.blogspot.com\/2015\/04\/abandoned-part-02.html\" target=\"_blank\">installments<\/a>\nI\n<a href=\"http:\/\/shadow-file.blogspot.com\/2015\/05\/abandoned-part-03.html\" target=\"_blank\">shared<\/a>\nproof-of-concept code that would exercise the Netgear R6200&rsquo;s hidden\n(and badly broken) SetFirmware SOAP action. It satisfied the various\nwonky conditions necessary to get into the <code>sa_parseRcvCmd()<\/code> function.\nThen I showed where in that function a firmware would be decoded from\nthe SOAP request and written to flash. I showed how to identify a code\npath that leads to firmware writing. In <a href=\"http:\/\/shadow-file.blogspot.com\/2015\/05\/abandoned-part-04.html\" target=\"_blank\">part\nfour<\/a>, I\nshowed how an undersized <code>malloc()<\/code> means a stock firmware crashes\n<code>upnpd<\/code>. Although we&rsquo;ll work around that bug later, for this and the\nnext several installments we&rsquo;ll be working out how the firmware image\ngets parsed so we can create our own.<\/p>"},{"title":"Broken, Abandoned, and Forgotten Code, Part 4","link":"https:\/\/shadowfile.inode.link\/blog\/2015\/05\/broken-abandoned-and-forgotten-code-part-4\/","pubDate":"Thu, 14 May 2015 09:18:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2015\/05\/broken-abandoned-and-forgotten-code-part-4\/","description":"<p>In the <a href=\"http:\/\/shadow-file.blogspot.com\/2015\/05\/abandoned-part-03.html\" target=\"_blank\">last\npost<\/a>, I\ndescribed how <code>upnpd<\/code>&rsquo;s <code>sa_parseRcvCmd()<\/code> function finds the body of a\nSOAP request and how it parses that SOAP request. This is a large and\ncomplicated function that processes many types of SOAP requests. I\ndemonstrated how to work out the desired path of execution to decode and\nwrite firmware. At the end I made an educated guess as to how the SOAP\nrequest should be formed, and how the firmware should be represented in\nthe request body.<\/p>"},{"title":"Broken, Abandoned, and Forgotten Code, Part 3","link":"https:\/\/shadowfile.inode.link\/blog\/2015\/05\/broken-abandoned-and-forgotten-code-part-3\/","pubDate":"Thu, 07 May 2015 08:00:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2015\/05\/broken-abandoned-and-forgotten-code-part-3\/","description":"<p>In the\n<a href=\"http:\/\/shadow-file.blogspot.com\/2015\/04\/abandoned-part-01.html\" target=\"_blank\">previous<\/a>\n<a href=\"http:\/\/shadow-file.blogspot.com\/2015\/04\/abandoned-part-02.html\" target=\"_blank\">posts<\/a>,\nI talked about the hidden &ldquo;SetFirmware&rdquo; SOAP action in the Netgear\nR6200&rsquo;s UPnP daemon, and the weird timing games we have play to deal\nwith UPnP daemon&rsquo;s broken networking code. I also discussed the\nhaphazard parsing of the HTTP headers across multiple functions. I made\na guess at what headers might get our SetFirmware SOAP request passed to\nthe <code>sa_parseRcvCmd()<\/code> function where hopefully an encapsulated firmware\nimage will be decoded.<\/p>"},{"title":"Broken, Abandoned, and Forgotten Code, Part 2","link":"https:\/\/shadowfile.inode.link\/blog\/2015\/04\/broken-abandoned-and-forgotten-code-part-2\/","pubDate":"Thu, 30 Apr 2015 07:59:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2015\/04\/broken-abandoned-and-forgotten-code-part-2\/","description":"<p>In the <a href=\"http:\/\/shadow-file.blogspot.com\/2015\/04\/abandoned-part-01.html\" target=\"_blank\">part\n1<\/a>, I\nshowed how the Netgear R6200&rsquo;s upnpd binary contains what appears to be\na hidden SOAP action related to the string &ldquo;<code>SetFirmware<\/code>&rdquo;. I also\nshowed how we can get into the <code>upnp_receive_firmware_packets()<\/code>\nfunction if we play timing games and send our request in multiple\nparts.<\/p>\n<p>In this part I&rsquo;ll describe additional timing considerations needed to\navoid hanging the server. I&rsquo;ll also discuss sloppy parsing of the SOAP\nrequest, and I&rsquo;ll make some guesses as to how that request should be\nformed.<\/p>"},{"title":"Broken, Abandoned, and Forgotten Code, Part 1","link":"https:\/\/shadowfile.inode.link\/blog\/2015\/04\/broken-abandoned-and-forgotten-code-part-1\/","pubDate":"Thu, 23 Apr 2015 12:00:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2015\/04\/broken-abandoned-and-forgotten-code-part-1\/","description":"<h4 id=\"introduction\">Introduction<\/h4>\n<p>This series of posts describes how abandoned, partially implemented\nfunctionality can be exploited to gain complete, persistent control of\nNetgear wireless routers. I&rsquo;ll describe a hidden SOAP method in the UPnP\nstack that, at first glance, appeared to allow unauthenticated remote\nfirmware upload to the router. After some reverse engineering, it became\napparent this functionality was never fully implemented, and could never\nwork properly given a well formed SOAP request and firmware image. If it\ncould work at all, it would be with only the most contrived of inputs.<\/p>"},{"title":"Broken, Abandoned, and Forgotten Code: Prologue","link":"https:\/\/shadowfile.inode.link\/blog\/2015\/04\/broken-abandoned-and-forgotten-code-prologue\/","pubDate":"Wed, 22 Apr 2015 17:11:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2015\/04\/broken-abandoned-and-forgotten-code-prologue\/","description":"<h3 id=\"a-secret-passage-to-persistant-soho-router-pwnage\">A Secret Passage to Persistant SOHO Router Pwnage<\/h3>\n<p>Almost two years ago plus a house selling, a cross-country move, a house\nbuying, a job change, and a wedding, I downloaded and unpacked the\nfirmware for Netgear&rsquo;s then-new <a href=\"http:\/\/www.amazon.com\/NETGEAR-Wireless-Router-Gigabit-R6200\/dp\/B008HO9DIG\/ref=sr_1_1\" target=\"_blank\">R6200 wireless\nrouter<\/a>.\nThis was one of Netgear&rsquo;s first entries into the nascent 802.11ac\nmarket. At around US$200 at the time, this device was at the high end of\nthe Netgear lineup. Finding some cool vulnerabilities in some of the\nnewest, swankiest, consumer WiFi gear would make for a neat paper, or at\nleast a good blog post or two.<\/p>"},{"title":"Bowcaster Feature: multipart\/form-data","link":"https:\/\/shadowfile.inode.link\/blog\/2015\/02\/bowcaster-feature-multipart-form-data\/","pubDate":"Fri, 20 Feb 2015 11:29:00 -0800","guid":"https:\/\/shadowfile.inode.link\/blog\/2015\/02\/bowcaster-feature-multipart-form-data\/","description":"<p>Need to reverse engineer or exploit a file upload vulnerability in an\nembedded web server? I added a <code>multipart\/form-data<\/code> class to Bowcaster\nto help with that. You can have a look here:<br>\n<a href=\"https:\/\/github.com\/zcutlip\/bowcaster\/blob\/master\/src\/bowcaster\/clients\/http.py\" target=\"_blank\">https:\/\/github.com\/zcutlip\/bowcaster\/blob\/master\/src\/bowcaster\/clients\/http.py<\/a><\/p>\n<p>Here&rsquo;s some background:<br>\nI&rsquo;ve been reverse engineering how the Netgear R6200 web server parses a\nnew firmware image when you use the firmware update facility in the web\ninterface. Manually browsing to the router&rsquo;s web interface, then to the\nfirmware update form, then browsing to a firmware file on disk, then\nclicking &ldquo;upload&rdquo; gets really tedious after a few times.<\/p>"},{"title":"Patching, Emulating, and Debugging a Netgear Embedded Web Server","link":"https:\/\/shadowfile.inode.link\/blog\/2015\/01\/patching-emulating-and-debugging-a-netgear-embedded-web-server\/","pubDate":"Sat, 31 Jan 2015 00:43:00 -0800","guid":"https:\/\/shadowfile.inode.link\/blog\/2015\/01\/patching-emulating-and-debugging-a-netgear-embedded-web-server\/","description":"<p>Previously I\n<a href=\"http:\/\/shadow-file.blogspot.com\/2015\/01\/dynamically-analyzing-wifi-routers-upnp.html\" target=\"_blank\">posted<\/a>\nabout running and remotely debugging a Netgear UPnP daemon using QEMU\nand IDA Pro. This time we\u2019ll take on the challenge of running the\nbuilt-in web server from the Netgear R6200 in emulation.<\/p>\n<p>The <code>httpd<\/code> daemon is responsible for so much more than the web\ninterface. This daemon is responsible for a silly amount of system\nmanagement, including configuring firewall rules, managing the samba and\nftp file servers, managing attached USB storage, and many other things.\nAnd it does all of this management as part of its initialization, which\nmeans lots of opportunities to fail or crash when running in emulation\nas a standalone service.<\/p>"},{"title":"Remote Debugging with QEMU and IDA Pro","link":"https:\/\/shadowfile.inode.link\/blog\/2015\/01\/remote-debugging-with-qemu-and-ida-pro\/","pubDate":"Sat, 03 Jan 2015 12:05:00 -0800","guid":"https:\/\/shadowfile.inode.link\/blog\/2015\/01\/remote-debugging-with-qemu-and-ida-pro\/","description":"<p>It&rsquo;s often the case, when analyzing an embedded device&rsquo;s firmware, that\nstatic analysis isn&rsquo;t enough. You need to actually execute a binary\nyou&rsquo;re analyzing in order to see how it behaves. In the world of\nembedded Linux devices, it&rsquo;s often fairly easy to put a debugger on the\ntarget hardware for debugging. However it&rsquo;s a lot more convenient if you\ncan run the binary right on your own system and not have to drag\nhardware around to do your analysis. Enter emulation with QEMU.<\/p>"},{"title":"Exploit Tunneling and Callback","link":"https:\/\/shadowfile.inode.link\/blog\/2014\/09\/exploit-tunneling-and-callback\/","pubDate":"Tue, 23 Sep 2014 17:32:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2014\/09\/exploit-tunneling-and-callback\/","description":"<p>A few years ago, when I worked for my previous employer, I put together\na proof-of-concept that was to be part of a client demo. I thought it\nwas kind of cool, so I recorded a screencast of it in action. I&rsquo;ve had\nthe video sitting on my laptop ever since, not really sure what to do\nwith it. I finally decided to post it.<\/p>\n<p>In the video, what you see is a custom exploit script that exploits a\nbuffer overflow in the web interfaces of several D-Link webcams. The\nneat part is that it tunnels the exploit and callback through each\nsuccessive webcam. It works basically like this:<\/p>"},{"title":"Infiltrate 2014","link":"https:\/\/shadowfile.inode.link\/blog\/2014\/05\/infiltrate-2014\/","pubDate":"Fri, 16 May 2014 14:06:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2014\/05\/infiltrate-2014\/","description":"<p>Here are some additional resources I may have mentioned in my Infiltrate\n2014 presentation.<\/p>\n<p>White Paper:\u00a0<a href=\"http:\/\/s3.amazonaws.com\/zcutlip_storage\/SQL%20Injection%20to%20MIPS%20Overflows%20-%20Part%20Deux.pdf\" target=\"_blank\">SQL Injection to MIPS Overflows - Part\nDeux<\/a><br>\nSlides: <a href=\"http:\/\/s3.amazonaws.com\/zcutlip_storage\/Cutlip_Infiltrate_2014_SQL_Injection_to_MIPS_Overflows_Part_Deux.pdf\" target=\"_blank\">SQL Injection to MIPS Overflows - Part\nDeux<\/a><\/p>\n<p>Original white paper from Black Hat USA 2012:<br>\n<a href=\"http:\/\/s3.amazonaws.com\/zcutlip_storage\/Netgear_Router_Exploitation.pdf\" target=\"_blank\">SQL Injections to MIPS Overflows: Rooting SOHO\nRouters<\/a><\/p>\n<p>Proof of Concept Exploit code:<br>\nHere&rsquo;s my Github repository for proof-of-concept exploit code. \u00a0In it,\nyou&rsquo;ll find the exploit code for the Netgear WNDR 3700v3 that I demoed\nat Infiltrate, among a few others. The white paper is in there as\nwell.<br>\n<a href=\"https:\/\/github.com\/zcutlip\/exploit-poc\" target=\"_blank\">https:\/\/github.com\/zcutlip\/exploit-poc<\/a><\/p>"},{"title":"Emulating and Debugging Workspace","link":"https:\/\/shadowfile.inode.link\/blog\/2013\/12\/emulating-and-debugging-workspace\/","pubDate":"Mon, 30 Dec 2013 12:17:00 -0800","guid":"https:\/\/shadowfile.inode.link\/blog\/2013\/12\/emulating-and-debugging-workspace\/","description":"<p>A grad student emailed me in response to my <a href=\"http:\/\/shadow-file.blogspot.com\/2013\/10\/complete-persistent-compromise-of.html\" target=\"_blank\">Netgear auth bypass\npost<\/a>.\n\u00a0He&rsquo;s working on a research project and wanted to know if I knew of any\nresources or techniques to use emulation for executing and debugging the\nnet-cgi binary in the Netgear firmware. \u00a0It turns out I&rsquo;ve got all the\nresources to do just that. \u00a0I replied with a description of my workspace\nand some links to resources I use, and, in many cases, have developed.\n\u00a0I thought this might make an interesting blog post, but I don&rsquo;t really\nhave time to write it up all blog-post-like. \u00a0Instead I&rsquo;ll just paste in\nmy email. \u00a0Maybe it&rsquo;ll be useful to other people as well.<\/p>"},{"title":"BayThreat 2013 Presentation - Additional Resources","link":"https:\/\/shadowfile.inode.link\/blog\/2013\/12\/baythreat-2013-presentation-additional-resources\/","pubDate":"Sat, 07 Dec 2013 11:30:00 -0800","guid":"https:\/\/shadowfile.inode.link\/blog\/2013\/12\/baythreat-2013-presentation-additional-resources\/","description":"<p>For my presentation at BayThreat, entitled &ldquo;BT Wireless Routers:\nAdventures in Reversing and Exploiting&rdquo;, rather than have one or two or\nthree slides packed with hard to read URLs, I included a single slide\nwith a link to this post. \u00a0Here you&rsquo;ll find links to additional\nresources that I may have referenced in my talk.<\/p>\n<p>White paper:\u00a0<a href=\"http:\/\/s3.amazonaws.com\/zcutlip_storage\/BT%20HomeHub3.0b%2044Con%20%28Zachary%20Cutlip%29.pdf\" target=\"_blank\">Reverse Engineering and Exploiting the BT HomeHub 3.0b\n(pdf)<\/a><br>\nSlides: <a href=\"http:\/\/s3.amazonaws.com\/zcutlip_storage\/Reversing%20and%20Exploiting%20BT%20CPE%20Devices%20-%20Cutlip%20-%20BayThreat.pdf\" target=\"_blank\">BT Wireless Routers: Adventures in Reversing and\nExploiting<\/a><\/p>"},{"title":"Netgear Root Compromise via Command Injection","link":"https:\/\/shadowfile.inode.link\/blog\/2013\/10\/netgear-root-compromise-via-command-injection\/","pubDate":"Thu, 24 Oct 2013 14:34:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2013\/10\/netgear-root-compromise-via-command-injection\/","description":"<p>At the end of my\n<a href=\"http:\/\/shadow-file.blogspot.com\/2013\/10\/complete-persistent-compromise-of.html\" target=\"_blank\">post<\/a>\non the Netgear wndr3700v4&rsquo;s authentication bugs, I said to expect\nfollowup posts. Once the web interface is unlocked, any further bugs\nthat normally require authentication become fair game. Well <a href=\"http:\/\/www.youtube.com\/watch?v=HHfOejlvVsY\" target=\"_blank\">good news,\neveryone!<\/a>!<\/p>\n<p>Previously, I talked about the <!-- raw HTML omitted -->net-cgi<!-- raw HTML omitted -->\nexecutable in the wndr3700&rsquo;s firmware. ;<!-- raw HTML omitted -->net-cgi<!-- raw HTML omitted --> is\na multi-call binary, a little like busybox. As such it has a lot of\nfunctionality baked in. One of its more interesting functions is called\n<!-- raw HTML omitted -->cmd_ping6()<!-- raw HTML omitted -->.\nHere&rsquo;s what it looks like:<\/p>"},{"title":"Complete, Persistent Compromise of Netgear Wireless Routers","link":"https:\/\/shadowfile.inode.link\/blog\/2013\/10\/complete-persistent-compromise-of-netgear-wireless-routers\/","pubDate":"Tue, 22 Oct 2013 06:27:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2013\/10\/complete-persistent-compromise-of-netgear-wireless-routers\/","description":"<p>UPDATE: Turns out, Jacob Holocomb\n(<a href=\"https:\/\/twitter.com\/roothak42\" target=\"_blank\">@rootHak42<\/a> on Twitter) of Independent\nSecurity Evaluators found this bug back in April on a different device,\nthe WNDR4700. Thanks for letting me know, Jacob. Nice find. Here&rsquo;s a\n<a href=\"http:\/\/securityevaluators.com\/content\/case-studies\/routers\/netgear_wndr4700.jsp\" target=\"_blank\">link<\/a>\nto that report.<\/p>\n<p>UPDATE 2: Because there are almost certainly fools who would go hack\nsomebody&rsquo;s router and say I told them to do it, I added a warning to not\ndo this. DON&rsquo;T DO IT.<\/p>"},{"title":"A Connect-back HTTP Exploit Server for Bowcaster","link":"https:\/\/shadowfile.inode.link\/blog\/2013\/10\/a-connect-back-http-exploit-server-for-bowcaster\/","pubDate":"Wed, 09 Oct 2013 09:25:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2013\/10\/a-connect-back-http-exploit-server-for-bowcaster\/","description":"<p>I&rsquo;ve just added a module to\n<a href=\"https:\/\/github.com\/zcutlip\/bowcaster\" target=\"_blank\">Bowcaster<\/a>\u00a0that I think is cool.\nActually, I just got around to finishing a module that was there all\nalong. It&rsquo;s a basic HTTP server module, but it has some unique features\nthat make it suitable for serving payloads to remotely exploited\ntargets.<\/p>\n<p>The connect-back server modules in Bowcaster are designed to run\nasynchronously so that they can be used right in line with your exploit\ncode. Basically the model is this:<\/p>"},{"title":"44CON Presentation - Additional Resources","link":"https:\/\/shadowfile.inode.link\/blog\/2013\/09\/44con-presentation-additional-resources\/","pubDate":"Thu, 12 Sep 2013 05:59:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2013\/09\/44con-presentation-additional-resources\/","description":"<p>Update December 2014: 44CON has posted the videos from all 2013 talks\nonline. Unfortunately, they don&rsquo;t allow the videos to be embedded, so\nhere&rsquo;s a <a href=\"http:\/\/vimeo.com\/109380798\" target=\"_blank\">link<\/a>.<\/p>\n<p>For my presentation at 44CON, entitled &ldquo;Reversing and Exploiting BT CPE\nDevices&rdquo;, rather than have one or two or three slides packed with hard\nto read URLs, I included a single slide with a link to this post. \u00a0Here\nyou&rsquo;ll find links to additional resources that I may have referenced in\nmy talk.<\/p>"},{"title":"Insulting Recruiter Emails","link":"https:\/\/shadowfile.inode.link\/blog\/2013\/09\/insulting-recruiter-emails\/","pubDate":"Mon, 09 Sep 2013 08:51:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2013\/09\/insulting-recruiter-emails\/","description":"<p><strong>Note<\/strong>: <em>I have a great job at a company called Tactical Network\nSolutions, based in Columbia, MD. \u00a0I&rsquo;m not looking for a new job.\n\u00a0That&rsquo;s not why I&rsquo;m writing this post. \u00a0I have way too much fun working\nwith crazy smart people right where I am.<\/em><\/p>\n<p>I get a lot of recruiter email. \u00a0Some are very thoughtful and are for\ncompanies that would be very cool to work for. \u00a0I love those, and I want\nto high five those people for being such class acts. \u00a0I try to always\nsend them a thoughtful response thanking them for thinking of me, but\nletting them know I&rsquo;m fine where I am.<\/p>"},{"title":"Running Debian MIPS Linux in QEMU","link":"https:\/\/shadowfile.inode.link\/blog\/2013\/05\/running-debian-mips-linux-in-qemu\/","pubDate":"Fri, 31 May 2013 13:35:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2013\/05\/running-debian-mips-linux-in-qemu\/","description":"<p>Sometimes I need a MIPS Linux system that I can use for development and\ntesting. \u00a0Maybe I need to test some shellcode or debug a binary I&rsquo;m\nanalyzing. \u00a0What I wish existed was a Raspberry Pi-like MIPS device.\n\u00a0I&rsquo;d love to have a bunch of small, sub-$50 devices that I could network\ntogether as a sort of desktop exploit lab. \u00a0Unfortunately I don&rsquo;t know\nof such a device. \u00a0There is MIPS hardware you can get and install Linux\non. \u00a0I have a Cobalt RAQ, and a lot of people like to get a hackable\nWiFi router and image it with OpenWRT.\u00a0\u00a0But there&rsquo;s nothing as small,\ncheap and convenient as the RPi that is MIPS.<\/p>"},{"title":"Is your Mac's File System Protected?","link":"https:\/\/shadowfile.inode.link\/blog\/2013\/05\/is-your-macs-file-system-protected\/","pubDate":"Fri, 03 May 2013 04:42:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2013\/05\/is-your-macs-file-system-protected\/","description":"<p>Nothing original here, but this is a great tip, so I want to share it.\n\u00a0Thanks to <a href=\"https:\/\/twitter.com\/thegrugq\" target=\"_blank\">@thegrugq<\/a>\u00a0for cluing me into\nthis via Twitter.<\/p>\n<p>For everyone running OS X <!-- raw HTML omitted -->10.7<!-- raw HTML omitted -->\nor <!-- raw HTML omitted -->10.8<!-- raw HTML omitted -->\non their Macs (and really, EVERYONE should <!-- raw HTML omitted -->be on <!-- raw HTML omitted -->10.8<!-- raw HTML omitted -->;<!-- raw HTML omitted -->\nthe security benefits are non-trivial) and are using FileVault 2 to\nencrypt your filesystems (you are, right?) here&rsquo;s a good tip I picked up\nthe other day:<\/p>"},{"title":"Bowcaster's EmptyOverflowBuffer class (Tutorial Part 5)","link":"https:\/\/shadowfile.inode.link\/blog\/2013\/04\/bowcasters-emptyoverflowbuffer-class-tutorial-part-5\/","pubDate":"Thu, 25 Apr 2013 13:56:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2013\/04\/bowcasters-emptyoverflowbuffer-class-tutorial-part-5\/","description":"<p>In previous parts of the Bowcaster tutorial, I showed how to construct\nyour buffer overflow using the <!-- raw HTML omitted -->OverflowBuffer<!-- raw HTML omitted -->\nclass. \u00a0I also mentioned there is another class, <!-- raw HTML omitted -->EmptyOverflowBuffer<!-- raw HTML omitted -->,\nthat I would explain later. \u00a0That class is going to be the topic of this\npost.<\/p>\n<p>When I started development of Bowcaster, I created it for myself and for\nthe way I develop exploits and think about buffer overflows. \u00a0 The <!-- raw HTML omitted -->OverflowBuffer<!-- raw HTML omitted -->\nclass works the way I think. \u00a0But when I talked to my colleague, Craig\nHeffner, about the project, Craig preferred a different API, I realized\nthat we each think about the same problem in different ways.<\/p>"},{"title":"Buffer Overflows with Bowcaster Part 4","link":"https:\/\/shadowfile.inode.link\/blog\/2013\/04\/buffer-overflows-with-bowcaster-part-4\/","pubDate":"Mon, 08 Apr 2013 09:08:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2013\/04\/buffer-overflows-with-bowcaster-part-4\/","description":"<p>In <a href=\"http:\/\/shadow-file.blogspot.com\/2013\/03\/buffer-overflows-with-crossbow-part-1.html\" target=\"_blank\">part\n1<\/a>\nof the Bowcaster tutorial I showed how to generate an overflow string\nwith the OverflowBuffer class. In <a href=\"http:\/\/shadow-file.blogspot.com\/2013\/03\/buffer-overflows-with-crossbow-part-2.html\" target=\"_blank\">part\n2<\/a>,\nI showed how to populate your your overflow string with ROP gadgets. In\n<a href=\"http:\/\/shadow-file.blogspot.com\/2013\/03\/buffer-overflows-with-crossbow-part-3.html\" target=\"_blank\">part\n3<\/a>,\nI showed how to add Bowcaster&rsquo;s connect-back payload for MIPS Linux to\nyour overflow string. I also showed how to encode your payload using\nBowcaster&rsquo;s MIPS Linux-specific XOR encoder in order to sanitize\nrestricted bytes.<\/p>\n<p>Part 3 ended by using a netcat listener to serve a connect-back root\nshell. \u00a0In this part I&rsquo;ll show how to use one of Bowcaster&rsquo;s server\nmodules to replace netcat.<\/p>"},{"title":"Crossbow is now Bowcaster","link":"https:\/\/shadowfile.inode.link\/blog\/2013\/04\/crossbow-is-now-bowcaster\/","pubDate":"Mon, 08 Apr 2013 05:57:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2013\/04\/crossbow-is-now-bowcaster\/","description":"<p>Crossbow has been renamed to Bowcaster. It turns out &ldquo;Crossbow&rdquo; is a\npopular word. \u00a0Who knew? \u00a0A company in California has the word\nregistered as a trademark in the US in connection with computer\nsoftware. \u00a0They might be cool with us using the word, since this is an\nopen-source, noncommercial product, but we&rsquo;ve decided to change the name\njust in case. \u00a0Hopefully the new name is esoteric enough to avoid any\nnaming conflicts, while still being cool and fun to say. \u00a0I left the\n<a href=\"http:\/\/shadow-file.blogspot.com\/2013\/03\/crossbow.html\" target=\"_blank\">original post<\/a>\nas-is, save for an update note and a new Github link. \u00a0The old Github\nproject will stay up for a while, but you should use the new one from\nthis point on.<\/p>"},{"title":"Buffer Overflows with Bowcaster Part 3","link":"https:\/\/shadowfile.inode.link\/blog\/2013\/03\/buffer-overflows-with-bowcaster-part-3\/","pubDate":"Fri, 29 Mar 2013 09:21:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2013\/03\/buffer-overflows-with-bowcaster-part-3\/","description":"<p>This is the third part in a multi part tutorial on using the Bowcaster\nexploit development framework to build a buffer overflow exploit. Here\nare\u00a0<a href=\"http:\/\/shadow-file.blogspot.com\/2013\/03\/buffer-overflows-with-crossbow-part-1.html\" target=\"_blank\">part\n1<\/a>\nand <a href=\"http:\/\/shadow-file.blogspot.com\/2013\/03\/buffer-overflows-with-crossbow-part-2.html\" target=\"_blank\">part\n2<\/a>.<\/p>\n<p>In the last part, we had built an exploit buffer and added a ROP chain\nthat would flush the MIPS CPU cache, locate the stack (which is\nrandomized), and return into it. \u00a0Now it&rsquo;s time to add a payload.<\/p>\n<p>Bowcaster provides a few MIPS Linux payloads, and the one we&rsquo;ll use for\nthis buffer overflow is the connect-back payload, which will yield an\ninteractive shell.<\/p>"},{"title":"Buffer Overflows with Bowcaster Part 2","link":"https:\/\/shadowfile.inode.link\/blog\/2013\/03\/buffer-overflows-with-bowcaster-part-2\/","pubDate":"Thu, 28 Mar 2013 13:54:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2013\/03\/buffer-overflows-with-bowcaster-part-2\/","description":"<p>This is the second in a multi-part tutorial on developing a buffer\noverflow exploit using Bowcaster. \u00a0Here&rsquo;s <a href=\"http:\/\/shadow-file.blogspot.com\/2013\/03\/buffer-overflows-with-crossbow-part-1.html\" target=\"_blank\">Part\n1<\/a>.<\/p>\n<p>In part 1, we had gotten a crash by sending a 2048-byte pattern to the\nvulnerable program.<\/p>\n<p>The saved return address had been overwritten with 0x41367241 and\nrestored to the $ra register. \u00a0That value is located at an offset of 528\nin our overflow buffer. \u00a0Now we need to start describing ROP gadgets and\nsubstituting them for parts of the 2048-byte overflow string.<\/p>"},{"title":"Buffer Overflows with Bowcaster Part 1","link":"https:\/\/shadowfile.inode.link\/blog\/2013\/03\/buffer-overflows-with-bowcaster-part-1\/","pubDate":"Thu, 28 Mar 2013 11:01:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2013\/03\/buffer-overflows-with-bowcaster-part-1\/","description":"<p>This is the first in a multi-part tutorial on developing a buffer\noverflow exploit using\n<a href=\"http:\/\/shadow-file.blogspot.com\/2013\/03\/crossbow.html\" target=\"_blank\">Crossbow<\/a>\u00a0(now\ncalled Bowcaster),\u00a0which I released earlier today.<\/p>\n<p>For this tutorial I&rsquo;ve written a simple program in C that overflows a\nbuffer on the stack with whatever it reads from the network. \u00a0I\ncross-compiled it for MIPS Linux and ran it using QEMU chrooted into the\nunpacked filesystem of the Netgear WNDR3700v3 (Firmware 1.0.0.18).<\/p>\n<p>The program, vulnerable.c contains the following function:<\/p>"},{"title":"Crossbow","link":"https:\/\/shadowfile.inode.link\/blog\/2013\/03\/crossbow\/","pubDate":"Thu, 28 Mar 2013 10:32:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2013\/03\/crossbow\/","description":"<p>UPDATE: Crossbow has been renamed to Bowcaster. It turns out &ldquo;Crossbow&rdquo;\nis a popular word. \u00a0Who knew? \u00a0A company in California has the word\nregistered as a trademark in the US in connection with computer\nsoftware. \u00a0They might be cool with us using the word, since this is an\nopen-source noncommercial product, but we&rsquo;ve decided to change the name\njust in case. \u00a0Hopefully the new name is esoteric enough to avoid any\nnaming conflicts, while still being cool and fun to say. \u00a0I&rsquo;m leaving\nthis post as-is, save for the new Github link. \u00a0The old Github project\nwill stay up for a while, but you should use the new one from this point\non.<\/p>"},{"title":"Hacking is Bullshit","link":"https:\/\/shadowfile.inode.link\/blog\/2013\/02\/hacking-is-bullshit\/","pubDate":"Sun, 10 Feb 2013 15:35:00 -0800","guid":"https:\/\/shadowfile.inode.link\/blog\/2013\/02\/hacking-is-bullshit\/","description":"<p>I love hacking. \u00a0I love vulnerability research. \u00a0I love software\nexploitation. \u00a0I love finding creative ways to subvert control of an\napplication or system to make it do something it wasn&rsquo;t intended to\ndo.<\/p>\n<p>But this is research, and like any research, lots of things never pan\nout. \u00a0It&rsquo;s weird because it involves hours, often hundreds or even\nthousands of hours, of frustration paid off by successes that last only\nmoments. \u00a0And the cycle repeats.<\/p>"},{"title":"DLink DIR-815 UPnP Command Injection","link":"https:\/\/shadowfile.inode.link\/blog\/2013\/02\/dlink-dir-815-upnp-command-injection\/","pubDate":"Fri, 01 Feb 2013 15:07:00 -0800","guid":"https:\/\/shadowfile.inode.link\/blog\/2013\/02\/dlink-dir-815-upnp-command-injection\/","description":"<p>With all the excitement regarding UPnP vulnerabilities lately, I though\nI&rsquo;d write up this one I found a few weeks back. \u00a0I had kind of forgotten\nabout it. \u00a0But it&rsquo;s pretty straight forward, and kind of fun, so here it\nis.<\/p>\n<p>In Tactical Network Solutions&rsquo; <a href=\"http:\/\/www.tacnetsol.com\/training\/\" target=\"_blank\">Intro to Embedded Device\nExploitation<\/a> class, we use the\nD-Link DIR-815 for the practical exercises since there are tons of great\n0-days for the students to find. \u00a0The last time we taught the class, I\nthought I&rsquo;d try my hand at finding a new one. Twenty minutes in, voila!\nCommand injection in a single multicast packet!<\/p>"},{"title":"UPDATED: Responsible (non)Disclosure","link":"https:\/\/shadowfile.inode.link\/blog\/2012\/11\/updated-responsible-nondisclosure\/","pubDate":"Thu, 29 Nov 2012 09:30:00 -0800","guid":"https:\/\/shadowfile.inode.link\/blog\/2012\/11\/updated-responsible-nondisclosure\/","description":"<p><strong>Update:<\/strong>\u00a0I received a personal communication from Mr. Flemming. \u00a0He\nmakes the case that what I believed to be a subtextual threat was not\nintended. \u00a0Not necessarily speaking for TNS, I am inclined to take him\nat his word and that my initial read of the situation may have been\nunduly skeptical. \u00a0I hope to post additional updates as things develop.\n\u00a0I&rsquo;m leaving the original text of this post intact, though, as it\nprovides meaningful context for the situation that is unfolding.<br>\n**<br>\nOriginal Post:**<br>\nSo here&rsquo;s something awesome. \u00a0And by &ldquo;awesome&rdquo; I mean &ldquo;kinda shitty.&rdquo;<\/p>"},{"title":"Specifying Preferred Load Addresses for ELF Shared Libraries","link":"https:\/\/shadowfile.inode.link\/blog\/2012\/10\/specifying-preferred-load-addresses-for-elf-shared-libraries\/","pubDate":"Tue, 23 Oct 2012 18:44:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2012\/10\/specifying-preferred-load-addresses-for-elf-shared-libraries\/","description":"<p>[NOTE: <em>This was going to be a post about how to relocate a shared\nlibrary that is loaded using LD_PRELOAD such that a program&rsquo;s linked\nlibraries get loaded at their normal addresses. \u00a0Sadly, the trick I\nthought would do that didn&rsquo;t actually work for me. \u00a0The library got\nrelocated, but the other libraries weren&rsquo;t restored to their\u00a0natural\nbase addresses.\u00a0\u00a0That said, it still is interesting and worth writing\nup.<\/em>]<\/p>"},{"title":"Parsing Email and Fixing Timestamps in Python","link":"https:\/\/shadowfile.inode.link\/blog\/2012\/06\/parsing-email-and-fixing-timestamps-in-python\/","pubDate":"Tue, 12 Jun 2012 09:06:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2012\/06\/parsing-email-and-fixing-timestamps-in-python\/","description":"<p>I decided to POP out all my Yahoo mail into my Google Apps account so I\ncould stop paying for Yahoo&rsquo;s &ldquo;premium&rdquo; service (WTF, it&rsquo;s 2012, and POP\nis a paid feature&ndash;and there&rsquo;s no IMAP?). \u00a0I have fetchmail then\ndownload all of my messages which get post-processed by procmail and\nre-served by dovecot. \u00a0Since a bunch of really old messages were just\ndownloaded by fetchmail, they appeared to be &ldquo;new&rdquo; from dovecot&rsquo;s\nperspective. \u00a0This is because the name of the message files stored in\nthe Maildir format used by dovecot starts with a number representing\nwhen the messages were downloaded. \u00a0So years-old messages that were just\ndownloaded will have a very recent timestamp encoded in their\nfilenames.<\/p>"},{"title":"Long-form Reading 2011","link":"https:\/\/shadowfile.inode.link\/blog\/2011\/12\/long-form-reading-2011\/","pubDate":"Fri, 16 Dec 2011 08:01:00 -0800","guid":"https:\/\/shadowfile.inode.link\/blog\/2011\/12\/long-form-reading-2011\/","description":"<p>Here are some long-form articles I&rsquo;ve enjoyed this year.<\/p>\n<p><a href=\"http:\/\/www.theatlantic.com\/technology\/print\/2010\/12\/the-hazards-of-nerd-supremacy-the-case-of-wikileaks\/68217\/\" target=\"_blank\">The Hazards of Nerd Supremacy: The Case of\nWikileaks<\/a>\n(theatlantic.com)<\/p>\n<p><a href=\"http:\/\/www.wired.com\/magazine\/2011\/02\/ff_octopus_conspiracy\/all\/1\" target=\"_blank\">The Octopus Conspiracy: One Woman&rsquo;s Search for Her Father&rsquo;s\nKiller<\/a>\n(wired.com)<\/p>\n<p><a href=\"http:\/\/www.theatlantic.com\/magazine\/archive\/2001\/09\/confessions-of-a-prep-school-college-counselor\/2281\/\" target=\"_blank\">Confessions of a Prep School College\nCounselor<\/a>\n(theatlantic.com)<\/p>\n<p><a href=\"http:\/\/berlinbooks.org\/brb\/2011\/01\/the-great-rubber-robbery-how-julius-fromm%E2%80%99s-condom-empire-fell-to-the-nazis\/\" target=\"_blank\">The Great Rubber Robbery: How Julius Fromm&rsquo;s Condom Empire Fell to the\nNazis<\/a>\n(berlinbooks.org)<\/p>\n<p><a href=\"http:\/\/www.houstonpress.com\/content\/printVersion\/218684\/\" target=\"_blank\">Bursting the\nBubble<\/a> (about\nDavid Vetter, the &ldquo;Bubble Boy&rdquo;, houstonpress.com)<\/p>\n<p><a href=\"http:\/\/www.slate.com\/articles\/news_and_politics\/assessment\/2011\/02\/the_stutterer.single.html\" target=\"_blank\">The Stutterer: How He Makes His Voice\nHeard<\/a>\n(slate.com)<\/p>"},{"title":"Reading List 2011","link":"https:\/\/shadowfile.inode.link\/blog\/2011\/12\/reading-list-2011\/","pubDate":"Tue, 13 Dec 2011 12:15:00 -0800","guid":"https:\/\/shadowfile.inode.link\/blog\/2011\/12\/reading-list-2011\/","description":"<p>I was using up all of my accumulated credits on Audible.com just now,\nand realized I&rsquo;ve listened to several great audiobooks over the last\nyear. Here&rsquo;s a list of what I&rsquo;ve listened to in 2011, along with a link\nto the book on Audible.com. I recommend them all.<\/p>\n<p><!-- raw HTML omitted -->Judas Unchained<!-- raw HTML omitted -->, Peter F. Hamilton, Part\n2 of the Commonwealth Saga\n(<a href=\"http:\/\/www.audible.com\/pd?asin=B002V0QZL0\" target=\"_blank\">link<\/a>)<br>\n<!-- raw HTML omitted -->The Gun<!-- raw HTML omitted -->,\u00a0C. J. Chivers\n(<a href=\"http:\/\/www.audible.com\/pd?asin=B0045KKG6E\" target=\"_blank\">link<\/a>)<br>\n<!-- raw HTML omitted -->The Windup Girl<!-- raw HTML omitted -->, Paolo Bacigalupi\n(<a href=\"http:\/\/www.audible.com\/pd?asin=B002UZN4MO\" target=\"_blank\">link<\/a>)<br>\n<!-- raw HTML omitted -->Snow Crash<!-- raw HTML omitted -->, Neal Stephenson\n(<a href=\"http:\/\/www.audible.com\/pd?asin=B002UUKWCY\" target=\"_blank\">link<\/a>)<br>\n<!-- raw HTML omitted -->Embassytown<!-- raw HTML omitted -->, China Mieville\n(<a href=\"http:\/\/www.audible.com\/pd?asin=B00500HQNE\" target=\"_blank\">link<\/a>)<br>\n<!-- raw HTML omitted -->Pattern Recognition<!-- raw HTML omitted -->, William Gibson\n(<a href=\"http:\/\/www.audible.com\/pd?asin=B002V8OCTY\" target=\"_blank\">link<\/a>)<br>\n<!-- raw HTML omitted -->Spook Country<!-- raw HTML omitted -->, William Gibson\n(<a href=\"http:\/\/www.audible.com\/pd?asin=B002V5GO3O\" target=\"_blank\">link<\/a>)<br>\n<!-- raw HTML omitted -->Zero History<!-- raw HTML omitted -->, William Gibson\n(<a href=\"http:\/\/www.audible.com\/pd?asin=B0040HTAHS\" target=\"_blank\">link<\/a>)<\/p>"},{"title":"Handling HTTP Redirection in Ruby","link":"https:\/\/shadowfile.inode.link\/blog\/2009\/03\/handling-http-redirection-in-ruby\/","pubDate":"Sun, 15 Mar 2009 09:18:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2009\/03\/handling-http-redirection-in-ruby\/","description":"<p>I have a Ruby project where I&rsquo;m dumping a bunch of bookmarks from\ndelicious.com, then fetching each bookmarked page for analysis.<\/p>\n<p>One of the problems I encountered early on is that the some of the web\npages bookmarked would redirect to some other location. Simply checking\nfor HTTP response code 200 was insufficient. I needed to check for\nredirection as well.<\/p>\n<p>A quick Google search for &ldquo;ruby follow http redirect&rdquo; yields lots of\n<a href=\"http:\/\/www.google.com\/search?q=ruby&#43;follow&#43;http&#43;redirect&amp;ie=utf-8&amp;oe=utf-8&amp;aq=t&amp;rls=org.mozilla:en-US:official&amp;client=firefox-a\" target=\"_blank\">results<\/a>.\nUnfortunately, they&rsquo;re all very similar, and not quite right. In\ngeneral, the examples you come across (even the one in the official Ruby\ndocumentation) don&rsquo;t handle the case when the redirected location is\npath relative to the original location. So you end up doing a get on a\nURL that looks like &ldquo;..\/..\/redirected\/location\/index.html,&rdquo; which\nclearly won&rsquo;t work.<\/p>"},{"title":"Mounting LVM Disks in Ubuntu","link":"https:\/\/shadowfile.inode.link\/blog\/2009\/03\/mounting-lvm-disks-in-ubuntu\/","pubDate":"Thu, 12 Mar 2009 06:30:00 -0700","guid":"https:\/\/shadowfile.inode.link\/blog\/2009\/03\/mounting-lvm-disks-in-ubuntu\/","description":"<p>I always thought LVM (Linux&rsquo;s Logical Volume Manager) was kind of neat\nfor the flexibility it gives you in adding and removing disks and\nresizing volumes such. However, in practice, I find it&rsquo;s usually more\ntrouble than it&rsquo;s worth. It adds a layer of complexity between me and my\ndata.<\/p>\n<p>Often I need to mount a disk configured with LVM on another Linux\nmachine or in an Ubuntu live CD environment. Out of the box the logical\nvolumes aren&rsquo;t recognized, so I can&rsquo;t mount them.<\/p>"},{"title":"How to sudoedit non-interactively","link":"https:\/\/shadowfile.inode.link\/blog\/2009\/01\/how-to-sudoedit-non-interactively\/","pubDate":"Thu, 08 Jan 2009 06:31:00 -0800","guid":"https:\/\/shadowfile.inode.link\/blog\/2009\/01\/how-to-sudoedit-non-interactively\/","description":"<p>Okay, this one&rsquo;s a bit esoteric, but I think it&rsquo;s pretty cool. How do\nyou use &lsquo;sudoedit&rsquo; non-interactively such as from a script? Just a brief\nbackground about sudo: sudo is an authentication mechanism in Unix &amp;\nLinux that allows unprivileged users to run specific commands (as\ndefined by the system administrator) with root privileges without having\nthe root password. This has several advantages over logging in as\nroot:<\/p>\n<ul>\n<li>Users can have specific, limited set of root privileges without\nhaving the entire set of root privileges.<\/li>\n<li>Users use their <!-- raw HTML omitted -->own<!-- raw HTML omitted -->\npassword, so the root password doesn&rsquo;t have to be shared. If a\nuser&rsquo;s sudo privileges are revoked, the root password doesn&rsquo;t have\nto be reset.<\/li>\n<li>Each use of sudo is audited per user, so that each time sudo\nprivileges are invoked, there is an event in the system logs that\nidentifies the specific user and the command they ran.<\/li>\n<\/ul>\n<p>Sudoedit is a command that is related to sudo. It lets users edit files\nthat normally only root can edit, such as system configuration files.\nHowever instead of using &ldquo;sudo&rdquo; followed by the editing command, the\nuser runs &ldquo;sudoedit filename&rdquo; and sudo invokes the user&rsquo;s default\neditor, letting them edit the file.<\/p>"},{"title":"The Shadow File","link":"https:\/\/shadowfile.inode.link\/blog\/2004\/12\/the-shadow-file\/","pubDate":"Wed, 15 Dec 2004 19:20:00 -0800","guid":"https:\/\/shadowfile.inode.link\/blog\/2004\/12\/the-shadow-file\/","description":"<p><!-- raw HTML omitted -->This is the first post to The\nShadow File. I suppose a brief explanation is in order. What is The\nShadow File? In Unix and Linux, an algorithm is used to create a one-way\nhash of a user&rsquo;s password. This hash, along with the username and other\ninformation used to be stored in \/etc\/passwd. In many modern *nix\nsystems, the password hash has been removed from the passwd file and is\nnow stored in a separate file, because the passwd file is\nworld-readable. This way, an attacker would have to obtain both files in\norder to attempt to recreate the password. The file that contains the\npassword hashes is \/etc\/shadow. Now you know.<\/p>"},{"title":"Resume","link":"https:\/\/shadowfile.inode.link\/resume\/","pubDate":"Mon, 01 Jan 0001 00:00:00 +0000","guid":"https:\/\/shadowfile.inode.link\/resume\/","description":"<h2 id=\"zachary-cutlip\">Zachary Cutlip<\/h2>\n<p>uid000 at icloud.com<\/p>\n<h3 id=\"offensive-security-researcher\">Offensive Security Researcher<\/h3>\n<p>I like memory corruption, debuggers, and hex editors. I love a good, artisanal gadget chain. I like making tools that make all of those things easier. I love sharing what I&rsquo;ve learned with others either in person, in writing, or doing technical presentations.<\/p>\n<h3 id=\"experience\">Experience<\/h3>\n<h4 id=\"azimuth-security-llc-now-l3harris-trenchant\"><strong>Azimuth Security, LLC<\/strong> (now L3Harris Trenchant)<\/h4>\n<p>Offensive Security Researcher, May 2018 - March 2023<\/p>\n<ul>\n<li>Conducted vulnerability research against iOS and macOS kernel and userspace<\/li>\n<li>Extensively reverse engineered critical operating system components<\/li>\n<li>Developed tooling to aid vulnerability research and attack surface enumeration\n<ul>\n<li>E.g., completely reverse engineered iOS binary sandbox format &amp; developed a sandbox profile decompiler<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h4 id=\"apple-inc\"><strong>Apple, Inc.<\/strong><\/h4>\n<p>Offensive Security Researcher, May 2014 - April 2018<\/p>"}]}}