Endless Christmas X-MAS CTF Writeup

This is a writeup for the Endless Christmas challenge, md5 hash 866c92038d6e9fc47db4424f71f6167a (download binary). It appeared in the X-MAS CTF, and it’s a Reverse challenge.

Using afl with Radare we can see there are calls to write and execve, both happening in main, a sign that this program creates (and maybe executes?) something else.

Putting a breakpoint just before the execve happens will reveal what file is being loaded (looking into the rax register).

I went down 60 rabbit holes disassembling this binary further, but the best thing we can do at this point is change point of view, step out of Radare, and launch the binary by itself – it certainly doesn’t seem to be doing anything nasty up to this point.

It takes some time before any output is shown, so this may be a sign that some decoding happens. The program creates a good number of other binaries which all look identical, albeit different from the original one (as their size shows), but that are actually different upon closer inspection with their md5 hashes.

Continue reading

On knowing when to stop in software development

One of the very few things I learnt in art class is what the role of Jackson Pollock was in his art. Because, we were asked, what is the role of the artist, if the only thing he does is let paint drop on a canvas? His role is to decide when the work is complete.

This is something we most often overlook in computer science: there comes a time when a project, or a feature, is complete, and any more improvements, any more work put into it is likely to decrease its value and ruin all the good work. Too often we want progress in our applications, without realizing that it’s actually destroying them. Sometimes it’s just better to move on and work on something else. Even if a solution is 10 years old, it doesn’t mean it has to be updated because progress requires it.

Let me present a couple examples.

The Gutenberg editor in WordPress

WordPress 5 introduced the new Gutenberg editor, a project that has been rated with 2 stars out of 5 with a total of around 2000 reviews at the time of writing. It’s a product that is so buggy and un-usable that it is bewildering that it made it into Core, but whatever (in 10 minutes of usage, I found 7 crucial and unreported bugs just 4 months prior to release – see my review).

gutenberg reviewsLet us pause and ponder why it was introduced. Any apology of Gutenberg will say that is because the classic editor felt old. It looked so much like Office 2003, and it’s 2018, they say! You see, they say, 15 years in computer science is a huge deal!

But, you see, what is the main purpose of an editor? To write. And to that it must be apt. Gutenberg shifted the focus from writing content to designing a page, effectively forcing a progress in the wrong direction. Not much has changed in writing since Office 2003 came around: we still use bold, italic, headings, text alignment and little more. Anything else requires the careful crafting of a designer and writing of some HTML, as it should be. Nothing else is needed, really, when it comes to writing. But, they say, you cannot even create a table with the classic editor! And I say, that’s right, it should be possible! But that doesn’t require trashing a whole editor and building a cumbersome React-y thing just so that we can have tables, does it?

But, they say, this way you don’t need a designer to design your pages anymore. Of course, people must be really stupid if they have been paying web-developers/designers to put up their websites for the last 25 years, of course! So stupid of us! There, instead of hiring a professional photographer to shoot at your weeding, just give a compact camera to your uncle, since technology and progress have enabled you to do so. Because it really is just the same. When I was a kid, websites designed with Dreamweaver were looked down on, and anybody who wanted a real site should have hired a professional. Not it looks like everybody can do everything – expect that, uhm, they can’t.

Too often the right questions are not asked and carefully considered. Those are the most basic ones: do we really need this thing? How difficult is it to build it? Is it really worth it? What is the impact it will have on users/market? Does it add something really useful and needed without breaking anything else?

Continue reading

Tasks un-owned are task that go forgotten

If you are a tech company, and your people commit code, then you probably have some code review policy. And if you do not, you definitely should: you want to have an extra pair of eyes on the code that goes live. You certainly do not want a mistake to break things. And that is why you do pull requests to contribute to GitHub repos, and why Google employees must have a certain degree of maturity to commit code without review.

BUT, as long as that is a good idea, we must be careful to implement it the right way. Just enforcing reviews is not enough. You want to make the time between the code is sent for review and the code is deployed as short as possible. The longer the review time span is, the more work will be needed when the review comes. That is because:

  1. Who wrote the code simply does not have it fresh in their mind anymore. The context switch between the current task and the code he wrote days/weeks ago is just more demanding;
  2. Conflicts are more likely to arise, and then more work is needed in solving them;
  3. Other issues may depend on the code being held for review. Other people may spend (waste) time debugging an issue for which a solution is already available;
  4. If the repo is public, it makes more difficult for other to jump in and contribute, because they also have to be aware of all the pending code.

