Hi everybody, it’s a shiny new day for a write-up!
The past two days were really busy in ZenHack headquarter:
we decided to deep dive into Swamp CTF!

The write-up I want to show you is the solution of Journey, the second Reversing challenge.
This is a samplle output of the program:

As you play this game, there will be many adventures for you to take,
quests on the side of this great journey.
This is one of the quests here, and you may not know it yet. You will
know when you complete the test, because all of the die will have been
cast in your favor.
Prove your worth, enter a password to continue!
> I'm a Tucano
Mission failed! You must try again, giving up was never an answer if
you have gotten this far!

Basically, it wants a password. Let’s try to guess what it does with radare2.
But first, I have to unpack the binary with UPX (yes, it was all scrambled…).

The binary is now readable!

The main function of journey just print that wall of text. There is a scanf:

FIRST TRICKY PART

What’s that strange sym.__moddi3?
It’s basically a%b, where a,b -> long. This is why there are two push on the stack for each argument.
The first one is BIGNUM (divided in HIGH and LOW), while the second is 10 (in 64 bit, so 63 \x00 and then \x0a).
Then, the reminder result is put in VARIABLE.

Wait wait wait wait. There is a comparison between 0 and the result of that function.
Which arguments does it take? The input string and… a constant string.
Remember that Journey manipulated INPUTSTR with reminders, divisions, subtractions and so on.
If the result is zero, then it prints a greetings (the flag is flag{<INPUTSTR>}).
The binary isn’t stripped, so… which function is that?
It’s a normal strcmp, dynamically linked using the .plt.got table:

So, if the manipulated string is equal to theresanotherstep the job is done.

All the ingredients have been introduced. Let’s hack this challenge!

The Intuition

If you didn’t fell asleep until now than you’re only few steps away to the solution. Let me recap what does Journey do:

Takes an input string -> INPUTSTR

for each char in INPUTSTR:

it calculates INPUTSTR[i] = INPUTSTR[i] - BIGNUM & 10

BIGNUM=BIGNUM/10

check if the manipulated string is equal to a const string.

What does it mean to divide and take the mod of a long int number?

It’s simple: extract the last digit of the number. So, the algorithm subtracts the last digit of BIGNUM from
INPUTSTR. Given the const string, here I present the algorithm I used to reverse the process: