Solving containous/jobs

Last year, we had this idea to create a little puzzle to hire new engineers on Traefik.

⚡️We are hiring⚡️$ docker run containous/jobs— Traefik (@traefik) December 15, 2016

As we are deeply linked to Docker on this project, we thought it would be great to focus on technical challenges around containers. So we pushed a Docker image:

$ docker run containous/jobs
Do you like puzzles ?

Few people informed us that our image must have an issue as it was only printing Do you like puzzles ?. Yup. That was the whole point. Something was indeed hidden here, and you had to find it 😉

Let’s jump into it!

First of all, how is made containous/job ?

Not really helpful… But there seems to be two files copied during the build process. docker inspect containous/jobs shows that /default is the entrypoint. Another file should be hidden there 😃

If we export the container file system using docker export, we see that there is our /default binary, and there is also, surprisingly, another binary: /secret. Wow ! Let’s test something…

Lineception… Kill me… Just kill me…

OK, so our container is not exiting anymore, until we press enter and then we get Game over :’(. Hum, not that easy 🤔

Kill me… Just kill me…

If we try to kill the container, it exits, but this time, without printing Game over :’(. Ha ! Let’s try with another kill signals then ! After few tries, you will end up using SIGABRT:

A wonderful stack trace is now on the screen. We can see that this binary has been created using go 1.7, and that the repository of the code is bitbucket.org/containous/jobs. Wait a minute… What ?

WE JUST FOUND WHERE IS HOSTED THE SOURCE CODE !!!

Damn private repository…

Let’s start from the beginning. If we look closely at each step, we used every piece of clue given by our Docker image. Except one:

Lineception…

Lineception = line + inception

Which line of our code is called when calling kill with SIGABRT?

bitbucket.org/containous/jobs/cmd/secret/secret.go:15

And now:

And that’s it!

It seems that the final part was a bit too complex as a lot a people found alternatives solutions. Many of you discovered a base 64 encoded string right into the binary:

V2VsbCBkb25lIQ0KV2Ugd291bGQgbG92ZSB0byBrbm93IG1vcmUgYWJvdXQgeW91Lg0KUGxlYXNlIHNlbmQgdXMgYSBtYWlsIGF0IGpvYnMgYXQgY29udGFpbm8udXMgYW5kIHRlbGwgdXMgaG93IHlvdSBzb2x2ZWQgdGhpcyBwdXp6bGUgYW5kIHdoeSB5b3Ugd2FudCB0byB3b3JrIGF0IENvbnRhaW5vdXMgOikNCig1MCB3b3JkcyBtYXgpDQo=

And yes, once decoded, you get straight away:

Well done!
We would love to know more about you.
...

In fact, very few people found the right solution using the line number. I would like to congratulate Cédric Nisio who was the first who solved this puzzle. Well done 👏👏👏

We really loved to read your feedback and answers on this little game and we think it’s now time to try something new 😉

Thanks to Vincent Demeester.

This is a companion discussion topic for the original entry at https://containo.us/blog/solving-containous-jobs-b4a5cae04f3/