Hi, I’m the author of ProjectO. To solve the challenge, player must reversing the game server to understand the protocol and mechanism.
A semi-auto game client is sufficient to gain the flag.
Though the binary is stripped, it’s not difficult to recognize it’s using some STLs in C++. But one should quickly realize that the layout of structures are differ from their equivalent in libc++. The concept is similar, it’s should not be a problem to figure out the correct layout. Here is the source code of MSVC STL. In case you have no idea about the libc++ STL, this is the tutorial made by flagbog.
Both of the code of server logic and the protobuf library were chosen as Release version at compile stage, but the information of protocol buffers wasn’t stripped. It helps to understand the functionality of the binary. The problem is how to send a valid request.
First step is to find out the vtable of protobuf, e.g the
balsn::Request::vftable is the vtable of
Request message in package
balsn. One of the functions in vtable contains the implementation of serialization. By following the function at
0x000140015A30, we can target the function responsible for serialization stored at
vtable+0x48, which is
A number in protobuf is represent by Variant Length Integer, the pattern can be observed in function
sub_140012B80, which also being called in
But it’s time consuming to review each of such functions of every types of message. Actually, after parsing a member of a message, the protobuf set a bit in the structure to indicate the present/absent of a member:
So, by following the usage of each message, we can construct the message now. Though the name of members are unimportant, you can find them in binary. The source code of message:
syntax = "proto2";
Besides the protobuf itself, the binary required client to send the length of the incoming protobuf, it looks like:
| (4 bytes) length of message | message |
The game is:
- 10 levels of random generated MAZE with 10 enemies and a portal to next level
- Have to kill 70 enemies to claim the flag after level 10
- Enemies won’t move and only slash it’s adjacent blocks every 3 turns
- Player only has 1 HP
- Connection timeout after 12 minutes