The validation logic is implemented in the function:
_BOOL8 __fastcall sub_1260(char *a1, int a2)
a1 is a pointer to the user input and a2 represents the expected length. By inspecting the global array unk_4060, we see that it contains 88 bytes. Since the code reads the table in 4-byte chunks (_DWORD), this corresponds to 22 entries, meaning the expected input length is 22 characters.
Since we know that PIE is enabled from:
checksec./clockout
We can find the Base Address with using vmmap in GDB then find the &unk_4060 values.
Base Address:
0x555555554000
Static &unk_4060 address (from IDA)
0x000000000004060
⇒ Real Address = 0x555555554000 + 0x000000000004060 = 0x555555558060
gdb./clock_outb*0x1106#entry point, got it from info filesrx/88bx0x555555558060
Two pointers are initialized:
v3 =&unk_4060;v5 =&unk_4060 +4* a2;
This sets up traversal over the table of 22 DWORD values.
Inside the loop, for each character of the input, the function performs:
Reads one byte from the input:
Reads a 4-byte value from the table:
Computes the SHA256 hash of that single character.
Takes only the first 4 bytes of the resulting digest:
Compares:
So the effective validation rule per position is:
After each iteration, the table pointer advances by 4 bytes:
This means each character of the input is checked independently against a corresponding 4-byte value in unk_4060.
There is additional logic in the function involving a variable that is incremented and decremented, but this does not affect how the correct characters are determined. For the purpose of recovering the flag, that logic is irrelevant and can be ignored. What matters is only the hash comparison.
Because each character is validated independently, the solution strategy is straightforward:
Extract the 88 bytes from unk_4060
Split them into 22 chunks of 4 bytes
For each chunk, brute-force possible characters
Compute SHA256(candidate)
Compare the first 4 bytes of the digest with the target chunk
The cleanest implementation compares raw bytes directly:
Since SHA256 is applied to a single byte and only 4 bytes are checked, brute-forcing over printable ASCII is extremely fast.