The right way to implement a code review system in a tech company

I think the best way to implement a code review system is to:

  1. Assign each code review to a particular member of the team. If everybody owns a task, then nobody does as well. That is why you want that particular review to be a responsibility of someone specific. An automated system can randomly assign a review to a team member.
  2. Each code review comes with a deadline. That’s it: code reviews are as important as any other task – basically because every other task often generates a code review at some point, so if we lag on those, nothing gets carried to the end and we are getting no work done at all! We may have different priorities associated with different deadlines, but we want each review to expire at some point (with the longest being a couple days)!
  3. Team members can turn down their assignments, but only if they have a good reason to. Again, if code does not get reviewed, it cannot go live, and thus the work has been done for nothing. Reviews are important and must be considered as such.
  4. Then just track how it goes: who is turning down most assignments? Is the weight uniformly distributed across the team?

A/B testing on WordPress: a framework for developers and tutorial

Some months ago, I changed one link in the menu in my website postpaycounter.com. After that, it looked to me more people were purchasing products, i.e. the conversion rate had increased. But how to check whther that was really the case, or if it was just an accident/impression? Use an A/B test, I told myself!

With an A/B test, half of the users are served one version of the page, the one with the old link, and half of them another version of it, the one with the new link in place. When a sale happens, we may then log that as a success for the kind of page that was used, be it the A version or the B one.

In my case, the two versions of the page simply consisted of two different links in the menu, while I wanted the success to be logged when the user purchased something (I use Easy Digital Downloads to handle purchases).

I could find a bunch of plugins that allowed to set up A/B tests, but they all seemed pretty difficult to customize from a developer perspective, and I was already seeing myself wrestling with someone else’s code that provide tons of features useless to me, but through which was nearly impossible to interact with Easy Digital Downloads. So I decided to build my own, simple implementation, with the aim of it being tailored to developers rather than users who needed an interface. 

An A/B test implementation example

This is an example of how to use the little framework. To set up a test, you only need to provide two functions:

Continue reading

Numpy histogram density does not sum to 1

During a Computational Vision lab, while comparing histograms, I stumbled upon a peculiar behavior. The histograms pairwise kernel matrix – which is just a fancy name for the matrix holding histograms correlations one with another – did not have ones on the diagonal. This means that one histogram was not fully correlated to itself, which is weird.

numpy histogram integral not 1The comparison metric I was using is the simple histogram intersection one, defined as

    \[K_{hi} = \sum^{d}_{m=1}min(x_m,y_m)\]

Continue reading

The one time pad and the many time pad vulnerability

The scope of this article is to present the one time pad cipher method and its biggest vulnerability: that of the many time pad.

The one time pad: what it is and how it works

The one time pad is the archetype of the idea of stream cipher. It’s very simple: if you want to make a message unintelligible to an eavesdropper, just change each character of the original message in a way that you can revert, but that looks random to another person.

The way the one time pad works is the following. Suppose \mathcal{M} is the clear-text message you would like to send securely, of length |\mathcal{M}| = s. First, you need to generate a string \mathcal{K} of equal length |\mathcal{K}| = s. Then, you can obtain a cipher-text version of your message by computing the bitwise XOR of the two strings:

    \[\mathcal{M} \oplus \mathcal{K}\]

The best thing is that decoding is just the same as encoding, as the XOR operator has the property that \mathcal{X} \oplus \mathcal{X} = 0 \ \forall X (and that \mathcal{X} \oplus 0 = \mathcal{X} \ \forall \mathcal{X}). The only difference is that the cipher-text is involved in the XOR, rather than the clear-text:

    \[\mathcal{C} \oplus \mathcal{K} = \mathcal{M} \oplus \mathcal{K} \oplus \mathcal{K} = \mathcal{M} \oplus 0 = \mathcal{M}\]

Below is an example of the one time pad encoding achieved with Python, with a made-up pad string.

In the first section, result holds the XOR result. In the second part, the result and one_time_pad variables are XORed together to obtain the original plain-text message again.

It is not difficult to realize that the whole strength of the algorithm lies in the \mathcal{K} pad. Of course, as an attacker, if you can obtain \mathcal{K} in some way, then it is not difficult to get the clear-text message from the ciphered one as well.

Continue reading