Books are a great thing. And since libraries are a big amount of books you can read in one place, they’re great, too.

But this secret library some guys started is a bit different. You have to know the exact title of a book to get it, you can’t look around. So you have to know another person in the library who knows some book titles or you won’t be able to read anything. A bit like an invite-only library.

This whole thing seems weird. Could you poke around and try to figure out what they’re up to? If you could grab one of their books, that would be awesome.

connect to school.fluxfingers.net:1527
download

Challenge Overview

To solve this challenge we need to reverse an ELF 64-bit binary. The user can interact with the program by submitting different “magic words” (8-digit hexadecimal numbers), which trigger different actions; for example, the magic word 420B65F7 permits the user to authenticate itself, while F1140B88 prints the content of a book, and so on.

After a bit of reversing, we summarized the logic of the program with the following pseudocode (relevant parts only):

library_card = 0

while True:
input = read_magic_word()

if input == "952A7224": # print the books titles
if library_card == "00278F03":
print_books_titles()
else:
print_not_authorized()

...

if input == "420B65F7": # authenticate
library_card = read_magic_word()
if library_card == "00278F03":
if can_prove_it():
print_welcome_back_librarian()
else:
print_you_are_not_the_librarian()
library_card = 0
else:
print_ok()

...

From the code we can see that there is a special user with library card 00278F03 - the head librarian - which is allowed to see the titles of all the books contained in this secret library. As the challenge description suggests, we can’t read the content of any book without knowing its name, and the only way to know the books titles is to authenticate as the head librarian.

~ ➤ nc school.fluxfingers.net 1527
hi! this is the secret library. if you want me to speak to you, you need to know the magic words.
420B65F7
alright, show me your library card.
00278F03
oh, you say you're the head librarian? prove it!
which book am I thinking of? tell me the level where it can be found.
13371337
uh, no, that's not the level where that book is. I don't believe you.

Unfortunately, by looking at the disassembled code we found it is not possible to bypass the can_prove_it() check, since it will require to blindly guess a lot of bytes picked from /dev/urandom. We must look for different ways to set the library card to 00278F03 and then print the list of book titles.

The “WTF is that doing there” moment

After a lot of time spent on the wrong track, we finally caught a very suspicious syscall in the middle of the following (decompiled) function:

signed __int64 __fastcall sub_400AF6(char a1)
{
signed __int64 result; // rax@2

if ( a1 > 47 )
{
if ( a1 > 57 )
{
if ( a1 > 64 )
{
if ( a1 > 70 )
result = 0xFFFFFFFFLL;
else
result = (unsigned int)(a1 - 55);
}
else
{
__asm { syscall }
result = 0xFFFFFFFFLL;
}
}
else
{
result = (unsigned int)(a1 - 48);
}
}
else
{
result = 0xFFFFFFFFLL;
}
return result;
}

This function is executed for every character of any magic word read by the program; if the character is one of 0123456789ABCDEF, then it simply returns its decimal value, otherwise -1.
But, in addition, if the character is one of :;<=>?@ (ascii code greater than 57 and less or equal to 64), then the function will also execute that strange syscall. Its disassembly is the following:

0x00400b21   mov rax, 0xe
0x00400b28 mov rdi, 0
0x00400b2f mov rsi, 0
0x00400b36 mov rdx, 0x603397
0x00400b3d mov r10, 8
0x00400b44 syscall

The syscall apparently sets the byte at 0x603397 to zero. How this can be useful to us? Well, by inspecting a little more the binary we found that the library card is stored at 0x603394 using four bytes; thus, the syscall will overwrite its most significative byte with zero! And, if you remember, the head librarian card starts exactly with the null byte ;)

The solution

We need first to authenticate (using the magic word 420B65F7) with a library card that is equal to the one of the head librarian except for the most significative byte (e.g. 11278F03); then, we input the very magic word 1337:123 to simply trigger the syscall that will zero the msb of the previously insterted library card. Finally, since we are now authenticated as the head librarian, we print the books titles (using the magic word 952A7224):

~ ➤ nc school.fluxfingers.net 1527
hi! this is the secret library. if you want me to speak to you, you need to know the magic words.
420B65F7
alright, show me your library card.
11278F03
alright!
1337:123
warning: invalid hexchar ';'
you do know the magic words, right?
952A7224
sure! the head librarian is allowed to know about all the books!
------------
16F7F4D391F030CF
------------

So, the library has only one book named 16F7F4D391F030CF. We can read the content of a book with the magic word F1140B88:

F1140B88
you want me to show you a book? certainly! just tell me the name of the book.
16F7F4D3
91F030CF
oh, yes, we have that! here you go...
flag{our_secret_is_that_we_really_just_have_this_one_book}

====================

\o/