<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>plaintext</title><link>https://spoons.fyi/</link><description>Recent content on plaintext</description><language>en-us</language><atom:link href="https://spoons.fyi/feeds/all.rss.xml" rel="self" type="application/rss+xml"/><item><title>A Universal .zshrc File</title><link>https://spoons.fyi/2026/02/15/a-universal-zshrc-file.html</link><pubDate>Sun, 15 Feb 2026 00:00:00 +0100</pubDate><guid>https://spoons.fyi/2026/02/15/a-universal-zshrc-file.html</guid><description>&lt;p>Since forver ago, I have been using &lt;a href="https://ohmyz.sh/">oh-my-zsh&lt;/a> with a fairly standard configuration. Plugins for commands I often use, utility functions, and all the clutter you accumulate after years of building and breaking software. That included fuzzing configuration, an unreal amount of version managers, and custom configurations, including those recklessly appended by automatic installers. Since my day-to-day work is fairly intense, it&amp;rsquo;s safe to say that for the last five years, not just my &lt;code>.zshrc&lt;/code> but also various other files connected to it were left unattended. Today, this changed.&lt;/p></description></item><item><title>Geth and Prysm in Docker Compose</title><link>https://spoons.fyi/2024/10/06/geth-and-prysm-in-docker-compose.html</link><pubDate>Sun, 06 Oct 2024 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2024/10/06/geth-and-prysm-in-docker-compose.html</guid><description>&lt;p>I&amp;rsquo;m getting back into hacking on Ethereum nodes. Some of my tests are RPC-heavy, so a local setup is required. This will also speed up development since requests remain in my local network. However, I haven&amp;rsquo;t found an easy Docker Compose setup for running Geth and Prysm together.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">version&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;3.8&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">services&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">geth&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">image&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ethereum/client-go:stable&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">container_name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">geth&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">restart&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">unless-stopped&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">ports&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="m">30303&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="m">30303&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="m">30303&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="m">30303&lt;/span>&lt;span class="l">/udp&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="m">8545&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="m">8545&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="m">8546&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="m">8546&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="m">8551&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="m">8551&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">volumes&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">/ethereum/execution:/root&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">command&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">http&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">http.api=eth,net,web3&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">http.addr=0.0.0.0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">authrpc.addr=0.0.0.0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">authrpc.vhosts=*&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">authrpc.jwtsecret=/root/jwt.hex&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">authrpc.port=8551&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">prysm&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">image&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">gcr.io/prysmaticlabs/prysm/beacon-chain&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">container_name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">prysm&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">restart&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">unless-stopped&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">volumes&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">/ethereum/consensus:/data&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">depends_on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">geth&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">ports&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="m">4000&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="m">4000&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="m">3500&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="m">3500&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">command&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">accept-terms-of-use&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">datadir=/data&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">disable-monitoring&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">rpc-host=0.0.0.0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">execution-endpoint=http://99.97.0.1:8551&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">jwt-secret=/data/jwt.hex&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">rpc-host=0.0.0.0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">rpc-port=4000&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">grpc-gateway-corsdomain=*&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">grpc-gateway-host=0.0.0.0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">grpc-gateway-port=3500&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">min-sync-peers=7&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">checkpoint-sync-url=https://mainnet.checkpoint.sigp.io&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">genesis-beacon-api-url=https://mainnet.checkpoint.sigp.io&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">networks&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">default&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">ipam&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">driver&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">default&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">config&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">subnet&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">99.97.0.0&lt;/span>&lt;span class="l">/16&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The network configuration is required to set Prysm&amp;rsquo;s execution endpoint to the Geth instance. The setup assumes two root paths are set on the server with approprivate permissions: &lt;code>/ethereum/consensus&lt;/code> and &lt;code>/ethereum/execution&lt;/code>. The JWT has been generated with openssl in the execution directory:&lt;/p></description></item><item><title>Migration and Business in Germany</title><link>https://spoons.fyi/2024/09/14/migration-and-business-in-germany.html</link><pubDate>Sat, 14 Sep 2024 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2024/09/14/migration-and-business-in-germany.html</guid><description>&lt;p>In recent weeks, Germany has been on the international news. In the state elections in Thuringia and Saxony (where I live), the extreme right-wing AfD and left-wing BSW have gotten huge voter support. Their focus on immigration, border security, and crime, as well as skilled harping on East-West differences in Germany, seems to have had a significant impact.&lt;/p>
&lt;h2 id="background">Background&lt;/h2>
&lt;p>Describing East Germany is tough. I grew up here, in Saxony-Anhalt, in a city close to where the border used to be, and countless people lost their lives trying to escape the socialist GDR regime. I was born in 1994, five years after the wall came down. Giant bald strips cut into the dense forest, abandoned surveillance buildings and watchtowers, and mined patches with warning signs are still vivid memories of my childhood.&lt;/p></description></item><item><title>Field Guide Tryhard</title><link>https://spoons.fyi/2024/09/01/field-guide-tryhard.html</link><pubDate>Sun, 01 Sep 2024 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2024/09/01/field-guide-tryhard.html</guid><description>&lt;p>Long story short, I got disillusioned with my previous work and its context. I started my project, the &lt;a href="https://scsfg.io/">Smart Contract Security Field Guide (SCSFG)&lt;/a> to cope with it. Here are some nice features:&lt;/p>
&lt;ul>
&lt;li>New code samples instead of the same-old code you see everyone steal over and over&lt;/li>
&lt;li>A section for hackers to give inspiration when stuck and explanations where the attack vector is clear&lt;/li>
&lt;li>A section for developers with general security guidelines, from audit preparation to running a bug bounty program&lt;/li>
&lt;li>No trackers, no ads, no shilling products, no bullshit. Just information.&lt;/li>
&lt;/ul>
&lt;p>In my day-to-day work, I interact with the field guide mainly through the search box, just to see whether I have written something about a certain keyword. The development recommendations are great to send to clients&amp;rsquo; dev teams if there is general uncertainty around a topic.&lt;/p></description></item><item><title>Excessive Growth and Corporate Parties</title><link>https://spoons.fyi/2023/07/20/excessive-growth-and-corporate-parties.html</link><pubDate>Thu, 20 Jul 2023 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2023/07/20/excessive-growth-and-corporate-parties.html</guid><description>&lt;p>Corporate parties - essentially designed to celebrate company triumphs, whether hitting revenue targets or instilling the company&amp;rsquo;s mission and vision into the employees - can often devolve into nothing more than an extravagant distraction. This illusion of harmony, of success, of the &amp;lsquo;perfect&amp;rsquo; work environment is essentially the art of corporate virtue signaling. It&amp;rsquo;s a façade masking the underbelly of what could potentially be inefficiency, misalignment, and, frankly, disarray.&lt;/p>
&lt;p>This form of virtue signaling is pervasive mainly in the growing web3 space. Despite the industry being a hotbed of innovation and progress, there is a noticeable shortage of leadership talent capable of shepherding this growth. As a result, there&amp;rsquo;s a tendency to fall back on old, traditional leadership and management patterns, including these orchestrated and, often, opulent celebrations.&lt;/p></description></item><item><title>Vacation Traditions</title><link>https://spoons.fyi/2023/01/13/vacation-traditions.html</link><pubDate>Fri, 13 Jan 2023 00:00:00 +0100</pubDate><guid>https://spoons.fyi/2023/01/13/vacation-traditions.html</guid><description>&lt;p>I enjoy getting lost in work. I mean, &lt;em>really&lt;/em> enjoy it. I forget to eat and sleep, especially when developing software. There is something addicting about building an MVP as fast as possible, finding the perfect architecture, refactoring your previous hacks, and eventually making your code observable and running smoothly. Whenever I take a vacation, I find myself not really taking time off, however. I&amp;rsquo;ll hack on other projects, &amp;ldquo;be around,&amp;rdquo; and I already find myself working before the holiday ends.&lt;/p></description></item><item><title>Honest Attempts to Secure an Ecosystem</title><link>https://spoons.fyi/2022/06/29/honest-attempts-to-secure-an-ecosystem.html</link><pubDate>Wed, 29 Jun 2022 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2022/06/29/honest-attempts-to-secure-an-ecosystem.html</guid><description>&lt;p>I have used my off-time from audits in the past months to write more about security. Especially in a nascent ecosystem like Ethereum still is, the most considerable impact can be delivered by educating people. Education has to happen in different modes of complexity, depending on the target audience:&lt;/p>
&lt;ul>
&lt;li>Developers must be educated on how previous hacks happened and how to avoid making similar mistakes in the code they
produce.&lt;/li>
&lt;li>Business leads must be educated about the general (in-)securities of smart contracts and what can and cannot be
expected of them.&lt;/li>
&lt;li>General users must be educated on spotting and avoiding scams while repeatedly preached to not invest any money they
can&amp;rsquo;t afford to lose. Ever.&lt;/li>
&lt;/ul>
&lt;p>My own contribution to the above is the &lt;a href="https://consensys.github.io/smart-contract-best-practices/">Ethereum Smart Contract Best Practices&lt;/a>. When I joined &lt;a href="https://consensys.net/diligence/">ConsenSys Diligence&lt;/a>, the repository already existed, and people enjoyed the content. In the rollercoaster of auditing smart contracts as the main business, little time was left to properly maintain code samples, keep best practices up to date, and polish the overall site. I intend to change that.This is a note for everyone who enjoys my technical posts to follow along as I develop the best practices. Occasionally, I also tweet about the sections I have revised previously. Contact me if you have suggestions on attacks, best practices, or helpful tooling to add. &lt;em>After all, this is about educating a community so it can make educated decisions!&lt;/em>&lt;/p></description></item><item><title>Remembering my Dad</title><link>https://spoons.fyi/2022/03/16/remembering-my-dad.html</link><pubDate>Wed, 16 Mar 2022 00:00:00 +0100</pubDate><guid>https://spoons.fyi/2022/03/16/remembering-my-dad.html</guid><description>&lt;p>On March 11, 18:11, my dad passed away. After about a year with lung cancer and two weeks with COVID-19, he finally does not have to struggle anymore.&lt;/p>
&lt;p>I miss him dearly. After he got COVID, the doctors diagnosed him with pneumonia. He spent a week in the hospital before being released. He needed oxygen 24/7 and, in 30-minute intervals, switched from lucid moments where he was his usual self to a confused state of mind where memories and thoughts meddled with his conscience. When able to talk, he seemed to relive moments from his past mixed with the input his senses gave him.&lt;/p></description></item><item><title>HackTheBox Registry</title><link>https://spoons.fyi/2021/02/13/hackthebox-registry.html</link><pubDate>Sat, 13 Feb 2021 00:00:00 +0100</pubDate><guid>https://spoons.fyi/2021/02/13/hackthebox-registry.html</guid><description>&lt;p>Registry is a box rated at hard difficulty. There are quite a few steps involved, but with a bit of persistence and little experience with Docker internals (&lt;a href="https://spoons.fyi/2018/09/16/low-level-debugging-of-stubborn-docker-containers.html">hint hint&lt;/a>), it looks more daunting than it actually is. Let&amp;rsquo;s go through the process of breaking in step by step! Out initial nmap scan is as unexciting as it can be:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Nmap 7.80 scan initiated Fri Jan 10 17:08:06 2020 as: nmap -sS -sC -oN registry.nmap -v 10.10.10.159&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Increasing send delay &lt;span class="k">for&lt;/span> 10.10.10.159 from &lt;span class="m">0&lt;/span> to &lt;span class="m">5&lt;/span> due to &lt;span class="m">238&lt;/span> out of &lt;span class="m">792&lt;/span> dropped probes since last increase.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nmap scan report &lt;span class="k">for&lt;/span> 10.10.10.159
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Host is up &lt;span class="o">(&lt;/span>0.10s latency&lt;span class="o">)&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Not shown: &lt;span class="m">997&lt;/span> closed ports
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PORT STATE SERVICE
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">22/tcp open ssh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> ssh-hostkey:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> &lt;span class="m">2048&lt;/span> 72:d4:8d:da:ff:9b:94:2a:ee:55:0c:04:30:71:88:93 &lt;span class="o">(&lt;/span>RSA&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> &lt;span class="m">256&lt;/span> c7:40:d0:0e:e4:97:4a:4f:f9:fb:b2:0b:33:99:48:6d &lt;span class="o">(&lt;/span>ECDSA&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_ &lt;span class="m">256&lt;/span> 78:34:80:14:a1:3d:56:12:b4:0a:98:1f:e6:b4:e8:93 &lt;span class="o">(&lt;/span>ED25519&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">80/tcp open http
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> http-methods:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_ Supported Methods: GET HEAD
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_http-title: Welcome to nginx!
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">443/tcp open https
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> http-methods:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_ Supported Methods: GET HEAD
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_http-title: Welcome to nginx!
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> ssl-cert: Subject: &lt;span class="nv">commonName&lt;/span>&lt;span class="o">=&lt;/span>docker.registry.htb
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> Issuer: &lt;span class="nv">commonName&lt;/span>&lt;span class="o">=&lt;/span>Registry
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> Public Key type: rsa
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> Public Key bits: &lt;span class="m">2048&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> Signature Algorithm: sha256WithRSAEncryption
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> Not valid before: 2019-05-06T21:14:35
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> Not valid after: 2029-05-03T21:14:35
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> MD5: 0d6f 504f 1cb5 de50 2f4e 5f67 9db6 a3a9
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_SHA-1: 7da0 &lt;span class="m">1245&lt;/span> 1d62 d69b a87e &lt;span class="m">8667&lt;/span> 083c 39a6 9eb2 b2b5
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Read data files from: /usr/bin/../share/nmap
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Nmap done at Fri Jan 10 17:08:20 2020 -- 1 IP address (1 host up) scanned in 14.34 seconds&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>On ports 80 and 443, we both see a default NGINX site. Only the TLS certificate&amp;rsquo;s Common Name &lt;code>docker.registry.htb&lt;/code> gives us a hint. With the box being called Registry, we can deduce that this server probably has a &lt;a href="https://docs.docker.com/registry/">Docker registry&lt;/a> installed. Accessing the referenced vhost gives us an empty response:&lt;/p></description></item><item><title>HackTheBox Fuzzy</title><link>https://spoons.fyi/2020/09/23/hackthebox-fuzzy.html</link><pubDate>Wed, 23 Sep 2020 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2020/09/23/hackthebox-fuzzy.html</guid><description>&lt;p>Fuzzy is a fun and short challenge on a docker container. It is especially good for teaching beginners the basics of using a fuzzer to discover new endpoints on a webserver.Spawning the container and probing around a bit, we don&amp;rsquo;t have too much success. Using dirbuster and a standard wordlist, we find the endpoint &lt;code>/api/action.php&lt;/code>. With &lt;code>wfuzz&lt;/code> we can now see whether passing any specific parameter to the endpoint significantly changes our response payload:&lt;/p></description></item><item><title>HackTheBox Mango</title><link>https://spoons.fyi/2020/08/08/hackthebox-mango.html</link><pubDate>Sat, 08 Aug 2020 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2020/08/08/hackthebox-mango.html</guid><description>&lt;p>Mango was an interesting box when it comes to enumeration. It taught me to look more closely and not brush off anything just because I have seen it before. The box is also a prime lesson to aggregate your recon info in a structured manner so it&amp;rsquo;s easier to apply it at other points when you hit a dead end somewhere. There were also some nice opportunities for small, specialised attack scripts, which I particularly enjoyed! When we start out by scanning the box, we get the following report:&lt;/p></description></item><item><title>Construct Truffle Artifact Source Lists</title><link>https://spoons.fyi/2020/05/12/construct-truffle-artifact-source-lists.html</link><pubDate>Tue, 12 May 2020 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2020/05/12/construct-truffle-artifact-source-lists.html</guid><description>&lt;figure class="gallery-item">
 &lt;a class="lightbox" href="/2020/05/12/construct-truffle-artifact-source-lists/photo-of-truffles-on-the-plate-783153.jpg">&lt;img src="/2020/05/12/construct-truffle-artifact-source-lists/photo-of-truffles-on-the-plate-783153_hu11905967307101159118.jpg" alt="Image" loading="lazy" width="800" height="533" />&lt;/a>
 &lt;/figure>&lt;p>This is a quick and dirty workaround for an issue that has been bugging me a lot. &lt;a href="https://github.com/trufflesuite/truffle/">Truffle&lt;/a> is one of the central, if not the most central development tool for building smart contracts on Ethereum to date. When compiling a Truffle project, the output is stored in &lt;code>build/contracts&lt;/code> by default. An artifact simply a JSON object containing a plethora of data. A short sample from the &lt;a href="https://github.com/skalenetwork/skale-manager">SKALE&lt;/a> project:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;contractName&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;SkaleDKG&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;abi&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;metadata&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;{\&amp;#34;compiler\&amp;#34;:{\&amp;#34;version\&amp;#34;:\&amp;#34;0.5.16+commit.9c3226ce\&amp;#34;},...}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;bytecode&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;0x...&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;deployedBytecode&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;0x...&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;sourceMap&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;1529:30527:18:-;;;;;;;;;&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;deployedSourceMap&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;1529:30527:18:-;;...&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;source&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;...&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;sourcePath&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;/path/to/skale-manager/contracts/SkaleDKG.sol&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;ast&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;legacyAST&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;compiler&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;name&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;solc&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;version&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;0.5.16+commit.9c3226ce.Emscripten.clang&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;networks&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;schemaVersion&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;3.0.20&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;updatedAt&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;2020-05-05T09:55:25.394Z&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;devdoc&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;userdoc&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;methods&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If we want to submit this artifact as a payload to &lt;a href="https://mythx.io/">MythX&lt;/a> for security analysis, we are lacking an important feature, however: The source list.&lt;/p></description></item><item><title>HackTheBox Postman</title><link>https://spoons.fyi/2020/03/21/hackthebox-postman.html</link><pubDate>Sat, 21 Mar 2020 00:00:00 +0100</pubDate><guid>https://spoons.fyi/2020/03/21/hackthebox-postman.html</guid><description>&lt;p>Postman was an easy-going box. It required careful enumeration and beyond that did not have too much resistance in privilege escalation. This makes it a prime example for real-world M&amp;amp;M security where the initial foothold is hard, but there is few resistance on the inside. Let&amp;rsquo;s start out by scanning the machine:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># nmap -sS -sC -oN postman.nmap -v 10.10.10.160&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Nmap 7.80 scan initiated Sun Dec 8 11:27:40 2019 as: nmap -sS -sC -oN postman.nmap -v -p1-10000 10.10.10.160&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Increasing send delay &lt;span class="k">for&lt;/span> 10.10.10.160 from &lt;span class="m">0&lt;/span> to &lt;span class="m">5&lt;/span> due to &lt;span class="m">674&lt;/span> out of &lt;span class="m">2245&lt;/span> dropped probes since last increase.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nmap scan report &lt;span class="k">for&lt;/span> 10.10.10.160
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Host is up &lt;span class="o">(&lt;/span>0.11s latency&lt;span class="o">)&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Not shown: &lt;span class="m">9996&lt;/span> closed ports
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PORT STATE SERVICE
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">22/tcp open ssh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> ssh-hostkey:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> &lt;span class="m">2048&lt;/span> 46:83:4f:f1:38:61:c0:1c:74:cb:b5:d1:4a:68:4d:77 &lt;span class="o">(&lt;/span>RSA&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> &lt;span class="m">256&lt;/span> 2d:8d:27:d2:df:15:1a:31:53:05:fb:ff:f0:62:26:89 &lt;span class="o">(&lt;/span>ECDSA&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_ &lt;span class="m">256&lt;/span> ca:7c:82:aa:5a:d3:72:ca:8b:8a:38:3a:80:41:a0:45 &lt;span class="o">(&lt;/span>ED25519&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">80/tcp open http
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_http-favicon: Unknown favicon MD5: E234E3E8040EFB1ACD7028330A956EBF
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> http-methods:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_ Supported Methods: GET POST OPTIONS HEAD
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_http-title: The Cyber Geek&lt;span class="err">&amp;#39;&lt;/span>s Personal Website
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">6379/tcp open redis
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">10000/tcp open snet-sensor-mgmt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> ssl-cert: Subject: &lt;span class="nv">commonName&lt;/span>&lt;span class="o">=&lt;/span>*/organizationName&lt;span class="o">=&lt;/span>Webmin Webserver on Postman
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> Issuer: &lt;span class="nv">commonName&lt;/span>&lt;span class="o">=&lt;/span>*/organizationName&lt;span class="o">=&lt;/span>Webmin Webserver on Postman
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> Public Key type: rsa
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> Public Key bits: &lt;span class="m">2048&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> Signature Algorithm: sha256WithRSAEncryption
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> Not valid before: 2019-08-25T16:26:22
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> Not valid after: 2024-08-23T16:26:22
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> MD5: 96f4 064c e63e &lt;span class="m">1277&lt;/span> &lt;span class="m">4954&lt;/span> a4d9 a099 56ac
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_SHA-1: &lt;span class="m">4322&lt;/span> 6ff3 ab7a 6ade &lt;span class="m">2887&lt;/span> 9b89 &lt;span class="m">6657&lt;/span> 401c 3afd &lt;span class="m">5217&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_ssl-date: TLS randomness does not represent &lt;span class="nb">time&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Read data files from: /usr/bin/../share/nmap
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Nmap done at Sun Dec 8 11:29:31 2019 -- 1 IP address (1 host up)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>There are a few interesting things here already. We have a webserver running on port 80, an unprotected Redis database server on the default port 6379, and a custom application on port 10000. The latter one apparently is using an SSL certificate where the &lt;code>organizationName&lt;/code> already tells us that we are dealing with a Webmin admin panel here. That is already decent information to start out with! Looking at the website on port 80, there is no real attack surface present. It&amp;rsquo;s just static content.&lt;/p></description></item><item><title>The Web3 API has come to Python!</title><link>https://spoons.fyi/2020/03/15/the-web3-api-has-come-to-python.html</link><pubDate>Sun, 15 Mar 2020 00:00:00 +0100</pubDate><guid>https://spoons.fyi/2020/03/15/the-web3-api-has-come-to-python.html</guid><description>&lt;p>Last week I received an email in my inbox about a hackathon hosted by the awesome folks over at &lt;a href="http://amberdata.io/">Amberdata&lt;/a>. They are a provider for on-chain data and cover a large variety of blockchains - including Ethereum, Bitcoin, and Stellar. I have met the developers in the team in late 2018 when I was looking for my next gig in the Ethereum ecosystem and long before that I was stunned by the large variety and volume of data they are handling.&lt;/p></description></item><item><title>36C3 Telnet Challenge (Cat CTF)</title><link>https://spoons.fyi/2020/01/18/36c3-telnet-challenge-cat-ctf.html</link><pubDate>Sat, 18 Jan 2020 00:00:00 +0100</pubDate><guid>https://spoons.fyi/2020/01/18/36c3-telnet-challenge-cat-ctf.html</guid><description>&lt;p>This is a write-up from the 36th Chaos Communication Congress, 2019. It has been my fourth Congress. Timed shortly after Christmas, it feels like meeting a second kind of family after the holidays. Hackers from all over the world gather in Leipzig to celebrate the weirdness of our community, break technology, learn new things, and have caffeine-fuelled fun.On my initial recon walk with friends we stumbled across the following poster.&lt;/p></description></item><item><title>HackTheBox Obscurity</title><link>https://spoons.fyi/2020/01/12/hackthebox-obscurity.html</link><pubDate>Sun, 12 Jan 2020 00:00:00 +0100</pubDate><guid>https://spoons.fyi/2020/01/12/hackthebox-obscurity.html</guid><description>&lt;p>Obscurity is a medium-difficulty box. It was super fun to solve because it involved great excuses for me to write some neat little helper scripts and find a vulnerability in Python code. Something you don&amp;rsquo;t do too often in these challenges. Let&amp;rsquo;s dive right in with a nmap scan:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">$ nmap -sS -sC -oN obscurity.nmap -v 10.10.10.168
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nmap 7.80 scan initiated Fri Jan &lt;span class="m">10&lt;/span> 12:57:06 &lt;span class="m">2020&lt;/span> as: nmap -sS -sC -oN obscurity.nmap -v 10.10.10.168
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nmap scan report &lt;span class="k">for&lt;/span> 10.10.10.168
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Host is up &lt;span class="o">(&lt;/span>0.16s latency&lt;span class="o">)&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Not shown: &lt;span class="m">996&lt;/span> filtered ports
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PORT STATE SERVICE
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">22/tcp open ssh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> ssh-hostkey:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> &lt;span class="m">2048&lt;/span> 33:d3:9a:0d:97:2c:54:20:e1:b0:17:34:f4:ca:70:1b &lt;span class="o">(&lt;/span>RSA&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> &lt;span class="m">256&lt;/span> f6:8b:d5:73:97:be:52:cb:12:ea:8b:02:7c:34:a3:d7 &lt;span class="o">(&lt;/span>ECDSA&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_ &lt;span class="m">256&lt;/span> e8:df:55:78:76:85:4b:7b:dc:70:6a:fc:40:cc:ac:9b &lt;span class="o">(&lt;/span>ED25519&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">80/tcp closed http
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">8080/tcp open http-proxy
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> http-methods:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_ Supported Methods: GET HEAD POST OPTIONS
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_http-title: 0bscura
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">9000/tcp closed cslistener
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Read data files from: /usr/bin/../share/nmap
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Nmap done at Fri Jan 10 12:57:35 2020 -- 1 IP address (1 host up) scanned in 29.44 seconds&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Checking port 8080 on the server, we find the following text:&lt;/p></description></item><item><title>HackTheBox OpenAdmin</title><link>https://spoons.fyi/2020/01/09/hackthebox-openadmin.html</link><pubDate>Thu, 09 Jan 2020 00:00:00 +0100</pubDate><guid>https://spoons.fyi/2020/01/09/hackthebox-openadmin.html</guid><description>&lt;p>OpenAdmin is yet another medium-difficulty machine, which was a blast to hack on! It involved dealing with various stack components, such as interacting directly with a MySQL database. Furthermore, hopping across multiple users through different escalation vectors was very satisfying. Let&amp;rsquo;s see how it is done!Our first nmap scan does not yield any exciting results:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">$ nmap -sS -sC -oN openadmin.nmap -v 10.10.10.171
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Nmap 7.80 scan initiated Wed Jan 8 14:33:26 2020 as: nmap -sS -sC -oN openadmin.nmap -v 10.10.10.171&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nmap scan report &lt;span class="k">for&lt;/span> 10.10.10.171
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Host is up &lt;span class="o">(&lt;/span>0.11s latency&lt;span class="o">)&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Not shown: &lt;span class="m">998&lt;/span> closed ports
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PORT STATE SERVICE
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">22/tcp open ssh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> ssh-hostkey:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> &lt;span class="m">2048&lt;/span> 4b:98:df:85:d1:7e:f0:3d:da:48:cd:bc:92:00:b7:54 &lt;span class="o">(&lt;/span>RSA&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> &lt;span class="m">256&lt;/span> dc:eb:3d:c9:44:d1:18:b1:22:b4:cf:de:bd:6c:7a:54 &lt;span class="o">(&lt;/span>ECDSA&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_ &lt;span class="m">256&lt;/span> dc:ad:ca:3c:11:31:5b:6f:e6:a4:89:34:7c:9b:e5:50 &lt;span class="o">(&lt;/span>ED25519&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">80/tcp open http
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> http-methods:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_ Supported Methods: GET POST OPTIONS HEAD
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_http-title: Apache2 Ubuntu Default Page: It works
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Read data files from: /usr/bin/../share/nmap
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Nmap done at Wed Jan 8 14:33:32 2020 -- 1 IP address (1 host up) scanned in 6.18 seconds&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>On port 80, we see the default Ubuntu Apache page. The server headers and error page leak the concrete version, but it is updated. Using dirbuster and a small directory wordlist, we find the &lt;code>/music&lt;/code> and &lt;code>/ona&lt;/code> endpoints. The first one hosts a custom web application without any exciting functionality. ONA is more attractive as it stands for &lt;a href="https://opennetadmin.com/">OpenNetAdmin&lt;/a>. In the OpenNetAdmin interface, we are automatically logged in as a guest account. The user info panel leaks some database details, however. We get to know that MySQL is running on localhost, the default DB name is, and the default user is named &lt;code>ona_sys&lt;/code>. We can also see the ONA version, which is &lt;code>v18.1.1&lt;/code>. This is plenty of information to go on!We find that an &lt;a href="https://www.exploit-db.com/exploits/47691">RCE is available&lt;/a> for our version when we check for exploits. With some minor target-related updates to the proof-of-concept, we can drop into a shell right away and dump some user data:&lt;/p></description></item><item><title>HackTheBox Traverxec</title><link>https://spoons.fyi/2020/01/04/hackthebox-traverxec.html</link><pubDate>Sat, 04 Jan 2020 00:00:00 +0100</pubDate><guid>https://spoons.fyi/2020/01/04/hackthebox-traverxec.html</guid><description>&lt;p>Traverxec is an interesting box, mainly because the HackTheBox team rated it as easy while the community disagreed and voted it to medium difficulty. It involved a funky privilege escalation that I had not seen before. Let&amp;rsquo;s see how it&amp;rsquo;s done! Our first nmap scan does not return exciting results:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">$ nmap -sS -sC -oN traverxec.nmap -v 10.10.10.165
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Nmap 7.80 scan initiated Mon Dec 9 13:49:03 2019 as: nmap -sS -sC -oN traverxec.nmap -v 10.10.10.165&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nmap scan report &lt;span class="k">for&lt;/span> 10.10.10.165
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Host is up &lt;span class="o">(&lt;/span>0.11s latency&lt;span class="o">)&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Not shown: &lt;span class="m">998&lt;/span> filtered ports
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PORT STATE SERVICE
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">22/tcp open ssh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> ssh-hostkey:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> &lt;span class="m">2048&lt;/span> aa:99:a8:16:68:cd:41:cc:f9:6c:84:01:c7:59:09:5c &lt;span class="o">(&lt;/span>RSA&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> &lt;span class="m">256&lt;/span> 93:dd:1a:23:ee:d7:1f:08:6b:58:47:09:73:a3:88:cc &lt;span class="o">(&lt;/span>ECDSA&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_ &lt;span class="m">256&lt;/span> 9d:d6:62:1e:7a:fb:8f:56:92:e6:37:f1:10:db:9b:ce &lt;span class="o">(&lt;/span>ED25519&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">80/tcp open http
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_http-favicon: Unknown favicon MD5: FED84E16B6CCFE88EE7FFAAE5DFEFD34
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> http-methods:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_ Supported Methods: GET HEAD POST
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span>_http-title: TRAVERXEC
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Read data files from: /usr/bin/../share/nmap
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Nmap done at Mon Dec 9 13:49:30 2019 -- 1 IP address (1 host up) scanned in 26.97 seconds&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>On port 80, we see a portfolio website. Nothing exciting seems to be hidden here. We have some static images, a Javascript gallery, a bootstrap template, and a bit of glue in between. The contact form initially seemed interesting, but on closer inspection, we simply perform a GET request to an empty file:&lt;/p></description></item><item><title>HackTheBox Wall</title><link>https://spoons.fyi/2019/12/07/hackthebox-wall.html</link><pubDate>Sat, 07 Dec 2019 00:00:00 +0100</pubDate><guid>https://spoons.fyi/2019/12/07/hackthebox-wall.html</guid><description>&lt;p>Wall was as much a fun and educational box as it was frustrating and stretching my patience. It felt like the system was updated by the creator to have some features in place meant to annoy people trying to break in. Nevertheless, there are some nice WAF evasion techniques to consider here, as well as the lesson to never give up on enumeration Starting with a SYN scan, executing scripts where possible:&lt;/p></description></item><item><title>Dear Medium,</title><link>https://spoons.fyi/2019/11/11/dear-medium.html</link><pubDate>Mon, 11 Nov 2019 00:00:00 +0100</pubDate><guid>https://spoons.fyi/2019/11/11/dear-medium.html</guid><description>&lt;p>My blogging journey has taken me far. I started writing articles about six years ago. Things got serious after I started studying Computer Science. Among the students of my class there was a lot of chatter. The tendency was that who was unable to communicate would soon start failing exams and eventually quit. In this setting, I started writing technical articles, first on an intranet website. Later GitHub gists. Finally I made the step to host my own blog.&lt;/p></description></item><item><title>The DEFCON 27 Packet Hacking Village Honeypot Challenge</title><link>https://spoons.fyi/2019/08/15/the-defcon-27-packet-hacking-village-honeypot-challenge.html</link><pubDate>Thu, 15 Aug 2019 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2019/08/15/the-defcon-27-packet-hacking-village-honeypot-challenge.html</guid><description>&lt;p>This year marks the first time I got to attend DEFCON Las Vegas — one of the largest hacker conferences in the world. There are a plethora of things to discover and try out. The talks can be streamed later, but the workshops and spontaneous gatherings? A challenge that caught my eye was the honeypot challenge in the packet hacking village. The setting is simple: You gain access to an SSH honeypot. In there you find challenges to solve and gather the credentials to the next one. The goal was to escalate through five machines and gain the secret passphrase.&lt;/p></description></item><item><title>A Code Review Story</title><link>https://spoons.fyi/2019/07/28/a-code-review-story.html</link><pubDate>Sun, 28 Jul 2019 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2019/07/28/a-code-review-story.html</guid><description>&lt;p>This is the first post of a sporadic series where we will dive into the weeds of more complex Python code review samples. I will take (slightly modified) real-world code samples, explain some common mistakes that have been made, and how we can improve things. Let’s jump right in!&lt;/p>
&lt;p>In this scenario, we have a component that is supposed to handle artifacts containing log messages. It is structured as an object implementing a pipeline of various sanitization and postprocessing tasks. Among a ton of other things, there is the &lt;code>groom_logs&lt;/code> method, which is static, and fulfills the task of validating and deduplicating the log list of a given artifact.&lt;/p></description></item><item><title>HackTheBox fs0sciety</title><link>https://spoons.fyi/2018/10/20/hackthebox-fs0sciety.html</link><pubDate>Sat, 20 Oct 2018 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2018/10/20/hackthebox-fs0sciety.html</guid><description>&lt;p>fs0ciety is yet another low-hanging fruit among the HackTheBox challenges. It&amp;rsquo;s great for beginners who want to test their process for cracking password-protected zip files and recognition of various encodings.For that, we will use &lt;code>fcrackzip &lt;/code>- simply for the reason that it has been around for ages and ships with Kali by default. I have sourced my wordlist from &lt;a href="https://github.com/berzerk0/Probable-Wordlists">here&lt;/a>. Let&amp;rsquo;s fire up the program:&lt;/p>
&lt;figure class="gallery-item">
 &lt;a class="lightbox" href="/2018/10/20/hackthebox-fs0sciety/35226399.png">&lt;img src="/2018/10/20/hackthebox-fs0sciety/35226399.png" alt="Image" loading="lazy" width="625" height="75" />&lt;/a>
 &lt;/figure>&lt;p>Unzipping the file with the password &lt;code>justdoit&lt;/code>: &lt;code>unzip -P justdoit fsociety.zip&lt;/code>; We find an interesting file containing credentials:&lt;/p></description></item><item><title>Explain like I'm five: Cryptographic Hashing</title><link>https://spoons.fyi/2018/10/15/explain-like-im-five-cryptographic-hashing.html</link><pubDate>Mon, 15 Oct 2018 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2018/10/15/explain-like-im-five-cryptographic-hashing.html</guid><description>&lt;p>&lt;strong>tl;dr&lt;/strong> Just check out the image and read the details below it if you want to know even more. :)&lt;/p>
&lt;p>A few days back I read an &lt;a href="https://medium.com/@yunyun_chen/guide-hashing-c04a049fac58">article by Yunyun Chen&lt;/a> explaining Hashing in an infographic. I enjoyed it and read some comments, which pointed out a couple of weak spots that result from common misconceptions about (cryptographic) hashing.&lt;/p>
&lt;p>Mostly this is a result of the distinction between the &lt;em>concept of a cryptographic hash function&lt;/em> (its formal, mathematical properties) and &lt;em>implementations of that concept&lt;/em> (concrete algorithms such as SHA-256). As the blockchain community attracts people from all kinds of backgrounds, it’s important to clarify these former and educate people about the basic cryptographic concepts blockchain technology is based on. Only when a community around a technology is educated about how it works it can make meaningful progress and ultimately create innovation.&lt;/p></description></item><item><title>HackTheBox 0ld_is_g0ld</title><link>https://spoons.fyi/2018/10/13/hackthebox-0ld_is_g0ld.html</link><pubDate>Sat, 13 Oct 2018 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2018/10/13/hackthebox-0ld_is_g0ld.html</guid><description>&lt;p>0ld_is_g0ld is a HackTheBox challenge and a great way for beginners to familiarize themselves with PDF password cracking. If you have used Hashcat before, it&amp;rsquo;s an easy win. Verifying we indeed are targeting the correct file format:&lt;/p>
&lt;pre tabindex="0">&lt;code>$ file 0ld\ is\ g0ld.pdf
0ld is g0ld.pdf: PDF document, version 1.6
&lt;/code>&lt;/pre>&lt;p>We can extract the hash using the &lt;a href="https://github.com/stricture/hashstack-server-plugin-hashcat/blob/12fc138d2864026765f55bb33e3d7b859eb2b48a/scrapers/pdf2hashcat.py">pdf2hashcat.py&lt;/a> util script:&lt;/p>
&lt;pre tabindex="0">&lt;code>./pdf2hashcat.py 0ld\ is\ g0ld.pdf &amp;gt; hash.txt
&lt;/code>&lt;/pre>&lt;p>Now all that&amp;rsquo;s left is run hashcat with a (large) wordlist against the hash file and with a little bit of luck we get a
hit:&lt;/p></description></item><item><title>The Thing about Mutable Default Arguments in Python</title><link>https://spoons.fyi/2018/10/10/the-thing-about-mutable-default-arguments-in-python.html</link><pubDate>Wed, 10 Oct 2018 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2018/10/10/the-thing-about-mutable-default-arguments-in-python.html</guid><description>&lt;p>Yesterday I stumbled across some code like this&amp;hellip;&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">search_children&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">statespace&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">node&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">start_index&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">depth&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">results&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[]):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">depth&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">MAX_SEARCH_DEPTH&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">n_states&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">len&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">node&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">states&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">n_states&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">start_index&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">j&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">start_index&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n_states&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">node&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">states&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">j&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get_current_instruction&lt;/span>&lt;span class="p">()[&lt;/span>&lt;span class="s1">&amp;#39;opcode&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s1">&amp;#39;SSTORE&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">results&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">node&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">states&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">j&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get_current_instruction&lt;/span>&lt;span class="p">()[&lt;/span>&lt;span class="s1">&amp;#39;address&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">...&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The semantics of the code don’t really matter here. Still spot the bug? It’s a very common Python gotcha that even experienced developers overlook from time to time. Look at the function header. The result list. Maybe a small example playing around will help here:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">In&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">9&lt;/span>&lt;span class="p">]:&lt;/span> &lt;span class="k">def&lt;/span> &lt;span class="nf">append_to_list&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">value&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">l&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[]):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">...&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">l&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">value&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">...&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="k">return&lt;/span> &lt;span class="n">l&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">...&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">In&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">]:&lt;/span> &lt;span class="n">append_to_list&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">42&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">Out&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">]:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">42&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">In&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">11&lt;/span>&lt;span class="p">]:&lt;/span> &lt;span class="n">append_to_list&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1337&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">Out&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">11&lt;/span>&lt;span class="p">]:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">42&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1337&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Setting the default argument you would normally expect to have an empty list every time you enter the function. However, as StackOverflow user &lt;a href="https://stackoverflow.com/questions/32326777/python-default-arguments-evaluation">skyking&lt;/a> points out, this is not the case. Default arguments in Python are evaluated once, when the function is declared.&lt;/p></description></item><item><title>Low-level Debugging of Stubborn Docker Containers</title><link>https://spoons.fyi/2018/09/16/low-level-debugging-of-stubborn-docker-containers.html</link><pubDate>Sun, 16 Sep 2018 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2018/09/16/low-level-debugging-of-stubborn-docker-containers.html</guid><description>&lt;p>A few weeks back I have started contributing to the awesome &lt;a href="https://github.com/ConsenSys/mythril">Mythril&lt;/a> project. Mythril is a security scanner for smart contracts that allows everyone to look for vulnerabilities on- and off-chain by being able to analyze raw smart contract code, as well as the actual Solidity code file. To make setting it up more easy, the devs provide a Docker container for easy deployment and use via &lt;code>docker run&lt;/code> .&lt;/p>
&lt;p>Looking for low-hanging fruits to start, I instinctively picked out an issue related to Docker, as there’s little new things about debugging containers. &lt;a href="https://github.com/ConsenSys/mythril/issues/479">Issue 479&lt;/a> described Mythril crashing with a Unicode decode error — but it was only reproducible with the Docker container:&lt;/p></description></item><item><title>Parsing KMZ Track Data in Python</title><link>https://spoons.fyi/2018/09/14/parsing-kmz-track-data-in-python.html</link><pubDate>Fri, 14 Sep 2018 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2018/09/14/parsing-kmz-track-data-in-python.html</guid><description>&lt;p>A few days back I stumbled across an interesting problem. I was asked to develop a solution that was doing some analysis work on geolocation data stored in KMZ format. Existing solutions like &lt;a href="https://pypi.python.org/pypi/fastkml/0.11">fastkml (64KB)&lt;/a> and &lt;a href="https://pypi.python.org/pypi/pykml/0.1.3">pykml (42KB)&lt;/a> seemed nice at the first glance, proved to be unnecessary overhead, however. They&amp;rsquo;re mostly meant to manipulate and write data into KML format. I just needed to read the data for my later calculations. So I decided to build a solution using the Python Standard Library.&lt;/p></description></item><item><title>HackTheBox Sense</title><link>https://spoons.fyi/2018/03/01/hackthebox-sense.html</link><pubDate>Thu, 01 Mar 2018 00:00:00 +0100</pubDate><guid>https://spoons.fyi/2018/03/01/hackthebox-sense.html</guid><description>&lt;p>Sense was a HackTheBox machine that really tested my patience during the enumeration phase. It is a box designed around the popular &lt;a href="https://www.pfsense.org/">pfSense&lt;/a> firewall. Let&amp;rsquo;s dive in! Firstly, we start our usual standard nmap scan:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">Starting Nmap 7.60 &lt;span class="o">(&lt;/span> https://nmap.org &lt;span class="o">)&lt;/span> at 2018-02-27 19:44 CET
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nmap scan report &lt;span class="k">for&lt;/span> 10.10.10.60
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Host is up &lt;span class="o">(&lt;/span>0.034s latency&lt;span class="o">)&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Not shown: &lt;span class="m">998&lt;/span> filtered ports
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PORT STATE SERVICE
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">80/tcp open http
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">443/tcp open https
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Nmap &lt;span class="k">done&lt;/span>: &lt;span class="m">1&lt;/span> IP address &lt;span class="o">(&lt;/span>&lt;span class="m">1&lt;/span> host up&lt;span class="o">)&lt;/span> scanned in 7.09 seconds
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Checking out port 80 with the browser automatically redirects us to HTTPS on port 443. We also have an information leak about the server technology in the responses, but that information does not lead us to a viable exploit.&lt;/p></description></item><item><title>HackTheBox Bashed</title><link>https://spoons.fyi/2018/02/27/hackthebox-bashed.html</link><pubDate>Tue, 27 Feb 2018 00:00:00 +0100</pubDate><guid>https://spoons.fyi/2018/02/27/hackthebox-bashed.html</guid><description>&lt;p>Bashed is a great entry-level box for people who are just getting started with HackTheBox. If you are just getting started with penetration testing, the value of this box is less in its technical content but rather in giving you the chance to exercise through your processes once. A bit like jumping into the water for the first time after doing dry-swimming. Let&amp;rsquo;s jump in!&lt;/p>
&lt;p>First we run a basic nmap scan to see what ports are running on the server:&lt;/p></description></item><item><title>HackTheBox Nibbles</title><link>https://spoons.fyi/2018/02/26/hackthebox-nibbles.html</link><pubDate>Mon, 26 Feb 2018 00:00:00 +0100</pubDate><guid>https://spoons.fyi/2018/02/26/hackthebox-nibbles.html</guid><description>&lt;p>Nibbles was one of the first machines I broke on HTB. It is a relatively simple machine that requires a little bit of reconnaissance and leads you to a (hopefully) easy win by letting you poke around the website. Let&amp;rsquo;s dive in!First, we run a quick port scan: &lt;code>nmap -sS 10.10.10.75 -oX htb-nibbles.xml&lt;/code>, which gives us the following result:&lt;/p>
&lt;pre tabindex="0">&lt;code>Starting Nmap 7.60 ( https://nmap.org ) at 2018-02-26 18:58 CET
Nmap scan report for 10.10.10.75
Host is up (0.056s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http

Nmap done: 1 IP address (1 host up) scanned in 0.80 seconds
&lt;/code>&lt;/pre>&lt;p>Access on port 80 gives us the following view:&lt;/p></description></item><item><title>Quick Hack: Generating PDFs with Python and XeTeX</title><link>https://spoons.fyi/2018/01/10/quick-hack-generating-pdfs-with-python-and-xetex.html</link><pubDate>Wed, 10 Jan 2018 00:00:00 +0100</pubDate><guid>https://spoons.fyi/2018/01/10/quick-hack-generating-pdfs-with-python-and-xetex.html</guid><description>&lt;p>A friend of mine is following a PhD in a non-technical field. And his boss is a bully. Work mainly happens with high-level statistical analysis tools. No one knows anything about programming and most problems are solved by hand. While on a positive note this means good chances to get a student job, it also means that progress moves slowly, especially when it comes to working with large datasets.&lt;/p>
&lt;p>Due to some kind of disorder related to social dominance, his boss regularly gives him harassing tasks. The ones that would take two students a month to complete - with a deadline set for the day after tomorrow. Obviously, this is impossible to complete if you don&amp;rsquo;t know how to automate the task. That&amp;rsquo;s where I come in - and boy was it satisfying to own his boss.&lt;/p></description></item><item><title>Converting MySQL Table Data to a Graphml File</title><link>https://spoons.fyi/2017/06/03/converting-mysql-table-data-to-a-graphml-file.html</link><pubDate>Sat, 03 Jun 2017 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2017/06/03/converting-mysql-table-data-to-a-graphml-file.html</guid><description>&lt;p>I recently found myself in the situation where I was given access to a huge MySQL database that contained network traffic flows and IDS signature match data. As I work a lot with graph-based approaches, I needed to convert the table&amp;rsquo;s flow data into a graphml file for later visualization and analysis with scripts I have already written. Now without further ado here&amp;rsquo;s the code:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">pymysql.cursors&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">pymysql&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">networkx&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">nx&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">sys&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Connect to the database&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">conn&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pymysql&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">connect&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">host&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;localhost&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">user&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;root&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">password&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;my-secret-pw&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">db&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;flowdata&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">charset&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;utf8mb4&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cursorclass&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">pymysql&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">cursors&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">SSCursor&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">graph&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">nx&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DiGraph&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cursor&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">conn&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">cursor&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cursor&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">execute&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;SELECT src_ip, dst_ip FROM flows&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">row&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">enumerate&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">cursor&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sys&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">stdout&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\r&lt;/span>&lt;span class="s2">Reading line &lt;/span>&lt;span class="si">%s&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sys&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">stdout&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">flush&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">graph&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add_edge&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">nx&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write_graphml&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">graph&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;trente-flowgraph.graphml&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>It&amp;rsquo;s obvious to see that I only need the data from the first two columns as they contain source and destination IP. The trick here is to use &lt;code>pymysql.cursors.SSCursor&lt;/code>. This will prevent &lt;code>pymysql&lt;/code> from loading the whole result set from the &lt;code>SELECT * ...&lt;/code> query into RAM. Another catch is that &lt;code>pymysql&lt;/code> apparently is not available for Python 3 yet. SQLAlchemy is a good workaround for bigger projects (such as my &lt;a href="https://github.com/dmuhs/pastebin-scraper">Pastebin Scraper&lt;/a>) but in this case it&amp;rsquo;s complete overkill. Just run the script with &lt;code>python2.7&lt;/code> and you&amp;rsquo;re good.&lt;/p></description></item><item><title>N-wise Iteration in Python</title><link>https://spoons.fyi/2017/04/17/n-wise-iteration-in-python.html</link><pubDate>Mon, 17 Apr 2017 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2017/04/17/n-wise-iteration-in-python.html</guid><description>&lt;p>A few hours back I stumbled into a problem where I had to perform a lookahead of n elements in a list to do some calculations. The first thought: Just take the current index and get all elements until i+n. I started writing..&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">for&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">len&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">iterable&lt;/span>&lt;span class="p">)):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">----&lt;/span> &lt;span class="n">SNAP&lt;/span> &lt;span class="o">----&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Stop. This is awfully unpythonic. There has to be a better way! Browsing the &lt;a href="https://docs.python.org/3/library/itertools.html#itertools-recipes">itertools recipes&lt;/a> I found the &lt;code>pairwise&lt;/code> function:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">pairwise&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">iterable&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;s -&amp;gt; (s0,s1), (s1,s2), (s2, s3), ...&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">tee&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">iterable&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">next&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">b&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kc">None&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nb">zip&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Perfect! Now I just have to adjust it to work with n iterators where the first iterator is at i, the second at i+1, etc.&lt;/p></description></item><item><title>My New (old) Blog on Github Pages</title><link>https://spoons.fyi/2017/03/25/my-new-old-blog-on-github-pages.html</link><pubDate>Sat, 25 Mar 2017 00:00:00 +0100</pubDate><guid>https://spoons.fyi/2017/03/25/my-new-old-blog-on-github-pages.html</guid><description>&lt;p>After the exams, I had some free hours so I decided to show my blog some more love and look for a new theme. The old one, a customized version of &lt;a href="https://github.com/onlyhavecans/pelican-chunk">Chunk&lt;/a> was little more than a hack to have a theme at all. Here&amp;rsquo;s a quick reminder of how this site used to look:&lt;/p>
&lt;figure class="gallery-item">
 &lt;a class="lightbox" href="/2017/03/25/my-new-old-blog-on-github-pages/chunk.png">&lt;img src="/2017/03/25/my-new-old-blog-on-github-pages/chunk_hu13212196066016813422.png" alt="Image" loading="lazy" width="800" height="450" />&lt;/a>
 &lt;/figure>&lt;p>I had a thorough look at &lt;a href="https://github.com/alexandrevicenzi/Flex">Flex&lt;/a>, &lt;a href="https://github.com/talha131/pelican-elegant">Elegant&lt;/a>, and many other popular themes but none of them struck me as &lt;em>really minimalist&lt;/em>. So even though I&amp;rsquo;m more of a backend-dev I decided to dust off my questionable CSS skills and give it a shot. Turns out a lot has changed since I last developed websites. Animations without JS? Magic! The whole thing turned out pretty neat and I even &lt;a href="https://github.com/dmuhs/hebe">published the code on Github&lt;/a>. Feel free to leave feedback!In this post I&amp;rsquo;ll explain some of my ideas about &lt;em>Hebe&lt;/em>, a &amp;ldquo;truly&amp;rdquo; minimalist &lt;a href="https://getpelican.com">Pelican&lt;/a> blog theme.&lt;/p></description></item><item><title>Hebe Design Decisions</title><link>https://spoons.fyi/2017/03/25/hebe-design-decisions.html</link><pubDate>Sat, 25 Mar 2017 00:00:00 +0100</pubDate><guid>https://spoons.fyi/2017/03/25/hebe-design-decisions.html</guid><description>&lt;p>After the exams I had some free hours so I decided to show my blog some more love and look for a new theme. The old one, a customized version of &lt;a href="https://github.com/onlyhavecans/pelican-chunk">Chunk&lt;/a> was little more than a hack to have a theme at all. Here&amp;rsquo;s a quick reminder of how this site used to look:&lt;/p>
&lt;p>&lt;figure class="gallery-item">
 &lt;a class="lightbox" href="/2017/03/25/hebe-design-decisions/chunk.png">&lt;img src="/2017/03/25/hebe-design-decisions/chunk_hu13212196066016813422.png" alt="Image" loading="lazy" width="800" height="450" />&lt;/a>
 &lt;/figure>&lt;/a>&lt;/p>
&lt;p>I had a thorough look at &lt;a href="https://github.com/alexandrevicenzi/Flex">Flex&lt;/a>, &lt;a href="https://github.com/talha131/pelican-elegant">Elegant&lt;/a> and many other popular themes but none of them struck me as &lt;em>really minimalist&lt;/em>. So even though I&amp;rsquo;m more of a backend-dev I decided to dust off my questionable CSS skills and give it a shot. Turns out a lot has changed since I last developed websites. Animations without JS? Magic! The whole thing turned out pretty neat and I even &lt;a href="https://github.com/dmuhs/hebe">published the code on Github&lt;/a>. Feel free to leave feedback!&lt;/p></description></item><item><title>PPP #13 Goodbye Trip: Campana &amp; Punta Chame</title><link>https://spoons.fyi/2016/09/04/ppp-13-goodbye-trip-campana-punta-chame.html</link><pubDate>Sun, 04 Sep 2016 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2016/09/04/ppp-13-goodbye-trip-campana-punta-chame.html</guid><description>&lt;p>As most of my stories in Panama this trip starts with some new friends. At my workplace, the &lt;em>Universidad Tecnológica de Panamá (UTP)&lt;/em>, I didn&amp;rsquo;t have much contact to students, because I spent most of my time on campus inside an office. The international office of the uni was very engaged however and regularly asked me to speak about my experiences and help respresent campus affairs. In this context I met some of the most amazing people!&lt;/p></description></item><item><title>PPP #12 Getting my Greens in Valle de Antón</title><link>https://spoons.fyi/2016/08/13/ppp-12-getting-my-greens-in-valle-de-anton.html</link><pubDate>Sat, 13 Aug 2016 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2016/08/13/ppp-12-getting-my-greens-in-valle-de-anton.html</guid><description>&lt;p>Social Networks are awesome for travelling. By pure accident I met some fellow &lt;em>viajeros&lt;/em> - two handsome women from Israel and Poland. After a quick chat and meetup we decided to spend our time in Valle de Antón - Anton Valley. From colleagues I already heard a lot about it&amp;rsquo;s natural beauty.&lt;/p>
&lt;figure class="gallery-item">
 &lt;a class="lightbox" href="/2016/08/13/ppp-12-getting-my-greens-in-valle-de-anton/valle-anton-1.jpg" data-caption="Valle de Antón Mountainside">&lt;img src="/2016/08/13/ppp-12-getting-my-greens-in-valle-de-anton/valle-anton-1_hu2812483374980310977.jpg" alt="Valle de Antón Mountainside" loading="lazy" width="800" height="450" />&lt;/a>&lt;figcaption>Valle de Antón Mountainside&lt;/figcaption>
 &lt;/figure>&lt;p>What has been recommended to all of us was &lt;em>La Cascada El Macho&lt;/em>: It&amp;rsquo;s the highest waterfall in the whole valley, measuring 70m in altitude. So on the first day we had a quick look at the map and went straight for it. The air was much cleaner than in Panama City. Breathing and walking were easier, the heat wasn&amp;rsquo;t as bad. We passed beautiful paths with great views..&lt;/p></description></item><item><title>PPP #11 Strolling through the Park</title><link>https://spoons.fyi/2016/08/06/ppp-11-strolling-through-the-park.html</link><pubDate>Sat, 06 Aug 2016 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2016/08/06/ppp-11-strolling-through-the-park.html</guid><description>&lt;figure class="gallery-item">
 &lt;a class="lightbox" href="/2016/08/06/ppp-11-strolling-through-the-park/metropolitano-1.jpg" data-caption="Metropolitano Entrance Sign">&lt;img src="/2016/08/06/ppp-11-strolling-through-the-park/metropolitano-1_hu7174232486515091294.jpg" alt="Metropolitano Entrance Sign" loading="lazy" width="800" height="432" />&lt;/a>&lt;figcaption>Metropolitano Entrance Sign&lt;/figcaption>
 &lt;/figure>&lt;p>Since 1988 there is a park just on the outskirts of Panama City - &lt;em>El Parque Natural Metropolitano&lt;/em>. It&amp;rsquo;s the only wildlife refuge in the city and is host to an amazing variety of wildlife. There are no special attractions there. It&amp;rsquo;s a place you just go to in a casual manner to relax and forget your everyday duties for some hours. It&amp;rsquo;s fairly big and you can also easily spend a day there - as I did with some friends from the university.&lt;/p></description></item><item><title>PPP #10 Gamboa: Welcome to the Jungle</title><link>https://spoons.fyi/2016/07/09/ppp-10-gamboa-welcome-to-the-jungle.html</link><pubDate>Sat, 09 Jul 2016 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2016/07/09/ppp-10-gamboa-welcome-to-the-jungle.html</guid><description>&lt;p>My sister and a colleague of her decided to visit me in Panamà. Still being busy with the investigation, I did not manage to find a lot of time for travels during the week. However on the weekends, we managed to make some small trips. One of them lead us into the jungle near the village of Gamboa.&lt;/p>
&lt;p>Gamboa once was one of several canal zone townships built to house employees working at the Panama Canal and their families. Later (due to a shortage in housing in the US military base) there were also soldiers living there. The architecture of Gamboa has been preserved with lots of love and nowadays you can find hotels there. The rise of tourism has not damaged the rural flair the least.&lt;/p></description></item><item><title>Install Intel Graphics Drivers for Fedora 23</title><link>https://spoons.fyi/2016/06/29/install-intel-graphics-drivers-for-fedora-23.html</link><pubDate>Wed, 29 Jun 2016 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2016/06/29/install-intel-graphics-drivers-for-fedora-23.html</guid><description>&lt;p>This is a thing I always forget and have to look up. My Dell XPS 13 (2013) runs on an Intel HD4000 and the drivers are obviously not in the standard repos. This script pulls the (at the time of this writing) most recent driver from the repos of the &lt;em>Intel Open Source Technology Centre&lt;/em>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> /tmp
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">wget --no-check-certificate https://download.01.org/gfx/RPM-GPG-KEY-ilg-2
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo rpm --import RPM-GPG-KEY-ilg-2
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># x86_64&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">wget https://download.01.org/gfx/fedora/23/x86_64/intel-linux-graphics-installer-1.4.0-23.intel20161.x86_64.rpm
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo dnf install intel-linux-graphics-installer-1.4.0-23.intel20161.x86_64.rpm
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo dnf upgrade
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo intel-linux-graphics-installer
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The installer takes a while to do its work. Just ignore all notifications of GNOME that the program is not responding. In the shell where you did the last call you can see the true progress. After the installation/ update progress a system reboot is required.&lt;/p></description></item><item><title>Visualizing IP Connections in Python</title><link>https://spoons.fyi/2016/06/27/visualizing-ip-connections-in-python.html</link><pubDate>Mon, 27 Jun 2016 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2016/06/27/visualizing-ip-connections-in-python.html</guid><description>&lt;p>For some research on botnet host detection in large-scale networks, I found myself in the situation that I had to apply a set of algorithms to a huge packet dump. To comprehend an amazing paper, I started to play around with the dataset and tried to reproduce the results presented in the whitepaper. Quickly I realized that there was something fishy with my own dataset, so I fired up &lt;code>jupyter-notebook&lt;/code> to gain some more insight in the IP structure of my dataset.&lt;/p></description></item><item><title>PPP #09 A Trip to Paradise - Bocas del Toro</title><link>https://spoons.fyi/2016/06/19/ppp-09-a-trip-to-paradise-bocas-del-toro.html</link><pubDate>Sun, 19 Jun 2016 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2016/06/19/ppp-09-a-trip-to-paradise-bocas-del-toro.html</guid><description>&lt;p>In the travel magazines you always see the same ad pictures. Cristal clear water gently stroking the white-sand beach bordered by palm trees. Deep cyan colours meet intense whites and greens. Amidst this paradisal scenery happily sits a woman drinking from a coconut, enjoying the sun. HARD CUT - company name appears. Guess what - I have been there. Not in the ad spot, in that kind of paradise. Just without the woman. You can&amp;rsquo;t have everything, right?&lt;/p></description></item><item><title>PPP #08 Conquering Volcán Barú</title><link>https://spoons.fyi/2016/06/13/ppp-08-conquering-volcan-baru.html</link><pubDate>Mon, 13 Jun 2016 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2016/06/13/ppp-08-conquering-volcan-baru.html</guid><description>&lt;p>This was an extraordinary hiking trip full of firsts. I have never ever before been hiking&lt;/p>
&lt;ul>
&lt;li>in Panama&lt;/li>
&lt;li>in tropical weather&lt;/li>
&lt;li>on an active volcano&lt;/li>
&lt;li>on a mountain higher than 2,500m&lt;/li>
&lt;/ul>
&lt;p>It all begins at the Albrook bus station in Panamá City. In the night from Friday to Saturday at midnight we take the bus to David, Chiriquí. The bus system in Panamá seems reliable and this particular bus was comfortable. For some reason we ended up in the VIP section without really paying any more. We took the opportunity and enjoyed! The ride lasted about six hours and the next morning we safely arrived in David. We took a small break and it didn&amp;rsquo;t take long until we found ourselves sitting in the next bus towards &lt;em>Boquete&lt;/em>, a small city close to the volcano.&lt;/p></description></item><item><title>PPP #07 Isla Grande</title><link>https://spoons.fyi/2016/06/05/ppp-07-isla-grande.html</link><pubDate>Sun, 05 Jun 2016 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2016/06/05/ppp-07-isla-grande.html</guid><description>&lt;p>A sunny day, 30°C and air humidity so high that breathing feels like waterboarding. Perfect conditions to go to the beach! Just some hours by car in the province of Colón north of Panamá City, you can find &lt;em>Isla Grande&lt;/em>. This island is your typical small Caribbean island with clear waters and palm trees. From &lt;em>Muelle de La Guaira&lt;/em> the crossing by boat just takes some minutes with the speedboat and costs less than $2.&lt;/p></description></item><item><title>ERROR 2999: Invalid preprocessor command specified</title><link>https://spoons.fyi/2016/06/03/error-2999-invalid-preprocessor-command-specified.html</link><pubDate>Fri, 03 Jun 2016 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2016/06/03/error-2999-invalid-preprocessor-command-specified.html</guid><description>&lt;p>I am quite new to working with &lt;a href="https://aws.amazon.com/elasticmapreduce/">Amazon Elastic MapReduce&lt;/a> clusters. To do some large scale data analysis, I built a Pig script and ran it on a local pig installation to verify its functionality. Works. Neat! Let&amp;rsquo;s push it to the cluster and get some serious results on the large dataset!&lt;/p>
&lt;p>Luckily for my bill, it didn&amp;rsquo;t take too long to fail.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>hadoop@ip-XXX-XXX-XXX-XXX samples&lt;span class="o">]&lt;/span>$ pig -x mapreduce -f pig/examples/snort.pig -param &lt;span class="nv">pcap&lt;/span>&lt;span class="o">=&lt;/span>data/sample204.pcap
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">16/06/03 14:05:13 INFO pig.ExecTypeProvider: Trying ExecType : LOCAL
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">16/06/03 14:05:13 INFO pig.ExecTypeProvider: Trying ExecType : MAPREDUCE
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">16/06/03 14:05:13 INFO pig.ExecTypeProvider: Picked MAPREDUCE as the ExecType
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="m">94&lt;/span> &lt;span class="o">[&lt;/span>main&lt;span class="o">]&lt;/span> INFO org.apache.pig.Main - Apache Pig version 0.14.0-amzn-0 &lt;span class="o">(&lt;/span>r: unknown&lt;span class="o">)&lt;/span> compiled Apr &lt;span class="m">06&lt;/span> 2016, 22:40:48
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">16/06/03 14:05:13 INFO pig.Main: Apache Pig version 0.14.0-amzn-0 &lt;span class="o">(&lt;/span>r: unknown&lt;span class="o">)&lt;/span> compiled Apr &lt;span class="m">06&lt;/span> 2016, 22:40:48
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="m">98&lt;/span> &lt;span class="o">[&lt;/span>main&lt;span class="o">]&lt;/span> INFO org.apache.pig.Main - Logging error messages to: /mnt/var/log/pig/pig_1464962713368.log
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">16/06/03 14:05:13 INFO pig.Main: Logging error messages to: /mnt/var/log/pig/pig_1464962713368.log
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="m">2542&lt;/span> &lt;span class="o">[&lt;/span>main&lt;span class="o">]&lt;/span> INFO org.apache.pig.Main - Final script path: /home/hadoop/packetpig/pig/examples/snort.pig
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">16/06/03 14:05:15 INFO pig.Main: Final script path: /home/hadoop/packetpig/pig/examples/snort.pig
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="m">2563&lt;/span> &lt;span class="o">[&lt;/span>main&lt;span class="o">]&lt;/span> INFO org.apache.pig.impl.util.Utils - Default bootup file /home/hadoop/.pigbootup not found
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">16/06/03 14:05:15 INFO util.Utils: Default bootup file /home/hadoop/.pigbootup not found
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="m">2698&lt;/span> &lt;span class="o">[&lt;/span>main&lt;span class="o">]&lt;/span> ERROR org.apache.pig.Main - ERROR 2999: Unexpected internal error. Pig Internal Error. Invalid preprocessor &lt;span class="nb">command&lt;/span> specified : %DEFAULT
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">16/06/03 14:05:15 ERROR pig.Main: ERROR 2999: Unexpected internal error. Pig Internal Error. Invalid preprocessor &lt;span class="nb">command&lt;/span> specified : %DEFAULT
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Details at logfile: /mnt/var/log/pig/pig_1464962713368.log
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="m">2740&lt;/span> &lt;span class="o">[&lt;/span>main&lt;span class="o">]&lt;/span> INFO org.apache.pig.Main - Pig script completed in &lt;span class="m">2&lt;/span> seconds and &lt;span class="m">915&lt;/span> milliseconds &lt;span class="o">(&lt;/span>&lt;span class="m">2915&lt;/span> ms&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">16/06/03 14:05:16 INFO pig.Main: Pig script completed in &lt;span class="m">2&lt;/span> seconds and &lt;span class="m">915&lt;/span> milliseconds &lt;span class="o">(&lt;/span>&lt;span class="m">2915&lt;/span> ms&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Wait, what? How can this fail? Setting %DEFAULT values for script parameters is a pretty standard thing! Well, turns out, all Amazon EMR components &lt;a href="https://docs.aws.amazon.com/ElasticMapReduce/latest/ReleaseGuide/emr-release-components.html">are running on Pig 0.14.0&lt;/a>. A pig version &lt;a href="https://pig.apache.org/releases.html">released in November 2014&lt;/a>. The latest version (0.15.0) was released in June 2015! Isn&amp;rsquo;t that enough time to at least provide a newer version to non-legacy customers?&lt;/p></description></item><item><title>PPP #06 The City of Knowledge</title><link>https://spoons.fyi/2016/05/19/ppp-06-the-city-of-knowledge.html</link><pubDate>Thu, 19 May 2016 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2016/05/19/ppp-06-the-city-of-knowledge.html</guid><description>&lt;p>Located about 20 minutes away from the Technological University of Panama - assuming you don&amp;rsquo;t run into a traffic jam - lies the &lt;em>Ciudad del Saber&lt;/em>, the City of Knowledge. When Panama was occupied by the United States, this base directly in front of the Miraflores locks was called Fort Clayton and the US Army headquarters here in Panama City. After the US departure the government founded a non-profit organization with the mission to turn the vacated facilities at Clayton into a center for knowledge exchange. Amidst the green beauty you can see the buildings showing logos of the Red Cross, the United Nations, the World Food Program, Plan International and plenty more.&lt;/p></description></item><item><title>PPP #05 Taboga - The Island of Flowers</title><link>https://spoons.fyi/2016/05/15/ppp-05-taboga-the-island-of-flowers.html</link><pubDate>Sun, 15 May 2016 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2016/05/15/ppp-05-taboga-the-island-of-flowers.html</guid><description>&lt;p>During a fair on stipends and opportunities to go abroad at the UTP I met some other interns and students of the uni! Amazing people from Portugal, Mexico, Honduras and Poland. We had a coffee together and got to know each other. They are very down to earth and easy-going people. Before we each left for office and studies again, some people invited me to join them on a trip to Taboga. &lt;em>&amp;ldquo;Of course! That would be awesome!&amp;rdquo;&lt;/em> was the instinctive answer, because after all I&amp;rsquo;m not here to spend the weekends with work. &lt;em>&amp;ldquo;Uhh, and what is Taboga exactly?&amp;rdquo;&lt;/em> was the follow-up question. Now I can answer it! It&amp;rsquo;s a beautiful volcanic island located in the Gulf of Panama. Ferries towards Taboga leave daily from the Amador Causeway and roughly take 40 minutes to reach land again. On the way there we had an amazing view on the giant container ships waiting for passage through the Panama Canal.&lt;/p></description></item><item><title>PPP #04 Turning the Tides</title><link>https://spoons.fyi/2016/05/02/ppp-04-turning-the-tides.html</link><pubDate>Mon, 02 May 2016 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2016/05/02/ppp-04-turning-the-tides.html</guid><description>&lt;p>A Monday. Got up early. Bought a Spartan breakfast (water and bread). Off we go to the uni! Work! Get shit done! Meet people! &lt;em>&amp;ldquo;Hoy está cerrado!&amp;rdquo;&lt;/em>. I stand before closed doors, next to me a wildly gesticulating and almost shouting security guard crossing his hands. Yeah, right. Today was a red-letter day! Ah, my forgetfulness followed me all the way to Panama! At least I got up early. So I took the chance to explore the neighbourhood a little as long as the sun was shining.&lt;/p></description></item><item><title>PPP #03 New Lands</title><link>https://spoons.fyi/2016/05/01/ppp-03-new-lands.html</link><pubDate>Sun, 01 May 2016 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2016/05/01/ppp-03-new-lands.html</guid><description>&lt;p>So today I moved out of Brigitte&amp;rsquo;s house into the new apartment. Before coming here I had the choice between a single apartment with my own fridge and bathroom or a flat-share with ten other people with a shared bathroom and a community kitchen. I decided for the latter, because I hoped to make some new friends, improve my Spanish and spend some good times with my flatmates. Now that I&amp;rsquo;m here I have to say that the people seem to be pretty reserved. All doors are closed and no one is in the hallway or kitchen.&lt;/p></description></item><item><title>PPP #02 A Helping Hand</title><link>https://spoons.fyi/2016/04/30/ppp-02-a-helping-hand.html</link><pubDate>Sat, 30 Apr 2016 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2016/04/30/ppp-02-a-helping-hand.html</guid><description>&lt;p>Brigitte, my mentor, is an amazing person. She does not only give me a place to sleep. She also hooked me up with a SIM card so I have mobile internet connection. That way I can now navigate around the city and cry for help on WhatsApp should I ever get lost. In order for me to get from A to B she also helped me to get a card for public transport. You can charge it with money and insert it when entering the means of your choice so the cost gets withdrawn. $0.25 each ride, no matter how far you go. I wonder whether there&amp;rsquo;s one of these &lt;a href="https://fail0verflow.com/blog/2014/proxmark3-fpga-iir-filter.html">crackable RFID chips&lt;/a> in this card. Of course I will not look further into this matter without permission. :)&lt;/p></description></item><item><title>PPP #01 Come Fly With Me</title><link>https://spoons.fyi/2016/04/28/ppp-01-come-fly-with-me.html</link><pubDate>Thu, 28 Apr 2016 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2016/04/28/ppp-01-come-fly-with-me.html</guid><description>&lt;p>This little series is about my &amp;ldquo;travel&amp;rdquo; to Panamá. I applied at IAESTE for an internship in the IT security department of the &lt;em>UTP (Universidad Tecnológica de Panamá)&lt;/em>. Here, in my &lt;em>P&lt;/em>ersonal &lt;em>P&lt;/em>anama &lt;em>P&lt;/em>apers I&amp;rsquo;ll write down some of my experiences, problems and solutions while I find my way into Panamanian society and hopefully some interesting security-related research.&lt;/p>
&lt;p>When I left Dresden yesterday, I threw my last keys to the flat into the mailbox outside. I still find it a little weird that at that moment I did not feel anything special. With my backpack and suitcase I stood in front of the doors and separated from my last possessions in this city - at least for the coming five months - and it felt like the most normal thing in the world. In Berlin I met up with a very good friend of mine, Alex. We spent a good late evening together having some dinner and talking about old and new times. What makes good friends stand out is not being together all the time. It&amp;rsquo;s the immediate intimacy when they meet again. Good friends often lose contact - but they always come find back to each other. And Alex is a very good friend. After some trouble with my accommodation he spontaneously agreed to give me shelter for a night and hence saved me plenty of money (and some sleep).&lt;/p></description></item><item><title>Saxon Switzerland in Autumn</title><link>https://spoons.fyi/2015/11/01/saxon-switzerland-in-autumn.html</link><pubDate>Sun, 01 Nov 2015 00:00:00 +0100</pubDate><guid>https://spoons.fyi/2015/11/01/saxon-switzerland-in-autumn.html</guid><description>&lt;p>When you have the chance to study in Dresden, it&amp;rsquo;s a &lt;em>must&lt;/em> for every outdoor person to go hiking in the Saxon Switzerland. It&amp;rsquo;s only ~30 minutes away from Dresden and you can get there for free with your semester ticket if you&amp;rsquo;re enrolled at the local uni, Technische Universität Dresden. Whether spring, summer, autumn or winter; there are always amazing views in a landscape that seems to completely change after every corner.&lt;/p></description></item><item><title>The "Pythonic" GOTO</title><link>https://spoons.fyi/2015/06/15/the-pythonic-goto.html</link><pubDate>Mon, 15 Jun 2015 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2015/06/15/the-pythonic-goto.html</guid><description>&lt;p>Nope, I&amp;rsquo;m not going to join the goto war. Even though it&amp;rsquo;s shunned among developers, there are still some situations where it makes sense. A good friend of mine with a background in C recently came to me with a very simple problem that still made him scratch his head when he tried to express it in Python. The problem broke down to comparing three lists to find an element that meets a special criterion. His basic naive concept looked something like this in pseudo-code:&lt;/p></description></item><item><title>Performing Well at CodeFEST8</title><link>https://spoons.fyi/2015/05/22/performing-well-at-codefest8.html</link><pubDate>Fri, 22 May 2015 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2015/05/22/performing-well-at-codefest8.html</guid><description>&lt;p>When we decided to enter the hackathon, some fellow students and I were in it for the fun. We had worked together before in a mandatory software project and wanted to revive the productive atmosphere of the good old times. Neither did we expect to &lt;em>win in Dresden&lt;/em> nor did we have in mind that there was a realistic chance of &lt;strong>winning at the CeBIT 2015&lt;/strong> against teams from Germany, Austria and Switzerland.&lt;/p></description></item><item><title>VPN with openconnect in Ubuntu 14.10</title><link>https://spoons.fyi/2015/05/12/vpn-with-openconnect-in-ubuntu-1410.html</link><pubDate>Tue, 12 May 2015 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2015/05/12/vpn-with-openconnect-in-ubuntu-1410.html</guid><description>&lt;p>Many services that my university offers have one requirement: to be in a trusted network. That is either eduroam or any network where you can connect through a VPN tunnel. As sad as it is, I don&amp;rsquo;t have an eduroam router next to my home. However, I ran into some minor problems when trying to create a VPN connection with network-manager.&lt;/p>
&lt;h2 id="the-good">The Good&lt;/h2>
&lt;p>After installing the necessary dependencies &lt;code>network-manager-openconnect&lt;/code> and &lt;code>network-manager-openconnect-gnome&lt;/code> there was a rather visual problem: When trying to create a VPN connection, network-manager would just present me with the option to &lt;em>Import from File&amp;hellip;&lt;/em>. Not a glimpse of my beloved &lt;em>Cisco AnyConnect Compatible VPN (openconnect)&lt;/em> option. So what do?&lt;/p></description></item><item><title>Some thoughts on the CodeFEST8 in Dresden</title><link>https://spoons.fyi/2015/05/12/some-thoughts-on-the-codefest8-in-dresden.html</link><pubDate>Tue, 12 May 2015 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2015/05/12/some-thoughts-on-the-codefest8-in-dresden.html</guid><description>&lt;figure class="gallery-item">
 &lt;a class="lightbox" href="/2015/05/12/some-thoughts-on-the-codefest8-in-dresden/codefest8.gif" data-caption="CodeFEST8 Logo">&lt;img src="/2015/05/12/some-thoughts-on-the-codefest8-in-dresden/codefest8.gif" alt="CodeFEST8 Logo" loading="lazy" width="468" height="129" />&lt;/a>&lt;figcaption>CodeFEST8 Logo&lt;/figcaption>
 &lt;/figure>&lt;h4 id="what-is-it">What is it?&lt;/h4>
&lt;p>The &lt;a href="http://www.group-it.volkswagenag.com/codefest/codefest.html">CodeFEST&lt;/a> is a hackathon held by Volkswagen. Basically, you&amp;rsquo;re joining a team and with the help of some mentors you tickle your brain for 26 hours of pure work until a great, innovative idea comes out. After reaching the deadline, you give a short five minute presentation about the problem, your solution, some technical details and marketing aspects. Bonus points for a live demo. This year&amp;rsquo;s motto was &amp;ldquo;Mobilität der Zukunft&amp;rdquo; - &lt;em>mobility of the future&lt;/em>.&lt;/p></description></item><item><title>Code Verification with Git Hooks and Flake8</title><link>https://spoons.fyi/2015/05/02/code-verification-with-git-hooks-and-flake8.html</link><pubDate>Sat, 02 May 2015 00:00:00 +0200</pubDate><guid>https://spoons.fyi/2015/05/02/code-verification-with-git-hooks-and-flake8.html</guid><description>&lt;p>We all have that special someone in our life. Someone who dares to commit and push something like this into the master-branch:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">math&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="nn">os&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="nn">sys&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">test_function&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">one&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">two&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">three&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">four&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">five&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">from&lt;/span> &lt;span class="nn">test.utils&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="o">*&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="nb">print&lt;/span> &lt;span class="n">y&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">two&lt;/span>&lt;span class="o">==&lt;/span>&lt;span class="n">three&lt;/span> &lt;span class="ow">and&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">four&lt;/span>&lt;span class="o">!=&lt;/span>&lt;span class="n">five&lt;/span> &lt;span class="ow">or&lt;/span> &lt;span class="n">one&lt;/span>&lt;span class="o">!=&lt;/span>&lt;span class="n">three&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="ow">and&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">sqrt&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">four&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">==&lt;/span>&lt;span class="n">two&lt;/span> &lt;span class="ow">or&lt;/span> &lt;span class="n">sqrt&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">two&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">==&lt;/span>&lt;span class="n">one&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">ldexp&lt;/span>&lt;span class="p">(&lt;/span> &lt;span class="n">one&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">two&lt;/span> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">else&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">None&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This code would be accepted by the Python interpreter without hesitation and it will &amp;ldquo;work&amp;rdquo;. However, there are many direct conflicts with the &lt;a href="https://www.python.org/dev/peps/pep-0008/">PEP8 guidelines&lt;/a>. But not only that! Correcting the code with the &lt;code>pep8&lt;/code> tool won&amp;rsquo;t make it completely nice and clean. For example, PEP8 doesn&amp;rsquo;t care for unused imports, variables or too complex functions. That&amp;rsquo;s what you then use so-called linters for. They analyze your code and look for parts that could potentially or will cause errors.&lt;/p></description></item></channel></rss>