<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>punktech</title>
        <link>https://paragraph.com/@phasewalk</link>
        <description>A punk writing about Cybersec, Privacy Tech, and whatever else.</description>
        <lastBuildDate>Fri, 05 Jun 2026 14:23:01 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>punktech</title>
            <url>https://storage.googleapis.com/papyrus_images/613eb3596637311d1b5f2c7f7eccafab8bdc90ad8268ff9705afd8126df9a777.jpg</url>
            <link>https://paragraph.com/@phasewalk</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[Homelab Ch.1: The MacNAS]]></title>
            <link>https://paragraph.com/@phasewalk/lab-ch1</link>
            <guid>ltyJKMsuYgpuU2aam7U8</guid>
            <pubDate>Tue, 03 Feb 2026 23:08:28 GMT</pubDate>
            <description><![CDATA[Kicking off my homelabbing journey by repurposing an old Mac Pro 5,1 as a network-attached storage (NAS) server.]]></description>
            <content:encoded><![CDATA[<hr><p>I think I’m just a man with expensive hobbies because two years I ago I got really into skiing — finally cashing out on my own gear and a season pass — and this year I’ve decided to start homelabbing.</p><p>And no, I don't mean the type of homelabbing Walter White was doing, I mean more the kind that Lain does:</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/81f311d964451193e3f0cbf660597b353c40c9e35ac9226fe96e8c61ad95ae4d.jpg" alt="" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAARCAIAAAAzPjmrAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEkklEQVR4nFVUS29cNRT2zL1+j+1r+47t+8i8JzOTB02TNi1toKElbWkoKkGwadQWhS5aUMUCCQlQQayQEN0gxA9ACLGFBb8AIbFmATt2LNmwYxF0byZtkY4s28c63/E55/sAaBCUL7utWzHTMWpFWEKaxNTENIG1IaYR11hoJAyq1mPjunLVNn9Wb2KSxETFSEEVIpoCwD2dbKswasa0ctQGqUbMIH5k89BY2v8BzCGPjdcPuIFUxzyNqIHcxawNYGcDmT5o4qei14nz5KkoGguDpafCVpsnXzFYGqpSolIkk+qoM5RkSKaxCg2WNrEEyA6imEZPRT+qyePUqNBUaCItUYFIR4Wp95YKw2TaMoGo+c8gE8QPROeE0ka00kF7QOwINCBrIgmJfAxAmKZ1aCwskRZyj3hBEkfa4zjZhGpGWBsjRYUi0lWoKq2rVyckU+qGWDrMrWS2FRZBA1aNjcmTlkJhoipxWwGIPIxft6NXoeiq8jnYvQSSHTDcBeuvEbNCpMVJEDaniZsX0zka+lBlkJmI6ggr0Kwn5zFGzHQQ6VAFKB2WKRP95yYHJ2a3WskMZPugdzdSLzQv3VMf/AjKfcol1hnR7igbJC02Abtuq38SCR9zGwsPmkgSpl3bB++ZMIDpFeVeVKEhPVUe6hWT7Al1mbZHjfFutPU1mL2JwnoULkBzGieWuoK5gtbFxColLmOT5fDSW4g7KCzNFwFoUoT4YCHrlblUrsH0VPmzSdYQKfETMNtrFmdhe9Iw02jp5Ue//f3KV7+A0R4ROeSOmAWa9bnNsLRUpdR4FnKSZWLtDLYDiDkOYwDz1ebkatEZDjpFoj2geqz8M7oANEUbb9z7/R97+UHTntTd89f2P/7j8PD+T3+B6QP27E118YCYAXY9ourRShxzmT010eenyfaSP7sVMQ+zIWi//cXen/+Wp290yjwUZZOlUnklPeQ2nuzsfvuz3DogxWbZna2tnLv97iN/9T0QLo4++mbt8x9APCALs6ruMsUqRSpl40I+P5XbE39tc3brIc6XQPPKOweHh8v7H+YuK8oS8hRLh+oOE90B9mRsR1Ro1e52x2c2Vs8j4akq8fIVuPvJ8P3v+NZNpAJNAhKWai+nA74+otNBa6nvt6/jbBnE4YS//yg/dXXUKTudIuY1j2oArFKsczLcYnah7ExHSxeK7hSqjJgy4t3szpefHh6Wtz9rYsd8UQO4dGMRu8AGHexzAJkbb4IYtQBoiSTkWRAqrfll5lMhU5qEdP06sZ21xaXgFyIimfSIG9FdH9x4eOf7X5OduzEzzOVVn41PhgMkUm6zqFIki3UAEZaIJZVCVSKaHMuDxRWAI9IT5SBLjM1C6NTYlRcpV00RK7HtVXzWnshUhA5tZ0R7bgtqPEl8LGxNtEok5jTGvKLMUXQkUun6ZniaJL66PL6v2qMCt0U1P8pV7a1pzFwmeguQaea6Iu9j55synTO5Sr/C0Eh4pDxWnlSra+UTOT6HpeMmb2WLpN0nSUGk48WqmZyt8CpBTZGqhJoa19tZlWUeI4WF58UI9nr/AbTnmUPybJpyAAAAAElFTkSuQmCC" nextheight="631" nextwidth="1201" class="image-node embed"><figcaption htmlattributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>A <strong>homelab</strong> is a personal setup of computers and networking devices that are owned and operated entirely by yourself! They can be used to provide services or conveniences on your home network, such as: Network Attached Storage (NAS), a Network-wide Adblocker, personal Streaming Services, and much, much more. Basically like doing sysadmin work — not for a paycheck — but for the sole satisfaction of relying less on expensive cloud platforms and corporate-owned services and more on your own technical skills and hardware.</p><h2 id="h-why-build-a-nas-server" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Why Build a NAS Server</h2><p>There are many small projects you can build to start homelabbing, but a personal NAS server is one of the most common places to start. It's like having your very own Google Drive, one that you control entirely. The only storage limit you'll run into is governed by the hardware you have on hand. And the best part is that your files will no longer live in the "cloud" -- fancy term for <em>someone else's computer</em> -- they'll live on <em>your drives</em> and served by <em>your server</em>.</p><h2 id="h-hardware" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Hardware</h2><p>First step of any homelab setup is hardware. No need to break the bank here, just start with whatever you’ve got laying around or source some for cheap (Dell Micro PCs are a great option).</p><p>I’m currently living in a place where my Dad used to live, and he left a 2010 Mac Pro 5,1 in the closet. It’s been collecting dust for years. I wanted to start my homelab with a smaller footprint and use something like a Dell Optiplex to run my NAS — but I don’t have one of those laying around — I have this huge cheese grater!</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/a2e96b9c8bfdc6f4a9b86d49294eec0498253bd7f3224cad11bbb819bf5fc296.png" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAG5UlEQVR4nKWW/W/T+B3HLYToVJVVgOAnVE2iPyE2EE/j+JFq10OHdrSoQ/R0p4E0CulTSNsrtLRN0ja0SfwU23EcJ3FSJ03ixLGdOM8PbnJtV8od2u4f6vS1ue7WkZvu9tZXlvODX6/P923HCQS1TyAQmJt7bbPZU6mUJBW3t7chCDo4OID+zywtLU1OTlosltd65ubmVDWfzxfC4Q2XywVBkCAImqb9YtPQ0BAEQSsrKy909Pz8a6fTqapqtVrd29vff/dud3e3Xq9rmvbTqw5lBwcHgp62YuNKSZJ2dnay2SzP806nc1lPtVp7+3Z/b2//++/f7+zstlqtRqOhaZogCL+sGWOipCDY7XbHmzfBYDCZTOZyuVZr+9vWNjh+u73797337/+x/+47batZqzUqlUqhUCgWiw6Hw2QyWa1W3O//OQEMoxzHlcvlnd3dd+++azabqqpubTWbze1mc3ur2dK0rUbjw2q1tvf23m5tbZVKpc3NTQzDGSbAMAyKoofAowKDXqlUolHe5/N5PB6apjVtS9MAWtNajYbWaGj1eqNSrZfLtUKxVCiUSsVyqVwtFsFuqtV6Nps97PyoIJEQYrEYTdPRaFRSlDJIRdO0OoAaq1GtAXqpXC2UyoViWVXz2awqy4okyZKklEplWZbbCiI8X63W//nDDzs7O7VaLZdTBUGo1eq1WqNaq1erYFUq9XK5UiyW84WiqhZyOVVSspIki6IkiplCoZhOpz8iMD6n0+lkUmBZlqIogiBQFKUoSu+sXi5XjVUqVQsGPZdXFFWWs2JGSouZVEpMpdK5XN54utoJMjzPEwRBkqThoCiq+KHisrEAOl/I5fL64NmMKKVSoiCkEgkhHhdkORuPtxdkMvLGxoZHD47jGIZ5PB5VLeQL5XweFKJ3kleUnCwDuiCIgiAmk6l4XNjcTMRiCVHMxGIxvfP/FBjfQEVROI5DEQRFUQRBYBjGMDSbU3M5cCeVrKooOUnOZqRsJiMLKZHnYwaaj8Z5PhqJRAVBDIXCH3lMDwXBYNDlchtxOp1ut1uSFUlRwVHniqKUTmcSCYENBH0MGwyFeT7GRTa4cCQUCsfjAsuGPiIw7oyiKKzfvw7iXFtbc7x5s76+nkqLmYycFqVUGtSd1DuJRHiKogmSYgPBcJgPBrlAgGPZIM/HGIZpK5Blmabp1dVVh8Oxurq6vLy86nAkEoLBTSRT8YSwCToRQqGwhyBxnKRpfyDAMX6WYVjax4TDPE3TbQWiKBIEYQdZttntVqvVbrfHYpuAu5mIbSaioOvYxkY0GORQDHe5YRwnGYb1en2klyZJbzDIeTzk/xAsLi4u6Vl4vbC4uBTZ4PlofIOPRTaiXITnwnwoFA4EOIKgMIwgSS/pBV0RBIV7SD8bQD2etoJoNKooyuqq49Wrufn5Bf04HwxygMtFQlwkEOTYAOdnwe2lfYzX6ydJL+jKQ2IYgaIen4/9+MvOEBivaJvNNjs7++rVy2++mX358iXjB48Kywb9/gDjDwA07Se9DGGg8Q9oBMVgBPV6fTDcfgcURfn97Nzc3PT09PTMzJRlamZmxkv7ANcHuF4dTZJeoxAMJwEawWEEhWHUDaMkRTthuK3A6XSSJDk7O/sCxGI2my0WC0FSoArwUHr1qSkwNU6i+uAwggO0G3G7EZcbAQJne4HVanW74ampqQmQyfHx8YnJSRwnSdIHuB6ja4BGjMH1qQ00WC647Q6MH/3p6RmrzWY2m8f0mEyjY+NjCIp9aAMjkEP0If2nAjdCUTSCEG0FZrPlhcUyOjpqGh01mUzPnj83mUZhGMEwEnCNQo7QXajTBbvcMIJ6MJwkKRqG0bYCk2lsfGJiZOTZcz0jz8CJG0ZRjPiRixtclxtxwyiM4BhOUhSNe8i1ddfyimN5xWE2Ww47/3fOnj0LQdDAwF8GBwcfPnz41ddf//Xx48ePnzx9+tTlghGUAGg35nZjP0IZ0su4XOjCwtKTvz37tP/u9Ruf9PX9aXh4uK+vD/rvnDhxAoKg+/eH+vs/u3Tp0ie3b3/a3z8wMPDo0fDamhNUhIAGvDSLYoTNtjI6NvHF/cGLFy/+pqPDIBw7duzUqVNQu3R2duo7GHry5Onv/3D59OnTv+3q6unpuXLlit2+QpA0jOA2+8rDR8M3bvyxu7v7yLUnT540znt7e422j6arqwuCoAsXLnz++b3BwaF79764efN2T8/vOjs7LZZp0OyLqevXb0IQdPz4cQiCOjo6zpw5c/78+bYj/0yuXr364MHQgwdDuunPX3751Wd37966dQuCoHPnzvX29v4aqBHjb6xx3t0N3blzZ2TEdPnyZQiCrl279iuI/wJ6MuRnn7Gs2wAAAABJRU5ErkJggg==" nextheight="512" nextwidth="512" class="image-node embed"><figcaption htmlattributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>But don’t let its size fool you! Although this thing used to be a workhorse back in its day, it’s sporting:</p><ul><li><p>Intel Xeon W3520 8-core 2.793 GHz CPU</p></li><li><p>AMD ATI Radeon HD 4870 GPU</p></li><li><p>8GB DDR3 RAM</p></li></ul><p>This won't be enough compute to do as much as I want, but here's why I find it an enticing machine to start with (aside from the fact that I have it at my disposal).</p><h3 id="h-pros-of-the-mac-pro-51" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Pros of the Mac Pro 5,1</h3><ul><li><p><strong>Modularity:</strong> These old Mac Pro towers are <em>extremely modular</em>. It was the last line of computers Apple built that were truly for the computer hobbyist. They are extremely easy to work on and upgrade (often times requiring no screws since things just slot into place), and they have 4 hard drive bays! That's pretty good for a starter NAS setup.</p></li><li><p><strong>Build Quality:</strong> It's Apple. Need I say more?</p></li></ul><p>But of course, with a machine this old, it is not without it's drawbacks.</p><h3 id="h-cons-of-the-mac-pro-51" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Cons of the Mac Pro 5,1</h3><ul><li><p><strong>Dated Hardware:</strong> This machine is old. Really old. It's also the single-processor model (dual-processor models offer more robust upgrade paths). I <em>could</em> upgrade the processor to something like a Xeon W3690 (a 6-core, 3.46 GHz chip) and up to 46GB RAM, <em>but</em> that's not in my current plans. Maybe someday.</p></li><li><p><strong>Power Draw:</strong> At idle this machine currently draws roughly 120-150W! That's a lot of power draw for something with such little compute! For reference, it's about 3x what a modern mini PC (like a Dell Optiplex) will draw. Here's some insane napkin math for ya (power is expensive where I live, roughly $0.45/kWh):</p></li></ul><p>Assuming the machine is running 24/7:</p><br><table style="min-width: 75px"><colgroup><col><col><col></colgroup><tbody><tr><th colspan="1" rowspan="1"><p>Power</p></th><th colspan="1" rowspan="1"><p>Cost</p></th><th colspan="1" rowspan="1"><p>Timespan</p></th></tr><tr><td colspan="1" rowspan="1"><p>3.6 kWh</p></td><td colspan="1" rowspan="1"><p>$1.62</p></td><td colspan="1" rowspan="1"><p>per Day</p></td></tr><tr><td colspan="1" rowspan="1"><p>25.2 kWh</p></td><td colspan="1" rowspan="1"><p>$11.34</p></td><td colspan="1" rowspan="1"><p>per Week</p></td></tr><tr><td colspan="1" rowspan="1"><p>109.6 kWh</p></td><td colspan="1" rowspan="1"><p>$49.31</p></td><td colspan="1" rowspan="1"><p>per Month</p></td></tr><tr><td colspan="1" rowspan="1"><p>1,315 kWh</p></td><td colspan="1" rowspan="1"><p>$591.71</p></td><td colspan="1" rowspan="1"><p>per Year</p></td></tr></tbody></table><br><p>That's insanely expensive for a homelab server! A more modern, power-efficient machine (like an Optiplex) would be way more cost effective (and powerful) in the long-term. But hey,</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/e10ee6454fd8e21582414dccab3eb492f652f87174926035f8d9edb0a427feba.webp" blurdataurl="data:image/png;base64,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" nextheight="361" nextwidth="640" class="image-node embed"><figcaption htmlattributes="[object Object]" class="">Am I right?</figcaption></figure><blockquote><p><strong>Quick Note:</strong> I didn't compute this until after I had already been tinkering with this machine for a bit. Oops. Don't make the same mistake as me! If you live somewhere with expensive electricity, be sure to consider power draw when picking out homelab hardware.</p><p>For the time being, and since I realized this so late in my journey, I will still setup a basic NAS server on this machine to get my feet wet. But I won't be running this thing 24/7. Once I pick up an Optiplex I'll take what I've learned here and migrate my NAS over to that machine. Maybe someday I'll upgrade this tower and use it for something else fun. I wonder if any of the upgrade paths available for this model could lessen the power draw?</p></blockquote><h2 id="h-weighing-the-pros-and-cons" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Weighing the Pros and Cons</h2><p>As it currently stands, this stock Mac Pro 5,1 is <em>not in my long term plans for my homelab.</em> It doesn't offer enough compute for how much it draws in power. However it can serve as a good starting machine to get my hands dirty. My current plan is to set it up as a NAS server so I can get familiar with administering tech like Samba shares or NFS. Once I pick up something like an Optiplex, or hell, even a Raspberry Pi, I'll migrate the server over to a new machine and decommission the tower — where it will return to collect dust once more. More seriously though, we'll likely keep it around as long as we have the space to store it. If I find myself with money burning a hole in my pocket, it would sure be fun to substantially upgrade it.</p><h2 id="h-schrodingers-important-data-and-the-mac-tower-debacle" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Schrödinger’s Important Data and the Mac Tower Debacle</h2><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/a248e0385ecc7230b611696467e236d4ecd779290b288bce48bf604dc9e1bec5.svg" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAARCAIAAAAzPjmrAAAACXBIWXMAAAsTAAALEwEAmpwYAAADCElEQVR4nK2TUUgTYQDHvx4ioichDBJ66qE3kUwIyQRjzeYskulyzg6PzZ3jjp1H50SdzIemQ1MiUTjTSCWQBrUN4ey84HSwWEwuDw8uF6vp0VAxEAaDPcR2asumWPbj/3DfB/f9vu/734FXRzJ5PGia5jguGAzyPC9JUiwWi8fjOzs7qVQKeE7MzMzMUQLv/4A+QkCfGFBQCzJ4PJ4cAp/Pz2VQdpENezzAmSpF4LDbcwgI4hGG4ThOtLd3Bv8Jjls4dzYfAPBycHB2YmJFWFrhmbWosCsYGBjEcRLHSQRBzeYWqxW1WjGTyZJJM4KgBNHmdvezLBs+hGAwqJyeYd6HPoQmn3Q9bjv1og98k9i0YHx8giDsZnMLQdiPCAxbfD6/kAue57NLZt95ulpAHw4+86/TAlEUKWrM6ezBsNbsWK227Dgc3Xp9A8dxfwrC4fC+IBxekiQpsrqyFl3+sb2VFjB7WCwten0DgqAQZDIam5QbQxAUQVCt9r7T2UNRYyhqY3IxMDDIsmymj8DBkgN7eDwetbqqsLC4qKhEq61RqTRFRcXl5SqV6o7B8BDDcJZlUdQ2NTW9/0ogEKDpOQAA3FinFJ7jK1Jacrl6Kypuq9XVpaU3DQaIJDtIsgPDWtXq6oqKyrq6BxDURFEUTdMmU7PX61XqFUURRbG8vPNX8sHkM7syeVDA83xnpwOCTCUlpXp9Q3m5CoaR9naHEp3OUFZ2C4YtGs3dmppaURRZlnW5eiVJWvq0tC6vS5IkCMLiIncJgLeT/YIgiKL4m8DtdpNkh0Zzr7ER1unqdToDBJlcLvfw8IhWW200Qj6fn6Zpmw2HYQtNz0WjUSEimCkTQC4AY/r/qrwGam6cvnox/bzMhyKRSDQa/SWIx+Oh0MfubqdOV08Q9qGhpwzDxA/ny9dVWZYL8Mvp1a+nF33upWbn38zT/umJETlDLBaTZXlXsJOB4xZwnPT5/MrwMLaz2NjckL/LLM9sbG5kzytsbW3tClJ7jI5SiURif3iA5N+TSCSSyeRPygxbWVCRX3QAAAAASUVORK5CYII=" nextheight="1060" nextwidth="1995" class="image-node embed"><figcaption htmlattributes="[object Object]" class="">Until I inspect the drives, the data is both important <em>and</em> garbage. It is only when I view the contents of the drive will the data reveal itself as one or the other!</figcaption></figure><p>Thus, my journey to build the MacNAS began ... with a rough start. The system booted up okay, but wouldn’t successfully log in to any user accounts. It would simply load and load and keep on loading, never dropping me into a desktop environment. I wanted the satisfaction of interacting with an ancient OSX desktop, and opening the “About” page to see the system’s specs. More importantly though, my first mission was to ensure no important data still resided on the machine’s internal HDD. When my dad was using this, he was working on movies he made with his best friend. I wouldn't want to jeopardize losing those files. He left behind two external HDDs, which I was pretty certain contained all his important data, but I wasn’t willing to risk it by wiping the internals until I double-checked myself (I couldn’t reach him at the time bc it was late though I shot him a message).</p><p>I followed a few common troubleshooting steps — booting into safe mode, various options in recovery mode, disk-repair, resetting NVRAM/PRAM, single-user mode, and even tried reinstalling the OS — none of that worked. I was fairly certain that the operating system had been corrupted beyond self-repair after running various commands in the terminal resulted in “cannot find this library”-type errors. On the other hand I was confident that the drive was still functional, not only because the disk-repair output seemed fine, but also because it wasn’t making any obvious noises that would point to HDD failure.</p><p>After torturing myself with this for far too long I realized I was being silly. I could just flash a live Ubuntu image onto a flash drive and boot into it on the tower, then mount the drive into my live Ubuntu environment. That way, I could explore the contents of the drive before performing a full-wipe.</p><p>After flashing the live Ubuntu image took nearly 20 minutes (it's a 6GB ISO), I decided to call it a night. In the morning I woke up to a text from my dad. He confirmed my suspicion that the OS install on the internal drive was corrupted, his OS was installed on one of the two external HDDs. He also told me that he has backups of all important files that he yanked off the externals a while ago, so I was clear to wipe everything.</p><p>But ... I realized there was another movie project he worked on. A documentary about my grandfather, for his 70th birthday. I asked him once more if that was included in his backups he has on hand. He wasn't sure. So I had to check the contents of all the drives I had before wiping anything. I was back to my original plan: I booted into the live Ubuntu environment the next morning.</p><h2 id="h-inspecting-the-drives" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Inspecting the Drives</h2><p>Within the Ubuntu live environment there are a few things we need to do in order to inspect the contents of the internal HDD and the external HDDs. For now, I can only connect one external HDD at a time (starting with the G-Drive), since I only have one FireWire800 cable. Additionally, I have no idea where the power cable for the WD drive is, so that will have to come later. We'll set aside the WD drive for now and only focus on the 4TB external and the corrupted internal.</p><p>First thing I like to do when preparing to mount drives is to run <code>lsblk</code> to see what I'm working with and how the drives are laid out:</p><pre data-type="codeBlock" text="ubuntu@ubuntu:~$ lsblk
#------------------------------------------
sda     8:0    0  596.2G 0 disk     # &lt;-- This is the Internal Drive
├─sda1  8:1    0  200M   0 part 
├─sda2  8:2    0  595.4G 0 part
├─sda3  8:3    0  619.9M 0 part

sdb     8:16   0  3.6T   0 disk     # &lt;-- This is the External Drive
├─sdb1  8:17   0  200M   0 part
├─sdb2  8:18   0  3.6T   0 part
├─sdb3  8:18   0  619.9M 0 part

sdc     8:32   1  14.9G  0 disk     # &lt;-- This is the Live USB
├─sdc1  8:17   1  5.9G   0 part /cdrom
├─sdc2  8:18   1  5M     0 part
├─sdc3  8:18   1  300K   0 part
├─sdc4  8:18   1  9G     0 part /var/crash
#------------------------------------------
"><code>ubuntu@ubuntu:<span class="hljs-operator">~</span>$ lsblk
#<span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span>
sda     <span class="hljs-number">8</span>:<span class="hljs-number">0</span>    <span class="hljs-number">0</span>  <span class="hljs-number">596</span>.2G <span class="hljs-number">0</span> disk     # <span class="hljs-operator">&lt;</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span> This <span class="hljs-keyword">is</span> the Internal Drive
├─sda1  <span class="hljs-number">8</span>:<span class="hljs-number">1</span>    <span class="hljs-number">0</span>  200M   <span class="hljs-number">0</span> part 
├─sda2  <span class="hljs-number">8</span>:<span class="hljs-number">2</span>    <span class="hljs-number">0</span>  <span class="hljs-number">595</span>.4G <span class="hljs-number">0</span> part
├─sda3  <span class="hljs-number">8</span>:<span class="hljs-number">3</span>    <span class="hljs-number">0</span>  <span class="hljs-number">619</span>.9M <span class="hljs-number">0</span> part

sdb     <span class="hljs-number">8</span>:<span class="hljs-number">16</span>   <span class="hljs-number">0</span>  <span class="hljs-number">3</span>.6T   <span class="hljs-number">0</span> disk     # <span class="hljs-operator">&lt;</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span> This <span class="hljs-keyword">is</span> the External Drive
├─sdb1  <span class="hljs-number">8</span>:<span class="hljs-number">17</span>   <span class="hljs-number">0</span>  200M   <span class="hljs-number">0</span> part
├─sdb2  <span class="hljs-number">8</span>:<span class="hljs-number">18</span>   <span class="hljs-number">0</span>  <span class="hljs-number">3</span>.6T   <span class="hljs-number">0</span> part
├─sdb3  <span class="hljs-number">8</span>:<span class="hljs-number">18</span>   <span class="hljs-number">0</span>  <span class="hljs-number">619</span>.9M <span class="hljs-number">0</span> part

sdc     <span class="hljs-number">8</span>:<span class="hljs-number">32</span>   <span class="hljs-number">1</span>  <span class="hljs-number">14</span>.9G  <span class="hljs-number">0</span> disk     # <span class="hljs-operator">&lt;</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span> This <span class="hljs-keyword">is</span> the Live USB
├─sdc1  <span class="hljs-number">8</span>:<span class="hljs-number">17</span>   <span class="hljs-number">1</span>  <span class="hljs-number">5</span>.9G   <span class="hljs-number">0</span> part <span class="hljs-operator">/</span>cdrom
├─sdc2  <span class="hljs-number">8</span>:<span class="hljs-number">18</span>   <span class="hljs-number">1</span>  5M     <span class="hljs-number">0</span> part
├─sdc3  <span class="hljs-number">8</span>:<span class="hljs-number">18</span>   <span class="hljs-number">1</span>  300K   <span class="hljs-number">0</span> part
├─sdc4  <span class="hljs-number">8</span>:<span class="hljs-number">18</span>   <span class="hljs-number">1</span>  9G     <span class="hljs-number">0</span> part <span class="hljs-operator">/</span><span class="hljs-keyword">var</span><span class="hljs-operator">/</span>crash
#<span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span><span class="hljs-operator">-</span>
</code></pre><p>This tells me the internal drive is <code>/dev/sda</code> (I know it's the ~600GB drive), the external drive is <code>/dev/sdb</code> (I know it's ~3.6TB), and the live USB I'm booted into is <code>/dev/sdc</code> (mounted at <code>/cdrom</code>). Next I can mount both the internal and external drives to inspect their contents, noting which partitions I need to mount (the root partitions) -- these are <code>/dev/sda2</code> and <code>/dev/sdb2</code> respectively. I create mount points for each drive and mount them:</p><pre data-type="codeBlock" text="sudo mkdir /mnt/{internal,external}
sudo mount /dev/sda2 /mnt/internal
sudo mount /dev/sdb2 /mnt/external"><code>sudo mkdir <span class="hljs-operator">/</span>mnt<span class="hljs-operator">/</span>{<span class="hljs-keyword">internal</span>,<span class="hljs-keyword">external</span>}
sudo mount <span class="hljs-operator">/</span>dev<span class="hljs-operator">/</span>sda2 <span class="hljs-operator">/</span>mnt<span class="hljs-operator">/</span><span class="hljs-keyword">internal</span>
sudo mount <span class="hljs-operator">/</span>dev<span class="hljs-operator">/</span>sdb2 <span class="hljs-operator">/</span>mnt<span class="hljs-operator">/</span><span class="hljs-keyword">external</span></code></pre><p>Then, in the Ubuntu file explorer, I can manually navigate to <code>/mnt/external</code> and <code>/mnt/internal</code> to inspect the contents of each drive. Going through <code>/mnt/external</code> I was quickly able to find the documentary about my grandfather! I also found other photos and stuff that seemed important to my dad.</p><h2 id="h-backing-up-important-data" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Backing Up Important Data</h2><p>There was a few ways I could go about backing up the data. I could:</p><ol><li><p>Buy a large enough external HDD to copy all the important files onto. <strong>(Cost: ~$100+)</strong></p></li><li><p>Buy one USB-B to USB-C cable, one USB-3.0 to USB-C cable, and one SATA to USB-C cable, then connect both externals <em>and</em> the internal to my laptop and copy the files over that way. <strong>(Cost: ~$60)</strong></p></li><li><p>Connect the Mac tower to my home network via Ethernet (already done), expose an SSH server on the live Ubuntu environment, and then copy the files over the network to my laptop. <strong>(Cost: $0)</strong> <span data-name="party" class="emoji" data-type="emoji">🎉</span></p></li></ol><blockquote><p><strong>Tip:</strong> <em>Always Consider All Possible Paths!</em> </p><p>When trying to solve a problem, it's always good to brainstorm all possible solutions before committing to one. This way you can weigh the pros and cons of each method and pick the one that best suits your needs. In this case, it's pretty clear that option 3 is the way to go. You don't have to go buy anything when good ol' SSH and SCP can get the job done. It's the most elegant solution by far.</p></blockquote><h3 id="h-exposing-ssh-on-the-live-ubuntu-environment" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Exposing SSH on the Live Ubuntu Environment</h3><p>First step is to install and start the SSH server:</p><pre data-type="codeBlock" text="sudo apt install openssh-server
sudo systemctl start ssh

# we set a password for the `ubuntu` user so we can log in remotely 
sudo passwd ubuntu # live sessions have no password by default"><code>sudo apt install openssh-server
sudo systemctl start ssh

<span class="hljs-comment"># we set a password for the `ubuntu` user so we can log in remotely </span>
sudo passwd ubuntu <span class="hljs-comment"># live sessions have no password by default</span></code></pre><p>Now before we connect from our laptop we need to know the IP address of the Mac tower. Thus we run:</p><pre data-type="codeBlock" text="ifconfig # Make note of the Mac Tower's private IP address"><code>ifconfig <span class="hljs-comment"># Make note of the Mac Tower's private IP address</span></code></pre><h3 id="h-copying-files-over-scp" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Copying Files Over SCP</h3><p>Now that we have an SSH server running on the Mac tower, and we know its IP address, we can use <code>scp</code> from our laptop to remotely copy the important files over the network.</p><pre data-type="codeBlock" text="scp -r ubuntu@&lt;ubuntu-local-ip&gt;:/mnt/external/path/to/files \ 
                                /path/to/local/destination"><code>scp <span class="hljs-operator">-</span>r ubuntu@<span class="hljs-operator">&lt;</span>ubuntu<span class="hljs-operator">-</span>local<span class="hljs-operator">-</span>ip<span class="hljs-operator">&gt;</span>:<span class="hljs-operator">/</span>mnt<span class="hljs-operator">/</span><span class="hljs-keyword">external</span><span class="hljs-operator">/</span>path<span class="hljs-operator">/</span>to<span class="hljs-operator">/</span>files \ 
                                <span class="hljs-operator">/</span>path<span class="hljs-operator">/</span>to<span class="hljs-operator">/</span>local<span class="hljs-operator">/</span>destination</code></pre><h2 id="h-until-next-time" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Until Next Time</h2><p>Oh something I forgot to mention is that my main display (and only in-use monitor at the moment) is a 3440x1440 ultrawide. The Mac <em>does not like this</em>. My guess is due to how old the GPU/GPU firmware is, but it caused a lot of annoyance when the picture would render halfway off the screen and I couldn't see what I was doing. Even adjusting the aspect-ratio on my monitor from "Full-wide" to "Original" didn't help. If I was installing Arch I could blind-type my way through the install but I'm not familiar enough with Ubuntu to reliably do this. I unearthed an old Asus 24" monitor I used to game on and hooked it up. This worked much better, but I had removed the base of the monitor when transporting it and I have no idea where it ended up, so I have it propped up against the wall :P</p><p>Pretty janky, but it works. I'll only need it for a bit longer now. Now that I'm done copying the important files off the external drive, my next step is to wipe the internal and external drive, install Ubuntu, and setup the NAS functionality.</p><p>Once Ubuntu is installed, one of the first things I'll do is set up SSH so I can remote into it from my laptop and do all the setup/administration headless. But this'll have to wait until our next post. See you then!</p>]]></content:encoded>
            <author>phasewalk@newsletter.paragraph.com (phasewalk)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/baa5243a9a2d42e1e237be9363696d3e767929eeadccd8bcfb30704990fd6415.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[DLL Injection]]></title>
            <link>https://paragraph.com/@phasewalk/dll-injection</link>
            <guid>sUVeiaQqygooBHD0Y9Km</guid>
            <pubDate>Tue, 11 Nov 2025 01:24:02 GMT</pubDate>
            <description><![CDATA[DLL Injection is an exploit technique that can be used for anything from harmless game mods to sophisticated malware campaigns. At its core, DLL Injection is about convincing a running process to execute code it never intended to run - whether that's adding custom features to your favorite game, or establishing persistence in a compromised system. As part of my 100 day Infosec challenge, I decided I would spend today diving deeper into DLLs, and learn about how they can be used to exploit Win...]]></description>
            <content:encoded><![CDATA[<p><strong>DLL Injection</strong> is an exploit technique that can be used for anything from harmless game mods to sophisticated malware campaigns. <em>At its core, DLL Injection is about convincing a running process to execute code it never intended to run</em> - whether that's adding custom features to your favorite game, or establishing persistence in a compromised system.</p><p>As part of my <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://x.com/phasewalk1/status/1987464837342056777">100 day Infosec challenge</a>, I decided I would spend today diving deeper into DLLs, and learn about how they can be used to exploit Windows machines.  Here are some of my key takeaways.</p><hr><h2 id="h-the-windows-pe-format-and-dynamic-linking" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">The Windows PE Format and Dynamic Linking</h2><p>Before we can understand what DLL injection is and how it works, we need to know what a DLL is!</p><p>A <strong>DLL (Dynamic Link Library)</strong> is a Windows binary in the <strong>Portable Executable (PE)</strong> format. They are used to export code/data that can be imported by other programs at <em>runtime</em>. Every PE file contains several important components. We'll briefly go over only a few of them here:</p><ul><li><p><strong>Import Address Table (IAT):</strong> Lists the functions that the DLL depends on from other DLLs. During the loading of these external DLLs, the Windows loader resolves the symbolic names and populates the IAT with function pointers. (Ref. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#import-address-table">https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#import-address-table</a>)</p></li><li><p><strong>Export Table:</strong> Lists the functions that the DLL exposes to other programs; its public API.  (Ref. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#the-edata-section-image-only">https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#the-edata-section-image-only</a>)</p></li><li><p><code>DllMain</code><strong>:</strong> An optional entry point called by the loader during process/thread attach/detach events. It allows the DLL to execute initialization code. (Ref. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://learn.microsoft.com/en-us/windows/win32/dlls/dllmain">https://learn.microsoft.com/en-us/windows/win32/dlls/dllmain</a>)</p></li></ul><h2 id="h-the-dll-loading-process" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">The DLL Loading Process</h2><p>For the sake of this article we’ll use the term <em>“Windows Loader”</em> to describe the cooperation between user-mode components (like <code>ntdll.dll</code>) and kernel-mode components (like the PE loader in <code>ntoskrnl.exe</code>) that make loading DLLs possible. So when we say “<em>the loader</em>” just know that it’s a system of multiple components working together, not a single program.</p><p>When a process needs a DLL, the Windows loader performs a carefully choreographed sequence:</p><ol><li><p>Map the PE file from disk into the process's virtual address space.</p></li><li><p>Apply address relocations if needed.</p></li><li><p>Walk the import table and resolve all external function references.</p></li><li><p>Call <code>DllMain</code> with <code>DLL_PROCESS_ATTACH</code> to allow the DLL to initialize.</p></li><li><p>The DLL is now ready for use by the process.</p></li></ol><p>Ref. <em>Microsoft Docs</em>  <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://learn.microsoft.com/en-us/windows/win32/dlls/run-time-dynamic-linking">Run-Time Dynamic Linking</a></p><h2 id="h-what-is-dll-injection" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">What is DLL Injection?</h2><blockquote><p>The key idea behind DLL injection is to subvert or otherwise manipulate this loading sequence to execute arbitrary code inside the target process.</p></blockquote><h3 id="h-classic-injection-method" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Classic Injection Method</h3><p>The traditional approach to achieving DLL injection follows this pattern:</p><ol><li><p><strong>Get a handle</strong> to the target process (<code>OpenProcess</code> with appropriate privileges)</p></li><li><p><strong>Allocate memory</strong> in the target’s address space (<code>VirtualAllocEx</code>)</p></li><li><p><strong>Write the DLL path</strong> into that memory (<code>WriteProcessMemory</code>)</p></li><li><p><strong>Create a remote thread</strong> that calls <code>LoadLibrary</code> on that path (<code>CreateRemoteThread</code>)</p></li></ol><p><code>LoadLibrary</code> does all the heavy lifting. The normal Windows loader takes over and performs all the steps we described earlier. The catch with this approach though is that it’s noisy. Modern Endpoint Detection and Response (EDR) solutions watch for exactly this pattern: <code>OpenProcess</code> → <code>VirtualAllocEx</code> → <code>WriteProcessMemory</code> → <code>CreateRemoteThread</code>.</p><h3 id="h-reflectivein-memory-injection" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Reflective/In-memory Injection</h3><p>The weakness (e.g., the ease in which it can be detected) in the classic injection method above is due to the traces left behind by the loading process. In the classic injection method, the malicious DLL must exist as a file on disk and <code>LoadLibrary</code> must be called. This leaves behind two easily detected artifacts: (1) the DLL file itself and (2) The event logs associated with <code>LoadLibrary</code> invocations. <em>Reflective injection</em>, on the other hand, <strong>contains its own custom loader code</strong>, <em>and</em> <strong>only lives in-memory (not on disk)</strong>. Hence reflective injection is harder to detect.</p><p>Because reflective DLLs bypass <code>LoadLibrary</code>, they must include a special function (the “reflective loader”) that manually implements everything the OS loader would normally do.</p><blockquote><h3 id="h-aside-meterpreter" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Aside: Meterpreter</h3><p>The <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.offsec.com/metasploit-unleashed/about-meterpreter/#how-meterpreter-works">Meterpreter</a> payload does all of this! First the initial stager (essentially a tiny piece of shellcode) establishes a reverse connection. This allows us to transfer the Meterpreter DLL over the network into target memory.  The remaining shellcode stages allocate memory (<code>VirtualAllocEx</code>) and write the reflective DLL into a process's memory region (<code>WriteProcessMemory</code>). Execution is transferred to the <em>reflective loader </em>, which performs all the PE loading tasks manually. <code>DllMain</code> then executes, and Meterpreter establishes its full C2 channel.</p></blockquote><p>In-memory injection makes incident response and forensics significantly harder. There’s no malicious binary to find on disk, no file creation events, and no <code>LoadLibrary</code> logs. Memory analysis requires knowing what to look for, so it is harder to detect, but by no means impossible (runtime/ memory artifacts are left behind). </p><h2 id="h-other-dll-attacks" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Other DLL Attacks</h2><p>I often get confused about related but distinct exploit techniques that are not considered injection attacks. I’ll attempt to make distinctions between them here.</p><p><strong>Disk-based DLL loading</strong>, for example, involves placing a malicious DLL where a process will naturally load it. Two methods of doing this are:</p><ul><li><p><strong>DLL search-order hijacking</strong>: Exploits the DLL search path when calling <code>LoadLibrary</code> to load a malicious DLL instead of the legitimate one</p></li><li><p><strong>DLL sideloading</strong>: placing a malicious DLL with the right name next to a legitimate executable that will load it. The following article goes more in-depth on this: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://techzone.bitdefender.com/en/tech-explainers/what-is-dll-sideloading.html">Bitdefender - What is DLL Sideloading</a>.</p></li></ul><p>Process replacement techniques like <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://attack.mitre.org/techniques/T1055/012/">process hollowing</a> or <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://attack.mitre.org/techniques/T1055/013/">process doppelgänging</a> create what looks like a benign process but replace its code entirely. These are all related but distinct from DLL injection; the main distinction is that they’re <em>not adding code to a running process.</em></p><blockquote><h3 id="h-process-attacks-vs-dll-injection" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Process Attacks vs. DLL Injection</h3><p>They key difference between DLL injection and process doppelgänging, for example, is that DLL injection involves forcefully loading a malicious DLL into an already running legitimate process, while process doppelgänging involves creating a new, hidden, malicious process that masquerades as a legitimate one using file transactions.</p></blockquote><h2 id="h-conclusion" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Conclusion</h2><p>DLL injection is a fundamental technique in offensive security. From dropping a Meterpreter shell in a CTF to advanced persistent threats, the ability to run code in another process’s context remains valuable across the threat spectrum. Reflective DLL injection specifically demonstrates how adversaries evolve techniques to evade detection -- by removing disk artifacts and implementing their own custom loaders, they operate in the gaps of traditional security mechanisms.</p><p>For security practitioners, understanding these techniques isn’t only about learning to attack systems, but about comprehending how modern malware operates so we can build better defenses, hunt more effectively, and respond to incidents with full knowledge of what adversaries are capable of.</p><h3 id="h-references" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">References</h3><p>Microsoft Docs <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://learn.microsoft.com/en-us/windows/win32/debug/pe-format?redirectedfrom=MSDN">PE Format</a></p><p>MITRE ATT&amp;CK <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://attack.mitre.org/techniques/T1055/001/">Process Injection: Dynamic-link Library Injection</a></p><p>red canary <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://redcanary.com/threat-detection-report/techniques/dll-search-order-hijacking/">DLL Search Order Hijacking</a></p><p>OffSec <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.offsec.com/metasploit-unleashed/about-meterpreter/">About the Metasploit Meterpreter</a></p><p>MITRE ATT&amp;CK <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://attack.mitre.org/techniques/T1055/012/">Process Injection: Process Hollowing</a></p><p>MITRE ATT&amp;CK <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://attack.mitre.org/techniques/T1055/013/">Process Injection: Process Doppelgänging</a></p><p>Scott Nusbaum, TrustedSec <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://trustedsec.com/blog/loading-dlls-reflections">Loading DLLS Reflections</a></p>]]></content:encoded>
            <author>phasewalk@newsletter.paragraph.com (phasewalk)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/2755d9edc6276b861de33d4ad6bd128f2dde40079eae2d880a5402e0570fdebd.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[The Final Summoning Rites: Penumbra Arrives]]></title>
            <link>https://paragraph.com/@phasewalk/the-final-summoning-rites-penumbra-arrives</link>
            <guid>tcUioB2CZrRcTGaj4zMC</guid>
            <pubDate>Sat, 06 Jul 2024 18:05:30 GMT</pubDate>
            <description><![CDATA[Penumbra is where bits find darkness in the Sun’s shadow. Over the past few months, cypherpunks have been summoning Penumbra. Now that the stage is set, the final summoning rites have begun. Happy Independence Day: https://penumbra.phasewalk.software. https://forum.penumbra.zone/t/the-final-summoning-rites-part-2-mainnet-phase-0/32What is Penumbra?Penumbra is a shielded, cross-chain network allowing anyone to securely transact, stake, swap, or marketmake without broadcasting their personal in...]]></description>
            <content:encoded><![CDATA[<p>Penumbra is where bits find darkness in the Sun’s shadow. Over the past few months, cypherpunks have been <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://penumbra.zone/blog/summoning-ceremony-deep-dive">summoning Penumbra</a>. Now that the stage is set, the final summoning rites have begun. Happy Independence Day: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://penumbra.phasewalk.software">https://penumbra.phasewalk.software</a>.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://forum.penumbra.zone/t/the-final-summoning-rites-part-2-mainnet-phase-0/32">https://forum.penumbra.zone/t/the-final-summoning-rites-part-2-mainnet-phase-0/32</a></p><hr><h1 id="h-what-is-penumbra" class="text-4xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">What is Penumbra?</h1><blockquote><p><strong>Penumbra is a shielded, cross-chain network allowing anyone to securely transact, stake, swap, or marketmake without broadcasting their personal information to the world.</strong></p></blockquote><p>At its core, Penumbra is a privacy-preserving CometBFT Proof-of-Stake (PoS) blockchain. It boasts several standout features, including a native decentralized exchange (DEX), interop with IBC, private staking and governance, and ultralight client software.</p><h2 id="h-home-is-where-the-shielded-pool-is" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Home is Where the Shielded Pool is</h2><p>Penumbra is natively cross-chain (IBC-enabled), making it akin to an ecosystem-wide shielded pool for the entire Cosmos and beyond. Inbound IBC transfers shield value as it moves into the zone, while outbound IBC transfers unshield value.</p><p>One of the most challenging aspects of designing a private blockchain is in reconciling the tension of simultaneously desiring individual privacy and network transparency. To address this tension, Penumbra records asset flow in batches utilizing a partially homomorphic encryption scheme coupled with Distributed Key Generation (DKG). Validators each hold a key-share, enabling them to perform threshold decryption of batch totals every block. Individual transactions are kept private using Groth16 proofs of valid state transitions, ensuring that every move you make remains your own.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://penumbra.zone/blog/how-were-building-penumbra">https://penumbra.zone/blog/how-were-building-penumbra</a></p><p>Penumbra boasts the world’s first shielded PoS network, through the use of a novel delegation mechanism, Penumbra provides privacy for delegators and accountability for validators. Each validator has their own unique delegation token (dPEN), which represents a share of the delegation pool staked with that validator. <strong>These tokens are recorded in the shielded pool and can be transferred or traded like any other asset</strong>. Users can privately delegate to a validator by exchanging staking tokens for the validator’s delegation token. Rewards are issued to the delegation pool and are realized only when a delegator withdraws their delegation.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://penumbra.zone/blog/shielded-staking-on-penumbra">https://penumbra.zone/blog/shielded-staking-on-penumbra</a></p><h1 id="h-network-bootstrapping" class="text-4xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Network Bootstrapping</h1><p>The Penumbra Labs team has not launched any public GRPC endpoints of their own. The network is in a <strong>bottom up</strong> bootstrapping phase spearheaded by the community. Community members have begun spinning up their nodes and sharing publicly accessible endpoints for use in client software (<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://praxwallet.com">Prax</a>, <code>pcli</code>).</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://x.com/penumbrazone/status/1810055221659504897">https://x.com/penumbrazone/status/1810055221659504897</a></p><p>To access the embedded frontend of a full-node’s endpoint, simply append <code>/app/</code> to the node’s url. Example: <code>https://penumbra.phasewalk.software/app/</code>.</p><h3 id="h-grpc-endpoints" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">GRPC Endpoints</h3><ul><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://void.s9.gay">https://void.s9.gay</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://penumbra.phasewalk.software">https://penumbra.phasewalk.software</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://grpc.penumbra.silentvalidator.com">https://grpc.penumbra.silentvalidator.com</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://grpc-penumbra.whispernode.com">https://grpc-penumbra.whispernode.com</a></p></li></ul><p>A longer list of endpoints can be found in the <code>community-rpc</code> channel in the discord.</p><h1 id="h-where-can-i-get-involved" class="text-4xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Where Can I Get Involved?</h1><p>Penumbra is decentralized and owned by no single entity, inviting participation from developers, researchers, node operators, and users who are passionate about privacy and decentralization. Here are some ways to get involved:</p><ul><li><p><strong>Forum</strong>: Join the discussion on the final summoning rites and stay updated on the latest developments at <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://forum.penumbra.zone">https://forum.penumbra.zone</a></p></li><li><p><strong>Guide</strong>: Learn how to use the Penumbra software to interact with the network or run a node at <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://guide.penumbra.zone">https://guide.penumbra.zone</a></p></li><li><p><strong>Spec</strong>: Dive into the technical details with the protocol specification at <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://protocol.penumbra.zone">https://protocol.penumbra.zone</a></p></li><li><p><strong>Code</strong>: Contribute to the project or explore the codebases at <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/penumbra-zone">https://github.com/penumbra-zone</a></p></li></ul><hr><blockquote><p><em>As we move forward, Penumbra stands as a beacon for the future of self-sovereignty, coordination, and freedom. Go forth and complete the final summoning rites. Where bits find darkness, in the Sun’s shadow.</em></p></blockquote>]]></content:encoded>
            <author>phasewalk@newsletter.paragraph.com (phasewalk)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/ec5aa9681cba61654ed66e92f0679f529c37984fe6d7bd71e1b409f82b54e3aa.jpg" length="0" type="image/jpg"/>
        </item>
    </channel>
</rss>