tag:blogger.com,1999:blog-15512234158483783882024-03-13T08:19:15.294+01:00Security | DMA | HackingUlf Friskhttp://www.blogger.com/profile/09730439109623573624noreply@blogger.comBlogger11125tag:blogger.com,1999:blog-1551223415848378388.post-12316207348186362842021-10-20T11:01:00.017+02:002022-04-15T14:05:21.905+02:00Modifying the Acorn CLE-215+ FPGA into a PCILeech DMA attack device<p><a href="https://github.com/ufrisk/PCILeech" target="_blank">PCILeech</a> and <a href="https://github.com/ufrisk/MemProcFS" target="_blank">MemProcFS</a> allows for easy-to-use user-friendly DMA attacks and hardware assisted memory analysis. This is possible since PCI Express supports DMA. Unfortunately production of compatible hardware, such as the <a href="https://shop.lambdaconcept.com/" target="_blank">Screamer series</a> has been hit hard by the global silicon shortage.</p><p>The goal with this project is to modify the Acorn CLE-215+ / Nitefury / Litefury FPGA boards, in a short time frame and on a relatively tight budget, to support PCILeech and MemProcFS at around 20-25MB/s.</p><p></p><div class="separator" style="clear: both; text-align: center;"><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHhwVyDjRMdgXnXqqDB890PGGRGfc15EGD1OtZwziMBfzOfe3rI5UKxfdcNDl4li6hQC2b0uwW2Bx478qPQaDoUUm42F7iEzY5Mmxa1-llsQrN_X6BEUWnBN5BhUcoOITSeoYXUjlK_Ck4/s1600/acorn_final-2.jpg" style="margin-left: auto; margin-right: auto;"><img data-original-height="400" data-original-width="2294" height="112" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHhwVyDjRMdgXnXqqDB890PGGRGfc15EGD1OtZwziMBfzOfe3rI5UKxfdcNDl4li6hQC2b0uwW2Bx478qPQaDoUUm42F7iEzY5Mmxa1-llsQrN_X6BEUWnBN5BhUcoOITSeoYXUjlK_Ck4/w640-h112/acorn_final-2.jpg" title="PCILeech DMA with modified Acorn CLE-215+ and FT2232H." width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">PCILeech DMA with a modified Acorn CLE-215+ and FT2232H.</td></tr></tbody></table><br /></div><p></p><h2 style="text-align: left;">The Hardware</h2><div style="text-align: left;">The Acorn CLE-215+ is a powerful FPGA board with PCI Express M.2 connector which is used for DMA hardware memory acquisition. It also have 12 additional GPIOs in a 20-pin DF52 header. It uses the most powerful Xilinx Artix7 FPGA chip - the 200T. The Acorn CLE-215+ was used for crypto mining but has been discontinued for some time. They can sometimes be found at a nice price at eBay. The <a href="https://github.com/RHSResearchLLC/NiteFury-and-LiteFury" target="_blank">Nitefury</a> FPGA board is basically the same board as the Acorn CLE-215+. The Litefury has a smaller, still very capable, Artix 7 100T FPGA.</div><p></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicd8F2H8JHBExgbZ4V82YCiPjunpnL8jbqfkFp4h2iGzh01nuKRffMAROlgtcQwkMsBDJjxQSPH9-XLPVrkud5SKHHpEQCESyp9NWvHRBAoDpKwy06-5fWQllQj3vmjihyphenhyphenoz_5e5rkFJxB/s1600/acorn_litefury.jpg" style="margin-left: auto; margin-right: auto;"><img data-original-height="400" data-original-width="1500" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicd8F2H8JHBExgbZ4V82YCiPjunpnL8jbqfkFp4h2iGzh01nuKRffMAROlgtcQwkMsBDJjxQSPH9-XLPVrkud5SKHHpEQCESyp9NWvHRBAoDpKwy06-5fWQllQj3vmjihyphenhyphenoz_5e5rkFJxB/w640-h170/acorn_litefury.jpg" title="Acorn CLE-215+ and Litefury." width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Acorn CLE-215+ and LiteFury.</td></tr></tbody></table><p></p><p>PCILeech traditionally connects to the FPGA device over USB3 resulting in DMA around 150MB/s. The now sold-out FTDI FT601 chip is used in synchronous FT245 mode to achieve this. The FT601 uses 40 signals between itself and the FPGA.</p><p>The goal with this project is to modify the Acorn CLE-215+ / Nitefury / Litefury to support the FTDI FT2232H USB2 chip. In FT245 mode this should allow for DMA transfer speeds around 20-25MB/s. This should allow PCILeech to work with the CLE-215+ with relatively minor software modifications. </p><p>Alternative ways that does not include hardware modifications would be UART (slow) or a carrier board with additional FPGA/chips (expensive and complex to design). The goal of this project was to create something low-cost in a limited time frame.</p><p>The FT2232H is readily available and an inexpensive mini module exists for labs. In this project the FT2232H-56Q mini module which has a micro-USB2 connector will be used.</p><p>The FT245 mode we require 15 signals: 8 data, 1 clock and 6 additional control signals. To make things even worse the FT2232H runs at 3.3V while the Acorn only have 4 GPIOs at 3.3V and 8 GPIOs at 2.5V. Also none of the GPIOs on the Acorn are clock capable - i.e. possible to use as a clock input pin.</p><h3 style="text-align: left;">Two hardware modifications are required:</h3><p>1) Make the 2.5V GPIOs 3.3V. This is done by removing a 3.3V to 2.5V voltage regulator and connecting the 2.5V power rail to 3.3V. This has been <a href="https://www.eevblog.com/forum/fpga/sqrl-acorn-as-an-interesting-artix-7-board/msg3050508/#msg3050508" target="_blank">previously discussed</a>. The Schematics also support this change and it should have little or no side effects.</p><p>2) Desolder LED2, LED3 and LED4 and use the FPGA connections as three additional GPIOs. The FPGA PIN driving LED4 is also clock capable which is great!</p><p>In addition to the above a custom JTAG connector cable may have to be created.</p><p><br /></p><h2 style="text-align: left;">Required Tools:</h2><div>This is a hardware modification project. In addition to the hardware for the project itself it's assumed that one has access to:</div><div><ul style="text-align: left;"><li>Molex crimp tool.</li><li>Hot-air rework station.</li><li>JTAG programmer cable.</li><li>Soldering paste. <br /></li></ul><div>Also nice to have, but not required, is access to a logic analyzer or oscilloscope in case something isn't working and some signal debugging is required. A multimeter to check voltage levels and cable connections would also be nice to have at hand.<br /></div></div><div><br /></div><div><br /></div><h2>JTAG connector cable</h2><div>JTAG is required to program the FPGA with PCILeech a compatible gateware.</div><div><br /></div><div>The Acorn has a Pico EzMate JTAG header on the bottom side. The LiteFury comes with a nice connector cable which allows for easy connection to your JTAG programmer cable. I use the Digilent HS2 JTAG cable since it's directly compatible with the Xilinx Vivado development environment. The LiteFury cable, shown below in (5), is compatible with the Nitefury and Acorn as well.</div><div><br /></div><div>If a LiteFury purchase is not desirable it's relatively easy to roll your own cable using the parts list below and molex crimp tool.</div><div><br /></div><div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRT-ZqRnk84xABg5VubpH8zsF55wrjEnUcuLhx7onPq3cr0iQsaAaKYUBjd2BKkycyw8aG_JVAHxVzgcuH4DcJNOBBCHE3piEpTH-OtD18nfPbz_8ILyfy289Z8UMmOoOrCcqRbFZNQoGG/s1600/jtag-1.jpg" style="margin-left: auto; margin-right: auto;"><img data-original-height="400" data-original-width="1471" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRT-ZqRnk84xABg5VubpH8zsF55wrjEnUcuLhx7onPq3cr0iQsaAaKYUBjd2BKkycyw8aG_JVAHxVzgcuH4DcJNOBBCHE3piEpTH-OtD18nfPbz_8ILyfy289Z8UMmOoOrCcqRbFZNQoGG/w640-h174/jtag-1.jpg" title="Custom JTAG connector cable (1-3). JTAG pinout (4). LiteFury JTAG connector cable (5)." width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Custom JTAG connector cable (1-3). JTAG pinout (4). LiteFury JTAG connector cable (5).</td></tr></tbody></table><br /></div><div><ol style="text-align: left;"><li>Cut the purchased Pico-EzMate cable in half.</li><li>Then crimp standard molex connectors on the cable endings.</li><li>Then insert the crimped connectors into the housing resulting to get a working JTAG cable adapter. Make sure the Pico-EzMate JTAG PINs are mapped to the correct PINs on your JTAG programming cable according to the pinout in (4).</li></ol><div><h3>Parts list custom JTAG connector cable:</h3><div>1x <a href="https://www.mouser.com/ProductDetail/538-50-57-9006" rel="nofollow" target="_blank">Molex 6x1 housing</a>.</div><div>6x <a href="https://www.mouser.com/ProductDetail/538-90119-2111" rel="nofollow" target="_blank">Molex crimp connectors</a> (get some extra just in case).</div><div>1x <a href="https://www.mouser.com/ProductDetail/538-36920-0606" rel="nofollow" target="_blank">Pre-crimped Pico-EzMate cable</a>.</div><div>Total: €6 + VAT + shipping.</div></div><div><br /></div><div><br /></div><div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiL0VjSCI3We4LDiuCcRzdZ4RydMSGzyNKIamHW3RXdYC2OKtO-NNntuMZ8g7uCxpSkwNq2GokfT33NMAhsuMJYHxBrc6TGvtIBfO0Jnw3WdEJKudxcIj6wcXp_QeLH2GT2dnOBlc35G9r2/s1600/2-litefury-flash-custom.jpg" style="margin-left: auto; margin-right: auto;"><img data-original-height="400" data-original-width="846" height="302" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiL0VjSCI3We4LDiuCcRzdZ4RydMSGzyNKIamHW3RXdYC2OKtO-NNntuMZ8g7uCxpSkwNq2GokfT33NMAhsuMJYHxBrc6TGvtIBfO0Jnw3WdEJKudxcIj6wcXp_QeLH2GT2dnOBlc35G9r2/w640-h302/2-litefury-flash-custom.jpg" title="Flashing the LiteFury with the custom made JTAG cable." width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Flashing the LiteFury with the custom made JTAG cable.</td></tr></tbody></table></div></div><div><br /></div><div><br /></div><div><br /></div><h2 style="text-align: left;">Modification #1 - 2.5V to 3.3V</h2><div>It's possible to modify the acorn 2.5V GPIOs to 3.3V which would support the FT2232H voltage levels. This has been <a href="https://www.eevblog.com/forum/fpga/sqrl-acorn-as-an-interesting-artix-7-board/msg3050508/#msg3050508" target="_blank">previously discussed</a>. This is possible by removing the voltage regulator U11 and shorting some of the underlying pads.</div><div><br /></div><div>When looking at the <a href="https://github.com/RHSResearchLLC/NiteFury-and-LiteFury/blob/master/Hardware/uEVB.pdf" rel="nofollow" target="_blank">schematics for the NiteFury/LiteFury</a> this becomes clear. The Voltage regulator U11 converts 3.3V into 2.5V. The 2.5V is only used to drive FPGA Bank34 - which drives the 2.5V LVDS/GPIOs and also the 200MHz DDR clock oscillator - which seems to be supporting 3.3V as well.</div><div><div class="separator" style="clear: both; text-align: center;"><br /></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzj4ocO4VgtuEGsr6X9iV1vafYLB7nBpcEUbAvn4FtrW25LbNQSei6jtXYS1UX0U-RHKs7-Lo8BEnrS1pI0j4U2FIbw4GL219payhGQn79qOtXdztT_lzHtCgPpn5of3WVI-D7sbDCHznF/s1600/power1.png" style="margin-left: auto; margin-right: auto;"><img data-original-height="400" data-original-width="1996" height="128" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzj4ocO4VgtuEGsr6X9iV1vafYLB7nBpcEUbAvn4FtrW25LbNQSei6jtXYS1UX0U-RHKs7-Lo8BEnrS1pI0j4U2FIbw4GL219payhGQn79qOtXdztT_lzHtCgPpn5of3WVI-D7sbDCHznF/w640-h128/power1.png" title="2.5V voltage regulator U11 and schematics extracts." width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">2.5V voltage regulator U11 and schematics extracts.</td></tr></tbody></table><br />Now let's remove U11 using a hot-air rework station and short the 2.5V power rail to the 3.3 power rail. The removal of U11 is likely to be destructive - the part is likely to fall apart. Please take great care not damaging the Acorn / LiteFury. If you are not familiar with work like this please practice on scrap components before attempting this!</div><div><br /></div><div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVvacUdYUKLfa0h50g9FVAwua7Tkd4NtL7b9U5LMOdyxbJoAISy_C_wj8Ux0c0S-_URp5IrQu301kyUhv2t-cHTR9FmWfQJt-gsZfvTz0w0pdSX1QB_NwZX8Q_ahnMAcXVUrfJyGWztPNc/s1600/power-rework-station.jpg" style="margin-left: auto; margin-right: auto;"><img data-original-height="400" data-original-width="713" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVvacUdYUKLfa0h50g9FVAwua7Tkd4NtL7b9U5LMOdyxbJoAISy_C_wj8Ux0c0S-_URp5IrQu301kyUhv2t-cHTR9FmWfQJt-gsZfvTz0w0pdSX1QB_NwZX8Q_ahnMAcXVUrfJyGWztPNc/s1600/power-rework-station.jpg" title="Hot-air rework station setup." /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Hot-air rework station setup.</td></tr></tbody></table><br />The topmost image below shows the Acorn when the U11 power regulator has been removed. In order to connect the 2.5V power rail to 3.3V a tiny amount of ChipQuik soldering paste as well as a tiny cable fragment is applied on the three "topmost" power regulator pads as shown in the bottom image below. Hot air is applied to make the modification permanent. Now the modification is complete and the Acorn 2.5V GPIOs has become 3.3V.</div><div><br /></div><div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLoLKAVUrEndvF07dkJcen7hZ3bYCPPauz3cJbjOgMrE0_lPda9jU7_R3Nuvl6SZDxDu8pnLIR8rdt-8QA7hPDWP7rRx3Y-ato_FadmW-uc6XHfEsUZi7K1cQksy6ExdF5usTy6uL5pX57/s1600/power-rework3.jpg" style="margin-left: auto; margin-right: auto;"><img data-original-height="400" data-original-width="693" height="370" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLoLKAVUrEndvF07dkJcen7hZ3bYCPPauz3cJbjOgMrE0_lPda9jU7_R3Nuvl6SZDxDu8pnLIR8rdt-8QA7hPDWP7rRx3Y-ato_FadmW-uc6XHfEsUZi7K1cQksy6ExdF5usTy6uL5pX57/w640-h370/power-rework3.jpg" title="Removal of power regulator U11 (top). Connecting 2.5V pad to 3.3V (bottom)." width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Removal of power regulator U11 (top). Connecting 2.5V pad to 3.3V (bottom).</td></tr></tbody></table><br /><br /></div><div><br /></div><h2 style="text-align: left;">Modification #2 - LEDs to GPIOs</h2><div>The 2nd modification is to desolder three LEDs and replace and solder on three cables on the innermost pad (which goes to the FPGA). The pad closes to the edge goes to ground - care should be taken not to connect the two by mistake.</div><div><br /></div><div>For cabling I used three short DF52 cables since I had them at hand. Other cables may be used as well, but please try to keep them fairly short. On the other end Molex connectors was crimped on (after the soldering to the acorn was completed). Housing from three standard lab cables was used to shield the crimped Molex connector.</div><div><br /></div><div>Image (1) shows the acorn LEDs before the hardware modification.</div><div><br /></div><div>Image (2) shows the LEDs removed using hot air and a cable to the pad of LED3 is being attached with a rather messy application of soldering paste. The wire were individually soldered on using soldering paste and hot air. The wires were then routed in the space behind the DF52 header for some additional stability.</div><div><br /></div><div>Image (3) shows the end result. The three additional GPIO wires are routed behind the DF51 had Molex connectors crimped on the other end after the soldering was complete. The worst ChipQuik mess was also cleaned up and the end result is decent enough and most importantly - fully functional :)</div><div><br /></div><div><br /></div><div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP3HRGMYKRnHgVL7GIuiPMN8A82bkUkzWo1nfaRbn1mcNn9pU5D5D8aTI7xhBQeZTmiqgqRFiwRWhbv2vK6edsAQM2dkYSlOz2MwZVSESb5V38wn589eSTAdIx8FNmpHDGwLrM756_V6zM/s1600/gpio-rework.jpg" style="margin-left: auto; margin-right: auto;"><img data-original-height="400" data-original-width="863" height="296" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP3HRGMYKRnHgVL7GIuiPMN8A82bkUkzWo1nfaRbn1mcNn9pU5D5D8aTI7xhBQeZTmiqgqRFiwRWhbv2vK6edsAQM2dkYSlOz2MwZVSESb5V38wn589eSTAdIx8FNmpHDGwLrM756_V6zM/w640-h296/gpio-rework.jpg" title="LED to GPIO hardware modification. (1) before, (2) during, (3) after." width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">LED to GPIO hardware modification. (1) before, (2) during, (3) after.</td></tr></tbody></table><br /></div><div><br /></div><h2 style="text-align: left;">FPGA/FT2232H custom signal cable</h2><div>Creating the custom signal cable is one of the more tedious parts of the project. Care should be taken to create a good quality relatively short cable to allow for good enough signal quality.</div><div><br /></div><div>The pinout of the DF52 connector is shown in the table below. PIN1 is at lower part (close to the SQRL logo) whilst PIN20 is on the upper part closest to LED1.</div><div><br /></div><div>
<table>
<tbody><tr><th>DF52</th><th>FPGA</th><th>NAME</th><th>FT2232H</th></tr>
<tr><td>1. </td><td> </td><td>3.3V (NC)</td><td></td></tr>
<tr><td>2. </td><td> </td><td>3.3V (NC)</td><td></td></tr>
<tr><td>3. </td><td>AB8</td><td>DATA[0]</td><td>CN2-7 (AD0)</td></tr>
<tr><td>4. </td><td>AA8</td><td>DATA[1]</td><td>CN2-10 (AD1)</td></tr>
<tr><td>5. </td><td> </td><td>GND </td><td>CN2-6* </td></tr>
<tr><td>6. </td><td>Y9 </td><td>DATA[2]</td><td>CN2-9 (AD2)</td></tr>
<tr><td>7. </td><td>W9 </td><td>DATA[3]</td><td>CN2-12 (AD3)</td></tr>
<tr><td>8. </td><td> </td><td>GND </td><td>CN2-6* </td></tr>
<tr><td>9. </td><td>Y8 </td><td>DATA[4]</td><td>CN2-14 (AD4)</td></tr>
<tr><td>10. </td><td>Y7 </td><td>DATA[5]</td><td>CN2-13 (AD5)</td></tr>
<tr><td>11. </td><td> </td><td>GND </td><td>CN2-4* </td></tr>
<tr><td>12. </td><td>V9 </td><td>DATA[6]</td><td>CN2-16 (AD6)</td></tr>
<tr><td>13. </td><td>V8 </td><td>DATA[7]</td><td>CN2-15 (AD7)</td></tr>
<tr><td>14. </td><td> </td><td>GND </td><td>CN2-4* </td></tr>
<tr><td>15. </td><td>K2 </td><td>RXF_N </td><td>CN2-18 (AC0)</td></tr>
<tr><td>16. </td><td>J2 </td><td>TXE_N </td><td>CN2-17 (AC1)</td></tr>
<tr><td>17. </td><td> </td><td>GND </td><td>CN2-2* </td></tr>
<tr><td>18. </td><td>J5 </td><td>RD_N </td><td>CN2-20 (AC2)</td></tr>
<tr><td>19. </td><td>H5 </td><td>WR_N </td><td>CN2-19 (AC3)</td></tr>
<tr><td>20. </td><td> </td><td>GND </td><td>CN2-2* </td></tr>
<tr><td>----</td><td> </td><td> </td><td> </td></tr>
<tr><td>LED2</td><td>H3 </td><td>OE_N </td><td>CN2-23 (AC6)</td></tr>
<tr><td>LED3</td><td>G4 </td><td>SIWU_N </td><td>CN2-22 (AC4)</td></tr>
<tr><td>LED4</td><td>H4 </td><td>CLK </td><td>CN2-24 (AC5)</td></tr>
</tbody></table></div><div><br /></div><div>Start by cutting the DF52 cables in half. Populate the DF52 header. Skip the 3.3V at PIN 1 and 2 or cut the cables after the cable is completed.</div><div><br /></div><div>I opted for a ~10cm cable length. I first populated the DF52. Then I put a 2x10 PIN molex connector on the FT2232H CN2 PINs 5-24 - skipping PIN 1,2,3,4,25,26. Ideal would be to have a 2x13 connector but I only had some 2x10 connectors at hand. The parts list should contain a 2x13 pin connector housing though.</div><div><br /></div><div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEif1r89Am4X1bxgIgi5N9B52bBRPXfvwbfWUOMO7ZOWlEt2jrZOjgNP1RUrdM8Lhc3ruE6A-nVyH2XP6m6PJN8EkpyODNSUaMbs_QjEwCxQJ1a2KAQJM3bKx_E6rzfbzwAw_SJbUky3XXNA/s1600/2-litefury-signalcable-short.jpg" style="margin-left: auto; margin-right: auto;"><img data-original-height="400" data-original-width="1811" height="142" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEif1r89Am4X1bxgIgi5N9B52bBRPXfvwbfWUOMO7ZOWlEt2jrZOjgNP1RUrdM8Lhc3ruE6A-nVyH2XP6m6PJN8EkpyODNSUaMbs_QjEwCxQJ1a2KAQJM3bKx_E6rzfbzwAw_SJbUky3XXNA/w640-h142/2-litefury-signalcable-short.jpg" title="Making of a short custom signal cable." width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Making of a short custom signal cable.</td></tr></tbody></table><br /></div><div>I first crimped one connector then populated the housing on the proper pin with it. Then I cut the next cable to the correct length; crimped it and populated it. Iterating over all signals. For the ground I crimped two cables into the same connector (since there were 6 ground cables and only 3 slots on FT2232H). This iterative process is a good way making sure the cables are of an optimal length.</div><div><br /></div><div>Upon completion I also glued the cable and taped it making sure every 2nd cable was ground like on the DF52 header. I also made some shorter (around 5cm) less impressive cables.</div><div><br /></div><div>For the OE_N, SIWU_N and CLK cables a standard lab cable was used to connect.</div><div><br /></div><div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQhrNXzs0WFCL4tS4q7N0YeFt-An5mIkkTSvjlgUzCmHSPRR65NN2ZoQcPBKCpiZ4F32vdYA3BvU7fnQQBeW8oAhQlR_KXZ4LLGDSLY4X2JA1cw9TmzGjzSbkNUqqEoUugznIAp_oiVkgu/s1600/signalcable.jpg" style="margin-left: auto; margin-right: auto;"><img data-original-height="400" data-original-width="983" height="260" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQhrNXzs0WFCL4tS4q7N0YeFt-An5mIkkTSvjlgUzCmHSPRR65NN2ZoQcPBKCpiZ4F32vdYA3BvU7fnQQBeW8oAhQlR_KXZ4LLGDSLY4X2JA1cw9TmzGjzSbkNUqqEoUugznIAp_oiVkgu/w640-h260/signalcable.jpg" title="The custom made signal cable." width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">The custom made signal cable.</td></tr></tbody></table><br /></div><div><h3>Parts list custom signal cable:</h3><div>1x <a href="https://octopart.com/ft2232h-56q+mini+mdl-ftdi-71780622" rel="nofollow" target="_blank">FT2232H-56Q mini module</a>.</div><div>1x <a href="https://www.mouser.com/ProductDetail/798-DF52-20P-0.8C" rel="nofollow" target="_blank">DF52 20p connector</a>.</div><div>12x <a href="https://www.mouser.com/ProductDetail/798-DF522832PF157128" rel="nofollow" target="_blank">DF52 pre-crimped cables</a> (get some extra just in case).</div><div>1x <a href="https://www.mouser.com/ProductDetail/538-22-55-2261" rel="nofollow" target="_blank">Molex housing 2x13</a>.</div><div>20x <a href="https://www.mouser.com/ProductDetail/538-90119-2111" rel="nofollow" target="_blank">Molex crimp connectors</a> (get some extra just in case).</div></div><div>Total: €41 + VAT + shipping.</div><div><br /></div><div><br /></div><h2 style="text-align: left;">Flashing FT2232H and FPGA</h2><div>The FT2232H must be flashed in FT245 mode prior to being usable by PCILeech. For the clock signal to enable it's required to both flash the FT2232H and start PCILeech/MemProcFS with the driver.</div><div><br /></div><div>Download <a href="https://ftdichip.com/utilities/" rel="nofollow" target="_blank">FT_Prog</a> from ftdichip. Connect to the device. On Port A change Hardware to 245 FIFO and Driver to D2XX Direct. Do the same on Port B. IO Pins are set to 4mA and Schmitt Input on both Port A and Port B.</div><div><br /></div><div>Remember to program the device after the changes have been made.</div><div><br /></div><div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjf_jyFDt-rIqJFl5tuiDSOwNZjLFUOZZni1OQPi-WfytTKrywClXYgWXtsJ9jX380HiUq_kNxxt9DLDyZhnxCuroMP8T-GZXc_iKA-Z3Ab5KVHpotiBowCmUVYIKc_751MJdfxM13xYBhyphenhyphen/s1600/ft_prog_1.png" style="margin-left: auto; margin-right: auto;"><img data-original-height="353" data-original-width="1049" height="216" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjf_jyFDt-rIqJFl5tuiDSOwNZjLFUOZZni1OQPi-WfytTKrywClXYgWXtsJ9jX380HiUq_kNxxt9DLDyZhnxCuroMP8T-GZXc_iKA-Z3Ab5KVHpotiBowCmUVYIKc_751MJdfxM13xYBhyphenhyphen/w640-h216/ft_prog_1.png" title="FT245 FIFO." width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">FT245 FIFO.</td></tr></tbody></table><br /></div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdrGykR4lpzUO7YOvLqlPfDrLvv1RtSNxb4pDj9l8f9Kkje5tNVIXXK9suu75BCO5JsxzQ94DRGrXHGtnZ4sqeumvwiURO18eKa-YPyDDmeNcUrL1G5Xir127-WSDx8KblZZGWJfW1X2RQ/s1600/ft_prog_2.png" style="margin-left: auto; margin-right: auto;"><img data-original-height="254" data-original-width="862" height="188" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdrGykR4lpzUO7YOvLqlPfDrLvv1RtSNxb4pDj9l8f9Kkje5tNVIXXK9suu75BCO5JsxzQ94DRGrXHGtnZ4sqeumvwiURO18eKa-YPyDDmeNcUrL1G5Xir127-WSDx8KblZZGWJfW1X2RQ/w640-h188/ft_prog_2.png" title="D2XX Direct." width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">D2XX Direct.</td></tr></tbody></table></div></div><div><br /></div><div><br /></div><div>To flash the FPGA first install Xilinx Vivado. It's possible to download a free <a href="https://www.xilinx.com/support/download.html" rel="nofollow" target="_blank">WebPack edition</a>. But beware - it's huge! After Vivado has been installed connect the JTAG cable and programmer. Open up Vivado and then Hardware Manager. Connect to the FPGA. Once connected right click the FPGA chip and select Spansion SPI memory according to the images below. Then program the bitstream / gateware. Please download the latest version from the <a href="https://github.com/ufrisk/pcileech-fpga/tree/master/acorn_ft2232h" target="_blank">PCILeech-FPGA</a> project on Github.</div><div><br /></div><div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPsnSEV652GlHWcRPYfKwiJ3ovea9DO4s43pkUgzom1EfV131tszUwc0CZN9MyHVeV5a5diVhbcHRRyKf_5brWBxolnzYiVUPA3CtU-xY7wFFYREXpoJjrUfJcah9AjGHV-L7-swSvGPcB/s1600/fpga-flash.png" style="margin-left: auto; margin-right: auto;"><img data-original-height="670" data-original-width="2455" height="175" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPsnSEV652GlHWcRPYfKwiJ3ovea9DO4s43pkUgzom1EfV131tszUwc0CZN9MyHVeV5a5diVhbcHRRyKf_5brWBxolnzYiVUPA3CtU-xY7wFFYREXpoJjrUfJcah9AjGHV-L7-swSvGPcB/w640-h175/fpga-flash.png" title="Flashing the FPGA." width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Flashing the FPGA.</td></tr></tbody></table></div><div><br /></div><div><br /></div><h2 style="text-align: left;">PCILeech DMA attacks and MemProcFS memory analysis</h2><div><br /></div><div>The Acorn CLE-215+ and LiteFury runs stable with PCILeech and MemProcFS with these modifications. For more information about how to use <a href="https://github.com/ufrisk/pcileech" target="_blank">PCIleech</a> and <a href="https://github.com/ufrisk/MemProcFS" target="_blank">MemProcFS</a> please check out my Github repos!</div><div><br /></div><div>When using PCILeech / MemProcFS with the FT2232H make sure to install the FT2232H drivers from <a href="https://ftdichip.com/drivers/d2xx-drivers/" rel="nofollow" target="_blank">ftdichip</a> and put the FTD2XX.DLL alongside the PCILeech / MemProcFS binaries.</div><div><br /></div><div>Also make sure to specify <span style="font-family: courier;"><b>-device fpga://ft2232h</b></span> in the connection string.</div><div><br /></div><h3 style="text-align: left;">Examples:</h3><div><span style="font-family: courier;"><b>pcileech.exe dump -out memdump.raw -device fp</b></span><b style="font-family: courier;">ga://ft2232h=1</b></div><div><span style="font-family: courier;"><b>memprocfs.exe -device </b></span><b style="font-family: courier;">fpga://ft2232h=1 -v -vv</b></div><div><br /></div><div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHJZsNX1JKNuUNKqt_H_Ysld1Gkv4T1OEas7X0f4thyphenhyphenwByjLhsiC3nFJp1Y6YD_NzCtTicigTFl0l9YtqaygnPYPMHu52D85m-O6EK4RAFwj_5nYDvtNr58RHESvrJC_OhlSNEhymJ9A0W/s1600/pcileech_dump1.png" style="margin-left: auto; margin-right: auto;"><img data-original-height="374" data-original-width="751" height="318" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHJZsNX1JKNuUNKqt_H_Ysld1Gkv4T1OEas7X0f4thyphenhyphenwByjLhsiC3nFJp1Y6YD_NzCtTicigTFl0l9YtqaygnPYPMHu52D85m-O6EK4RAFwj_5nYDvtNr58RHESvrJC_OhlSNEhymJ9A0W/w640-h318/pcileech_dump1.png" title="Dumping memory using the acorn with PCILeech PCIe DMA attacks." width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Dumping memory using the acorn with PCILeech PCIe DMA attacks.</td></tr></tbody></table><br /><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRMtoqq58WC3UqiIreqPiV9tr30Mj-GszzIQsH-7A1pWq-lquvqjU0NiCdqqNDDjyK-P0UG6g8BvuJZe2e_WpCKaZJaqKSZtJHno3jYqSl7v1CPxAyMgYPq3H1rjO29oOxRsIJ90qOhBgo/s1600/memprocfs_ft2232h.png" style="margin-left: auto; margin-right: auto;"><img data-original-height="730" data-original-width="1502" height="312" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRMtoqq58WC3UqiIreqPiV9tr30Mj-GszzIQsH-7A1pWq-lquvqjU0NiCdqqNDDjyK-P0UG6g8BvuJZe2e_WpCKaZJaqKSZtJHno3jYqSl7v1CPxAyMgYPq3H1rjO29oOxRsIJ90qOhBgo/w640-h312/memprocfs_ft2232h.png" title="MemProcFS live memory analysis with the Acorn CLE-215+ works nicely." width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">MemProcFS live memory analysis with the Acorn CLE-215+ works nicely.</td></tr></tbody></table><br /><br /></div><div><br /></div><h2 style="text-align: left;">Final Notes</h2><div>This was an interesting project creating a fully usable low-cost (€50 + FPGA board) DMA attack device with decent performance.</div><div><br /></div><div><div>Having FT2232H support in the code base - both in LeechCore and in the form of an FPGA IP core may be useful for other projects that doesn't require the higher performance of the FT601.</div><div><br /></div><div>The device as such is due to the relative lack of available I/O however inferior to the USB3 variants of PCILeech compatible hardware such as the Screamer series. Latency is much higher and transfer speeds are significantly lower on the modified Acorn. But more high-speed alternatives are currently sold out due to the global chip shortage.</div></div><div><br /></div><div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghiStqH0lrolJKIKoj0aMFf7gPwrv2ngQ5K360TByK7kkgNtQKQ67cYTGCWAbXkr88dbgW6e9XnizIjswWFTMNkjWBJnsK-zbWK4Jyu8nkhw84VFyiWHxoy1qed2GxEDLe_GT0fixXPPYq/s1600/2-litefury-final.jpg" style="margin-left: auto; margin-right: auto;"><img data-original-height="400" data-original-width="732" height="350" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghiStqH0lrolJKIKoj0aMFf7gPwrv2ngQ5K360TByK7kkgNtQKQ67cYTGCWAbXkr88dbgW6e9XnizIjswWFTMNkjWBJnsK-zbWK4Jyu8nkhw84VFyiWHxoy1qed2GxEDLe_GT0fixXPPYq/w640-h350/2-litefury-final.jpg" title="The LiteFury with a short custom signal cable." width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">The LiteFury with a short custom signal cable.</td></tr></tbody></table></div><div><br /></div><div>More performant alternatives would be possible if designing a <a href="https://twitter.com/enjoy_digital/status/1450037624446586883" target="_blank">carrier board</a> - utilizing some of the FPGA GTX lanes for communication with a 2nd FPGA then handling additional GPIOs. Such an approach would however be a larger undertaking and also be more costly. The Acorn Artix7 200T FPGA is however very powerful and is highly suitable for such an approach.</div><div><br /></div><div>If you're interesting in doing these hardware modifications yourself please do so at your own risk.</div><div><br /></div><div>PCILeech and MemProcFS is free open source and will continue to stay so. Many people and large corporations are using my tools for free - but few show any appreciation. If you enjoy using PCILeech and MemProcFS please consider becoming a <a href="https://github.com/sponsors/ufrisk" target="_blank">Github Sponsor</a>. Thank You 💖<br /></div><div><br /></div>Ulf Friskhttp://www.blogger.com/profile/09730439109623573624noreply@blogger.comtag:blogger.com,1999:blog-1551223415848378388.post-84306937703759740982019-04-05T11:26:00.000+02:002019-04-05T11:26:21.684+02:00Introducing the LeechAgentThe LeechAgent is a 100% free open source endpoint solution geared towards remote physical memory acquisition and analysis on Windows endpoints in Active Directory environments.<br />
<br />
The LeechAgent provides an easy, but yet high performant and secure, way of accessing and querying the physical memory (RAM) of a remote system. Mount the remote memory with MemProcFS as an easy point-and-click file system - perfect for quick and easy triage. Dump the memory over the network with PCILeech. Query the physical memory using the MemProcFS Python API by submitting analysis scripts to the remote host! Do all of the above simultaneously. <br />
<br />
Physical memory analysis have many advantages - a main one being able to analyze the state of a system independently from the, potentially compromised, system APIs.<br />
<br />
The video below shows how easy it is to install the LeechAgent service on a remote computer and then using it to mount MemProcFS, dump physical memory and submit Python analysis scripts using the MemProcFS API to the remote LeechAgent.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/UIsNWJ5KTvQ/0.jpg" frameborder="0" height="480" src="https://www.youtube.com/embed/UIsNWJ5KTvQ?feature=player_embedded" width="854"></iframe></div>
<br />
The LeechAgent offers security and simplicity. Security is built transparently upon built-in Windows functionality. Only administrators are allowed to connect. Other authentication mechanisms does not exist. This simplicity means that there is no need to create users, provision certificates or set up authentication mechanisms to use the LeechAgent. Everything required for security is already there without any configuration!<br />
<br />
<b><span style="font-size: x-large;">Using the LeechAgent</span></b><br />
The
LeechAgent allows up to 10 simultaneously connected clients to remotely
acquire physical memory and execute code in the form of Python analysis
scripts with access to the MemProcFS API. Use command-line PCILeech or file-system based MemProcFS to dump the physical memory from the remote computer running the LeechAgent. Use the MemProcFS file system and/or API to quickly analyze the memory of the remote computer.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGPUD5lPMR7BJOw1iJo7mOQJYbtSoevgNGqAw-R79_dXOlbNhqhg1Rs2Rp2ufax2YFlxw8r14R4TBgCe0O3pkkBiqr-4OWQM_Ir688h0X_OFS8AoJJTkgZw-wH9siwm6uMXa_Q4vPIKhDC/s1600/memprocfs.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="504" data-original-width="1243" height="258" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGPUD5lPMR7BJOw1iJo7mOQJYbtSoevgNGqAw-R79_dXOlbNhqhg1Rs2Rp2ufax2YFlxw8r14R4TBgCe0O3pkkBiqr-4OWQM_Ir688h0X_OFS8AoJJTkgZw-wH9siwm6uMXa_Q4vPIKhDC/s640/memprocfs.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Using MemProcFS to mount the physical memory of the remote computer as a File System - enabling quick and easy access to remote physical memory with your favorite tools - or just for taking a quick look.</td></tr>
</tbody></table>
Acquring memory from the remote computer running the LeechAgent works fairly well even over medium-bandwidth medium-latency network connections. It may also be desirable to execute a Python memory analysis script accessing the MemProcFS API directly on the remote computer. The LeechAgent will upon receival of a script automatically spawn an embedded Python environment and execute the script. The Python analysis script will never touch disk on the target system.<br />
<br />
This approach has many advantages. The main advantage is that physical memory may be accessed locally on the remote system - completely eliminating bandwidth and latency issues - making it ideal for physical memory analysis even over low-bandwith and highly laggy networks. Also since workload is shifted to the LeechAgent scripts may be run simultaneous on a large number of hosts - for example in an incident response scenario.<br />
<br />
More information about the MemProcFS Python API is available in the <a href="https://github.com/ufrisk/MemProcFS/wiki/API_Python" target="_blank">MemProcFS wiki</a>.<br />
<br />
Consider you have a Python script looking for read-write-execute sections in user-mode applications by analyzing physical memory. This may be useful for some kinds of malware. Please note that rwx-sections may also exist in legit applications in some cases.<br />
<br />
The script retrieves process information for all processes and then iterates over each process and will retrieve its memory map by walking the CPU page tables. <br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-jgBPKv-At_BG3iKAsYN_zxrXlwLffM8HTQcRnD9TWHLNRsAu64zYOvcqd_P9lXQtH4jrKuFeGtE-B2ymc_kAEFANKdxvqqnpzXKMSi0SLOylgxWMCevPpgi27zNEbvZHEthBw5G5SQs5/s1600/script-rwx.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="217" data-original-width="641" height="216" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-jgBPKv-At_BG3iKAsYN_zxrXlwLffM8HTQcRnD9TWHLNRsAu64zYOvcqd_P9lXQtH4jrKuFeGtE-B2ymc_kAEFANKdxvqqnpzXKMSi0SLOylgxWMCevPpgi27zNEbvZHEthBw5G5SQs5/s640/script-rwx.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Sample Python script making use of the VmmPy MemProcFS API to analyze memory.</td></tr>
</tbody></table>
Submit the Python memory analysis script to the remote LeechAgent with PCILeech and wait for the result. The LeechAgent will capture all output written to the console by the submitted analysis script.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi555aOnX_KhkbyH3mGLUwLxehuVA8LUOsxRe-K2GdeeUysoMtruvZ_CrrItLZnFEQnrDzoswbhMVvS-iby7p-t1K9rpO7hUWXERatqYSyxSR_ra2Yo04jaM34NyqM_Df9dWLKp6VEZJTPB/s1600/remote-exec.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="341" data-original-width="1095" height="198" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi555aOnX_KhkbyH3mGLUwLxehuVA8LUOsxRe-K2GdeeUysoMtruvZ_CrrItLZnFEQnrDzoswbhMVvS-iby7p-t1K9rpO7hUWXERatqYSyxSR_ra2Yo04jaM34NyqM_Df9dWLKp6VEZJTPB/s640/remote-exec.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Submitting the analysis script to the remote LeechAgent and waiting for the result.</td></tr>
</tbody></table>
If anything should go wrong with the analysis script - for example if it should happen to contain a never ending loop execution will automatically be aborted after two minutes. In rare cases it may also be a good idea to disconnect all clients from the remote LeechAgent and wait a few minutes for it to clean up any problematic jobs.<br />
<br />
<span style="font-size: x-large;"><b>Installing the LeechAgent</b></span><br />
The LeechAgent supports both 32-bit and 64-bit Windows systems. The 32-bit version will work on both 32-bit and 64-bit systems - but in limited mode without the ability to process memory analysis scripts on the remote host. The 64-bit LeechAgent is strongly recommended!<br />
<br />
The LeechAgent may be downloaded from <a href="https://github.com/ufrisk/LeechCore" target="_blank">the LeechCore repository on Github</a>. The 64-bit version of the LeechAgent is located in <a href="https://github.com/ufrisk/LeechCore/tree/master/files/agent/x64" target="_blank"><b><span style="font-family: "courier new" , "courier" , monospace;">LeechCore/files/agent/x64</span></b></a>. The LeechAgent have dependencies on Python for analysis and WinPMEM for memory dumping. <a href="https://www.comae.com/" target="_blank">DumpIt</a> may also be used for memory dumping if running in interactive (non-service) mode.<br />
<br />
<b>Dependencies:</b><br />
<ul>
<li>Python: download <b><a href="https://www.python.org/ftp/python/3.7.3/python-3.7.3-embed-amd64.zip" target="_blank"><span style="font-family: "courier new" , "courier" , monospace;">Windows x86-64 embeddable zip</span></a></b> file from <b><a href="https://www.python.org/downloads/" target="_blank"><span style="font-family: "courier new" , "courier" , monospace;">python.org</span></a></b> and unzip its contents in the <b><span style="font-family: "courier new" , "courier" , monospace;">LeechAgent\Python</span></b> sub-folder.</li>
<li>WinPMem: download the <a href="https://github.com/Velocidex/c-aff4/blob/master/tools/pmem/resources/winpmem/att_winpmem_64.sys" target="_blank"><b><span style="font-family: "courier new" , "courier" , monospace;">signed 64-bit driver</span></b></a> from <a href="https://github.com/Velocidex/c-aff4/tree/master/tools/pmem/resources/winpmem" target="_blank"><b><span style="font-family: "courier new" , "courier" , monospace;">Github</span></b></a> and place it in the <b><span style="font-family: "courier new" , "courier" , monospace;">LeechAgent</span></b> folder alongside <b><span style="font-family: "courier new" , "courier" , monospace;">leechagent.exe</span></b>.</li>
</ul>
<span style="font-size: small;"><b>Target system requirements:</b></span><br />
<ul>
<li><span style="font-size: small;">Windows 7 or later.</span></li>
<li><span style="font-size: small;">Bitness - it's not possible to install the 64-bit version of the LeechAgent on a 32-bit system. </span></li>
<li><span style="font-size: small;">Active Directory environment: if installing as a service. (In lab environments it's possible to execute LeechAgent in an unauthenticated insecure mode which does not rely on Active Directory for authentication).</span></li>
<li><span style="font-size: small;">Administrative access: user running the LeechAgent installation is required to be an administrator on the remote computer. If installing on localhost the user is required to be an elevated administrator.</span></li>
<li><span style="font-size: small;">File share - Installation: access to the <b>C$</b> administrative file share. </span></li>
<li><span style="font-size: small;">Firewall openings - Installation: Access to the service control manager (SCM) and File sharing is required for installation only.</span></li>
<li><span style="font-size: small;">Firewall openings - Using: Access to the LeechAgent or <b><span style="font-family: "courier new" , "courier" , monospace;">tcp/28473</span></b> is required. </span></li>
</ul>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRNdw7Dayz9BPhHzWyZC_AL1GxFfB63WmZRE4HTjdHUtMNeAE3zcPPlaqe2yn5sQTu68FlIj2_CCMJ66HPp_e2qGb0H_nisQWJJ3m3wzGhiv1j5zV6Rc_-gVaEPkMcuHAt4lkBmHozL74R/s1600/fw_install.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="275" data-original-width="1073" height="164" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRNdw7Dayz9BPhHzWyZC_AL1GxFfB63WmZRE4HTjdHUtMNeAE3zcPPlaqe2yn5sQTu68FlIj2_CCMJ66HPp_e2qGb0H_nisQWJJ3m3wzGhiv1j5zV6Rc_-gVaEPkMcuHAt4lkBmHozL74R/s640/fw_install.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Windows firewall rules recommended for remote LeechAgent installation.</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiqRr3z0XNVDsjiHDBvG2QDS1OS5iMfQ3M2cgxMfQixvr-RtOBar-6uyM8FYS4quFKvIZK9TYnP7TrWlXxm3zO819EiNLt7OZxlDt_Luc5ocJ_uKI34mNuOOcz3h3-6BJhI5QkgGkJS0pG/s1600/fw_leechagent.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="155" data-original-width="1222" height="80" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiqRr3z0XNVDsjiHDBvG2QDS1OS5iMfQ3M2cgxMfQixvr-RtOBar-6uyM8FYS4quFKvIZK9TYnP7TrWlXxm3zO819EiNLt7OZxlDt_Luc5ocJ_uKI34mNuOOcz3h3-6BJhI5QkgGkJS0pG/s640/fw_leechagent.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Windows Firewall rule for the LeechAgent endpoint - <b><span style="font-family: "courier new" , "courier" , monospace;">tcp/28473</span></b>.</td></tr>
</tbody></table>
<b>Installation:</b><br />
<br />
Installation is easy - run the command:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><b>LeechAgent.exe -remoteinstall <remote_computer_name></b></span><br />
<br />
The LeechAgent and its dependencies will be copied to the <b><span style="font-family: "courier new" , "courier" , monospace;">Program Files\LeechAgent</span></b> directory of the remote host. Uninstallation is possible in a similar way but with the -remoteuninstall command.<br />
<br />
<b><span style="font-size: x-large;">Security and Authentication</span></b><br />
The primary design goal of the LeechAgent is to keep it simple and secure.<br />
<br />
The LeechAgent relies exclusively on built-in Windows functionality for Kerberos authentication of connecting clients. Only remote users with administrative privileges on the computer running the LeechAgent are allowed to connect. In addition to this the connecting client is also required, by default, to verify the authenticity of the LeechAgent by supplying the Kerberos SPN of the user that runs the LeechAgent. This is usually the Active Directory computer account.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_Q5m7aQLvcV-FEL4GTJCdIDq-mJh8vuB-j2WpB-epSbemIlIAJXO1MGZhWphNHqyIuwKDQWtUrgS49vLRxVV37yv6h-ua38XjeGv9Wwhz28usrby1sDAR6t65_YllX1c4dQ_JlzukPlZ6/s1600/remoterpc.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="164" data-original-width="983" height="106" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_Q5m7aQLvcV-FEL4GTJCdIDq-mJh8vuB-j2WpB-epSbemIlIAJXO1MGZhWphNHqyIuwKDQWtUrgS49vLRxVV37yv6h-ua38XjeGv9Wwhz28usrby1sDAR6t65_YllX1c4dQ_JlzukPlZ6/s640/remoterpc.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Connecting client mutually authenticates the remote LeechAgent user for additional security.</td></tr>
</tbody></table>
<br />
The RPC connection between connecting client and the remote LeechAgent is secured by mutually authenticated Kerberos and is also encrypted using built-in Windows functionality also relying on Kerberos.The connection is also compressed if both client and server is running on Windows 10.<br />
<br />
Connecting clients are logged to the Application Event Log the computer running the LeechAgent.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh_tkRes9egy6WlQMXx4OmN-aNOyFHr10RxHL0Q2WMKN0g57FiOlhC9gT4Q0PfzQNIIfwpHg-aWE0jGbX5EPr_ljWOTr36Yj_6qAfqZUrNgCgdyENKRr5FUr_WvqsYPIo2SLvbBMICQE3D/s1600/event.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="414" data-original-width="794" height="332" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh_tkRes9egy6WlQMXx4OmN-aNOyFHr10RxHL0Q2WMKN0g57FiOlhC9gT4Q0PfzQNIIfwpHg-aWE0jGbX5EPr_ljWOTr36Yj_6qAfqZUrNgCgdyENKRr5FUr_WvqsYPIo2SLvbBMICQE3D/s640/event.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The connecting user ulf@ad.frizk.net is logged to the Application Event Log by the LeechAgent.</td></tr>
</tbody></table>
<br />
<b>Note!</b> The LeechAgent allows authenticated remote administrators to both access physical memory and run arbitrary code as SYSTEM on the computer running the LeechAgent. This is by design. Since only administrators are allowed to connect this is not a security issue.<br />
<br />
<b>Note!</b> It's also possible possible to run the LeechAgent without any form of authentication in interactive mode only. This is not recommended and should only be used in otherwise secure lab environments.<br />
<br />
<b><span style="font-size: x-large;">The Future</span></b><br />
The primary design goal is to keep the LeechAgent secure, simple and easy to use. As such it's not likely that more authentication mechanisms or supported operating systems will be added in the near future. For now built-in Kerberos-based Windows authentication is suficient.<br />
<br />
The MemProcFS Python API, while fast and powerful, is still somewhat limited. New and extended API functionality is a priority.<br />
<br />
Also further optimizations of memory dumping will be looked into.<br />
<br />
The MemProcFS Python API is already fast - the underlying multi-threaded native C analysis library is amazingly fast - but things may always be improved. Additional performance optimizations are planned.<br />
<br />
<b><span style="font-size: x-large;">Links and Additional information</span></b><br />
The LeechAgent, PCILeech and MemProcFS are available for free on Github and are all licensed as Open Source GPLv3. Please find the projects below:<br />
<a href="https://github.com/ufrisk/LeechCore" target="_blank">LeechAgent and LeechCore</a><br />
<a href="https://github.com/ufrisk/MemProcFS" target="_blank">MemProcFS</a><br />
<a href="https://github.com/ufrisk/pcileech" target="_blank">PCILeech </a><br />
<br />
<br />
<br />Ulf Friskhttp://www.blogger.com/profile/09730439109623573624noreply@blogger.com6tag:blogger.com,1999:blog-1551223415848378388.post-41182124946716716182019-02-06T14:35:00.002+01:002019-02-18T13:37:29.318+01:00Remote LIVE Memory Analysis with The Memory Process File System v2.0This blog entry aims to give an introduction to The Memory Process File System and show how easy it is to do high-performant memory analysis even from live remote systems over the network.<br />
<br />
This and much more is presented in my <a href="https://www.bluehatil.com/" target="_blank">BlueHatIL 2019</a> talk on February 6th.<br />
<br />
Connect to a remote system over the network over a kerberos secured connection. Acquire only the live memory you require to do your analysis/forensics - even over medium latency/bandwidth connections.<br />
<br />
An easy to understand file system user interface combined with continuous background refreshes, made possible by the multi-threaded analysis core, provides an interesting new different way of performing incident response by live memory analysis.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhB3MrwSEpF1n6UD68wRtNd0Oc7HTBZ3NR3xKrx0tksbbKYQ9QQ2Q6JOAWDFd0gIRjjuhyphenhyphen77w1SiJTKgU-eBrcGYcBLmCmLGeG9uFHdAQzuJOOZoqLHkAg40Lw1jGGn5XpfIOMl8IrIbPmd/s1600/image-dump.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="416" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhB3MrwSEpF1n6UD68wRtNd0Oc7HTBZ3NR3xKrx0tksbbKYQ9QQ2Q6JOAWDFd0gIRjjuhyphenhyphen77w1SiJTKgU-eBrcGYcBLmCmLGeG9uFHdAQzuJOOZoqLHkAg40Lw1jGGn5XpfIOMl8IrIbPmd/s640/image-dump.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Analyzing and Dumping remote live memory with the Memory Process File System.</td></tr>
</tbody></table>
The image above shows the user staring <span style="font-family: "courier new" , "courier" , monospace;">MemProcFS.exe</span> with a connection to the remote computer <span style="font-family: "courier new" , "courier" , monospace;">book-test.ad.frizk.net</span> and with the DumpIt live memory acquisition method. it is then possible to analyze live memory simply by clicking around in the file system. Dumping the physical memory is done by copying the <span style="font-family: "courier new" , "courier" , monospace;">pmem</span> file in the root folder. <br />
<br />
<span style="font-size: large;">Background</span><br />
<span style="font-size: large;"><span style="font-size: small;">The Memory Process File System was released for <a href="http://blog.frizk.net/2018/03/memory-process-file-system.html">PCILeech in March 2018</a>, supporting 64-bit Windows, and was used to find the <a href="http://blog.frizk.net/2018/03/total-meltdown.html">Total Meltdown</a> / CVE-2018-1038 page table permission bit vulnerability in the Windows 7 kernel. People have also used it to cheat in games - primarily cs:go using it via the PCILeech API.</span></span><br />
<br />
<span style="font-size: large;"><span style="font-size: small;"><a href="https://github.com/ufrisk/MemProcFS">The Memory Process File System</a> was released as a stand-alone project focusing exclusively on memory analysis in November 2018. The initial release included both APIs and Plugins for C/C++ and a Python. Support was added soon thereafter for 32-bit memory models and Windows support was expanded as far back as Windows XP.</span></span><br />
<br />
<span style="font-size: large;"><span style="font-size: small;"><span style="font-size: large;">What is new? </span></span></span><br />
<span style="font-size: large;"><span style="font-size: small;"><span style="font-size: large;"><span style="font-size: small;">Version 2.0 of The Memory Process File System marks a major release that was released in conjunction with the <a href="https://www.bluehatil.com/" target="_blank">BlueHatIL 2019</a> talk <a href="https://www.bluehatil.com/abstracts#collapsePractical" target="_blank">Practical Uses for Hardware-assisted Memory Visualization.</a></span></span></span></span><br />
<br />
New functionality includes:<br />
<ul>
<li>A new separate physical memory acquisition library - the <a href="https://github.com/ufrisk/LeechCore">LeechCore</a>.</li>
<li>Live memory acquisition with DumpIt or WinPMEM.</li>
<li>Remote memory capture via a remotely running LeechService.</li>
<li>Support from Microsoft Crash Dumps and Hyper-V save files.</li>
<li>Full multi-threaded support in the memory analysis library.</li>
<li>Major performance optimizations.</li>
</ul>
The combination live memory capture via <a href="http://www.comae.com/" target="_blank">Comae DumpIt</a>, or WinPMEM, and secure remote access may be interesting both for convenience and incident-response. It even works remarkably well over medium latency- and bandwidth connections.<br />
<br />
<span style="font-size: large;">The LeechCore library</span><br />
The LeechCore library, focusing exclusively on memory acquisition, is released as a standalone open source project as a part of The Memory Process File System v2 release. The LeechCore library abstracts memory acquisition from analysis and makes things more modular and easier to re-use. The library supports multiple memory acquisition methods - such as:<br />
<ul>
<li>Hardware: USB3380, <a href="https://github.com/ufrisk/pcileech-fpga">PCILeech FPGA</a> and iLO</li>
<li>Live memory: Comae DumpIt and WinPMEM</li>
<li>Dump files: raw memory dump files, full crash dump files and Hyper-V save files.</li>
</ul>
The LeechCore library also allows for transparently connecting to a remote LeechService running on a remote system over a compressed mutually authenticated RPC connection secured by Kerberos. Once connected any of the supported memory acquisition methods may be used.<br />
<br />
<span style="font-size: large;">The LeechService </span><br />
The LeechService may be installed as a service with the command <span style="font-family: "courier new" , "courier" , monospace;">LeechSvc.exe install</span>. Make sure all necessary dependencies are in the folder of <span style="font-family: "courier new" , "courier" , monospace;">leechsvc.exe</span> - i.e. <span style="font-family: "courier new" , "courier" , monospace;">leechcore.dll</span> and <span style="font-family: "courier new" , "courier" , monospace;">att_winpmem_64.sys</span> (if using winpmem). The LeechService will write an entry, containing the kerberos SPN to the application event log once started provided that the computer is a part of an Active Directory domain.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJsYUUwSbW2Xmo3OucWmxQjYHcgopv1wzYB5SzEZDzImBW6P77z_7ogAvO0GozbN36gIM5WktwpY5XGREgMwm7I57u6-MHmR2CL2aHyi-OL24gSznNV14d_tL9J-RfBW6XULH5s5pJqa5W/s1600/leechsvc_svc.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="384" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJsYUUwSbW2Xmo3OucWmxQjYHcgopv1wzYB5SzEZDzImBW6P77z_7ogAvO0GozbN36gIM5WktwpY5XGREgMwm7I57u6-MHmR2CL2aHyi-OL24gSznNV14d_tL9J-RfBW6XULH5s5pJqa5W/s640/leechsvc_svc.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The LeechService is installed and started with the Kerberos SPN: book-test$@AD.FRIZK.NET</td></tr>
</tbody></table>
Now connect to the remote LeechService with The Memory Process File System - provided that the port <span style="font-family: "courier new" , "courier" , monospace;">28473</span> is open in the firewall. The connecting user must be an administrator on the system being analyzed. An event will also be logged for each successful connection. In the example below winpmem is used.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXSuKqeNPHlvzeb4Eru5UbznHb9Tv-JfbWXdfkXdjXfnJWqDnF70LU97BonickcIyfBdyDZ4V37XPKny1OvCiT9DOo9FNwIyYr1EaJMRq2jNdv8PxWBpngjVryDYUDt2rYXXZ2H0XZumDH/s1600/leechsvc_pmem.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="262" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXSuKqeNPHlvzeb4Eru5UbznHb9Tv-JfbWXdfkXdjXfnJWqDnF70LU97BonickcIyfBdyDZ4V37XPKny1OvCiT9DOo9FNwIyYr1EaJMRq2jNdv8PxWBpngjVryDYUDt2rYXXZ2H0XZumDH/s640/leechsvc_pmem.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Securely connected to the remote system - acquiring and analyzing live memory.</td></tr>
</tbody></table>
It's also possible to start the LeechService in interactive mode. If starting it in interactive mode it can be started with DumpIt to provide more stable memory acquisition. It may also be started in insecure no-security mode - which may be useful if the computer is not joined to an Active Directory domain.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><img alt="" height="304" src="data:image/png;base64,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" style="margin-left: auto; margin-right: auto;" width="640" /></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Using DumpIt to start the LeechSvc in interactive insecure mode.</td></tr>
</tbody></table>
If started in insecure mode everyone with access to port <span style="font-family: "courier new" , "courier" , monospace;">28473</span> will be able to connect and capture live memory. No logs will be written. The insecure mode is not available in service mode. It is only recommended in secure environments in which the target computer is not domain joined. Please also note that it is also possible to start the LeechService in interactive secure mode.<br />
<br />
To connect to the example system from a remote system specify:<br />
<span style="font-family: "courier new" , "courier" , monospace;">MemProcFS.exe -device dumpit -remote rpc://insecure:<address_of_remote_system></span><br />
<br />
<span style="font-size: large;">How do I try it out?</span><br />
Yes! - both the Memory Process File System and the LeechService is 100% open source.<br />
<ol>
<li>Download <a href="https://github.com/ufrisk/MemProcFS">The Memory Process File System</a> from Github - pre-built binaries are found in the files folder. Also, follow the instructions to install the open source <a href="https://github.com/dokan-dev/dokany/releases">Dokany file system</a>.</li>
<li>Download the <a href="https://github.com/ufrisk/LeechCore">LeechService</a> from Github - pre-built binaries with no external dependencies are found in the files folder. Please also note that you may have to download <a href="https://www.comae.com/" target="_blank">Comae DumpIt</a> or <a href="https://github.com/Velocidex/c-aff4/blob/master/tools/pmem/resources/winpmem/att_winpmem_64.sys" target="_blank">WinPMEM</a> (download and copy .sys driver file to directory of MemProcFS.exe) to acquire live memory.</li>
</ol>
<br />
<span style="font-size: large;">The Future</span><br />
Please do keep in mind that this is a hobby project. Since I'm not working professionally with this future updates may take time and are also not guaranteed.<br />
<br />
The Memory Process File System and the LeechCore is already somewhat mature with its focus on fast, efficient, multi-threaded live memory acquisition and analysis even though current functionality is somewhat limited.<br />
<br />
The plan for the near future is to add additional core functionality - such as page hashing and PFN database support. Page hashing will allow for more efficient remote memory acquisition and better forensics capabilities. PFN database support will strengthen virtual memory support in general.<br />
<br />
Also, additional and more efficient analysis methods - primarily in the form of new plugins will also be added in the medium future.<br />
<br />
Support for additional operating systems, such as Linux and macOS is a long-term goal. It shall however be noted that the LeechCore library is already supported on Linux.<br />
<br />
<span style="font-size: large;">Update</span><br />
2019-02-18: Please also have a look at my Microsoft <a href="https://www.bluehatil.com/" target="_blank">BlueHatIL</a> 2019 talk in which I, among other things, talk about using the Memory Process File System v2.0 with the remote capture functionality discussed in this blog post. In the talk I also make use the Python API and demo the "Total Meltdown/CVE-2018-1038" vulnerability. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/Da_9SV9FA34/0.jpg" frameborder="0" height="360" src="https://www.youtube.com/embed/Da_9SV9FA34?feature=player_embedded" width="640"></iframe></div>
<br />
<br />Ulf Friskhttp://www.blogger.com/profile/09730439109623573624noreply@blogger.com23tag:blogger.com,1999:blog-1551223415848378388.post-58188560756270733142018-03-27T17:32:00.001+02:002018-03-30T13:39:15.817+02:00Total Meltdown?Did you think <a href="https://meltdownattack.com/" target="_blank">Meltdown</a> was bad? Unprivileged applications being able to read kernel memory at speeds possibly as high as megabytes per second was not a good thing.<br />
<br />
Meet the Windows 7 Meltdown patch from January. It stopped Meltdown but opened up a vulnerability way worse ... It allowed any process to read the complete memory contents at gigabytes per second, oh - it was possible to write to arbitrary memory as well.<br />
<br />
No fancy exploits were needed. Windows 7 already did the hard work of mapping in the required memory into every running process. Exploitation was just a matter of read and write to already mapped in-process virtual memory. No fancy APIs or syscalls required - just standard read and write! <br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdbP0zfFMygTjfsC6NqNprZoWYBPn6DG5T3H7DwN_S_phczSB3mXIAc5y_PCp6LtmzGB-8nSMilbZelH10EQPQPCDHhPDvinohBnr9CR7m3ibRWI9GbMwrGeassxoogiw35lxPaMj-qrbk/s1600/win7-dump-combined.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="164" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdbP0zfFMygTjfsC6NqNprZoWYBPn6DG5T3H7DwN_S_phczSB3mXIAc5y_PCp6LtmzGB-8nSMilbZelH10EQPQPCDHhPDvinohBnr9CR7m3ibRWI9GbMwrGeassxoogiw35lxPaMj-qrbk/s640/win7-dump-combined.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Accessing memory at over 4GB/s, dumping to disk is slower due to disk transfer speeds.</td></tr>
</tbody></table>
<br />
<span style="font-size: large;">How is this possible? </span><br />
In short - the User/Supervisor permission bit was set to User in the PML4 self-referencing entry. This made the page tables available to user mode code in every process. The page tables should normally only be accessible by the kernel itself.<br />
<br />
The PML4 is the base of the 4-level in-memory page table hierarchy that the CPU Memory Management Unit (MMU) uses to translate the virtual addresses of a process into physical memory addresses in RAM. For more in-depth information about paging please have a look at Getting Physical: Extreme abuse of Intel based Paging Systems - <a href="https://www.coresecurity.com/blog/getting-physical-extreme-abuse-of-intel-based-paging-systems-part-1" target="_blank">Part 1</a> and <a href="https://www.coresecurity.com/blog/getting-physical-extreme-abuse-of-intel-based-paging-systems-part-2-windows" target="_blank">Part 2</a>.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipv56hkJADW_EIluqDDXv-Q3YY0qotgVVpYezOMWl1WXWLOoSjWtczGD1SM6HcjOGg6GSBFBJIdzgXbcO-WZb1VX3XrMogtSbqJG4bAWkJF9BgYMh6mJ_itByp3FsU4pzW7KbI3bov0wb5/s1600/win7-pml4-2.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipv56hkJADW_EIluqDDXv-Q3YY0qotgVVpYezOMWl1WXWLOoSjWtczGD1SM6HcjOGg6GSBFBJIdzgXbcO-WZb1VX3XrMogtSbqJG4bAWkJF9BgYMh6mJ_itByp3FsU4pzW7KbI3bov0wb5/s640/win7-pml4-2.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">PML4 self-referencing entry at offset 0xF68 with value 0x0000000062100867.</td></tr>
</tbody></table>
<br />
Windows have a special entry in this topmost PML4 page table that references itself, a self-referencing entry. In Windows 7 the PML4 self-referencing is fixed at the position 0x1ED, offset 0xF68 (it is randomized in Windows 10). This means that the PML4 will always be mapped at the address: 0xFFFFF6FB7DBED000 in virtual memory. This is normally a memory address only made available to the kernel (Supervisor). Since the permission bit was erroneously set to User this meant the PML4 was mapped into every process and made available to code executing in user-mode.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfNixk_kauwYSk3qGDXyqt37gh3JjQhWy6myY1TH4f7USP1wqsdXzp9E1kQaIZAtI__3j6MRyS0zFQzBCShUH8_Hu9uOwuFGiwKMOo4FHIn5SyNFT08JwGgwX0phireg1wmqnndV7yEuFn/s1600/win7-notepad-memmap.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfNixk_kauwYSk3qGDXyqt37gh3JjQhWy6myY1TH4f7USP1wqsdXzp9E1kQaIZAtI__3j6MRyS0zFQzBCShUH8_Hu9uOwuFGiwKMOo4FHIn5SyNFT08JwGgwX0phireg1wmqnndV7yEuFn/s640/win7-notepad-memmap.PNG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">"kernel address" memory addresses mapped in every process as user-mode read/write pages.</td></tr>
</tbody></table>
<br />
Once read/write access has been gained to the page tables it will be trivially easy to gain access to the complete physical memory, unless it is additionally protected by Extended Page Tables (EPTs) used for Virtualization. All one has to do is to write their own Page Table Entries (PTEs) into the page tables to access arbitrary physical memory.<br />
<br />
The last '7' in the PML4e 0x0000000062100867 (from above example) indicates that bits 0, 1, 2 are set, which means it's Present, Writable and User-mode accessible as per the description in the Intel Manual.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjueh7vpSu7l7_M9gl1wjYGKqodsPQQ6qde4vFmBX1aS_MubBUTgjDFN1iS4Ocu92PSSOmDtN7Wzsiw3IzekBBbVjem0mcjHgQ47Gcg5VtMDmH-Yh6X9tey1EeFmHc4cm1KuVQq1a-Z8SQc/s1600/win7-pml4.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="156" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjueh7vpSu7l7_M9gl1wjYGKqodsPQQ6qde4vFmBX1aS_MubBUTgjDFN1iS4Ocu92PSSOmDtN7Wzsiw3IzekBBbVjem0mcjHgQ47Gcg5VtMDmH-Yh6X9tey1EeFmHc4cm1KuVQq1a-Z8SQc/s640/win7-pml4.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Excerpt from the Intel Manual, if bit 2 is set to '1' user-mode access are permitted.</td></tr>
</tbody></table>
<br />
<span style="font-size: large;">Can I try this out myself?</span><br />
Yes absolutely. The technique has been added as a memory acquisition device to the <a href="https://github.com/ufrisk/pcileech" target="_blank">PCILeech direct memory access attack toolkit</a>. Just download PCILeech and execute it with device type: <span style="font-family: "courier new" , "courier" , monospace;">-device totalmeltdown</span> on a vulnerable Windows 7 system.<br />
<br />
Dump memory to file with the command: <span style="font-size: small;"><span style="font-family: "courier new" , "courier" , monospace;">pcileech.exe dump -out memorydump.raw -device totalmeltdown -v -force</span></span> .<br />
<br />
If you have the <a href="https://github.com/dokan-dev/dokany/releases" target="_blank">Dokany</a> file system driver installed you should be able to mount the running processes as files and folders in the <a href="https://blog.frizk.net/2018/03/memory-process-file-system.html">Memory Process File System</a> - with the virtual memory of the kernel and the processes as read/write.<br />
<br />
To mount the processes issue the command: <span style="font-family: "courier new" , "courier" , monospace;">pcileech.exe mount -device totalmeltdown</span> .<br />
<br />
Please remember to re-install your security updates if you temporarily uninstall the latest one in order to test this vulnerability.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEit2VYPOf7Tox74iKFYFa9EOQzmZTwuQLPOVEO8aeQ66VFp4x9bCaw-2KbD4-kNU2EdalN-4W0dcuGb7KNHA5vbPiMSUcVcFWnRjFq1QgOwn4vmykRfTUpeNiq5GXLEDwbXfZ0C2YHUOItp/s1600/win7-prsc-pcileech-mount.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEit2VYPOf7Tox74iKFYFa9EOQzmZTwuQLPOVEO8aeQ66VFp4x9bCaw-2KbD4-kNU2EdalN-4W0dcuGb7KNHA5vbPiMSUcVcFWnRjFq1QgOwn4vmykRfTUpeNiq5GXLEDwbXfZ0C2YHUOItp/s640/win7-prsc-pcileech-mount.PNG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">A vulnerable system is "exploited" and the running processes are mounted with PCILeech.<br />
Process memory maps and PML4 are accessed.</td></tr>
</tbody></table>
<br />
<span style="font-size: large;">Is my system vulnerable?</span><br />
Only Windows 7 x64 systems patched with the 2018-01 or 2018-02 patches are vulnerable. If your system isn't patched since December 2017 or if it's patched with the <strike>2018-03</strike> 2018-03-29 patches or later it will be secure.<br />
<br />
Other Windows versions - such as Windows 10 or 8.1 are completely secure with regards to this issue and have never been affected by it.<br />
<br />
<span style="font-size: large;">Other</span><br />
I discovered this vulnerability just after it had been patched in the 2018-03 Patch Tuesday. I have not been able to correlate the vulnerability to known CVEs or other known issues.<br />
<br />
<span style="font-size: large;">Updates</span><br />
Windows 2008R2 was vulnerable as well.<br />
<a href="https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-1038" target="_blank">OOB security update</a> released to fully resolve the vulnerability on 2018-03-29. <a href="https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-1038" target="_blank">CVE-2018-1038</a>. Apply immediately if affected!<br />
<br />
<span style="font-size: large;">Timeline</span><br />
2018-03-xx--25:
Issue identified in Windows 7 x64. Issue seemed to be patched already.
PoC coded. Contacted MSRC with technical description asking if OK to
publish a blog entry or if I should hold off publication.<br />
2018-03-26: Green light given by MSRC for me to publish blog entry.<br />
2018-03-27: Published blog entry and PoC.<br />
2018-03-28: Found out that the March patches only partially resolved the vulnerability. Contacted MSRC again.<br />
2018-03-29: <a href="https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-1038" target="_blank">OOB security update</a> released by Microsoft. <a href="https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-1038" target="_blank">CVE-2018-1038</a>. Apply immediately if affected!<br />
<br />
Huge Thank You to everyone at Microsoft that worked hard to resolve this issue. It is super impressive to be able to be able to roll out a complex kernel update in little over a day. It was never my intention to release a fairly potent kernel 0-day publicly. I hope the above timeline explains how this could happen.<br />
<br />Ulf Friskhttp://www.blogger.com/profile/09730439109623573624noreply@blogger.comtag:blogger.com,1999:blog-1551223415848378388.post-69126678765530493482018-03-12T13:14:00.001+01:002018-11-28T12:50:52.098+01:00Introducing the Memory Process File System for PCILeech<br />
<div>
The Memory Process File System for PCILeech is an easy and convenient way to quickly look into memory dumps. The processes in a memory dump and their virtual memory should be mapped as files and folders in less than a second.<br />
<br />
Click around the processes, look at their memory maps and corresponding virtual memory! Oh - if you run it in live mode with a supported PCILeech FPGA device you'll be able to write to memory as well! Super convenient if your target system employs software based anti-forensic or anti-cheating functionality since this is all handled in hardware on the target!<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnqQzWM_deM5voy6LGLYxhla_iY6O-sbs1LRwhYCxLPoE-42k7Z3oB8uQ0buHRKbkpec7BcnLsWTTY3IOMZ4yyIzpC4YidimjNxiucuSinEf0SctpNHYXtUst5tGuxM0kNKgLW5cSpGqM6/s1600/blog_head.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnqQzWM_deM5voy6LGLYxhla_iY6O-sbs1LRwhYCxLPoE-42k7Z3oB8uQ0buHRKbkpec7BcnLsWTTY3IOMZ4yyIzpC4YidimjNxiucuSinEf0SctpNHYXtUst5tGuxM0kNKgLW5cSpGqM6/s640/blog_head.gif" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Using the Memory Process File System for PCILeech to explore Windows processes in a memory dump file.</td></tr>
</tbody></table>
<br />
<br />
<span style="font-size: large;">Cool! So how do I try it out?</span><br />
Check out and download <a href="https://github.com/ufrisk/pcileech">PCILeech on Github</a>. PCILeech is open source and totally free of charge! You'll find both source code and pre-compiled binaries on Github.<br />
<br />
<span style="font-size: large;">How does it work?</span><br />
It works by parsing in-memory page tables which are used by the CPU to translate the virtual memory of a process into physical memory. Since page tables are hardware dependent this means that the Memory Process File System is able to map processes from all 64-bit operating systems running on x64 hardware, if the base of the process page table called PageDirectoryBase or PML4 or CR3 is known.<br />
<br />
If parts of the page tables, or other process memory, doesn't exist in the memory, it may have been swapped out to the swap on disk, analysis of that part of memory will fail.<br />
<br />
If analyzing Windows memory dumps additional analysis will be performed to identify running processes, modules and which memory regions they belong to.<br />
<br />
<span style="font-size: large;">What about Functionality and Limitations?</span><br />
- The Memory Process File System is currently only supported when running PCILeech on Windows.<br />
- x64 64-bit target operating systems only, no 32-bit, no ARM.<br />
- Read-only mode on memory dump files, read-write mode if PCILeech FPGA is used on a live system.<br />
- Automatic process identification only in Windows memory dumps.<br />
- Automatic identification of EPROCESS, PEB and DLL addresses in Windows memory dumps.<br />
- May fail on memory dumps taken from Virtual Machines, such as VirtualBox.<br />
- May fail for various other reasons as well.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjCh9-RfgTPIAFDeX4_7YTvekIcVlAtw5HCGkwI7NUu-T1-tgm4OALTL3N2qOYjH6kPf6m7Vt6zxVh4qnXfGFmbul6aJSIXGnD7OQVZhEo7VwTwDG64J5woKHldK2R_yRh2FpCfYI-09mV/s1600/blog_linux.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjCh9-RfgTPIAFDeX4_7YTvekIcVlAtw5HCGkwI7NUu-T1-tgm4OALTL3N2qOYjH6kPf6m7Vt6zxVh4qnXfGFmbul6aJSIXGnD7OQVZhEo7VwTwDG64J5woKHldK2R_yRh2FpCfYI-09mV/s640/blog_linux.gif" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Looking at the Linux kernel by manually specifying a valid CR3 value (PageDirectoryBase/PML4).</td></tr>
</tbody></table>
<br />
<br />
<span style="font-size: large;">How Forensically Secure is it?</span><br />
Memory swapped out to disk will also be invisible to the Memory Process File System - there is no guarantee that everything will be mapped.<br />
<br />
There is no way for user-mode malware to hide from the Memory Process File System though. Since the Memory Process File System analyzes page tables, which are used by the CPU and thus must remain in memory somewhat unobfuscated.<br />
<br />
The Memory Process File System however employs some tricks to filter out what looks like invalid page tables. This means that malware running with kernel privileges may hide from the Memory Process File System at the moment<br />
<br /></div>
<div>
<span style="font-size: large;">Acquiring Memory Dumps</span></div>
<div>
If you have access to a PCILeech supported FPGA device this is the preferred acquisition method. Insert the PCILeech FPGA device in your target computer. Then identify the size of the physical memory address space. This is likely to be slightly larger than the amount of RAM in the computer. Do this by running the command "pcileech.exe probe". This will give an output similar to the one below. Here the maximum address 0x21E5FFFFF is important.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFj8RhTsu2Gf32zJQMeVCS-mRXqXEnNcZTmTOgkmMaYx7NpNcd_T3b1cLOYXkJ4ngoU6HAW4RZw894jo3njlm2f1sb5ljryOca6G2T3npp2hzZpcIMAVIxCS54Lb6JvBfuDOsV1CIPky7X/s1600/blog_probe.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="281" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFj8RhTsu2Gf32zJQMeVCS-mRXqXEnNcZTmTOgkmMaYx7NpNcd_T3b1cLOYXkJ4ngoU6HAW4RZw894jo3njlm2f1sb5ljryOca6G2T3npp2hzZpcIMAVIxCS54Lb6JvBfuDOsV1CIPky7X/s640/blog_probe.gif" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Enumerating target system memory with a PCILeech FPGA device (PCIeScreamer in image).</td></tr>
</tbody></table>
</div>
<div>
Now we are able to dump the memory. Dump using "pcileech.exe dump -v -force -max 0x21E5FFFFF -out my_dump.raw". The -force option tells PCILeech not to abort when it encounters unreadable memory, such as memory holes between 3-4 GB or memory protected with Vt-d.</div>
<div>
<br /></div>
<div>
</div>
<div>
DumpIt is a software one-click dumper that is easy to run. The older MoonSols DumpIt may however create corrupt memory dumps on more recent Windows 10 computers, hence it's recommended to use the more recent up-to-date Comae DumpIt or WinPMEM on Windows 10.<br />
<br />
<a href="https://www.comae.com/" target="_blank">Comae DumpIt</a> may be run in an elevated command prompt with the /t raw switch to create raw memory dumps. "DumpIt.exe /t raw dump.raw"<br />
<br />
WinPMEM is a software memory dumping utility which is part of the Google Rekall memory forensics project on Github. You'll find a signed WinPMEM to download <a href="https://github.com/google/rekall/releases/tag/v1.5.1" target="_blank">here</a>. Execute, from an administrator elevated command prompt, "winpmem-2.1.post4.exe --format raw -o dump-pmem.raw.aff4". WinPMEM will dump to an .aff4 volume. Open this volume in 7-Zip and unpack the memory dump named PhysicalMemory.<br />
<br />
<span style="font-size: large;">Reading and Writing to Memory</span><br />
Reading and writing to virtual memory can be done in two ways. Either open the vmem file in the process directory, which contains the whole process virtual memory, or open a file in the vmemd directory which contains individual virtual memory mappings. The memory map is found in the map file.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeF3QQcyfRYi2NIbRjyTQsZZNDeqAfOvbsqUMb4KvXrOHi4vCvbz-wzlBlzqsG5o6CSwoV7INtt5gR2BFhtH-rrO5DFefJLEa8DvjZR8QRzg-t6dIIL_bAV1QiTodLolvLTMNltNL-Fx5P/s1600/blog_memmap.GIF" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="208" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeF3QQcyfRYi2NIbRjyTQsZZNDeqAfOvbsqUMb4KvXrOHi4vCvbz-wzlBlzqsG5o6CSwoV7INtt5gR2BFhtH-rrO5DFefJLEa8DvjZR8QRzg-t6dIIL_bAV1QiTodLolvLTMNltNL-Fx5P/s640/blog_memmap.GIF" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The memory map, vmem memory file and vmemd directory for the Notepad process.</td></tr>
</tbody></table>
If using PCILeech FPGA with a hardware based target the virtual memory files will be writable. Please note that writes go the the corresponding physical memory which may be shared between multiple processes! As an example, alterations written to ntdll.dll in one process is likely to be written into the ntdll.dll of all processes.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMKgUcVz0sn-Tqxu1HAqJ27ZTl7mJgPX8jtOPd0H9YGRniZihxJ4zrUGNwFkT-uFAzGMAX6eiow-gxpO7bl2oHkWi9hkgoK15F8IgCbII6fwi1i1ePDrIxvbV0Bia-5qpxKKOxMa8SuH8j/s1600/blog_hexedit.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMKgUcVz0sn-Tqxu1HAqJ27ZTl7mJgPX8jtOPd0H9YGRniZihxJ4zrUGNwFkT-uFAzGMAX6eiow-gxpO7bl2oHkWi9hkgoK15F8IgCbII6fwi1i1ePDrIxvbV0Bia-5qpxKKOxMa8SuH8j/s640/blog_hexedit.gif" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Looking at the notepad.exe virtual memory in hexedit in Ubuntu WSL.</td></tr>
</tbody></table>
When reading to, or writing to a kernel address, for example 0xFFFFF801'10000000 please open the vmem file in your favorite hex editor and navigate to the address as seen when cutting away the first four F's. That is 0xF801'1000000 in the example from above. The topmost 16-bits are what is called sign-extended so this won't matter. It's still the same address. This is done since Windows don't support file sizes above 63-bits (file size becomes negative).<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi048ghXDS2Egl5V-8aeGJwpqhwtHn9MgoZ9O3Dic-EhNqUPycOz_sAXV5WkctwMEM-alpWe6-W36Zf4iZbNIQ96zHzsPNFXse98sROb62F3MnWeq-tzSm5gZxr0w6MTD1BTdT5PeAf0jhX/s1600/blog_eprocess_system.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="216" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi048ghXDS2Egl5V-8aeGJwpqhwtHn9MgoZ9O3Dic-EhNqUPycOz_sAXV5WkctwMEM-alpWe6-W36Zf4iZbNIQ96zHzsPNFXse98sROb62F3MnWeq-tzSm5gZxr0w6MTD1BTdT5PeAf0jhX/s640/blog_eprocess_system.gif" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Looking at notepads EPROCESS struct in kernel memory. Note that we look at it in the System process (PID 4) and that the leading four (4) FFFF are skipped from the address.</td></tr>
</tbody></table>
<span style="font-size: large;"></span><br />
<span style="font-size: large;">Special Files</span><br />
The virt2phys file is a special always writable file. The first 64-bit value contains the virtual address and the second 64-bit value is the corresponding physical address. Whenever a new virtual address gets written the physical address will update.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjchCLJBaLEEBIRTWCzLDozHbZLRRBBK3o3RcETs_otqQH2F7VUyNPxkVQEd27zIOgtOFYle_u6U9wm5dNeA1KgrDqIuvoY-8vsCQLHfVUmbH54lHLXt3_fpx2gBhNCKkY7RJ-woPpVIsMV/s1600/blog_virt2phys.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="70" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjchCLJBaLEEBIRTWCzLDozHbZLRRBBK3o3RcETs_otqQH2F7VUyNPxkVQEd27zIOgtOFYle_u6U9wm5dNeA1KgrDqIuvoY-8vsCQLHfVUmbH54lHLXt3_fpx2gBhNCKkY7RJ-woPpVIsMV/s640/blog_virt2phys.gif" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">notepads 0x7FF660160000 virtual address maps to the physical address 0x14C40D000.</td></tr>
</tbody></table>
<br />
The win-process file contains the address of the EPROCESS kernel struct that belongs to the process. Since the EPROCESS struct resides in kernel memory one must look for this one in the System (PID 4) process virtual memory.<br />
<br />
The win-peb file contains the address of the PEB (Process Environment Block), which resides in process memory. The win-entry contains the process entry point, win-modules the modules (.dlls) in the PEB Ldr list.<br />
<br />
The pml4 file contains the physical address of the PML4 a.k.a. the CR3 register a.k.a. the Page Directory Base.<br />
<br />
<span style="font-size: large;">The Future</span><br />
The future of the Memory Process File System will depend on how useful it is. If useful I see a lot of possibilities, somewhat limited by time available to implement them. The Memory Process File System is not meant to become a serious forensic file system, that space will continue to be reserved by industry standard tools, such as the excellent <a href="http://www.volatilityfoundation.org/" target="_blank">Volatility</a>. The Memory Process File System should nevertheless provide convenient easy-to use access if performing a quick analysis, or be helpful when patching live processes via DMA.<br />
<br />
Comments, suggestions and ideas are very welcome. <a href="https://github.com/ufrisk/pcileech">PCILeech</a> in both source and binary distributions is found on Github. Also check out <a href="https://twitter.com/UlfFrisk" target="_blank">Twitter</a> for updated information and announcements.<br />
<br />
<span style="font-size: large;">Updates</span><br />
Updated reference to Comae DumpIt.<br />
The Memory Process File System is now released as a stand-alone separate project <a href="https://github.com/ufrisk/MemProcFS" target="_blank">here</a>.<br />
</div>
Ulf Friskhttp://www.blogger.com/profile/09730439109623573624noreply@blogger.comtag:blogger.com,1999:blog-1551223415848378388.post-64381791550245188372017-08-30T10:53:00.000+02:002017-08-30T10:53:02.949+02:00Attacking UEFIUnlike <a href="http://blog.frizk.net/2016/12/filevault-password-retrieval.html" target="_blank">macs</a> many PCs are likely to be vulnerable to pre-boot Direct Memory Access (DMA) attacks against UEFI. If an attack is successful on a system configured with secure boot - then the chain of trust is broken and secure boot becomes insecure boot.<br />
<div>
<br /></div>
<div>
If code execution is gained before the operating system is started further compromise of the not yet loaded operating system may be possible. As an example it may be possible to compromise a Windows 10 system running Virtualization Based Security (VBS) with Device Guard. This have already been researched by <a href="https://twitter.com/d_olex/status/898365202936119296" target="_blank">Dmytro Oleksiuk</a>.</div>
<div>
<br /></div>
<div>
This post will focus on attacking UEFI over DMA and not potential further compromises of the system.<br />
<br />
<span style="font-size: large;">What is UEFI?</span><br />
UEFI is short for <i>Unified Extensible Firmware Interface</i>. It is the firmware that is running on the computer before the operating system is booted. UEFI is responsible for detecting memory, disks and other hardware required to boot the operating system. UEFI is a small operating system in itself. It's also sometimes a bit sloppily called the BIOS.<br />
<br />
<span style="font-size: large;">The Targets</span><br />
A brand new Intel NUC i3 "Kaby Lake" purchased in June. 8GB RAM, Win10 1703 with Secure Boot, Bitlocker+TPM, Virtualization Based Security (VBS) Device Guard is enabled. BIOS revision: BNKBL357.86A.0036.2017.0105.1112. DMA access via internal M.2 slot.<br />
<br />
An older Lenovo T430, 8GB RAM, Win10 1703 with Secure Boot, Bitlocker+TPM, Virtualization Based Security (VBS) Device Guard is enabled. DMA access via ExpressCard slot.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVbLRfgBuzZDcoAMjeXC2ytiKzb9cJNbO5V4H9k_YUx3XHtAih3sB8glKSWptFskcVo1WUxDm6cOA5CEFy81zrr6g8mY7NjbZget9MQwkRt_WibLmei7bw7KMMJfmTPz2zk_XWGSFKkCm6/s1600/blog_victims.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="178" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVbLRfgBuzZDcoAMjeXC2ytiKzb9cJNbO5V4H9k_YUx3XHtAih3sB8glKSWptFskcVo1WUxDm6cOA5CEFy81zrr6g8mY7NjbZget9MQwkRt_WibLmei7bw7KMMJfmTPz2zk_XWGSFKkCm6/s640/blog_victims.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">T430 to the left, NUC to the right.</td></tr>
</tbody></table>
<span style="font-size: large;">The Problem</span><br />
The root problem is that many UEFIs still do not protect themselves against DMA attacks, despite the hardware (VT-d/IOMMU) to do so being included in all CPUs for many years. The screenshot below shows PCILeech first searching the memory of a target computer over DMA trying to find where to hook into UEFI. Once inside it's easy to dump memory (also shown) and do other evilness - such as executing arbitrary code despite secure boot being enabled.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjypwhXUD9aEKim4QjGKCuNhlCXo3Z8Lybe5xrfRnkWVLe-jStYlA0-vB6JS93_f54L79NRTnuISxRQ4sSNkdipRAiPnmUVH5RrhGDemrMk1XEGenWwjXbnRE5ckC5mLFboj82uB3nTgp3R/s1600/blog_dump.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="302" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjypwhXUD9aEKim4QjGKCuNhlCXo3Z8Lybe5xrfRnkWVLe-jStYlA0-vB6JS93_f54L79NRTnuISxRQ4sSNkdipRAiPnmUVH5RrhGDemrMk1XEGenWwjXbnRE5ckC5mLFboj82uB3nTgp3R/s640/blog_dump.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Loading a PCILeech module into UEFI, dumping the memory and unloading the module.</td></tr>
</tbody></table>
<span style="font-size: large;">The Attack</span><br />
Taking control is a simple matter of finding the correct memory structures and overwriting them if DMA access is allowed. This process is automated with PCILeech. It's possible to automatically search for the memory address of the EFI system table <i>"IBI SYST"</i> - or even better specify it directly to PCILeech. The EFI System Table contains the location of the EFI boot services table <i>"BOOTSERV"</i> which contains many useful function pointers. The boot services functions are useful for both hooking and also calling into from our implanted module.<br />
<br />
In the example below the boot services function SignalEvent() is hooked. Once the PCILeech "kernel" module for UEFI is inserted it's possible to use it to dump memory and execute code - just as any normal PCILeech kernel module. In the example below the PCILeech UEFI implant uefi_textout is called multiple times. The output is printed on the screen of the victim computer.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjubJd9lu5Uhbex9QvIjN4KCjTHDm9QZ1pgDMHdTEhjJNMgzZbGtSzRKb0kctmKnNCYQ2C5ljYdVnEGRcPTaN4Sic8yZGoh_4WwSMJlcrhSx4D8iru_hya9gRN1ja8xgwaEKmLW7uhqTG12/s1600/blog_insert.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="348" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjubJd9lu5Uhbex9QvIjN4KCjTHDm9QZ1pgDMHdTEhjJNMgzZbGtSzRKb0kctmKnNCYQ2C5ljYdVnEGRcPTaN4Sic8yZGoh_4WwSMJlcrhSx4D8iru_hya9gRN1ja8xgwaEKmLW7uhqTG12/s640/blog_insert.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The text HELLO FROM EVIL PCILEECH IMPLANT !!! is printed multiple times after the PCILeech module for UEFI have been inserted.</td></tr>
</tbody></table>
Once the attack was completed the kmdexit command was issued to PCILeech and the UEFI implant was unloaded. In this case Windows will start booting as shown below. If targeting the operating system loaded it's better to hook ExitBootServices() - which is called by the EFI based operating system loader when the operating system is taking over control of the computer from UEFI. At this point in time it will be possible for malicious code to modify the operating system loader.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5Km3aJcwQHUjkwD2GK0v_6VvrIQ42t1t5sK6nDXRDjgiFL55mkuvnwk5CrFoar5DBOrdqSITed5NQYtFZlEMqJCEJmBmsC0CbU_rMNapWF16YDc1xtQ9Ooc9bF44Yf1whkZ3ZIaA_doTJ/s1600/blog_winboot.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="328" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5Km3aJcwQHUjkwD2GK0v_6VvrIQ42t1t5sK6nDXRDjgiFL55mkuvnwk5CrFoar5DBOrdqSITed5NQYtFZlEMqJCEJmBmsC0CbU_rMNapWF16YDc1xtQ9Ooc9bF44Yf1whkZ3ZIaA_doTJ/s640/blog_winboot.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Windows is booting normally once the PCILeech UEFI module is unloaded.</td></tr>
</tbody></table>
<span style="font-size: large;">Can I try it myself?</span><br />
Absolutely! The code is available as a part of the open source <a href="https://github.com/ufrisk/pcileech" target="_blank">PCILeech Direct Memory Access Attack Toolkit</a> on Github.<br />
<br />
<span style="font-size: large;">Conclusions</span><br />
UEFI DMA attacking with PCILeech is now public, inexpensive and easy to perform. DMA attacks agaunst UEFI are no longer theoretical.<br />
<br />
Vendors should enable VT-d to protect against DMA attacks.<br />
<br />
Further compromise of the operating system may be possible. It may not be possible to rely on Virtualization Based Security if having a vulnerable UEFI.</div>
Ulf Friskhttp://www.blogger.com/profile/09730439109623573624noreply@blogger.com0tag:blogger.com,1999:blog-1551223415848378388.post-92058090085173966002017-01-11T10:33:00.001+01:002017-01-11T10:33:48.278+01:00Attacking UEFI Runtime Services and LinuxAttackers with physical access are able to attack the firmware on many fully patched computers with DMA - Direct Memory Access. Once code execution is gained in UEFI/EFI Runtime Services it is possible to use this foothold to take control of a running Linux system.<br />
<br />
The Linux 4.8 kernel fully randomizes the physical memory location of the kernel. There is a high likelyhood that the kernel will be randomized above 4GB on computers with sufficient memory. This means that DMA attack hardware only capable of 32-bit addressing (4GB), such as <a href="https://github.com/ufrisk/pcileech" target="_blank">PCILeech</a>, cannot reach the Linux kernel directly.<br />
<br />
Since the EFI Runtime Services are usually located below 4GB they offer a way into Linux on high memory EFI booting systems.<br />
<br />
Please see the video below for an example of how an attack may look like.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i9.ytimg.com/vi/PiUVRHYTDUg/default.jpg?sqp=COzz18MF&rs=AOn4CLCyMFsU7Yclnh_lzpovlhwpBsYr1g" frameborder="0" height="360" src="https://www.youtube.com/embed/PiUVRHYTDUg?feature=player_embedded" width="640"></iframe></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<span style="font-size: large;">What are the EFI Runtime Services?</span><br />
UEFI on PCs, EFI on macs, is the modern day BIOS. UEFI is short for Unified Extensible Firmware Interface. UEFI is responsible for detecting hardware and configuring devices so that the control can be handed over to the operating system that should be loaded.<br />
<br />
Two main components of UEFI are the Boot Services and the Runtime Services. Very early on the operating system calls ExitBootServices. After this Boot Services are no longer in use.<br />
<br />
The EFI Runtime Services lives on even after the operating system is loaded and running though. They provide various functionality that the operating system can call into. The UEFI specification specifies a fixed set of functions that the Runtime Services should provide to the operating system, as seen below.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrQIZxltjQo2kSnP9R92r4hF3J2kTE6v13oV-JkcsygitpMPOUez7nHMR8ymyuztMOAMoIjfkFU4QMHsUeYiOqxX5VfhXLv-qN8qLsExROBGlcoXP-8BMA6ZbQnsVLwHvjU1b02Y2P46hP/s1600/uefi_manual.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrQIZxltjQo2kSnP9R92r4hF3J2kTE6v13oV-JkcsygitpMPOUez7nHMR8ymyuztMOAMoIjfkFU4QMHsUeYiOqxX5VfhXLv-qN8qLsExROBGlcoXP-8BMA6ZbQnsVLwHvjU1b02Y2P46hP/s640/uefi_manual.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The UEFI Runtime Services according to the UEFI specification.</td></tr>
</tbody></table>
Initially the location of the Runtime Services functionality is communicated to the operating system via the Runtime Services table. The physical address for each function is 64-bit/8-byte long and is stored in memory as little endian. The memory addresses are however in the 32-bit range on all systems looked at so far. The physical memory addresses also seems to be completely static, i.e. no randomization occurs between reboots.<br />
<br />
Linux later on maps these addresses into virtual address space and overwrites the initial addresses in the table with the corresponding virtual addresses. An example of the initial table and the table altered by Linux is shown side-by-side below.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRxCVM81oAIyWV2hraMAypFbRhSSPYdrfYTEvsc5DhazfBQHJjcsqZeIG6t1Cpa2UN7Hsg8orghnxxdNpDfBLHpgAMlqjgsq7cFa9sy3nepW0my2hqSmB2TvIxmcXz4GDaPhGcjfywRdb5/s1600/runtserv_before_after.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="154" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRxCVM81oAIyWV2hraMAypFbRhSSPYdrfYTEvsc5DhazfBQHJjcsqZeIG6t1Cpa2UN7Hsg8orghnxxdNpDfBLHpgAMlqjgsq7cFa9sy3nepW0my2hqSmB2TvIxmcXz4GDaPhGcjfywRdb5/s640/runtserv_before_after.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The EFI Runtime services table, original to the left, modified by Linux to the right.</td></tr>
</tbody></table>
<span style="font-size: large;">The Attack</span><br />
What if we overwrite the EFI Runtime Services with our own code by using DMA? Or even better what if we overwrite function pointers in the EFI Runtime Services table to point to previously inserted attack code?<br />
<br />
Code execution is gained on the target system when the operating system calls into EFI Runtime Services - for example whenever it's reading an EFI variable. Code execution is gained in a special context, in which pages in lower memory are mapped 1:1 between virtual and physical addresses. The Linux kernel is reachable at its normal virtual addresses. Execution is gained in ring0 / supervisor mode.<br />
<br />
It is however not possible to call into all functions in the Linux kernel. Some functions will fail due to the special EFI context Linux have set up for Runtime Services to execute in. The way around this is to patch a "random" hook function in the Linux kernel. When a "normal" kernel thread hits that hook "normal" kernel code execution is gained...<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN2Q-OO8Z60XM7m60S7N5u4V3Mm-Kp5XX0HTlrZURAg8YRIgxpKZQG3v4YcickmEWfHn3D84z3c4v4I31PNm_NOg8B6fCQCYGP4XlbL5jGG2oYYS2h_sYk6dbOlITcY70YZYeGIXdH9wjJ/s1600/efi_rt_linux.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="478" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN2Q-OO8Z60XM7m60S7N5u4V3Mm-Kp5XX0HTlrZURAg8YRIgxpKZQG3v4YcickmEWfHn3D84z3c4v4I31PNm_NOg8B6fCQCYGP4XlbL5jGG2oYYS2h_sYk6dbOlITcY70YZYeGIXdH9wjJ/s640/efi_rt_linux.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The target system running Ubuntu 16.10 with the PCILeech attack hardware connected (to the left). Detailed view of PCILeech (to the right).</td></tr>
</tbody></table>
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">The Targets</span><br />
This have been tested on a Lenovo T430 with 8GB memory and on an Intel NUC Skull Canyon with 32GB memory. The ExpressCard slot was used to gain DMA access on the T430 On the NUC the Thunderbolt mode was set to "Legacy" in the "BIOS" settings - enabling DMA access via Thunderbolt3/USB-C.<br />
<br />
The T430 is very straight forward. Just insert the PCILeech device and issue the <i>pcileech.exe kmdload -kmd linux_x64_efi</i> command. PCILeech will search for the EFI Runtime Services table and hook it. The user will be asked to do something resulting in a call to the Runtime Services - triggering the hook.<br />
<br />
The NUC is different. PCILeech will encounter unreadable memory before the target is found and will fail. Luckily the location of the Runtime Services table is static and won't change between reboots. This goes for all tested systems. The easiest way to find out the location is by USB-booting a live Linux in EFI mode on the same system, or on a similar system. Once booted issue the command <i>cat /sys/firmware/efi/runtime</i> to see the physical address of the Runtime Services table. Once the address is known as <i>0x3b294e18</i> we may issue the command <i>pcileech.exe kmdload -kmd linux_x64_efi -min 0x3b294000 -max 0x3b295000 </i>.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBwiJnVz0kjOjYuwicjQrLl3f1pXRPml8BfYqDO9ZsEEGyV2zJ1ZOyRIPPMy8TUcm5ESIChi67cWw5blFQpwTZEohwFww57qcjBftd3pU0t-TUfLjSFwVprlQAw7apWPSg4cNSurfaplgV/s1600/efi_rt_linux_nuc.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="258" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBwiJnVz0kjOjYuwicjQrLl3f1pXRPml8BfYqDO9ZsEEGyV2zJ1ZOyRIPPMy8TUcm5ESIChi67cWw5blFQpwTZEohwFww57qcjBftd3pU0t-TUfLjSFwVprlQAw7apWPSg4cNSurfaplgV/s640/efi_rt_linux_nuc.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td class="tr-caption" style="font-size: 12.8px;">The NUC setup. Displaying the NUC EFI Runtime Services table on the Surface attack computer.</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Notes</span><br />
To try this out yourself please have a look at <a href="https://github.com/ufrisk/pcileech/" target="_blank">PCILeech at Github</a>.<br />
<br />
The attack is not 100% stable in the sense that the exploit always works. Sometimes the search for the Runtime Services table will fail and sometimes it's hard to trigger a call into the Runtime Services. Target system crashes are rare though.<br />
<br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Conclusions</span><br />
Linux 4.8 based operating systems, such as Ubuntu 16.10, are no longer completely secure from PCILeech.<br />
<br />
Even though your laptop may not have an ExpressCard slot chances are that it will have a mini-PCIe or M.2 slot for a WiFi card if the back cover is unscrewed ...<br />
<br />
Operating systems cannot protect themselves from DMA attacks by putting everything of interest in memory above the 32-bit / 4GB address limit. 32-bit hardware such as PCILeech may attack firmware code and data residing below 4GB. Other malicious hardware may also reach into 64-bit address space.<br />
<br />
Operating systems should protect both themselves and firmware, such as the Runtime Services, from malicious devices by enabling VT-d.<br />
<br />Ulf Friskhttp://www.blogger.com/profile/09730439109623573624noreply@blogger.comtag:blogger.com,1999:blog-1551223415848378388.post-11356848295545519402016-12-15T09:26:00.001+01:002017-03-30T20:32:32.432+02:00macOS FileVault2 Password RetrievalmacOS FileVault2 let attackers with physical access retrieve the password in clear text by plugging in a $300 Thunderbolt device into a locked or sleeping mac. The password may be used to unlock the mac to access everything on it. To secure your mac just update it with the December 2016 patches.<br />
<br />
Anyone including, but not limited to, your colleagues, the police, the evil maid and the thief will have full access to your data as long as they can gain physical access - unless the mac is completely shut down. If the mac is sleeping it is still vulnerable.<br />
<br />
Just stroll up to a locked mac, plug in the Thunderbolt device, force a reboot (ctrl+cmd+power) and wait for the password to be displayed in less than 30 seconds! Check out the demo video below:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/n_3eIFMR46Y/0.jpg" frameborder="0" height="360" src="https://www.youtube.com/embed/n_3eIFMR46Y?feature=player_embedded" width="640"></iframe></div>
<br />
<span style="font-size: large;">How is this possible?</span><br />
At the very core of this issue there are two separate issues.<br />
<br />
The first issue is that the mac does not protect itself against Direct Memory Access (DMA) attacks before macOS is started. EFI which is running at this early stage enables Thunderbolt allowing malicious devices to read and write memory. At this stage macOS is not yet started. macOS resides on the encrypted disk - which must be unlocked before it can be started. Once macOS is started it will enable DMA protections by default.<br />
<br />
The second issue is that the the FileVault password is stored in clear text in memory and that it's not automatically scrubbed from memory once the disk is unlocked. The password is put in multiple memory locations - which all seems to move around between reboots, but within a fixed memory range.<br />
<br />
This makes it easy to just plug in the DMA attack hardware and reboot the mac. Once the mac is rebooted the DMA protections that macOS previously enabled are dropped. The memory contents, including the password, is still there though. There is a time window of a few seconds before the memory containing the password is overwritten with new content.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEp_Ym6xW-YrOVgw_tODQhGpyRHAL04KFu_QVH9ZueJTYoQdw0Rr_S5Kw9uCQrqH0aAJzKWm141hed_kph-vBHt1pzeKsW-LppIsfAeeCg0to5VO8EA5wpfezTqWlnnUsMzPYAu0cpq4dE/s1600/mac_pcileech.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="370" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEp_Ym6xW-YrOVgw_tODQhGpyRHAL04KFu_QVH9ZueJTYoQdw0Rr_S5Kw9uCQrqH0aAJzKWm141hed_kph-vBHt1pzeKsW-LppIsfAeeCg0to5VO8EA5wpfezTqWlnnUsMzPYAu0cpq4dE/s640/mac_pcileech.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The PCILeech DMA attack hardware attached to a mac victim.</td></tr>
</tbody></table>
<span style="font-size: small;">After the PCILeech hardware is connected just run the <span style="font-family: inherit;"><i>mac_fvrecover</i></span> command on the attacker computer.</span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEje63ajYf2aQl3Q1WAyRurdJCbfWNjgPlIrfybs3zlRHrM9eXeRLUZW2xV_HZAn64j_o1srBsz5geIrAmwGBpWSHeOt3dnpU5R38Bv32NvVnvDDnhgB49XQLFns5jswMq3EiCbL-iL71VGX/s1600/fvrecover_cmd.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="318" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEje63ajYf2aQl3Q1WAyRurdJCbfWNjgPlIrfybs3zlRHrM9eXeRLUZW2xV_HZAn64j_o1srBsz5geIrAmwGBpWSHeOt3dnpU5R38Bv32NvVnvDDnhgB49XQLFns5jswMq3EiCbL-iL71VGX/s640/fvrecover_cmd.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Retrieving the FileVault password with PCILeech. The correct password is DonaldDuck.</td></tr>
</tbody></table>
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">In Details</span><br />
The password, when entered, is stored in memory as unicode. Every 2nd byte will be zero if a password consisting only of ascii characters is used. Enter a "random" phrase, not naturally occurring in memory, at the password promp<span style="font-family: inherit;">t. In this example the phrase <i>eerrbbnn</i> is used. In memory this is stored as <span style="font-family: "courier new" , "courier" , monospace;"><i>6500650072007200620062006e006e</i></span>.</span> Search for this using PCILeech and you'll notice that the phrase is stored in multiple memory locations as per the example below.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj82UXNPXLDWVRwCvQ5RyUhLPhHWUG-ALTLPzX3Ui-s8ceiAGKll_sIBzt_oUSdDwSz2O_WlyxvMbXxLzkdGaLoDd4F8jhZcBLyXGykvCuGU2kGoIbu-SfdriEzrjWpNSsGR3ScCd0oZvnb/s1600/fvrecover_search.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="326" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj82UXNPXLDWVRwCvQ5RyUhLPhHWUG-ALTLPzX3Ui-s8ceiAGKll_sIBzt_oUSdDwSz2O_WlyxvMbXxLzkdGaLoDd4F8jhZcBLyXGykvCuGU2kGoIbu-SfdriEzrjWpNSsGR3ScCd0oZvnb/s640/fvrecover_search.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Searching the mac memory for the test phrase eerrbbnn.</td></tr>
</tbody></table>
<br />
After finding the memory locations it's possible to have a look at it. One might have to re-attach the attack device to the mac if the first read fails.<br />
<br />
If the locations found are checked out the password will be clearly visible. In addition to this other signatures that may be scanned for are also found, s<span style="font-family: inherit;">uch as <span style="font-family: "courier new" , "courier" , monospace;"><i>phd0</i></span> at the</span> beginning of the memory page read.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_NEfr4vPo8SVbPF4E7-H6eyhkJ6MtPSXKMA9onII4AQZ2jTzP5CKAs458IREmvTfvJsckYoDcK-kSAKvwmsduOt1X4RMn4D-LyPMGEx-yJ7_bCFW4WPweh36RtUyXg8HiamRIT5vf75DZ/s1600/fvrecover_result.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="210" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_NEfr4vPo8SVbPF4E7-H6eyhkJ6MtPSXKMA9onII4AQZ2jTzP5CKAs458IREmvTfvJsckYoDcK-kSAKvwmsduOt1X4RMn4D-LyPMGEx-yJ7_bCFW4WPweh36RtUyXg8HiamRIT5vf75DZ/s640/fvrecover_result.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The phrase is clearly visible at the memory location.</td></tr>
</tbody></table>
<br />
<span style="font-size: large;">Can I try it out myself?</span><br />
Yes - Absolutely! Download <a href="https://github.com/ufrisk/pcileech" target="_blank">PCILeech from Github</a> and purchase the hardware. Password recovery have been tested and found to work on multiple macbooks and macbook airs (all with Thunderbolt 2). The attack is not tested on more recent macs with USB-C.<br />
<br />
Password recovery may fail if the user uses special (non ascii) characters in the password. In those cases a memory dump will be saved so that it can be manually searched for the password.<br />
<br />
Please note that trying this on other macs than your own might not be legal.<br />
<br />
<span style="font-size: large;">Other Notes</span><br />
Recovering the password is just one of the things that are possible unless the security update is applied. Since EFI memory can be overwritten it is possible to do more evil ...<br />
<br />
The disclosure timeline is as follows:<br />
<ul>
<li>End of July: Issue found.</li>
<li>August 5th: PCILeech <a href="https://www.youtube.com/watch?v=fXthwl6ShOg" target="_blank">presented</a> and released at DEF CON 24. (FileVault issue not mentioned).</li>
<li>August 15th: Apple notified.</li>
<li>August 16th: Apple confirmed issue and asked to hold off disclosure.</li>
<li>December 13th: Apple released macOS 10.12.2 which contains the security update. At least for some hardware - like my MacBook Air.</li>
</ul>
<div>
<br /></div>
<span style="font-size: large;">Conclusion</span><br />
The solution Apple decided upon and rolled out is a complete one. At least to the extent that I have been able to confirm. It is no longer possible to access memory prior to macOS boot. The mac is now one of the most secure platforms with regards to this specific attack vector.<br />
<br />
<b>Update:</b><br />
This issue is classified as: CVE-2016-7585Ulf Friskhttp://www.blogger.com/profile/09730439109623573624noreply@blogger.comtag:blogger.com,1999:blog-1551223415848378388.post-69714627031451668942016-11-23T00:07:00.000+01:002020-04-09T12:05:00.343+02:00Windows 10 KASLR Recovery with TSXIt is possible to break Kernel Address Space Layout Randomization (KASLR) on modern operating systems running on modern x86 CPU's.<br />
<div>
<br />
<div>
One possible way of doing this is to time certain operations when using the Transactional Synchronization Extensions (TSX) instruction set. TSX makes it possible for unprivileged user mode programs to detect whether certain virtual memory pages are mapped or unmapped in kernel mode. It is also possible to detect whether a kernel page is executable or not.</div>
<div>
<br /></div>
<div>
It has been known since at least 2014 that timing attacks against KASLR, using TSX, is possible. This was discussed by Rafal Wojtczuk from Bromium Labs in the blog post <i><a href="https://labs.bromium.com/2014/10/27/tsx-improves-timing-attacks-against-kaslr/" rel="nofollow" target="_blank">TSX improves timing attacks against KASLR</a></i>. The technique was popularized and presented at Black Hat US-16 by Yeongjin, Sangho, and Taesoo from Georgia Institute of Technology. Their <a href="https://www.blackhat.com/us-16/briefings.html#breaking-kernel-address-space-layout-randomization-kaslr-with-intel-tsx" rel="nofollow" target="_blank">presentation and white paper</a> is found on the Black Hat site. Example <a href="https://github.com/sslab-gatech/DrK" rel="nofollow" target="_blank">code for Linux</a> was published on Github after the talk.</div>
<div>
<br /></div>
<div>
Since no example code was published for Windows I decided to look into this to see if I could make the technique work reliably on Windows as well. The result is presented in this blog post and the resulting code is found my my <a href="https://github.com/ufrisk/kaslrfinder" target="_blank">Github as kaslrfinder</a>.</div>
</div>
<div>
<br /></div>
<div>
<span style="font-size: large;">Test System</span><br />
<span style="font-family: inherit;">I used my NUC to develop and test kaslrfinder. It is the only system capable of TSX I have access to. It also have plenty of memory and an USB-C/Thunderbolt3 port. This made development easy since I could use <a href="https://github.com/ufrisk/pcileech/" target="_blank">PCILeech</a> to query the kernel for addresses over Direct Memory Access (DMA).</span><br />
<br />
<ul>
<li>Intel NUC Skull Canyon with a Skylake i7 CPU. 32GB RAM. M.2 SSD.</li>
<li>Windows 10 Enterprise version 1607.</li>
<li>No Virtualization Based Security (VBS).</li>
</ul>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIGsjwCDKOZxHhrw1wNZHnBQ7i8PkokWNZYUUIE_Npfw3xAtn1RwnrL1jUKIU1Oh2dbH_QemVuHhkERpVmjJ21qAouNyqXsA0BTZn_cXXfFpavfl_vZG-VXSrG7We05skOlFtZFVbmM7oM/s1600/kaslr_nuc.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="377" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIGsjwCDKOZxHhrw1wNZHnBQ7i8PkokWNZYUUIE_Npfw3xAtn1RwnrL1jUKIU1Oh2dbH_QemVuHhkERpVmjJ21qAouNyqXsA0BTZn_cXXfFpavfl_vZG-VXSrG7We05skOlFtZFVbmM7oM/s640/kaslr_nuc.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The NUC Skull Canyon test system. PCILeech connected via Apple USB-C to Thunderbolt2 adapter.</td></tr>
</tbody></table>
<span style="font-size: large;"><br />The Kernel</span></div>
<div>
The Windows 10 kernel is loaded into consecutive large (2MB) pages in the range <span style="font-family: "courier new" , "courier" , monospace;">0xFFFFF80000000000-0xFFFFF803FFFFFFFF</span>. The location is randomized. In total there are 13 bits of entropy, or 8192 possible locations. The Windows 10 kernel is further randomized within the large (2MB) pages.<br />
<br /></div>
<div>
The table below contains ten (10) randomly sampled ntoskrnl.exe base addresses. The addresses are shown both in hexadecimal and binary. The columns in the binary denotes changes in paging levels.</div>
<div>
<br /></div>
<div>
<div>
<b><span style="font-family: "courier new" , "courier" , monospace;">0xFFFFF800B2877000 </span></b><b><span style="font-family: "courier new" , "courier" , monospace;">1111111111111111 111110000 000000010 110010100 001110111 000000000000</span></b></div>
<div>
<b><span style="font-family: "courier new" , "courier" , monospace;">0x</span></b><b><span style="font-family: "courier new" , "courier" , monospace;">FFFFF801B2A19000 </span></b><b><span style="font-family: "courier new" , "courier" , monospace;">1111111111111111 111110000 000000110 110010101 000011001 000000000000</span></b></div>
<div>
<b><span style="font-family: "courier new" , "courier" , monospace;">0x</span></b><b><span style="font-family: "courier new" , "courier" , monospace;">FFFFF8013DC05000 </span></b><b><span style="font-family: "courier new" , "courier" , monospace;">1111111111111111 111110000 000000100 111101110 000000101 000000000000</span></b></div>
<div>
<b><span style="font-family: "courier new" , "courier" , monospace;">0x</span></b><b><span style="font-family: "courier new" , "courier" , monospace;">FFFFF8010A81B000 </span></b><b><span style="font-family: "courier new" , "courier" , monospace;">1111111111111111 111110000 000000100 001010100 000011011 000000000000</span></b></div>
<div>
<b><span style="font-family: "courier new" , "courier" , monospace;">0x</span></b><b><span style="font-family: "courier new" , "courier" , monospace;">FFFFF8003FE12000 </span></b><b><span style="font-family: "courier new" , "courier" , monospace;">1111111111111111 111110000 000000000 111111111 000010010 000000000000</span></b></div>
<div>
<b><span style="font-family: "courier new" , "courier" , monospace;">0x</span></b><b><span style="font-family: "courier new" , "courier" , monospace;">FFFFF8014B21F000 </span></b><b><span style="font-family: "courier new" , "courier" , monospace;">1111111111111111 111110000 000000101 001011001 000011111 000000000000</span></b></div>
<div>
<b><span style="font-family: "courier new" , "courier" , monospace;">0x</span></b><b><span style="font-family: "courier new" , "courier" , monospace;">FFFFF80065891000 </span></b><b><span style="font-family: "courier new" , "courier" , monospace;">1111111111111111 111110000 000000001 100101100 010010001 000000000000</span></b></div>
<div>
<b><span style="font-family: "courier new" , "courier" , monospace;">0x</span></b><b><span style="font-family: "courier new" , "courier" , monospace;">FFFFF8020D47F000 </span></b><b><span style="font-family: "courier new" , "courier" , monospace;">1111111111111111 111110000 000001000 001101010 001111111 000000000000</span></b></div>
<div>
<b><span style="font-family: "courier new" , "courier" , monospace;">0x</span></b><b><span style="font-family: "courier new" , "courier" , monospace;">FFFFF803F0486000 </span></b><b><span style="font-family: "courier new" , "courier" , monospace;">1111111111111111 111110000 000001111 110000010 010000110 000000000000</span></b></div>
<div>
<b><span style="font-family: "courier new" , "courier" , monospace;">0x</span></b><b><span style="font-family: "courier new" , "courier" , monospace;">FFFFF80066203000 </span></b><b><span style="font-family: "courier new" , "courier" , monospace;">1111111111111111 111110000 000000001 100110001 000000011 000000000000</span></b></div>
</div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">The table makes it clear that while the kernel is mapped into large pages its base address is randomized down to 4kB. Windows randomizes the kernel base address within the large pages. The table indicates, in the 5th binary column, that the kernel is randomized between 0-1MB within the large pages. Since the TSX attack technique is dependent on detecting whether a page is executable or not it cannot be used to further detect randomization within the large pages. KASLR entropy is however effectively reduced from 21 bits (13+8) to 8 bits/256 possibilities.</span></div>
<div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit; font-size: large;">The Modules</span><br />
<span style="font-family: inherit;">The kernel modules and drivers in Windows 10 version 1607 have been observed to load into standard (4kB) pages in the range </span><span style="font-family: "courier new" , "courier" , monospace;"><span style="font-family: inherit;">0xFFFFF80000000000-</span>0xFFFFF80FFFFFFFFF</span>. In previous Windows 10 versions the modules have been observed to load into the same more limited range as the kernel.<br />
<br />
The modules are randomized to an even 64kB (0x10000) boundary. This holds true for most, but not all, modules. The notable exceptions are win32k.sys and related modules which may be randomized outside this area. Special modules like hal.dll and ci.dll have been observed to load at 4kB, 0x1000, boundaries.<br />
<br />
<span style="font-size: large;">How is it possible?</span><br />
At the very core of the issue is the <span style="font-family: "courier new" , "courier" , monospace;">XBEGIN</span> and <span style="font-family: "courier new" , "courier" , monospace;">XEND</span> TSX instructions first introduced in some Haswell CPU's. Everything between <span style="font-family: "courier new" , "courier" , monospace;">XBEGIN</span> and <span style="font-family: "courier new" , "courier" , monospace;">XEND</span> is guaranteed to execute as an atomic operation. If some other thread interferes with memory while executing in an <span style="font-family: "courier new" , "courier" , monospace;">XBEGIN</span>-<span style="font-family: "courier new" , "courier" , monospace;">XEND</span> TSX block the TSX operation is guranteed to fail and any changes are rolled back and will become void. In fact if anything happens inside the <span style="font-family: "courier new" , "courier" , monospace;">XBEGIN</span>-<span style="font-family: "courier new" , "courier" , monospace;">XEND</span> block the operation will fail and execution will continue at the address of xabort specified in the <span style="font-family: "courier new" , "courier" , monospace;">XBEGIN</span> op. This includes page faults and various types of access violations.<br />
<br />
Normally the control is handed over to the kernel when a page fault or an access violation occurs. This is not the case when executing inside a TSX block. TSX is an unprivileged op that can be run in user mode. There are distinct timing differences between:<br />
<ul>
<li>Reading memory from a "forbidden" mapped kernel compared to an unmapped page.</li>
<li>Writing memory to a "forbidden" writable kernel page compared to an unmapped or read-only page.</li>
<li>Executing in a "forbidden" mapped executable kernel page compared a non executable or unmapped kernel page.</li>
</ul>
<div>
The addresses we wish to test must also be mapped into the page table of the current process. Windows, Linux and macOS all do this for performance reasons. It shall however be noted that Windows is not mapping hypervisor memory into the process page table. As a result of this it is not possible to disclose hypervisor memory addresses with this technique.</div>
<div>
<br /></div>
<br />
In the assembly code listing below only <span style="font-family: "courier new" , "courier" , monospace;">XBEGIN</span> is shown. <span style="font-family: "courier new" , "courier" , monospace;">XEND</span> is not required since the <span style="font-family: "courier new" , "courier" , monospace;">JMP rsi</span> is always guaranteed to fail.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHZTr_9SedpX5k7S6Q_tV8udW4jXqm9yAf4g-zytdXQIFMdLccT3cLcAQkZM-IjnJwoVg_PH5swqJP2wSKJTc_S-M5QFGlJ4tuGH933mL8uz_ahwws5FvqLhG32OhyWtVuhP72FAxgDVQz/s1600/kaslr_asm.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHZTr_9SedpX5k7S6Q_tV8udW4jXqm9yAf4g-zytdXQIFMdLccT3cLcAQkZM-IjnJwoVg_PH5swqJP2wSKJTc_S-M5QFGlJ4tuGH933mL8uz_ahwws5FvqLhG32OhyWtVuhP72FAxgDVQz/s1600/kaslr_asm.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Assembly listing the XBEGIN op, the JMP to the kernel address and the timing before and after measurements.</td></tr>
</tbody></table>
<span style="font-size: large;">How do I try it out?</span><br />
Download <a href="https://github.com/ufrisk/kaslrfinder" target="_blank">kaslrfinder from Github</a>.A CPU with the TSX instruction set is required. Kaslrfinder have only been tested on Skylake CPU's, but nothing indicates it shouldn't work on Kaby Lake CPU's and even on some Haswells if they have TSX enabled.<br />
<br />
Please note that kaslrfinder isn't 100% stable. It may at times fail to uncover the address of the kernel or the driver that is searched for. Timing measurement algorithms may be tweaked some more to improve accuracy in the future.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0vhzn3itEZpvNDGI615_J8neBZtJo9VGNVWs8acJQxdUzYh3pWQsevjgm0hLjghsnTPdMCmm2phE0F7uT8QuyXvSd6KIPyFnPCL6Og8KC9V4X7UTHx5Kt7hcLgGQi1YyiFru4eeh3nKFB/s1600/kaslr_kaslrfinder.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="227" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0vhzn3itEZpvNDGI615_J8neBZtJo9VGNVWs8acJQxdUzYh3pWQsevjgm0hLjghsnTPdMCmm2phE0F7uT8QuyXvSd6KIPyFnPCL6Og8KC9V4X7UTHx5Kt7hcLgGQi1YyiFru4eeh3nKFB/s640/kaslr_kaslrfinder.PNG" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">kaslrfinder locates the address of tcpip.sys in Windows 10 1607/14393 patched with the November 2016 patches.</td></tr>
</tbody></table>
<br />
<span style="font-size: large;">What can be done to mitigate?</span><br />
First please note that Kernel Address Space Randomization (KASLR) is an additional protection mechanism designed to make some kernel security issues harder to exploit. Finding out about kernel addresses won't do anything bad unless another security issue exists as well. kaslrfinder is not a malicious program. Please also note that it is not possible to use this technique to find out the address of the actual kernel itself for reasons discussed above.<br />
<br />
What can users do to mitigate? Answer: nothing.<br />
<br />
What can operating system vendors do? Probably several things, but finding a solution without any downsides will be hard. The best thing for now might actually be to do nothing. I plan to follow up on this in the RS2 Windows insider releases.<br />
<br />
It will be interesting to see how this will develop in the future. Will TSX be kept as-is?, will constant timing be guaranteed? or will the instruction behavior change in future CPU's?<br />
<br />
<b>Update:</b><br />
This should no longer work if post-meltdown attack patches have been applied to the operating system.<br />
Windows 10 have since 1903 altered the kernel alignment to be mapped into the base of a 2MB large page.<br />
<br /></div>
Ulf Friskhttp://www.blogger.com/profile/09730439109623573624noreply@blogger.comtag:blogger.com,1999:blog-1551223415848378388.post-5510881866166309592016-11-14T14:18:00.000+01:002016-11-14T14:18:36.127+01:00Disable Virtualization Based Security (VBS) on auto-booting systems<div class="MsoNormal">
<span lang="EN-US">I this post
I will show how it's possible to disable Windows 10 Virtualization Based
Security (VBS), Credential and Device Guard, by corrupting in-memory structures
prior to operating system boot.</span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
For this
attack to succeed the target computer must not be protected by a pre-boot
authentication password. Auto-booting Bitlocker with TPM and/or Network unlock
will work. The target computer is also required to have Direct Memory Access (DMA) capable ports and a
BIOS which will allow DMA before operating system boot.</div>
<div class="MsoNormal">
<span lang="EN-US"><br /></span></div>
<span lang="EN-US"><span style="font-size: large;">The Target</span></span><br />
<div class="MsoNormal">
</div>
<ul>
<li>Intel NUC
Skull Canyon with a Skylake i7 CPU. 32GB RAM. M.2 SSD.</li>
<li>Windows 10
Enterprise version 1607.</li>
</ul>
<br />
<div class="MsoNormal">
<span lang="EN-US">The NUC
have two options for DMA. The obvious choice is the USB-C port at the back which is capable of Thunderbolt 3. Thunderbolt is however secure by
default on the NUC - which is unfortunate for us. The Thunderbolt to
PCI-Express adapters I use also doesn't seem to be working prior to OS boot
even in the less secure Thunderbolt Legacy Mode.<o:p></o:p></span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span lang="EN-US">The second
option is to use one of the M.2 slots inside the NUC. M.2 is pretty much just
another from factor for PCI-Express. The M.2 slots are easily accessible;
just unscrew the bottom cover and open up the NUC. In this example I will
connect PCILeech to the available M.2 slot.<o:p></o:p></span></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjw_K201iMZar7IXcF1RG0mShvEZJHUA2UO2l0hk5ZIzbPVcc2fj63K4-uhuJ2BFcq-QyejU3rGiLcBW2R12tr33_eV9fr-kcD4YVta38cn48Pxk7TsXEo2AvFtscz-x1Jfmvr5yBRDGkTa/s1600/vbs_nuc.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="369" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjw_K201iMZar7IXcF1RG0mShvEZJHUA2UO2l0hk5ZIzbPVcc2fj63K4-uhuJ2BFcq-QyejU3rGiLcBW2R12tr33_eV9fr-kcD4YVta38cn48Pxk7TsXEo2AvFtscz-x1Jfmvr5yBRDGkTa/s640/vbs_nuc.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The M.2 to PCIe adapter and PCILeech mounted in one of the NUC M.2 slots.</td></tr>
</tbody></table>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Windows 10
Enterprise version 1607 was installed and the computer joined to an AD. Group Policies enabling virtualization based security with UEFI lock and Bitlocker with with secure boot validation was deployed to the system.</div>
<div class="MsoNormal">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGx_ZV18TxpI6XW7MsVuBF4n2VJmujPNZNiFqY1AMPkc0pL8xb4bJMbhHRPxagFt9heEPgFJ-q7oM0-XSO99eZJ-LxYN_ZQHSCZyZ-dtHIpr1D217lXGpaauwo_rTTf7szZRfd2ggcn9Zm/s1600/vbs_gpo.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGx_ZV18TxpI6XW7MsVuBF4n2VJmujPNZNiFqY1AMPkc0pL8xb4bJMbhHRPxagFt9heEPgFJ-q7oM0-XSO99eZJ-LxYN_ZQHSCZyZ-dtHIpr1D217lXGpaauwo_rTTf7szZRfd2ggcn9Zm/s640/vbs_gpo.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The relevant GPO VBS and Bitlocker settings deployed to Windows on the NUC.</td></tr>
</tbody></table>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
The result is that Windows 10 enabled the virtualization based security features. It's not possible to disable them by altering the GPO since the UEFI lock was configured. The test system have a BIOS password configured so it shouldn't be possible to get into the BIOS to disable it. The system should be secure even though auto-booting Bitlocker is deployed.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
If we check the task manager we see that the secure system is up and running as well as other secure processes such as LsaIso.</div>
<div class="MsoNormal">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgB6YW1mHIAXkfHq4EeM5-qy8gvdi_W0VeuD3f-2VYM9R8ZZwt847r5xZ-1Z_oV_DZHnDAQTFNeF3Xs0fU3D6zp3nWY5VJt_KqiV0kiRrHuk9vs0dzSyejxV2IrBMVaccRJDXGPMaBeV2cU/s1600/vbs_secure_system.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="443" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgB6YW1mHIAXkfHq4EeM5-qy8gvdi_W0VeuD3f-2VYM9R8ZZwt847r5xZ-1Z_oV_DZHnDAQTFNeF3Xs0fU3D6zp3nWY5VJt_KqiV0kiRrHuk9vs0dzSyejxV2IrBMVaccRJDXGPMaBeV2cU/s640/vbs_secure_system.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The Secure System including LsaIso is running on the NUC together with Bitlocker.</td></tr>
</tbody></table>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span style="font-size: large;">Overwriting the DMAR ACPI table</span></div>
<div class="MsoNormal">
The DMAR ACPI table is an in-memory reporting structure used to report the memory mapped location of the IOMMU to the operating system. DMAR is short for DMA Remapping. If the OS cannot read the configuration data from a valid DMAR table it cannot locate the IOMMU and cannot enable the virtualization features.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
The DMAR table is not protected or signed. It loads at a predictable memory address on the NUC (also on other tested hardware). It is possible to overwrite the DMAR table on the NUC before the OS boots.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
This attack was discussed on a theoretical level already back in 2009 in the paper <a href="http://invisiblethingslab.com/resources/misc09/Another%20TXT%20Attack.pdf"><i>Another Way to Circumvent Intel® Trusted Execution Technology</i></a> by Rutkowska et al.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
It's possible to search for the DMAR table in memory by using PCILeech since it's starting with the signature DMAR. It turns out that while entirely possible to do so it was a bit problematic on the tested hardware. When PCILeech encounters unreadable memory it needs to be power-cycled before able to read memory again. It was easier to boot into Ubuntu on an USB stick and check the location of the DMAR table with the dmesg command.</div>
<div class="MsoNormal">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVoHgQXF2j0TpXLv7oS8ZtU-oIebHDGOh_rOZAba4RbOxsuuGJ4L9D848B73X5dc3rSDBXDjn4DrLXvs6rCHSSDVWlNBahC60lVoZum3ZU_Ke9y5QLRzRUs4TxEuBaTCIVoP0Ejhyphenhyphen1ihe2/s1600/vbs_dmar_linux.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVoHgQXF2j0TpXLv7oS8ZtU-oIebHDGOh_rOZAba4RbOxsuuGJ4L9D848B73X5dc3rSDBXDjn4DrLXvs6rCHSSDVWlNBahC60lVoZum3ZU_Ke9y5QLRzRUs4TxEuBaTCIVoP0Ejhyphenhyphen1ihe2/s640/vbs_dmar_linux.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The DMAR ACPI table is located at address: 0x3A529CB0.</td></tr>
</tbody></table>
<div class="MsoNormal">
Once knowledge of the memory address of the DMAR table has been gained it's possible to overwrite it. The address is usually completely static between reboots. It might change if extensive changes are made to the BIOS configuration - such as enabling/disabling secure boot though.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
We'll overwrite the beginning of the DMAR table before Windows starts to boot. Just issue the command: </div>
<div class="MsoNormal">
<span style="font-family: "courier new" , "courier" , monospace;"><b>pcileech.exe write -min 0x3a529cb0 -in 000000000000000000000000000000000000000000000000</b></span> </div>
<div class="MsoNormal">
which will effectively overwrite the start of the DMAR table with 24 bytes of null data.</div>
<div class="MsoNormal">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4pnkA-1CGXiQUryY8Z38qFADTzDHQOP_cVC8Ub4lmJ-m0yTnsTF5YuIzU9UwjabKubQZ48pqegpyG6t0Zne4IOC5TmS7QNe6NYfVyftgf3LNgJ-K6f-mbp0CEYxRvE2smG01I7D1ZH58m/s1600/vbs_before_after.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="114" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4pnkA-1CGXiQUryY8Z38qFADTzDHQOP_cVC8Ub4lmJ-m0yTnsTF5YuIzU9UwjabKubQZ48pqegpyG6t0Zne4IOC5TmS7QNe6NYfVyftgf3LNgJ-K6f-mbp0CEYxRvE2smG01I7D1ZH58m/s640/vbs_before_after.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The obligatory before/after image. The original DMAR table to the left. The overwritten DMAR table to the right.</td></tr>
</tbody></table>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span style="font-size: large;">The Result</span></div>
<div class="MsoNormal">
Even though the beginning of the DMAR table is now overwritten Bitlocker will unlock the OS disk allowing Windows to boot. Windows don't find the DMAR table so it can't locate the IOMMU. Even though UEFI lock has been configured Windows will just disable virtualization based security features and continue to boot normally.</div>
<div class="MsoNormal">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJXcj5KEciK9bGgMMVKWiBw-9K3-F_1KUOjto8aW9x7GVjQee_JJvLO84bxija_OP1BDUkYvSP1YqjFr_VJwKkcTaqZ3wmFS_oIVAne2pzFF2nJ9tkM3ptmbMDyYKdr2643Mb_M_MrNV4T/s1600/vbs_windisable.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="378" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJXcj5KEciK9bGgMMVKWiBw-9K3-F_1KUOjto8aW9x7GVjQee_JJvLO84bxija_OP1BDUkYvSP1YqjFr_VJwKkcTaqZ3wmFS_oIVAne2pzFF2nJ9tkM3ptmbMDyYKdr2643Mb_M_MrNV4T/s640/vbs_windisable.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Windows with Bitlocker. Credential and Device Guard not started despite configuration. PCILeech kernel module loaded.</td></tr>
</tbody></table>
<div class="MsoNormal">
<span style="font-size: large;">Other</span></div>
<div class="MsoNormal">
</div>
<ul>
<li>It's possible to nuke the DMAR table on other hardware as well.</li>
<li>Virtualization Based Security isn't designed to fully protect against physical and firmware based attacks.</li>
<li>Issue mentioned to MSRC in July as part of pre-existing case. Case closed after DEF CON talk <i>Direct Memory Attack the Kernel</i>.</li>
<li>BIOS version: KYSKLi70.86A.0037.2016.0603.1032.</li>
<li>Did I miss something? Please let me know.</li>
</ul>
<br />
<div class="MsoNormal">
<span style="font-size: large;">Conclusions</span></div>
<div class="MsoNormal">
</div>
<ul>
<li>Computers with active DMA ports and auto-booting full disk encryption might be at risk if physical access could be gained.</li>
<li>Windows 10 Virtualization Based Security might not fully protect against physical DMA attacks with PCILeech on autobooting systems.</li>
<li>It's possible to disable unused M.2 slots and set a BIOS password on the NUC if one wish to be extra secure.</li>
</ul>
Ulf Friskhttp://www.blogger.com/profile/09730439109623573624noreply@blogger.comtag:blogger.com,1999:blog-1551223415848378388.post-42272253620895547422016-10-10T00:38:00.000+02:002016-10-10T12:38:49.813+02:00DMA attacking over USB-C and Thunderbolt 3I just got an Intel NUC Skull Canyon that has an USB-C port capable of Thunderbolt 3. Thunderbolt is interesting since it's able to carry PCI Express which is Direct Memory Access (DMA) capable. I have previously demonstrated how it is possible to DMA-attack macs over Thunderbolt 2 in my DEF CON talk "Direct Memory Attack the Kernel".<br />
<br />
To attack my MacBook Air in the DEF CON demo I used a Sonnet Echo ExpressCard Thunderbolt 2 to ExpressCard adapter together with a PCILeech ExpressCard.<br />
<br />
I also got a Thunderbolt 3 to Thunderbolt 2 adapter from Startech and I wanted to try it on the NUC to see if it's possible to use it for DMA attacks, or if Thunderbolt has been secured. The setup looks like this: NUC <b>-></b> Startech TB3 to TB2 adapter <b>-></b> Sonnet TB2 to ExpressCard adapter <b>-></b> PCILeech ExpressCard.<br />
<br />
There exists a BIOS setting for the Thunderbolt Security Level. The default setting is <i>Unique ID</i>. The other possible security levels are <i>Legacy Mode</i>, <i>One time saved Key</i> and <i>DP++ only</i>. The Legacy Mode is of special interest when it comes to DMA attacking.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdhMcojTXQpu78ULGPh2g4EwO4e_CMsesD0LtziLAhPDaSN6EAo5YFTskt7M4tUs0qnsIx3itbpcKGyTOUqwLw3FtKQMportM5wBzB9VxtlOhVgiEX7O6DQneALEG5Uw5Zh0V-cSLaU7kU/s1600/bios_security_settings.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="304" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdhMcojTXQpu78ULGPh2g4EwO4e_CMsesD0LtziLAhPDaSN6EAo5YFTskt7M4tUs0qnsIx3itbpcKGyTOUqwLw3FtKQMportM5wBzB9VxtlOhVgiEX7O6DQneALEG5Uw5Zh0V-cSLaU7kU/s640/bios_security_settings.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Thunderbolt Security Level in BIOS - Unique ID is the default.</td></tr>
</tbody></table>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<span style="font-size: large;">Thunderbolt 3 with Unique ID (Default)</span><br />
It was not possible to access memory before the OS started - when the computer was still in BIOS/UEFI mode. The PCILeech device wasn't initialized at all.<br />
<br />
It was not possible to access memory in Linux. Ubuntu detected that the Sonnet Echo ExpressCard adapter was connected but there was a lot of error messages; probably due to lack of driver support. No driver was installed in this test.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqNHqEWODC2z6f4Eh3-BSym4-lvzEIatPD5UTMKM-PvZG1tvHJCxOr5HrcEZmGcqISM-VhL__pYBxwINl4V4PHVTbDfK0hIrDowGH_BhsEYCDqOA4vzbh2p80Sam6O3NK8M8CH2G0xD6O2/s1600/linux_errors.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="172" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqNHqEWODC2z6f4Eh3-BSym4-lvzEIatPD5UTMKM-PvZG1tvHJCxOr5HrcEZmGcqISM-VhL__pYBxwINl4V4PHVTbDfK0hIrDowGH_BhsEYCDqOA4vzbh2p80Sam6O3NK8M8CH2G0xD6O2/s640/linux_errors.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Error messages when connecting the Sonnet Echo ExpressCard adapter to the Startech adapter.</td></tr>
</tbody></table>
It was not possible to access memory straight out of the box in Windows 10 with the Unique ID Thunderbolt Security Mode. Windows 10 first didn't react at all to the Thunderbolt devices connected. The devices were then disconnected and the proper Thunderbolt drivers from Intel was installed. When the Startech Thunderbolt 3 to Thunderbolt 2 adapter was connected nothing happened at all.<br />
<br />
When the Sonnet Echo ExpressCard Thunderbolt 2 to ExpressCard adapter was connected Windows popped up a prompt asking to approve the adapter. Administrative privileges was required to approve the Sonnet Thunderbolt 2 to ExpressCard adapter. It seems like the Thunderbolt 3 to Thunderbolt 2 adapter from Startech is transparent in this setup - while the Sonnet adapter is not. The Sonnet adapter was approved by the logged on administrator.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0juwsI_jG0NJLxbRt8RjJTAG23H0RPYornmLmFfhkZ36BWb48uH5yUgkCzySotqOU7UppV1786N7LLcX1Fvx43fgtuL85COu8ZZTcwhl4nDghWBZ9kig3QLtK3UVzJge6a6xFwzcAYkcC/s1600/tb_security_windows.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="210" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0juwsI_jG0NJLxbRt8RjJTAG23H0RPYornmLmFfhkZ36BWb48uH5yUgkCzySotqOU7UppV1786N7LLcX1Fvx43fgtuL85COu8ZZTcwhl4nDghWBZ9kig3QLtK3UVzJge6a6xFwzcAYkcC/s400/tb_security_windows.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Approve Thunderbolt Devices administrative box.</td></tr>
</tbody></table>
After the Sonnect Echo ExpressCard device was approved the PCILeech device was inserted into the Sonnet adapter. Windows did not react at all. The PCILeech device was working. It seems like if the Thunderbolt Security Mode set to Unique ID and do have a Sonnet adapter approved you are at risk for DMA attacks even though the PCILeech may never have been connected to the system previously.<br />
<br />
On the other hand if you are just running Windows 10 and never connected a PCI Express adapter, like the Sonnet Echo ExpressCard, you should be secure.<br />
<br />
<span style="font-size: large;">Thunderbolt 3 in Legacy Mode</span><br />
Just like previously it was not possible to access memory before the OS started - when the computer was still in BIOS/UEFI mode. The PCILeech device wasn't initialized at all.<br />
<div>
<br /></div>
Dumping memory over Thunderbolt 3 is working perfectly on a locked Ubuntu 16.04 LTS provided that the Thunderbolt Security Level is set to Legacy Mode in the BIOS settings. If Thunderbolt security is set to Legacy Mode just plug in the PCILeech device via the adapters into the Thunderbolt 3 port in the NUC and start dumping. It's as easy as that. No drivers are required on the target system. In the example below the adapters and the PCILeech device was connected to the Linux system for the very first time.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieMzJ7ZeVFsfSRbjorx6vZOPjMeITtw6z-LgNj4j7bMaSN8Fi71wQwdM12L3szmP8TDxw5zL6LYGFp8CAzYGsjuMnN_nO2GrUWLEa1bnCYi30h49EklBphyZ0taVbUSXgc4NbxcbTx_F65/s1600/tb3_lecagy.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="339" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieMzJ7ZeVFsfSRbjorx6vZOPjMeITtw6z-LgNj4j7bMaSN8Fi71wQwdM12L3szmP8TDxw5zL6LYGFp8CAzYGsjuMnN_nO2GrUWLEa1bnCYi30h49EklBphyZ0taVbUSXgc4NbxcbTx_F65/s640/tb3_lecagy.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Dumping 32GB memory over USB-C/Thunderbolt 3 on Ubuntu 16.04 LTS.</td></tr>
</tbody></table>
<br />
<div>
Accessing the memory of a Windows 10 system also works if the Thunderbolt Security Level is set to Legacy Mode. It is possible to access the memory of a Windows 10 system by just plugging in the adapters and the PCILeech device - no drivers are required on the target system - it just works! There was no need to install the Intel Thunderbolt drivers in order to access the memory.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKgR-zSjr390CF11YQTvtDCi7pvV1MmAZ1jMqtyjxBSOf1DOg2iEpi86x6ZWPOwSnBe0X3YFRGizJLv_8nzBnd6LphvEdsMatde77g2kuOwGHf9eOELdV9Ws7Vf6GJ0rchxG4DhKetL_6p/s1600/win10_system_shell.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="302" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKgR-zSjr390CF11YQTvtDCi7pvV1MmAZ1jMqtyjxBSOf1DOg2iEpi86x6ZWPOwSnBe0X3YFRGizJLv_8nzBnd6LphvEdsMatde77g2kuOwGHf9eOELdV9Ws7Vf6GJ0rchxG4DhKetL_6p/s640/win10_system_shell.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Windows 10 system shell spawned over Thunderbolt 3.</td></tr>
</tbody></table>
<div>
<br /></div>
</div>
<div>
<span style="font-size: large;">Other</span></div>
<div>
The setup was incompatible with the other two remaining Thunderbolt Security Levels.<br />
<br />
Not all USB-C connectors support Thunderbolt 3. </div>
<div>
<span style="font-size: large;"><br /></span></div>
<span style="font-size: large;">Conclusion</span><br />
The default Thunderbolt security settings are secure - unless you approve a Thunderbolt to PCI Express adapter like the Sonnet Echo ExpressCard.<br />
<br />
Also set a BIOS password to prevent an attacker to change into Legacy Mode without you noticing.<br />
<br />
<br />Ulf Friskhttp://www.blogger.com/profile/09730439109623573624noreply@blogger.com