This challenge spawns a listening socket that takes 4 bytes. Then; it ANDs this with 0xFF (so effectively only uses one byte) and feeds it to a function that decodes a piece of code in the executable (hence the expression ‘greek to me’; there’s code in there that is unreadable).

I extracted the hash function and encoded data from the binary to be able to easely brute-force it:

#include <stdint.h>
#include <string.h>
#include <stdio.h>

const char magic[] = {
	0x33, 0xe1, 0xc4, 0x99, 0x11, 0x06, 0x81, 0x16, 0xf0, 0x32, 0x9f, 0xc4, 0x91, 0x17, 0x06, 0x81,
	0x14, 0xf0, 0x06, 0x81, 0x15, 0xf1, 0xc4, 0x91, 0x1a, 0x06, 0x81, 0x1b, 0xe2, 0x06, 0x81, 0x18,
	0xf2, 0x06, 0x81, 0x19, 0xf1, 0x06, 0x81, 0x1e, 0xf0, 0xc4, 0x99, 0x1f, 0xc4, 0x91, 0x1c, 0x06,
	0x81, 0x1d, 0xe6, 0x06, 0x81, 0x62, 0xef, 0x06, 0x81, 0x63, 0xf2, 0x06, 0x81, 0x60, 0xe3, 0xc4,
	0x99, 0x61, 0x06, 0x81, 0x66, 0xbc, 0x06, 0x81, 0x67, 0xe6, 0x06, 0x81, 0x64, 0xe8, 0x06, 0x81,
	0x65, 0x9d, 0x06, 0x81, 0x6a, 0xf2, 0xc4, 0x99, 0x6b, 0x06, 0x81, 0x68, 0xa9, 0x06, 0x81, 0x69,
	0xef, 0x06, 0x81, 0x6e, 0xee, 0x06, 0x81, 0x6f, 0xae, 0x06, 0x81, 0x6c, 0xe3, 0x06, 0x81, 0x6d,
	0xef, 0x06, 0x81, 0x72, 0xe9, 0x06, 0x81, 0x73, 0x7c

const int len = 121;

int32_t __declspec(naked) hashfunc(char * a1, int32_t a2) {
	__asm {
		push ebp
		mov ebp, esp
		push ecx
		mov edx, dword ptr ss : [ebp + 0x0C]
		mov ecx, 0xFF
		mov dword ptr ss : [ebp - 4], ecx
		test edx, edx
		je J124A
		push ebx
		mov ebx, dword ptr ss : [ebp + 8]
		push esi
		push edi
		push 14
		pop eax
		mov di, word ptr ss : [ebp - 4]
		cmp edx, eax
		mov esi, edx
		cmova esi, eax
		sub edx, esi
		movzx eax, byte ptr ds : [ebx]
		add di, ax
		mov word ptr ss : [ebp - 4], di
		add ecx, dword ptr ss : [ebp - 4]
		inc ebx
		sub esi, 1
		jne J120F
		movzx eax, byte ptr ss : [ebp - 4]
		shr di, 8
		add ax, di
		movzx eax, ax
		mov dword ptr ss : [ebp - 4], eax
		movzx eax, cl
		shr cx, 8
		add ax, cx
		movzx ecx, ax
		push 14
		pop eax
		test edx, edx
		jne J1202
		pop edi
		pop esi
		pop ebx
		movzx edx, byte ptr ss : [ebp - 4]
		mov eax, ecx
		shl ecx, 8
		and eax, 0xFF00
		add eax, ecx
		mov cx, word ptr ss : [ebp - 4]
		shr cx, 8
		add dx, cx
		or ax, dx
		mov esp, ebp
		pop ebp
		ret }

uint16_t guess(uint8_t inp) {
	uint16_t hash;
	char b[121];
	memcpy(b, magic, len);

	for (int x = 0; x < len; x++) {
		b[x] = (b[x] ^ inp) + 34;

	hash = hashfunc(b, len);	
	return hash;

int main(void) {
	for (uint8_t i = 0; i < 255; i++) {
		uint16_t hash = guess(i);
		printf("%02X = %04X\n", i, hash);
		if (hash == 0xFB5E) {
	return 0;

The key turns out to be A2 00 00 00. On sending this to the socket, we get the following message:

Congratulations! But wait, where's my flag?

The debugger provides the answer:

Flag in debugger