# clock\_out

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:

```bash
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
```

```shellscript
gdb ./clock_out
b *0x1106 #entry point, got it from info files
r
x/88bx 0x555555558060
```

***

Two pointers are initialized:

```c
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:

1. Reads one byte from the input:

   ```
   v6 = *a1;
   ```
2. Reads a 4-byte value from the table:

   ```
   v7 = *(_DWORD *)v3;
   ```
3. Computes the SHA256 hash of that single character.
4. Takes only the first 4 bytes of the resulting digest:

   ```
   v11[0]
   ```
5. Compares:

   ```
   v7 == v11[0]
   ```

So the effective validation rule per position is:

```python
first_4_bytes_of_SHA256(input[i]) == table[i]
```

After each iteration, the table pointer advances by 4 bytes:

```c
v3 += 4;
```

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:

```python
sha256(candidate.encode()).digest()[:4] == target_chunk
```

Since SHA256 is applied to a single byte and only 4 bytes are checked, brute-forcing over printable ASCII is extremely fast.

### Bruteforce Python Script

```python
from hashlib import sha256
import string

hex_data = "08 f2 71 88 3f 79 bb 7b e3 b9 8a 4d ca 97 81 12 6b 23 c0 d5 e6 32 b7 09 f6 7a b1 0a 02 1f b5 96 e3 b9 8a 4d de 7d 1b 72 62 c6 6a 7a 3f 79 bb 7b 39 73 e0 22 62 b6 7e 1f e3 b9 8a 4d 62 c6 6a 7a d2 e2 ad f7 aa a9 40 26 65 c7 4c 15 0b fe 93 5e 45 43 49 e4 d1 0b 36 aa"
data = bytes.fromhex(hex_data)
targets = []

for i in range(0, len(data), 4):
    chunk = data[i:i + 4]
    targets.append(chunk)

candidates = string.printable

for chunk in targets:

    for letter in candidates:
        hash = sha256(letter.encode()).digest()[:4]

        if hash == chunk:
            print(letter, end = "")
            break

```

*made by k0d*
