Blog
November 14, 2017

Solving containous/jobs

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

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.

About the Author

Emile Vauge is a developer. He created Traefik Proxy (the OSS project with over 3 billion downloads) and founded Traefik Labs where he leads the tech as CTO.

Latest from Traefik Labs

How to Keep Your Services Secure With Traefik’s Rate Limiting
Blog

How to Keep Your Services Secure With Traefik’s Rate Limiting

Read more
Taming The Wild West of LLMs with Traefik AI Gateway
Blog

Taming The Wild West of LLMs with Traefik AI Gateway

Read more
GitOps-Driven Runtime API Governance: The Secret Sauce for Scale
Webinar

GitOps-Driven Runtime API Governance: The Secret Sauce for Scale

Watch now

Traefik Labs uses cookies to improve your experience. By continuing to browse the site you are agreeing to our use of cookies. Find out more in the Cookie Policy.