<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Posts on The Shadow File</title>
    <link>https://shadowfile.inode.link/posts/</link>
    <description>Recent content in Posts on The Shadow File</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Sun, 26 Apr 2026 21:04:20 -0700</lastBuildDate>
    <atom:link href="https://shadowfile.inode.link/posts/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Forrester Research Note - Mythos 10 Consequences - Finance Translation</title>
      <link>https://shadowfile.inode.link/blog/2026/04/forrester-research-note-mythos-10-consequences-finance-translation/</link>
      <pubDate>Sun, 26 Apr 2026 21:04:20 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2026/04/forrester-research-note-mythos-10-consequences-finance-translation/</guid>
      <description>&lt;p&gt;A few weeks ago Forrester Research, who would not normally be on my radar, posted a very concise &amp;ldquo;Project Glasswing: The 10 Consequences Nobody’s Writing About Yet.&amp;rdquo; Short version: the infosec industry is about to be turned upside down over the next 2–5 years, and in many ways the transition is well underway.&lt;/p&gt;&#xA;&lt;p&gt;This is one of the most important things I&amp;rsquo;ve read this year, and it exists at the intersection of infosec, artificial intelligence, and business &amp;amp; economics. I feel like people in our industry are snoozing on this.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Revisiting Pegasus on iOS9</title>
      <link>https://shadowfile.inode.link/blog/2022/07/revisiting-pegasus-on-ios9/</link>
      <pubDate>Sat, 02 Jul 2022 13:50:48 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2022/07/revisiting-pegasus-on-ios9/</guid>
      <description>&lt;p&gt;What follows is a writeup of the kernel bugs NSO Group&amp;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.&lt;/p&gt;&#xA;&lt;p&gt;Why now? Well, &amp;ldquo;now&amp;rdquo; isn&amp;rsquo;t exactly the right word; I wrote this up just over four years ago. At the time, my intent wasn&amp;rsquo;t to publish. Rather it was to better understand the practical aspects of exploiting kernel bugs in XNU, iOS&amp;rsquo;s and macOS&amp;rsquo;s kernel. As I explain in the writeup, there&amp;rsquo;s often a lot of discussion of bugs themselves, and sometimes some superficial discussion of their exploitability. But there&amp;rsquo;s rarely a soup-to-nuts discussion along the lines of &amp;ldquo;What do these bugs actually get you? What does exploiting kernel bugs on iOS &lt;em&gt;actually&lt;/em&gt; look like, and what do you next, having exploited them?&amp;rdquo;. I wanted to understand &lt;em&gt;those aspects&lt;/em&gt; 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:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Source Level Debugging the XNU Kernel</title>
      <link>https://shadowfile.inode.link/blog/2018/10/source-level-debugging-the-xnu-kernel/</link>
      <pubDate>Wed, 24 Oct 2018 19:50:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2018/10/source-level-debugging-the-xnu-kernel/</guid>
      <description>&lt;p&gt;Whether you&amp;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. &lt;a href=&#34;https://twitter.com/damiendeville&#34; target=&#34;_blank&#34;&gt;Damien DeVille&lt;/a&gt;, &lt;a href=&#34;https://twitter.com/snare&#34; target=&#34;_blank&#34;&gt;Snare&lt;/a&gt; and probably others have written about this process. Here are some of their articles:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;http://ho.ax/posts/2012/02/debugging-the-mac-os-x-kernel-with-vmware-and-gdb/&#34; target=&#34;_blank&#34;&gt;Debugging the Mac OS X kernel with VMware and GDB&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;http://ho.ax/posts/2012/02/vmware-hardware-debugging/&#34; target=&#34;_blank&#34;&gt;VMware debugging II: &amp;ldquo;Hardware&amp;rdquo; debugging&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;http://ddeville.me/2015/08/using-the-vmware-fusion-gdb-stub-for-kernel-debugging-with-lldb&#34; target=&#34;_blank&#34;&gt;Using the VMware Fusion GDB stub for kernel debugging with LLDB&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;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&amp;rsquo;t addressed. So let&amp;rsquo;s go through it here, from scratch.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Autogenerating defaults(1) Commands</title>
      <link>https://shadowfile.inode.link/blog/2018/08/autogenerating-defaults1-commands/</link>
      <pubDate>Tue, 28 Aug 2018 13:00:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2018/08/autogenerating-defaults1-commands/</guid>
      <description>&lt;p&gt;In &lt;a href=&#34;https://shadowfile.inode.link/blog/2018/06/advanced-defaults1-usage/&#34;&gt;previous&lt;/a&gt; posts, I described some advanced uses of the macOS &lt;code&gt;defaults(1)&lt;/code&gt; command, including adding arbitrarily complex data structures to defaults dictionaries. I also &lt;a href=&#34;https://shadowfile.inode.link/blog/2018/08/defaults-non-obvious-locations/&#34;&gt;described&lt;/a&gt; less than obvious locations where system and applicaton preferences get recorded. Those were all background for this article.&lt;/p&gt;&#xA;&lt;p&gt;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&amp;rsquo;ll describe a tool I&amp;rsquo;ve written for detecting what file on disk is changed and exactly what the change was.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Defaults Non-obvious Locations</title>
      <link>https://shadowfile.inode.link/blog/2018/08/defaults-non-obvious-locations/</link>
      <pubDate>Sat, 18 Aug 2018 14:37:00 -0800</pubDate>
      <guid>https://shadowfile.inode.link/blog/2018/08/defaults-non-obvious-locations/</guid>
      <description>&lt;p&gt;I wrote a tool that sniffs changes to macOS defaults as they change and autogenerates the &lt;code&gt;defaults&lt;/code&gt; 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.&lt;/p&gt;&#xA;&lt;p&gt;Here&amp;rsquo;s a rundown of places where &lt;code&gt;defaults&lt;/code&gt; plist files can exist if they&amp;rsquo;re not in &lt;code&gt;~/Library/Preferences&lt;/code&gt; or &lt;code&gt;/Library/Preferences&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Advanced defaults(1) Usage</title>
      <link>https://shadowfile.inode.link/blog/2018/06/advanced-defaults1-usage/</link>
      <pubDate>Sat, 16 Jun 2018 12:34:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2018/06/advanced-defaults1-usage/</guid>
      <description>&lt;p&gt;Want to change Finder&amp;rsquo;s preferred view to column view from the command line? There&amp;rsquo;s a &lt;code&gt;defaults&lt;/code&gt; command for that. Want to alter trackpad behavior from a shell script? Yep, &lt;code&gt;defaults&lt;/code&gt; can do it.&lt;/p&gt;&#xA;&lt;p&gt;Lots of (most?) macOS and iOS settings manifest in the defaults subsystem (see Apple&amp;rsquo;s &lt;a href=&#34;https://developer.apple.com/library/content/documentation/CoreFoundation/Conceptual/CFPreferences/CFPreferences.html&#34; target=&#34;_blank&#34;&gt;Preferences Programming Topics for Core Foundation&lt;/a&gt; and &lt;a href=&#34;https://developer.apple.com/documentation/foundation/userdefaults&#34; target=&#34;_blank&#34;&gt;UserDefaults&lt;/a&gt;). What this means for you, the macOS user, is many of these settings exist somewhere on disk in the form of &lt;code&gt;.plist&lt;/code&gt; files. You can find them in &lt;code&gt;/Library/Preferences&lt;/code&gt;, &lt;code&gt;~/Library/Preferences&lt;/code&gt;, among other places.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Broken, Abandoned, and Forgotten Code, Part 14</title>
      <link>https://shadowfile.inode.link/blog/2015/11/broken-abandoned-and-forgotten-code-part-14/</link>
      <pubDate>Thu, 05 Nov 2015 08:30:00 -0800</pubDate>
      <guid>https://shadowfile.inode.link/blog/2015/11/broken-abandoned-and-forgotten-code-part-14/</guid>
      <description>&lt;p&gt;In the previous&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2015/10/abandoned-part-13.html&#34; target=&#34;_blank&#34;&gt;post&lt;/a&gt;,&#xA;we walked through building a stage 1 firmware image that can be flashed&#xA;to the Netgear R6200 by exploiting the hidden &lt;code&gt;SetFirmware&lt;/code&gt; SOAP action&#xA;in &lt;code&gt;upnpd&lt;/code&gt;. Due to an undersized memory allocation, we aren&amp;rsquo;t able to&#xA;flash a full sized image using this exploit. Whereas a stock firmware is&#xA;nearly 9MB, the buffer &lt;code&gt;upnpd&lt;/code&gt; base64 decodes into is 4MB, leading to a&#xA;crash. As a result we have to load our trojanized firmware in two&#xA;stages.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Broken, Abandoned, and Forgotten Code, Part 13</title>
      <link>https://shadowfile.inode.link/blog/2015/10/broken-abandoned-and-forgotten-code-part-13/</link>
      <pubDate>Thu, 08 Oct 2015 08:30:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2015/10/broken-abandoned-and-forgotten-code-part-13/</guid>
      <description>&lt;p&gt;In the&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2015/04/abandoned-part-01.html&#34; target=&#34;_blank&#34;&gt;first&lt;/a&gt;&#xA;twelve parts of this&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2015/06/abandoned-intermission.html&#34; target=&#34;_blank&#34;&gt;series&lt;/a&gt;,&#xA;we identified an unauthenticated firmware update feature in the Netgear&#xA;R6200 wireless router. Unfortunately, this feature was broken and only&#xA;partially implemented, making exploitation less that straightforward. We&#xA;reverse engineered the timing requirements and structure of the SOAP&#xA;request required to exploit this vulnerability. We also reverse&#xA;engineered the firmware image format, including its undocumented&#xA;firmware header.&lt;/p&gt;&#xA;&lt;p&gt;As of the previous&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2015/09/abandoned-part-12.html&#34; target=&#34;_blank&#34;&gt;part&lt;/a&gt;,&#xA;the exploitation phase is complete, which is to say we are able to have&#xA;the Netgear UPnP daemon overwrite the firmware on flash storage with&#xA;arbitrary data of our choosing. We are able to do this without&#xA;authentication.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Broken, Abandoned, and Forgotten Code, Part 12</title>
      <link>https://shadowfile.inode.link/blog/2015/09/broken-abandoned-and-forgotten-code-part-12/</link>
      <pubDate>Thu, 17 Sep 2015 08:30:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2015/09/broken-abandoned-and-forgotten-code-part-12/</guid>
      <description>&lt;p&gt;In the previous&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2015/07/abandoned-part-11.html&#34; target=&#34;_blank&#34;&gt;part&lt;/a&gt;,&#xA;I described how to strip out all but the most essential services and&#xA;libraries in the stock firmware in order to get the firmware image down&#xA;to under 4MB. This avoids crashing &lt;code&gt;upnpd&lt;/code&gt;, which allocates less than&#xA;half enough memory to base64 decode a stock-sized firmware image.&lt;/p&gt;&#xA;&lt;p&gt;In this part, we&amp;rsquo;ll walk through a crasher you might encounter (or might&#xA;not, depending how you formatted your ambit header) and how to sidestep&#xA;it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Broken, Abandoned, and Forgotten Code, Part 11</title>
      <link>https://shadowfile.inode.link/blog/2015/07/broken-abandoned-and-forgotten-code-part-11/</link>
      <pubDate>Thu, 16 Jul 2015 08:00:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2015/07/broken-abandoned-and-forgotten-code-part-11/</guid>
      <description>&lt;p&gt;In the previous part, we moved away from emulation to working with&#xA;physical hardware. We identified a UART header inside the Netgear R6200&#xA;that can be used for console access. I demonstrated how to access the&#xA;CFE bootloader&amp;rsquo;s recovery mode to reflash a working firmware over TFTP.&#xA;This makes it possible to iteratively modify and test firmware images&#xA;that will be used in the &lt;code&gt;SetFirmware&lt;/code&gt; UPnP exploit.&lt;/p&gt;&#xA;&lt;p&gt;In this part, I&amp;rsquo;ll talk about regenerating the filesystem portion of the&#xA;firmware image. I&amp;rsquo;ll also walk through shrinking the filesystem in order&#xA;to avoid crashing &lt;code&gt;upnpd&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Broken, Abandoned, and Forgotten Code, Part 10</title>
      <link>https://shadowfile.inode.link/blog/2015/07/broken-abandoned-and-forgotten-code-part-10/</link>
      <pubDate>Thu, 09 Jul 2015 08:11:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2015/07/broken-abandoned-and-forgotten-code-part-10/</guid>
      <description>&lt;h3 id=&#34;debugging-and-de-bricking-the-netgear-r6200-via-uart&#34;&gt;Debugging and De-bricking the Netgear R6200 via UART&lt;/h3&gt;&#xA;&lt;p&gt;&lt;em&gt;Update: I forgot to credit my former colleague, Tim&#xA;(&lt;a href=&#34;https://twitter.com/bjt2n3904&#34; target=&#34;_blank&#34;&gt;@bjt2n3904&lt;/a&gt;), for helping me locate the&#xA;UART header. This project would have been way more challenging without&#xA;the serial connection. It would have involved desoldering the flash&#xA;memory chip, probably replacing it with a ZIF socket, and then removing&#xA;and reprogramming the chip for each iteration of testing.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;In the previous&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2015/06/abandoned-part-09.html&#34; target=&#34;_blank&#34;&gt;installment&lt;/a&gt;,&#xA;we filled out the ambit firmware header just enough to satisfy Netgear&amp;rsquo;s&#xA;broken UPnP server. We also patched out several &lt;code&gt;ioctl()&lt;/code&gt; calls in&#xA;&lt;code&gt;upnpd&lt;/code&gt; in order to test the &lt;code&gt;SetFirmware&lt;/code&gt; exploit in emulation.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Broken, Abandoned, and Forgotten Code, Part 9</title>
      <link>https://shadowfile.inode.link/blog/2015/06/broken-abandoned-and-forgotten-code-part-9/</link>
      <pubDate>Thu, 25 Jun 2015 08:30:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2015/06/broken-abandoned-and-forgotten-code-part-9/</guid>
      <description>&lt;p&gt;In the &lt;a href=&#34;http://shadow-file.blogspot.com/2015/06/abandoned-part-08.html&#34; target=&#34;_blank&#34;&gt;previous&#xA;part&lt;/a&gt;,&#xA;we switched gears back to the Netgear R6200 &lt;code&gt;upnpd&lt;/code&gt; after spending some&#xA;time analyzing &lt;code&gt;httpd&lt;/code&gt;. The HTTP daemon provided an understanding of how&#xA;the firmware header is &lt;em&gt;supposed&lt;/em&gt; to be constructed. We found a header&#xA;parsing function in &lt;code&gt;upnpd&lt;/code&gt; that was similar to its &lt;code&gt;httpd&lt;/code&gt; counterpart.&#xA;So similar that it has the same &lt;code&gt;memcpy()&lt;/code&gt; buffer overflow. This&#xA;overflow was more interesting this time around, as it did not require&#xA;authentication. Additionally, we discovered a reference to the &amp;ldquo;Ambit&#xA;image&amp;rdquo; via an error message string. Presumably an ambit image is a&#xA;firmware format analogous to TRX. In this case, however, the ambit image&#xA;encapsulates a TRX image.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Broken, Abandoned, and Forgotten Code, Part 8</title>
      <link>https://shadowfile.inode.link/blog/2015/06/broken-abandoned-and-forgotten-code-part-8/</link>
      <pubDate>Thu, 18 Jun 2015 08:30:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2015/06/broken-abandoned-and-forgotten-code-part-8/</guid>
      <description>&lt;p&gt;In the&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2015/05/abandoned-part-05.html&#34; target=&#34;_blank&#34;&gt;previous&lt;/a&gt;&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2015/05/abandoned-part-06.html&#34; target=&#34;_blank&#34;&gt;few&lt;/a&gt;&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2015/06/abandoned-part-07.html&#34; target=&#34;_blank&#34;&gt;posts&lt;/a&gt;,&#xA;we spent time reversing how the Netgear R6200&amp;rsquo;s HTTP daemon parses a&#xA;firmware header before writing the firmware image to flash. The goal was&#xA;to work out how the 58-byte firmware header is constructed and how to&#xA;generate a new one that can replace the header in a stock firmware. In&#xA;the end we identified the purpose of all but 4 bytes. The regenerated&#xA;header plus the original TRX firmware image allowed the HTTP daemon,&#xA;running in emulation, to reach the stage where it would start writing&#xA;data to the &lt;code&gt;/dev/mtd1&lt;/code&gt; flash partition. Considering this a win, we&amp;rsquo;ll&#xA;now circle back to analyzing &lt;code&gt;upnpd&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Broken, Abandoned, and Forgotten Code, Intermission</title>
      <link>https://shadowfile.inode.link/blog/2015/06/broken-abandoned-and-forgotten-code-intermission/</link>
      <pubDate>Mon, 08 Jun 2015 06:31:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2015/06/broken-abandoned-and-forgotten-code-intermission/</guid>
      <description>&lt;p&gt;We&amp;rsquo;re about halfway through the &lt;a href=&#34;http://shadow-file.blogspot.com/2015/04/broken-abandoned-and-forgotten-code_22.html&#34; target=&#34;_blank&#34;&gt;Broken,&#xA;Abandoned&lt;/a&gt;&#xA;series, so this is a good time to pause for a minute and take stock. At&#xA;this point, things have gotten pretty technical; if you&amp;rsquo;ve only joined&#xA;recently, you may be wondering what this series is about. I want to take&#xA;a moment to summarize where we&amp;rsquo;ve been and where we can expect to go&#xA;from here.&lt;/p&gt;&#xA;&lt;h3 id=&#34;overview&#34;&gt;Overview&lt;/h3&gt;&#xA;&lt;p&gt;This series, entitled &lt;em&gt;Broken, Abandoned, and Forgotten Code&lt;/em&gt;, is about&#xA;an unauthenticated firmware update mechanism in the Netgear R6200&#xA;wireless router&amp;rsquo;s UPnP service. Bypassing authentication and updating&#xA;the firmware would be moderately interesting by itself. What makes this&#xA;particularly interesting, however, is this capability appears only&#xA;partially implemented. It&amp;rsquo;s not quite dead code; more like zombie code.&#xA;It&amp;rsquo;s wired up just enough to &lt;em&gt;kind of&lt;/em&gt; work. There are many artifacts of&#xA;incomplete implementation that stand in the way of straightforward&#xA;exploitation.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Broken, Abandoned, and Forgotten Code, Part 7</title>
      <link>https://shadowfile.inode.link/blog/2015/06/broken-abandoned-and-forgotten-code-part-7/</link>
      <pubDate>Thu, 04 Jun 2015 10:37:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2015/06/broken-abandoned-and-forgotten-code-part-7/</guid>
      <description>&lt;p&gt;In the &lt;a href=&#34;http://shadow-file.blogspot.com/2015/05/abandoned-part-06.html&#34; target=&#34;_blank&#34;&gt;previous&#xA;post&lt;/a&gt;, I&#xA;finished discussing the &lt;code&gt;abCheckBoardID()&lt;/code&gt; function. I called attention&#xA;to a checksum in the header generated by an unknown algorithm. I&#xA;provided a python implementation of that algorithm ported from IDA&#xA;disassembly. In total, I identified four fields parsed by this function,&#xA;accounting for 30 bytes of the 58 byte header.&lt;/p&gt;&#xA;&lt;p&gt;In this part I&amp;rsquo;ll give an overview of the remaining functions that parse&#xA;and validate the firmware header. By the end we will be able to generate&#xA;a header that allows the firmware to be programmed to flash memory. I&#xA;won&amp;rsquo;t discuss each header field in quite as much detail as I did&#xA;previously, but if you&amp;rsquo;ve made it this far, it shouldn&amp;rsquo;t be too hard to&#xA;understand how each field is used.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Broken, Abandoned, and Forgotten Code, Part 6</title>
      <link>https://shadowfile.inode.link/blog/2015/05/broken-abandoned-and-forgotten-code-part-6/</link>
      <pubDate>Thu, 28 May 2015 08:26:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2015/05/broken-abandoned-and-forgotten-code-part-6/</guid>
      <description>&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;em&gt;It is assumed that the reader is debugging the processes&#xA;described in this and the next several posts using emulation and IDA&#xA;Pro. Those topics are outside the scope of this series and are covered&#xA;in detail&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2015/01/dynamically-analyzing-wifi-routers-upnp.html&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;&#xA;and&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2015/01/patching-emulating-and-debugging.html&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;In the &lt;a href=&#34;http://shadow-file.blogspot.com/2015/05/abandoned-part-05.html&#34; target=&#34;_blank&#34;&gt;previous&#xA;post&lt;/a&gt;,&#xA;we switched gears and started looking at the web server for the Netgear&#xA; R6200. That&amp;rsquo;s because the HTTP daemon&amp;rsquo;s code for upgrading the firmware&#xA;is less broken and easier to analyze. We also analyzed a stock firmware&#xA;image downloaded from Netgear to see how it is composed. Craig Heffner&amp;rsquo;s&#xA;binwalk identified three parts, a TRX header at offset 58, followed by a&#xA;compressed Linux kernel, followed by a squashfs filesystem. All of those&#xA;parts are well understood, which only leaves the first 58 bytes to&#xA;analyze.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Broken, Abandoned, and Forgotten Code, Part 5</title>
      <link>https://shadowfile.inode.link/blog/2015/05/broken-abandoned-and-forgotten-code-part-5/</link>
      <pubDate>Thu, 21 May 2015 09:30:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2015/05/broken-abandoned-and-forgotten-code-part-5/</guid>
      <description>&lt;p&gt;In&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2015/04/abandoned-part-01.html&#34; target=&#34;_blank&#34;&gt;previous&lt;/a&gt;&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2015/04/abandoned-part-02.html&#34; target=&#34;_blank&#34;&gt;installments&lt;/a&gt;&#xA;I&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2015/05/abandoned-part-03.html&#34; target=&#34;_blank&#34;&gt;shared&lt;/a&gt;&#xA;proof-of-concept code that would exercise the Netgear R6200&amp;rsquo;s hidden&#xA;(and badly broken) SetFirmware SOAP action. It satisfied the various&#xA;wonky conditions necessary to get into the &lt;code&gt;sa_parseRcvCmd()&lt;/code&gt; function.&#xA;Then I showed where in that function a firmware would be decoded from&#xA;the SOAP request and written to flash. I showed how to identify a code&#xA;path that leads to firmware writing. In &lt;a href=&#34;http://shadow-file.blogspot.com/2015/05/abandoned-part-04.html&#34; target=&#34;_blank&#34;&gt;part&#xA;four&lt;/a&gt;, I&#xA;showed how an undersized &lt;code&gt;malloc()&lt;/code&gt; means a stock firmware crashes&#xA;&lt;code&gt;upnpd&lt;/code&gt;. Although we&amp;rsquo;ll work around that bug later, for this and the&#xA;next several installments we&amp;rsquo;ll be working out how the firmware image&#xA;gets parsed so we can create our own.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Broken, Abandoned, and Forgotten Code, Part 4</title>
      <link>https://shadowfile.inode.link/blog/2015/05/broken-abandoned-and-forgotten-code-part-4/</link>
      <pubDate>Thu, 14 May 2015 09:18:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2015/05/broken-abandoned-and-forgotten-code-part-4/</guid>
      <description>&lt;p&gt;In the &lt;a href=&#34;http://shadow-file.blogspot.com/2015/05/abandoned-part-03.html&#34; target=&#34;_blank&#34;&gt;last&#xA;post&lt;/a&gt;, I&#xA;described how &lt;code&gt;upnpd&lt;/code&gt;&amp;rsquo;s &lt;code&gt;sa_parseRcvCmd()&lt;/code&gt; function finds the body of a&#xA;SOAP request and how it parses that SOAP request. This is a large and&#xA;complicated function that processes many types of SOAP requests. I&#xA;demonstrated how to work out the desired path of execution to decode and&#xA;write firmware. At the end I made an educated guess as to how the SOAP&#xA;request should be formed, and how the firmware should be represented in&#xA;the request body.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Broken, Abandoned, and Forgotten Code, Part 3</title>
      <link>https://shadowfile.inode.link/blog/2015/05/broken-abandoned-and-forgotten-code-part-3/</link>
      <pubDate>Thu, 07 May 2015 08:00:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2015/05/broken-abandoned-and-forgotten-code-part-3/</guid>
      <description>&lt;p&gt;In the&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2015/04/abandoned-part-01.html&#34; target=&#34;_blank&#34;&gt;previous&lt;/a&gt;&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2015/04/abandoned-part-02.html&#34; target=&#34;_blank&#34;&gt;posts&lt;/a&gt;,&#xA;I talked about the hidden &amp;ldquo;SetFirmware&amp;rdquo; SOAP action in the Netgear&#xA;R6200&amp;rsquo;s UPnP daemon, and the weird timing games we have play to deal&#xA;with UPnP daemon&amp;rsquo;s broken networking code. I also discussed the&#xA;haphazard parsing of the HTTP headers across multiple functions. I made&#xA;a guess at what headers might get our SetFirmware SOAP request passed to&#xA;the &lt;code&gt;sa_parseRcvCmd()&lt;/code&gt; function where hopefully an encapsulated firmware&#xA;image will be decoded.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Broken, Abandoned, and Forgotten Code, Part 2</title>
      <link>https://shadowfile.inode.link/blog/2015/04/broken-abandoned-and-forgotten-code-part-2/</link>
      <pubDate>Thu, 30 Apr 2015 07:59:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2015/04/broken-abandoned-and-forgotten-code-part-2/</guid>
      <description>&lt;p&gt;In the &lt;a href=&#34;http://shadow-file.blogspot.com/2015/04/abandoned-part-01.html&#34; target=&#34;_blank&#34;&gt;part&#xA;1&lt;/a&gt;, I&#xA;showed how the Netgear R6200&amp;rsquo;s upnpd binary contains what appears to be&#xA;a hidden SOAP action related to the string &amp;ldquo;&lt;code&gt;SetFirmware&lt;/code&gt;&amp;rdquo;. I also&#xA;showed how we can get into the &lt;code&gt;upnp_receive_firmware_packets()&lt;/code&gt;&#xA;function if we play timing games and send our request in multiple&#xA;parts.&lt;/p&gt;&#xA;&lt;p&gt;In this part I&amp;rsquo;ll describe additional timing considerations needed to&#xA;avoid hanging the server. I&amp;rsquo;ll also discuss sloppy parsing of the SOAP&#xA;request, and I&amp;rsquo;ll make some guesses as to how that request should be&#xA;formed.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Broken, Abandoned, and Forgotten Code, Part 1</title>
      <link>https://shadowfile.inode.link/blog/2015/04/broken-abandoned-and-forgotten-code-part-1/</link>
      <pubDate>Thu, 23 Apr 2015 12:00:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2015/04/broken-abandoned-and-forgotten-code-part-1/</guid>
      <description>&lt;h4 id=&#34;introduction&#34;&gt;Introduction&lt;/h4&gt;&#xA;&lt;p&gt;This series of posts describes how abandoned, partially implemented&#xA;functionality can be exploited to gain complete, persistent control of&#xA;Netgear wireless routers. I&amp;rsquo;ll describe a hidden SOAP method in the UPnP&#xA;stack that, at first glance, appeared to allow unauthenticated remote&#xA;firmware upload to the router. After some reverse engineering, it became&#xA;apparent this functionality was never fully implemented, and could never&#xA;work properly given a well formed SOAP request and firmware image. If it&#xA;could work at all, it would be with only the most contrived of inputs.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Broken, Abandoned, and Forgotten Code: Prologue</title>
      <link>https://shadowfile.inode.link/blog/2015/04/broken-abandoned-and-forgotten-code-prologue/</link>
      <pubDate>Wed, 22 Apr 2015 17:11:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2015/04/broken-abandoned-and-forgotten-code-prologue/</guid>
      <description>&lt;h3 id=&#34;a-secret-passage-to-persistant-soho-router-pwnage&#34;&gt;A Secret Passage to Persistant SOHO Router Pwnage&lt;/h3&gt;&#xA;&lt;p&gt;Almost two years ago plus a house selling, a cross-country move, a house&#xA;buying, a job change, and a wedding, I downloaded and unpacked the&#xA;firmware for Netgear&amp;rsquo;s then-new &lt;a href=&#34;http://www.amazon.com/NETGEAR-Wireless-Router-Gigabit-R6200/dp/B008HO9DIG/ref=sr_1_1&#34; target=&#34;_blank&#34;&gt;R6200 wireless&#xA;router&lt;/a&gt;.&#xA;This was one of Netgear&amp;rsquo;s first entries into the nascent 802.11ac&#xA;market. At around US$200 at the time, this device was at the high end of&#xA;the Netgear lineup. Finding some cool vulnerabilities in some of the&#xA;newest, swankiest, consumer WiFi gear would make for a neat paper, or at&#xA;least a good blog post or two.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Bowcaster Feature: multipart/form-data</title>
      <link>https://shadowfile.inode.link/blog/2015/02/bowcaster-feature-multipart/form-data/</link>
      <pubDate>Fri, 20 Feb 2015 11:29:00 -0800</pubDate>
      <guid>https://shadowfile.inode.link/blog/2015/02/bowcaster-feature-multipart/form-data/</guid>
      <description>&lt;p&gt;Need to reverse engineer or exploit a file upload vulnerability in an&#xA;embedded web server? I added a &lt;code&gt;multipart/form-data&lt;/code&gt; class to Bowcaster&#xA;to help with that. You can have a look here:&lt;br&gt;&#xA;&lt;a href=&#34;https://github.com/zcutlip/bowcaster/blob/master/src/bowcaster/clients/http.py&#34; target=&#34;_blank&#34;&gt;https://github.com/zcutlip/bowcaster/blob/master/src/bowcaster/clients/http.py&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Here&amp;rsquo;s some background:&lt;br&gt;&#xA;I&amp;rsquo;ve been reverse engineering how the Netgear R6200 web server parses a&#xA;new firmware image when you use the firmware update facility in the web&#xA;interface. Manually browsing to the router&amp;rsquo;s web interface, then to the&#xA;firmware update form, then browsing to a firmware file on disk, then&#xA;clicking &amp;ldquo;upload&amp;rdquo; gets really tedious after a few times.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Patching, Emulating, and Debugging a Netgear Embedded Web Server</title>
      <link>https://shadowfile.inode.link/blog/2015/01/patching-emulating-and-debugging-a-netgear-embedded-web-server/</link>
      <pubDate>Sat, 31 Jan 2015 00:43:00 -0800</pubDate>
      <guid>https://shadowfile.inode.link/blog/2015/01/patching-emulating-and-debugging-a-netgear-embedded-web-server/</guid>
      <description>&lt;p&gt;Previously I&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2015/01/dynamically-analyzing-wifi-routers-upnp.html&#34; target=&#34;_blank&#34;&gt;posted&lt;/a&gt;&#xA;about running and remotely debugging a Netgear UPnP daemon using QEMU&#xA;and IDA Pro. This time we’ll take on the challenge of running the&#xA;built-in web server from the Netgear R6200 in emulation.&lt;/p&gt;&#xA;&lt;p&gt;The &lt;code&gt;httpd&lt;/code&gt; daemon is responsible for so much more than the web&#xA;interface. This daemon is responsible for a silly amount of system&#xA;management, including configuring firewall rules, managing the samba and&#xA;ftp file servers, managing attached USB storage, and many other things.&#xA;And it does all of this management as part of its initialization, which&#xA;means lots of opportunities to fail or crash when running in emulation&#xA;as a standalone service.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Remote Debugging with QEMU and IDA Pro</title>
      <link>https://shadowfile.inode.link/blog/2015/01/remote-debugging-with-qemu-and-ida-pro/</link>
      <pubDate>Sat, 03 Jan 2015 12:05:00 -0800</pubDate>
      <guid>https://shadowfile.inode.link/blog/2015/01/remote-debugging-with-qemu-and-ida-pro/</guid>
      <description>&lt;p&gt;It&amp;rsquo;s often the case, when analyzing an embedded device&amp;rsquo;s firmware, that&#xA;static analysis isn&amp;rsquo;t enough. You need to actually execute a binary&#xA;you&amp;rsquo;re analyzing in order to see how it behaves. In the world of&#xA;embedded Linux devices, it&amp;rsquo;s often fairly easy to put a debugger on the&#xA;target hardware for debugging. However it&amp;rsquo;s a lot more convenient if you&#xA;can run the binary right on your own system and not have to drag&#xA;hardware around to do your analysis. Enter emulation with QEMU.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Exploit Tunneling and Callback</title>
      <link>https://shadowfile.inode.link/blog/2014/09/exploit-tunneling-and-callback/</link>
      <pubDate>Tue, 23 Sep 2014 17:32:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2014/09/exploit-tunneling-and-callback/</guid>
      <description>&lt;p&gt;A few years ago, when I worked for my previous employer, I put together&#xA;a proof-of-concept that was to be part of a client demo. I thought it&#xA;was kind of cool, so I recorded a screencast of it in action. I&amp;rsquo;ve had&#xA;the video sitting on my laptop ever since, not really sure what to do&#xA;with it. I finally decided to post it.&lt;/p&gt;&#xA;&lt;p&gt;In the video, what you see is a custom exploit script that exploits a&#xA;buffer overflow in the web interfaces of several D-Link webcams. The&#xA;neat part is that it tunnels the exploit and callback through each&#xA;successive webcam. It works basically like this:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Infiltrate 2014</title>
      <link>https://shadowfile.inode.link/blog/2014/05/infiltrate-2014/</link>
      <pubDate>Fri, 16 May 2014 14:06:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2014/05/infiltrate-2014/</guid>
      <description>&lt;p&gt;Here are some additional resources I may have mentioned in my Infiltrate&#xA;2014 presentation.&lt;/p&gt;&#xA;&lt;p&gt;White Paper: &lt;a href=&#34;http://s3.amazonaws.com/zcutlip_storage/SQL%20Injection%20to%20MIPS%20Overflows%20-%20Part%20Deux.pdf&#34; target=&#34;_blank&#34;&gt;SQL Injection to MIPS Overflows - Part&#xA;Deux&lt;/a&gt;&lt;br&gt;&#xA;Slides: &lt;a href=&#34;http://s3.amazonaws.com/zcutlip_storage/Cutlip_Infiltrate_2014_SQL_Injection_to_MIPS_Overflows_Part_Deux.pdf&#34; target=&#34;_blank&#34;&gt;SQL Injection to MIPS Overflows - Part&#xA;Deux&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Original white paper from Black Hat USA 2012:&lt;br&gt;&#xA;&lt;a href=&#34;http://s3.amazonaws.com/zcutlip_storage/Netgear_Router_Exploitation.pdf&#34; target=&#34;_blank&#34;&gt;SQL Injections to MIPS Overflows: Rooting SOHO&#xA;Routers&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Proof of Concept Exploit code:&lt;br&gt;&#xA;Here&amp;rsquo;s my Github repository for proof-of-concept exploit code.  In it,&#xA;you&amp;rsquo;ll find the exploit code for the Netgear WNDR 3700v3 that I demoed&#xA;at Infiltrate, among a few others. The white paper is in there as&#xA;well.&lt;br&gt;&#xA;&lt;a href=&#34;https://github.com/zcutlip/exploit-poc&#34; target=&#34;_blank&#34;&gt;https://github.com/zcutlip/exploit-poc&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Emulating and Debugging Workspace</title>
      <link>https://shadowfile.inode.link/blog/2013/12/emulating-and-debugging-workspace/</link>
      <pubDate>Mon, 30 Dec 2013 12:17:00 -0800</pubDate>
      <guid>https://shadowfile.inode.link/blog/2013/12/emulating-and-debugging-workspace/</guid>
      <description>&lt;p&gt;A grad student emailed me in response to my &lt;a href=&#34;http://shadow-file.blogspot.com/2013/10/complete-persistent-compromise-of.html&#34; target=&#34;_blank&#34;&gt;Netgear auth bypass&#xA;post&lt;/a&gt;.&#xA; He&amp;rsquo;s working on a research project and wanted to know if I knew of any&#xA;resources or techniques to use emulation for executing and debugging the&#xA;net-cgi binary in the Netgear firmware.  It turns out I&amp;rsquo;ve got all the&#xA;resources to do just that.  I replied with a description of my workspace&#xA;and some links to resources I use, and, in many cases, have developed.&#xA; I thought this might make an interesting blog post, but I don&amp;rsquo;t really&#xA;have time to write it up all blog-post-like.  Instead I&amp;rsquo;ll just paste in&#xA;my email.  Maybe it&amp;rsquo;ll be useful to other people as well.&lt;/p&gt;</description>
    </item>
    <item>
      <title>BayThreat 2013 Presentation - Additional Resources</title>
      <link>https://shadowfile.inode.link/blog/2013/12/baythreat-2013-presentation-additional-resources/</link>
      <pubDate>Sat, 07 Dec 2013 11:30:00 -0800</pubDate>
      <guid>https://shadowfile.inode.link/blog/2013/12/baythreat-2013-presentation-additional-resources/</guid>
      <description>&lt;p&gt;For my presentation at BayThreat, entitled &amp;ldquo;BT Wireless Routers:&#xA;Adventures in Reversing and Exploiting&amp;rdquo;, rather than have one or two or&#xA;three slides packed with hard to read URLs, I included a single slide&#xA;with a link to this post.  Here you&amp;rsquo;ll find links to additional&#xA;resources that I may have referenced in my talk.&lt;/p&gt;&#xA;&lt;p&gt;White paper: &lt;a href=&#34;http://s3.amazonaws.com/zcutlip_storage/BT%20HomeHub3.0b%2044Con%20%28Zachary%20Cutlip%29.pdf&#34; target=&#34;_blank&#34;&gt;Reverse Engineering and Exploiting the BT HomeHub 3.0b&#xA;(pdf)&lt;/a&gt;&lt;br&gt;&#xA;Slides: &lt;a href=&#34;http://s3.amazonaws.com/zcutlip_storage/Reversing%20and%20Exploiting%20BT%20CPE%20Devices%20-%20Cutlip%20-%20BayThreat.pdf&#34; target=&#34;_blank&#34;&gt;BT Wireless Routers: Adventures in Reversing and&#xA;Exploiting&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Netgear Root Compromise via Command Injection</title>
      <link>https://shadowfile.inode.link/blog/2013/10/netgear-root-compromise-via-command-injection/</link>
      <pubDate>Thu, 24 Oct 2013 14:34:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2013/10/netgear-root-compromise-via-command-injection/</guid>
      <description>&lt;p&gt;At the end of my&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2013/10/complete-persistent-compromise-of.html&#34; target=&#34;_blank&#34;&gt;post&lt;/a&gt;&#xA;on the Netgear wndr3700v4&amp;rsquo;s authentication bugs, I said to expect&#xA;followup posts. Once the web interface is unlocked, any further bugs&#xA;that normally require authentication become fair game. Well &lt;a href=&#34;http://www.youtube.com/watch?v=HHfOejlvVsY&#34; target=&#34;_blank&#34;&gt;good news,&#xA;everyone!&lt;/a&gt;!&lt;/p&gt;&#xA;&lt;p&gt;Previously, I talked about the &lt;!-- raw HTML omitted --&gt;net-cgi&lt;!-- raw HTML omitted --&gt;&#xA;executable in the wndr3700&amp;rsquo;s firmware. ;&lt;!-- raw HTML omitted --&gt;net-cgi&lt;!-- raw HTML omitted --&gt; is&#xA;a multi-call binary, a little like busybox. As such it has a lot of&#xA;functionality baked in. One of its more interesting functions is called&#xA;&lt;!-- raw HTML omitted --&gt;cmd_ping6()&lt;!-- raw HTML omitted --&gt;.&#xA;Here&amp;rsquo;s what it looks like:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Complete, Persistent Compromise of Netgear Wireless Routers</title>
      <link>https://shadowfile.inode.link/blog/2013/10/complete-persistent-compromise-of-netgear-wireless-routers/</link>
      <pubDate>Tue, 22 Oct 2013 06:27:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2013/10/complete-persistent-compromise-of-netgear-wireless-routers/</guid>
      <description>&lt;p&gt;UPDATE: Turns out, Jacob Holocomb&#xA;(&lt;a href=&#34;https://twitter.com/roothak42&#34; target=&#34;_blank&#34;&gt;@rootHak42&lt;/a&gt; on Twitter) of Independent&#xA;Security Evaluators found this bug back in April on a different device,&#xA;the WNDR4700. Thanks for letting me know, Jacob. Nice find. Here&amp;rsquo;s a&#xA;&lt;a href=&#34;http://securityevaluators.com/content/case-studies/routers/netgear_wndr4700.jsp&#34; target=&#34;_blank&#34;&gt;link&lt;/a&gt;&#xA;to that report.&lt;/p&gt;&#xA;&lt;p&gt;UPDATE 2: Because there are almost certainly fools who would go hack&#xA;somebody&amp;rsquo;s router and say I told them to do it, I added a warning to not&#xA;do this. DON&amp;rsquo;T DO IT.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Connect-back HTTP Exploit Server for Bowcaster</title>
      <link>https://shadowfile.inode.link/blog/2013/10/a-connect-back-http-exploit-server-for-bowcaster/</link>
      <pubDate>Wed, 09 Oct 2013 09:25:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2013/10/a-connect-back-http-exploit-server-for-bowcaster/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve just added a module to&#xA;&lt;a href=&#34;https://github.com/zcutlip/bowcaster&#34; target=&#34;_blank&#34;&gt;Bowcaster&lt;/a&gt; that I think is cool.&#xA;Actually, I just got around to finishing a module that was there all&#xA;along. It&amp;rsquo;s a basic HTTP server module, but it has some unique features&#xA;that make it suitable for serving payloads to remotely exploited&#xA;targets.&lt;/p&gt;&#xA;&lt;p&gt;The connect-back server modules in Bowcaster are designed to run&#xA;asynchronously so that they can be used right in line with your exploit&#xA;code. Basically the model is this:&lt;/p&gt;</description>
    </item>
    <item>
      <title>44CON Presentation - Additional Resources</title>
      <link>https://shadowfile.inode.link/blog/2013/09/44con-presentation-additional-resources/</link>
      <pubDate>Thu, 12 Sep 2013 05:59:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2013/09/44con-presentation-additional-resources/</guid>
      <description>&lt;p&gt;Update December 2014: 44CON has posted the videos from all 2013 talks&#xA;online. Unfortunately, they don&amp;rsquo;t allow the videos to be embedded, so&#xA;here&amp;rsquo;s a &lt;a href=&#34;http://vimeo.com/109380798&#34; target=&#34;_blank&#34;&gt;link&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;For my presentation at 44CON, entitled &amp;ldquo;Reversing and Exploiting BT CPE&#xA;Devices&amp;rdquo;, rather than have one or two or three slides packed with hard&#xA;to read URLs, I included a single slide with a link to this post.  Here&#xA;you&amp;rsquo;ll find links to additional resources that I may have referenced in&#xA;my talk.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Insulting Recruiter Emails</title>
      <link>https://shadowfile.inode.link/blog/2013/09/insulting-recruiter-emails/</link>
      <pubDate>Mon, 09 Sep 2013 08:51:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2013/09/insulting-recruiter-emails/</guid>
      <description>&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: &lt;em&gt;I have a great job at a company called Tactical Network&#xA;Solutions, based in Columbia, MD.  I&amp;rsquo;m not looking for a new job.&#xA; That&amp;rsquo;s not why I&amp;rsquo;m writing this post.  I have way too much fun working&#xA;with crazy smart people right where I am.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;I get a lot of recruiter email.  Some are very thoughtful and are for&#xA;companies that would be very cool to work for.  I love those, and I want&#xA;to high five those people for being such class acts.  I try to always&#xA;send them a thoughtful response thanking them for thinking of me, but&#xA;letting them know I&amp;rsquo;m fine where I am.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Running Debian MIPS Linux in QEMU</title>
      <link>https://shadowfile.inode.link/blog/2013/05/running-debian-mips-linux-in-qemu/</link>
      <pubDate>Fri, 31 May 2013 13:35:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2013/05/running-debian-mips-linux-in-qemu/</guid>
      <description>&lt;p&gt;Sometimes I need a MIPS Linux system that I can use for development and&#xA;testing.  Maybe I need to test some shellcode or debug a binary I&amp;rsquo;m&#xA;analyzing.  What I wish existed was a Raspberry Pi-like MIPS device.&#xA; I&amp;rsquo;d love to have a bunch of small, sub-$50 devices that I could network&#xA;together as a sort of desktop exploit lab.  Unfortunately I don&amp;rsquo;t know&#xA;of such a device.  There is MIPS hardware you can get and install Linux&#xA;on.  I have a Cobalt RAQ, and a lot of people like to get a hackable&#xA;WiFi router and image it with OpenWRT.  But there&amp;rsquo;s nothing as small,&#xA;cheap and convenient as the RPi that is MIPS.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Is your Mac&#39;s File System Protected?</title>
      <link>https://shadowfile.inode.link/blog/2013/05/is-your-macs-file-system-protected/</link>
      <pubDate>Fri, 03 May 2013 04:42:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2013/05/is-your-macs-file-system-protected/</guid>
      <description>&lt;p&gt;Nothing original here, but this is a great tip, so I want to share it.&#xA; Thanks to &lt;a href=&#34;https://twitter.com/thegrugq&#34; target=&#34;_blank&#34;&gt;@thegrugq&lt;/a&gt; for cluing me into&#xA;this via Twitter.&lt;/p&gt;&#xA;&lt;p&gt;For everyone running OS X &lt;!-- raw HTML omitted --&gt;10.7&lt;!-- raw HTML omitted --&gt;&#xA;or &lt;!-- raw HTML omitted --&gt;10.8&lt;!-- raw HTML omitted --&gt;&#xA;on their Macs (and really, EVERYONE should &lt;!-- raw HTML omitted --&gt;be on &lt;!-- raw HTML omitted --&gt;10.8&lt;!-- raw HTML omitted --&gt;;&lt;!-- raw HTML omitted --&gt;&#xA;the security benefits are non-trivial) and are using FileVault 2 to&#xA;encrypt your filesystems (you are, right?) here&amp;rsquo;s a good tip I picked up&#xA;the other day:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Bowcaster&#39;s EmptyOverflowBuffer class (Tutorial Part 5)</title>
      <link>https://shadowfile.inode.link/blog/2013/04/bowcasters-emptyoverflowbuffer-class-tutorial-part-5/</link>
      <pubDate>Thu, 25 Apr 2013 13:56:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2013/04/bowcasters-emptyoverflowbuffer-class-tutorial-part-5/</guid>
      <description>&lt;p&gt;In previous parts of the Bowcaster tutorial, I showed how to construct&#xA;your buffer overflow using the &lt;!-- raw HTML omitted --&gt;OverflowBuffer&lt;!-- raw HTML omitted --&gt;&#xA;class.  I also mentioned there is another class, &lt;!-- raw HTML omitted --&gt;EmptyOverflowBuffer&lt;!-- raw HTML omitted --&gt;,&#xA;that I would explain later.  That class is going to be the topic of this&#xA;post.&lt;/p&gt;&#xA;&lt;p&gt;When I started development of Bowcaster, I created it for myself and for&#xA;the way I develop exploits and think about buffer overflows.   The &lt;!-- raw HTML omitted --&gt;OverflowBuffer&lt;!-- raw HTML omitted --&gt;&#xA;class works the way I think.  But when I talked to my colleague, Craig&#xA;Heffner, about the project, Craig preferred a different API, I realized&#xA;that we each think about the same problem in different ways.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Buffer Overflows with Bowcaster Part 4</title>
      <link>https://shadowfile.inode.link/blog/2013/04/buffer-overflows-with-bowcaster-part-4/</link>
      <pubDate>Mon, 08 Apr 2013 09:08:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2013/04/buffer-overflows-with-bowcaster-part-4/</guid>
      <description>&lt;p&gt;In &lt;a href=&#34;http://shadow-file.blogspot.com/2013/03/buffer-overflows-with-crossbow-part-1.html&#34; target=&#34;_blank&#34;&gt;part&#xA;1&lt;/a&gt;&#xA;of the Bowcaster tutorial I showed how to generate an overflow string&#xA;with the OverflowBuffer class. In &lt;a href=&#34;http://shadow-file.blogspot.com/2013/03/buffer-overflows-with-crossbow-part-2.html&#34; target=&#34;_blank&#34;&gt;part&#xA;2&lt;/a&gt;,&#xA;I showed how to populate your your overflow string with ROP gadgets. In&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2013/03/buffer-overflows-with-crossbow-part-3.html&#34; target=&#34;_blank&#34;&gt;part&#xA;3&lt;/a&gt;,&#xA;I showed how to add Bowcaster&amp;rsquo;s connect-back payload for MIPS Linux to&#xA;your overflow string. I also showed how to encode your payload using&#xA;Bowcaster&amp;rsquo;s MIPS Linux-specific XOR encoder in order to sanitize&#xA;restricted bytes.&lt;/p&gt;&#xA;&lt;p&gt;Part 3 ended by using a netcat listener to serve a connect-back root&#xA;shell.  In this part I&amp;rsquo;ll show how to use one of Bowcaster&amp;rsquo;s server&#xA;modules to replace netcat.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Crossbow is now Bowcaster</title>
      <link>https://shadowfile.inode.link/blog/2013/04/crossbow-is-now-bowcaster/</link>
      <pubDate>Mon, 08 Apr 2013 05:57:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2013/04/crossbow-is-now-bowcaster/</guid>
      <description>&lt;p&gt;Crossbow has been renamed to Bowcaster. It turns out &amp;ldquo;Crossbow&amp;rdquo; is a&#xA;popular word.  Who knew?  A company in California has the word&#xA;registered as a trademark in the US in connection with computer&#xA;software.  They might be cool with us using the word, since this is an&#xA;open-source, noncommercial product, but we&amp;rsquo;ve decided to change the name&#xA;just in case.  Hopefully the new name is esoteric enough to avoid any&#xA;naming conflicts, while still being cool and fun to say.  I left the&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2013/03/crossbow.html&#34; target=&#34;_blank&#34;&gt;original post&lt;/a&gt;&#xA;as-is, save for an update note and a new Github link.  The old Github&#xA;project will stay up for a while, but you should use the new one from&#xA;this point on.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Buffer Overflows with Bowcaster Part 3</title>
      <link>https://shadowfile.inode.link/blog/2013/03/buffer-overflows-with-bowcaster-part-3/</link>
      <pubDate>Fri, 29 Mar 2013 09:21:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2013/03/buffer-overflows-with-bowcaster-part-3/</guid>
      <description>&lt;p&gt;This is the third part in a multi part tutorial on using the Bowcaster&#xA;exploit development framework to build a buffer overflow exploit. Here&#xA;are &lt;a href=&#34;http://shadow-file.blogspot.com/2013/03/buffer-overflows-with-crossbow-part-1.html&#34; target=&#34;_blank&#34;&gt;part&#xA;1&lt;/a&gt;&#xA;and &lt;a href=&#34;http://shadow-file.blogspot.com/2013/03/buffer-overflows-with-crossbow-part-2.html&#34; target=&#34;_blank&#34;&gt;part&#xA;2&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;In the last part, we had built an exploit buffer and added a ROP chain&#xA;that would flush the MIPS CPU cache, locate the stack (which is&#xA;randomized), and return into it.  Now it&amp;rsquo;s time to add a payload.&lt;/p&gt;&#xA;&lt;p&gt;Bowcaster provides a few MIPS Linux payloads, and the one we&amp;rsquo;ll use for&#xA;this buffer overflow is the connect-back payload, which will yield an&#xA;interactive shell.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Buffer Overflows with Bowcaster Part 2</title>
      <link>https://shadowfile.inode.link/blog/2013/03/buffer-overflows-with-bowcaster-part-2/</link>
      <pubDate>Thu, 28 Mar 2013 13:54:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2013/03/buffer-overflows-with-bowcaster-part-2/</guid>
      <description>&lt;p&gt;This is the second in a multi-part tutorial on developing a buffer&#xA;overflow exploit using Bowcaster.  Here&amp;rsquo;s &lt;a href=&#34;http://shadow-file.blogspot.com/2013/03/buffer-overflows-with-crossbow-part-1.html&#34; target=&#34;_blank&#34;&gt;Part&#xA;1&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;In part 1, we had gotten a crash by sending a 2048-byte pattern to the&#xA;vulnerable program.&lt;/p&gt;&#xA;&lt;p&gt;The saved return address had been overwritten with 0x41367241 and&#xA;restored to the $ra register.  That value is located at an offset of 528&#xA;in our overflow buffer.  Now we need to start describing ROP gadgets and&#xA;substituting them for parts of the 2048-byte overflow string.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Buffer Overflows with Bowcaster Part 1</title>
      <link>https://shadowfile.inode.link/blog/2013/03/buffer-overflows-with-bowcaster-part-1/</link>
      <pubDate>Thu, 28 Mar 2013 11:01:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2013/03/buffer-overflows-with-bowcaster-part-1/</guid>
      <description>&lt;p&gt;This is the first in a multi-part tutorial on developing a buffer&#xA;overflow exploit using&#xA;&lt;a href=&#34;http://shadow-file.blogspot.com/2013/03/crossbow.html&#34; target=&#34;_blank&#34;&gt;Crossbow&lt;/a&gt; (now&#xA;called Bowcaster), which I released earlier today.&lt;/p&gt;&#xA;&lt;p&gt;For this tutorial I&amp;rsquo;ve written a simple program in C that overflows a&#xA;buffer on the stack with whatever it reads from the network.  I&#xA;cross-compiled it for MIPS Linux and ran it using QEMU chrooted into the&#xA;unpacked filesystem of the Netgear WNDR3700v3 (Firmware 1.0.0.18).&lt;/p&gt;&#xA;&lt;p&gt;The program, vulnerable.c contains the following function:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Crossbow</title>
      <link>https://shadowfile.inode.link/blog/2013/03/crossbow/</link>
      <pubDate>Thu, 28 Mar 2013 10:32:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2013/03/crossbow/</guid>
      <description>&lt;p&gt;UPDATE: Crossbow has been renamed to Bowcaster. It turns out &amp;ldquo;Crossbow&amp;rdquo;&#xA;is a popular word.  Who knew?  A company in California has the word&#xA;registered as a trademark in the US in connection with computer&#xA;software.  They might be cool with us using the word, since this is an&#xA;open-source noncommercial product, but we&amp;rsquo;ve decided to change the name&#xA;just in case.  Hopefully the new name is esoteric enough to avoid any&#xA;naming conflicts, while still being cool and fun to say.  I&amp;rsquo;m leaving&#xA;this post as-is, save for the new Github link.  The old Github project&#xA;will stay up for a while, but you should use the new one from this point&#xA;on.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hacking is Bullshit</title>
      <link>https://shadowfile.inode.link/blog/2013/02/hacking-is-bullshit/</link>
      <pubDate>Sun, 10 Feb 2013 15:35:00 -0800</pubDate>
      <guid>https://shadowfile.inode.link/blog/2013/02/hacking-is-bullshit/</guid>
      <description>&lt;p&gt;I love hacking.  I love vulnerability research.  I love software&#xA;exploitation.  I love finding creative ways to subvert control of an&#xA;application or system to make it do something it wasn&amp;rsquo;t intended to&#xA;do.&lt;/p&gt;&#xA;&lt;p&gt;But this is research, and like any research, lots of things never pan&#xA;out.  It&amp;rsquo;s weird because it involves hours, often hundreds or even&#xA;thousands of hours, of frustration paid off by successes that last only&#xA;moments.  And the cycle repeats.&lt;/p&gt;</description>
    </item>
    <item>
      <title>DLink DIR-815 UPnP Command Injection</title>
      <link>https://shadowfile.inode.link/blog/2013/02/dlink-dir-815-upnp-command-injection/</link>
      <pubDate>Fri, 01 Feb 2013 15:07:00 -0800</pubDate>
      <guid>https://shadowfile.inode.link/blog/2013/02/dlink-dir-815-upnp-command-injection/</guid>
      <description>&lt;p&gt;With all the excitement regarding UPnP vulnerabilities lately, I though&#xA;I&amp;rsquo;d write up this one I found a few weeks back.  I had kind of forgotten&#xA;about it.  But it&amp;rsquo;s pretty straight forward, and kind of fun, so here it&#xA;is.&lt;/p&gt;&#xA;&lt;p&gt;In Tactical Network Solutions&amp;rsquo; &lt;a href=&#34;http://www.tacnetsol.com/training/&#34; target=&#34;_blank&#34;&gt;Intro to Embedded Device&#xA;Exploitation&lt;/a&gt; class, we use the&#xA;D-Link DIR-815 for the practical exercises since there are tons of great&#xA;0-days for the students to find.  The last time we taught the class, I&#xA;thought I&amp;rsquo;d try my hand at finding a new one. Twenty minutes in, voila!&#xA;Command injection in a single multicast packet!&lt;/p&gt;</description>
    </item>
    <item>
      <title>UPDATED: Responsible (non)Disclosure</title>
      <link>https://shadowfile.inode.link/blog/2012/11/updated-responsible-nondisclosure/</link>
      <pubDate>Thu, 29 Nov 2012 09:30:00 -0800</pubDate>
      <guid>https://shadowfile.inode.link/blog/2012/11/updated-responsible-nondisclosure/</guid>
      <description>&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I received a personal communication from Mr. Flemming.  He&#xA;makes the case that what I believed to be a subtextual threat was not&#xA;intended.  Not necessarily speaking for TNS, I am inclined to take him&#xA;at his word and that my initial read of the situation may have been&#xA;unduly skeptical.  I hope to post additional updates as things develop.&#xA; I&amp;rsquo;m leaving the original text of this post intact, though, as it&#xA;provides meaningful context for the situation that is unfolding.&lt;br&gt;&#xA;**&lt;br&gt;&#xA;Original Post:**&lt;br&gt;&#xA;So here&amp;rsquo;s something awesome.  And by &amp;ldquo;awesome&amp;rdquo; I mean &amp;ldquo;kinda shitty.&amp;rdquo;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Specifying Preferred Load Addresses for ELF Shared Libraries</title>
      <link>https://shadowfile.inode.link/blog/2012/10/specifying-preferred-load-addresses-for-elf-shared-libraries/</link>
      <pubDate>Tue, 23 Oct 2012 18:44:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2012/10/specifying-preferred-load-addresses-for-elf-shared-libraries/</guid>
      <description>&lt;p&gt;[NOTE: &lt;em&gt;This was going to be a post about how to relocate a shared&#xA;library that is loaded using LD_PRELOAD such that a program&amp;rsquo;s linked&#xA;libraries get loaded at their normal addresses.  Sadly, the trick I&#xA;thought would do that didn&amp;rsquo;t actually work for me.  The library got&#xA;relocated, but the other libraries weren&amp;rsquo;t restored to their natural&#xA;base addresses.  That said, it still is interesting and worth writing&#xA;up.&lt;/em&gt;]&lt;/p&gt;</description>
    </item>
    <item>
      <title>Parsing Email and Fixing Timestamps in Python</title>
      <link>https://shadowfile.inode.link/blog/2012/06/parsing-email-and-fixing-timestamps-in-python/</link>
      <pubDate>Tue, 12 Jun 2012 09:06:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2012/06/parsing-email-and-fixing-timestamps-in-python/</guid>
      <description>&lt;p&gt;I decided to POP out all my Yahoo mail into my Google Apps account so I&#xA;could stop paying for Yahoo&amp;rsquo;s &amp;ldquo;premium&amp;rdquo; service (WTF, it&amp;rsquo;s 2012, and POP&#xA;is a paid feature&amp;ndash;and there&amp;rsquo;s no IMAP?).  I have fetchmail then&#xA;download all of my messages which get post-processed by procmail and&#xA;re-served by dovecot.  Since a bunch of really old messages were just&#xA;downloaded by fetchmail, they appeared to be &amp;ldquo;new&amp;rdquo; from dovecot&amp;rsquo;s&#xA;perspective.  This is because the name of the message files stored in&#xA;the Maildir format used by dovecot starts with a number representing&#xA;when the messages were downloaded.  So years-old messages that were just&#xA;downloaded will have a very recent timestamp encoded in their&#xA;filenames.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Long-form Reading 2011</title>
      <link>https://shadowfile.inode.link/blog/2011/12/long-form-reading-2011/</link>
      <pubDate>Fri, 16 Dec 2011 08:01:00 -0800</pubDate>
      <guid>https://shadowfile.inode.link/blog/2011/12/long-form-reading-2011/</guid>
      <description>&lt;p&gt;Here are some long-form articles I&amp;rsquo;ve enjoyed this year.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;http://www.theatlantic.com/technology/print/2010/12/the-hazards-of-nerd-supremacy-the-case-of-wikileaks/68217/&#34; target=&#34;_blank&#34;&gt;The Hazards of Nerd Supremacy: The Case of&#xA;Wikileaks&lt;/a&gt;&#xA;(theatlantic.com)&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;http://www.wired.com/magazine/2011/02/ff_octopus_conspiracy/all/1&#34; target=&#34;_blank&#34;&gt;The Octopus Conspiracy: One Woman&amp;rsquo;s Search for Her Father&amp;rsquo;s&#xA;Killer&lt;/a&gt;&#xA;(wired.com)&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;http://www.theatlantic.com/magazine/archive/2001/09/confessions-of-a-prep-school-college-counselor/2281/&#34; target=&#34;_blank&#34;&gt;Confessions of a Prep School College&#xA;Counselor&lt;/a&gt;&#xA;(theatlantic.com)&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;http://berlinbooks.org/brb/2011/01/the-great-rubber-robbery-how-julius-fromm%E2%80%99s-condom-empire-fell-to-the-nazis/&#34; target=&#34;_blank&#34;&gt;The Great Rubber Robbery: How Julius Fromm&amp;rsquo;s Condom Empire Fell to the&#xA;Nazis&lt;/a&gt;&#xA;(berlinbooks.org)&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;http://www.houstonpress.com/content/printVersion/218684/&#34; target=&#34;_blank&#34;&gt;Bursting the&#xA;Bubble&lt;/a&gt; (about&#xA;David Vetter, the &amp;ldquo;Bubble Boy&amp;rdquo;, houstonpress.com)&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;http://www.slate.com/articles/news_and_politics/assessment/2011/02/the_stutterer.single.html&#34; target=&#34;_blank&#34;&gt;The Stutterer: How He Makes His Voice&#xA;Heard&lt;/a&gt;&#xA;(slate.com)&lt;/p&gt;</description>
    </item>
    <item>
      <title>Reading List 2011</title>
      <link>https://shadowfile.inode.link/blog/2011/12/reading-list-2011/</link>
      <pubDate>Tue, 13 Dec 2011 12:15:00 -0800</pubDate>
      <guid>https://shadowfile.inode.link/blog/2011/12/reading-list-2011/</guid>
      <description>&lt;p&gt;I was using up all of my accumulated credits on Audible.com just now,&#xA;and realized I&amp;rsquo;ve listened to several great audiobooks over the last&#xA;year. Here&amp;rsquo;s a list of what I&amp;rsquo;ve listened to in 2011, along with a link&#xA;to the book on Audible.com. I recommend them all.&lt;/p&gt;&#xA;&lt;p&gt;&lt;!-- raw HTML omitted --&gt;Judas Unchained&lt;!-- raw HTML omitted --&gt;, Peter F. Hamilton, Part&#xA;2 of the Commonwealth Saga&#xA;(&lt;a href=&#34;http://www.audible.com/pd?asin=B002V0QZL0&#34; target=&#34;_blank&#34;&gt;link&lt;/a&gt;)&lt;br&gt;&#xA;&lt;!-- raw HTML omitted --&gt;The Gun&lt;!-- raw HTML omitted --&gt;, C. J. Chivers&#xA;(&lt;a href=&#34;http://www.audible.com/pd?asin=B0045KKG6E&#34; target=&#34;_blank&#34;&gt;link&lt;/a&gt;)&lt;br&gt;&#xA;&lt;!-- raw HTML omitted --&gt;The Windup Girl&lt;!-- raw HTML omitted --&gt;, Paolo Bacigalupi&#xA;(&lt;a href=&#34;http://www.audible.com/pd?asin=B002UZN4MO&#34; target=&#34;_blank&#34;&gt;link&lt;/a&gt;)&lt;br&gt;&#xA;&lt;!-- raw HTML omitted --&gt;Snow Crash&lt;!-- raw HTML omitted --&gt;, Neal Stephenson&#xA;(&lt;a href=&#34;http://www.audible.com/pd?asin=B002UUKWCY&#34; target=&#34;_blank&#34;&gt;link&lt;/a&gt;)&lt;br&gt;&#xA;&lt;!-- raw HTML omitted --&gt;Embassytown&lt;!-- raw HTML omitted --&gt;, China Mieville&#xA;(&lt;a href=&#34;http://www.audible.com/pd?asin=B00500HQNE&#34; target=&#34;_blank&#34;&gt;link&lt;/a&gt;)&lt;br&gt;&#xA;&lt;!-- raw HTML omitted --&gt;Pattern Recognition&lt;!-- raw HTML omitted --&gt;, William Gibson&#xA;(&lt;a href=&#34;http://www.audible.com/pd?asin=B002V8OCTY&#34; target=&#34;_blank&#34;&gt;link&lt;/a&gt;)&lt;br&gt;&#xA;&lt;!-- raw HTML omitted --&gt;Spook Country&lt;!-- raw HTML omitted --&gt;, William Gibson&#xA;(&lt;a href=&#34;http://www.audible.com/pd?asin=B002V5GO3O&#34; target=&#34;_blank&#34;&gt;link&lt;/a&gt;)&lt;br&gt;&#xA;&lt;!-- raw HTML omitted --&gt;Zero History&lt;!-- raw HTML omitted --&gt;, William Gibson&#xA;(&lt;a href=&#34;http://www.audible.com/pd?asin=B0040HTAHS&#34; target=&#34;_blank&#34;&gt;link&lt;/a&gt;)&lt;/p&gt;</description>
    </item>
    <item>
      <title>Handling HTTP Redirection in Ruby</title>
      <link>https://shadowfile.inode.link/blog/2009/03/handling-http-redirection-in-ruby/</link>
      <pubDate>Sun, 15 Mar 2009 09:18:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2009/03/handling-http-redirection-in-ruby/</guid>
      <description>&lt;p&gt;I have a Ruby project where I&amp;rsquo;m dumping a bunch of bookmarks from&#xA;delicious.com, then fetching each bookmarked page for analysis.&lt;/p&gt;&#xA;&lt;p&gt;One of the problems I encountered early on is that the some of the web&#xA;pages bookmarked would redirect to some other location. Simply checking&#xA;for HTTP response code 200 was insufficient. I needed to check for&#xA;redirection as well.&lt;/p&gt;&#xA;&lt;p&gt;A quick Google search for &amp;ldquo;ruby follow http redirect&amp;rdquo; yields lots of&#xA;&lt;a href=&#34;http://www.google.com/search?q=ruby&amp;#43;follow&amp;#43;http&amp;#43;redirect&amp;amp;ie=utf-8&amp;amp;oe=utf-8&amp;amp;aq=t&amp;amp;rls=org.mozilla:en-US:official&amp;amp;client=firefox-a&#34; target=&#34;_blank&#34;&gt;results&lt;/a&gt;.&#xA;Unfortunately, they&amp;rsquo;re all very similar, and not quite right. In&#xA;general, the examples you come across (even the one in the official Ruby&#xA;documentation) don&amp;rsquo;t handle the case when the redirected location is&#xA;path relative to the original location. So you end up doing a get on a&#xA;URL that looks like &amp;ldquo;../../redirected/location/index.html,&amp;rdquo; which&#xA;clearly won&amp;rsquo;t work.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Mounting LVM Disks in Ubuntu</title>
      <link>https://shadowfile.inode.link/blog/2009/03/mounting-lvm-disks-in-ubuntu/</link>
      <pubDate>Thu, 12 Mar 2009 06:30:00 -0700</pubDate>
      <guid>https://shadowfile.inode.link/blog/2009/03/mounting-lvm-disks-in-ubuntu/</guid>
      <description>&lt;p&gt;I always thought LVM (Linux&amp;rsquo;s Logical Volume Manager) was kind of neat&#xA;for the flexibility it gives you in adding and removing disks and&#xA;resizing volumes such. However, in practice, I find it&amp;rsquo;s usually more&#xA;trouble than it&amp;rsquo;s worth. It adds a layer of complexity between me and my&#xA;data.&lt;/p&gt;&#xA;&lt;p&gt;Often I need to mount a disk configured with LVM on another Linux&#xA;machine or in an Ubuntu live CD environment. Out of the box the logical&#xA;volumes aren&amp;rsquo;t recognized, so I can&amp;rsquo;t mount them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to sudoedit non-interactively</title>
      <link>https://shadowfile.inode.link/blog/2009/01/how-to-sudoedit-non-interactively/</link>
      <pubDate>Thu, 08 Jan 2009 06:31:00 -0800</pubDate>
      <guid>https://shadowfile.inode.link/blog/2009/01/how-to-sudoedit-non-interactively/</guid>
      <description>&lt;p&gt;Okay, this one&amp;rsquo;s a bit esoteric, but I think it&amp;rsquo;s pretty cool. How do&#xA;you use &amp;lsquo;sudoedit&amp;rsquo; non-interactively such as from a script? Just a brief&#xA;background about sudo: sudo is an authentication mechanism in Unix &amp;amp;&#xA;Linux that allows unprivileged users to run specific commands (as&#xA;defined by the system administrator) with root privileges without having&#xA;the root password. This has several advantages over logging in as&#xA;root:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Users can have specific, limited set of root privileges without&#xA;having the entire set of root privileges.&lt;/li&gt;&#xA;&lt;li&gt;Users use their &lt;!-- raw HTML omitted --&gt;own&lt;!-- raw HTML omitted --&gt;&#xA;password, so the root password doesn&amp;rsquo;t have to be shared. If a&#xA;user&amp;rsquo;s sudo privileges are revoked, the root password doesn&amp;rsquo;t have&#xA;to be reset.&lt;/li&gt;&#xA;&lt;li&gt;Each use of sudo is audited per user, so that each time sudo&#xA;privileges are invoked, there is an event in the system logs that&#xA;identifies the specific user and the command they ran.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Sudoedit is a command that is related to sudo. It lets users edit files&#xA;that normally only root can edit, such as system configuration files.&#xA;However instead of using &amp;ldquo;sudo&amp;rdquo; followed by the editing command, the&#xA;user runs &amp;ldquo;sudoedit filename&amp;rdquo; and sudo invokes the user&amp;rsquo;s default&#xA;editor, letting them edit the file.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Shadow File</title>
      <link>https://shadowfile.inode.link/blog/2004/12/the-shadow-file/</link>
      <pubDate>Wed, 15 Dec 2004 19:20:00 -0800</pubDate>
      <guid>https://shadowfile.inode.link/blog/2004/12/the-shadow-file/</guid>
      <description>&lt;p&gt;&lt;!-- raw HTML omitted --&gt;This is the first post to The&#xA;Shadow File. I suppose a brief explanation is in order. What is The&#xA;Shadow File? In Unix and Linux, an algorithm is used to create a one-way&#xA;hash of a user&amp;rsquo;s password. This hash, along with the username and other&#xA;information used to be stored in /etc/passwd. In many modern *nix&#xA;systems, the password hash has been removed from the passwd file and is&#xA;now stored in a separate file, because the passwd file is&#xA;world-readable. This way, an attacker would have to obtain both files in&#xA;order to attempt to recreate the password. The file that contains the&#xA;password hashes is /etc/shadow. Now you know.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
