---
title: 'Αντίστροφη μηχανική CTF: Πρόγραμμα ελέγχου σημαίας DownUnderCTF — REA'
url: https://rea.tools/el/showcase/ctf/
---

[Αρχική](https://rea.tools/el/) / [Μελέτες](https://rea.tools/el/showcase/) / CTF

Μελέτη · DownUnderCTF 2023

# Βρείτε τη σημαία σε ένα δυαδικό αρχείο CTF.

Χρησιμοποιήστε το REA για να εξετάσετε ένα μικρό πρόγραμμα ελέγχου σημαίας, να μετατρέψετε τους κανόνες του σε εξισώσεις και να βρείτε μια είσοδο που κάνει το αρχικό πρόγραμμα να τυπώσει `Correct!`.

masked squares flag checker · Εύκολο · Linux x86-64

[Δείτε την αρχική πρόκληση](https://github.com/DownUnderCTF/Challenges_2023_Public/tree/b48f83db2984bc7fa2ec7879a32d7efb1be8d333/rev/masked-squares-flag-checker)

Από ένα δυαδικό αρχείο σε μια ελεγμένη απάντηση

1. 01 · Βρείτε τον έλεγχο

   **Συμβολοσειρές → συναρτήσεις ελέγχου**

   Το REA βρίσκει την προτροπή, τις αναφορές της και τον κώδικα που αποδέχεται ή απορρίπτει μια είσοδο.
2. 02 · Εξαγάγετε τους κανόνες

   **36 χαρακτήρες · 26 αθροίσματα**

   Το REA επιστρέφει τις εντολές και τα δεδομένα πίσω από κάθε έλεγχο. Ο βοηθός τα μετατρέπει σε εξισώσεις.
3. 03 · Λύστε και εκτελέστε

   **Ανακτημένη σημαία → Correct!**

   Ένα script Python λύνει τις εξισώσεις. Το REA καταγράφει την αποδοχή του αποτελέσματος από το αρχικό πρόγραμμα.

Η πρόκληση είναι του joseph και δημοσιεύτηκε στο επίσημο αποθετήριο του DownUnderCTF.

## Βρείτε τον κώδικα ελέγχου

Το παρεχόμενο αρχείο είναι ένα εκτελέσιμο 15 KB. Ζητά μια σημαία και έπειτα τυπώνει `Correct!` ή `Incorrect!`. Ξεκινήστε με ένα απλό αίτημα προς τον βοηθό σας.

Ο βοηθός προγραμματισμού σας

Χρησιμοποιήστε το REA για να αναλύσετε το ms_flag_checker και να βρείτε τη σημαία. Εξηγήστε πώς λειτουργούν οι έλεγχοι και έπειτα επαληθεύστε την απάντηση με το αρχικό πρόγραμμα.

Παράδειγμα προτροπής, με την πρόκληση που κατεβάσατε διαθέσιμη τοπικά και συνδεδεμένο πάροχο ανάλυσης κώδικα μηχανής.

1. #### Ακολουθήστε την προτροπή εισόδου μέχρι τη συνάρτησή της

   Βοηθός → REA

   ```
   open_binary
   {"path": "ms_flag_checker"}

   search_strings
   {"pattern": "flag|correct|wrong|input",
    "mode": "regex", "case_sensitive": false}

   xrefs
   {"address": "0x102004"}

   resolve_containing_procedure
   {"address": "0x10126d"}
   ```

   REA → βοηθός · επιλεγμένα αποτελέσματα

   ```
   0x102004  "What is the flag? "
   0x10201c  "Incorrect!"
   0x102027  "Correct!"

   Prompt referenced at: 0x10126d
   Containing function: 0x10124d
   ```

   Η αναφορά δίνει στον βοηθό ένα σημείο για διερεύνηση, παρότι τα αρχικά ονόματα συναρτήσεων του εκτελέσιμου έχουν αφαιρεθεί.
2. #### Διαβάστε το πρόγραμμα ελέγχου και τις δύο βοηθητικές συναρτήσεις του

   Βοηθός → REA

   ```
   analyze_function
   {"procedure": "0x10124d"}

   analyze_function
   {"procedure": "0x101189"}

   analyze_function
   {"procedure": "0x101217"}
   ```

   REA → βοηθός · επιλεγμένες εντολές

   ```
   0x1012c1: CMP EDI, 0x24
   0x1012c6: LEA RBX, [0x1040e0]
   0x1012cd: LEA RBP, [0x104060]
   0x1012d4: LEA R13, [RBX + 0x270]
   0x1012e1: CALL 0x00101189
   0x1012ec: CALL 0x00101217
   0x1012f1: CMP dword ptr [RBP], EAX
   0x1012f4: JNZ 0x00101335
   0x1012f6: ADD RBX, 0x18
   ```

   Ο πρώτος βρόχος αντιγράφει 36 κωδικούς χαρακτήρων. Ο βρόχος ελέγχου αποκωδικοποιεί μια μάσκα, αθροίζει τους επιλεγμένους κωδικούς και συγκρίνει το αποτέλεσμα με έναν αποθηκευμένο αριθμό. Τα βήματα των `0x18` byte σε `0x270` byte δίνουν 26 μάσκες.

Αυτά είναι επιλεγμένα αποτελέσματα από νέα ανάλυση του REA. Η τοπική διαδρομή του στόχου συντομεύεται για την εμφάνιση· οι διευθύνσεις αναφέρονται στην εικόνα που εισήγαγε το REA.

## Ένας έλεγχος αποκαλύπτει έναν χαρακτήρα

Το πρόγραμμα ελέγχου τοποθετεί την είσοδο σε πλέγμα 6×6. Μια μάσκα επιλέγει ποια κελιά συνεισφέρουν σε ένα άθροισμα. Η συμπαγής κωδικοποίησή της χρησιμοποιεί αρνητικούς αριθμούς για να παραλείπει κελιά και θετικούς για να τα επιλέγει.

![Η έβδομη μάσκα παραλείπει 21 κελιά, επιλέγει τη θέση 21 και έπειτα παραλείπει 14. Μόνο αυτό το κελί συνεισφέρει στο άθροισμα. Ο απαιτούμενος κωδικός χαρακτήρα του είναι 55, που σημαίνει ότι ο χαρακτήρας είναι 7.](https://rea.tools/assets/localized/el/figures/ctf-mask-equation.svg)

Ο έβδομος έλεγχος επιλέγει μία μόνο θέση. [Ανοίξτε το σχήμα](https://rea.tools/assets/localized/el/figures/ctf-mask-equation.svg).

### Διαβάστε τη μάσκα και την τιμή-στόχο της από το δυαδικό αρχείο

Βοηθός → REA · read_bytes

```
{"address": "0x1040e0", "length": 624}
{"address": "0x104060", "length": 144}
```

REA → βοηθός · έβδομες εγγραφές

```
Mask at 0x104170:
eb 01 f2 00  →  -21, +1, -14, stop

Target at 0x104078:
37 00 00 00  →  55
```

Η εντολή `MOVSX` διαβάζει τα byte της μάσκας ως προσημασμένες τιμές. Γι' αυτό το `eb` σημαίνει −21. Η τιμή-στόχος είναι ακέραιος little-endian. Μαζί, αυτά τα byte λένε στον βοηθό ότι `code[21] = 55`, άρα ο χαρακτήρας είναι `7`.

## Από τις εντολές σε έναν ευανάγνωστο έλεγχο

Επιλέξτε ένα βήμα για να συνδέσετε τη βοηθητική συνάρτηση αθροίσματος και τον καλούντα της με τον ίδιο κανόνα σε C.

REA · επιλεγμένες αρχικές εντολές

```
0x10121c: MOV ECX, 0x0

0x10122c: CMP dword ptr [RSI + RAX*0x1], 0x0
0x101230: JZ 0x00101223

0x101232: ADD ECX, dword ptr [RDI + RAX*0x1]

0x101223: ADD RAX, 0x4

0x1012f1: CMP dword ptr [RBP], EAX
0x1012f4: JNZ 0x00101335
```

Ευανάγνωστος κώδικας C · σύνοψη ενός ελέγχου

```
int check_one_mask(const int codes[36],
                   const int mask[36],
                   int target) {
    int total = 0;
    for (int i = 0; i < 36; ++i) {
        if (mask[i]) {
            total += codes[i];
        }
    }
    return total == target;
}
```

**01 · Ξεκινήστε από το μηδέν.** Ο `ECX` κρατά το τρέχον άθροισμα.

**02 · Ελέγξτε το κελί της μάσκας.** Η μηδενική τιμή παραλείπει τον χαρακτήρα· μια μη μηδενική τιμή τον συμπεριλαμβάνει.

**03 · Προσθέστε έναν κωδικό χαρακτήρα.** Ο ακέραιος της εισόδου στην ίδια μετατόπιση προστίθεται στο άθροισμα.

**04 · Μεταβείτε στο επόμενο κελί.** Ο αρχικός βρόχος προχωρά κατά τέσσερα byte ανά ακέραιο και διατρέχει έξι σειρές των έξι κελιών.

**05 · Συγκρίνετε με την αποθηκευμένη τιμή-στόχο.** Ο καλών λαμβάνει το άθροισμα στον `EAX`. Μια διαφορά οδηγεί σε άλμα στο `Incorrect!`.

Οι εντολές προέρχονται από τη βοηθητική συνάρτηση αθροίσματος και τον καλούντα της. Ο κώδικας C είναι μια επεξηγηματική σύνοψη με περιγραφικά ονόματα και έναν ενιαίο βρόχο 36 κελιών.

## Λύστε τις 26 εξισώσεις

Οι περισσότερες μάσκες επιλέγουν πολλά κελιά. Για παράδειγμα, ο πρώτος έλεγχος προσθέτει 16 κωδικούς χαρακτήρων και απαιτεί σύνολο 1441. Οι αλληλεπικαλυπτόμενες επιλογές δίνουν εξισώσεις που ένα μικρό script Python μπορεί να λύσει μαζί.

Python · απόσπασμα του λύτη

```
from z3 import Int, Or, Solver, Sum, sat

codes = [Int(f"code_{i}") for i in range(36)]
solver = Solver()
alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_{}"
for code in codes:
    solver.add(Or(*[code == ord(c) for c in alphabet]))
for code, char in zip(codes, "DUCTF{"):
    solver.add(code == ord(char))
solver.add(codes[-1] == ord("}"))

for selected, target in checks:
    solver.add(Sum([codes[i] for i in selected]) == target)

assert solver.check() == sat
model = solver.model()
print("".join(chr(model.eval(code).as_long()) for code in codes))
```

Το Z3 είναι ένας λύτης που βρίσκει τιμές οι οποίες ικανοποιούν αυτές τις εξισώσεις. Αυτό το απόσπασμα χρησιμοποιεί τους εξαγόμενους ελέγχους και υποθέτει μια σημαία `DUCTF{…}` με γράμματα, ψηφία, κάτω παύλες και άγκιστρα. Το πλήρες αρχείο λήψης περιλαμβάνει και τις 26 μάσκες και τιμές-στόχους.

[Λήψη του πλήρους λύτη](https://rea.tools/showcase/ctf/solve.py)

## Ελέγξτε την απάντηση με το αρχικό πρόγραμμα

Η καταγραφή διεργασίας του REA καταγράφει την αποδοχή της σημαίας που βρέθηκε από το αρχικό εκτελέσιμο. Η αλλαγή ενός επιλεγμένου χαρακτήρα από `z` σε `y` κάνει το πρώτο άθροισμα 1440 αντί για 1441 και το πρόγραμμα το απορρίπτει.

| Είσοδος | Παρατηρημένη έξοδος | Κωδικός εξόδου |
| --- | --- | --- |
| Σημαία του λύτη | `Correct!` | 0 |
| Ένας χαρακτήρας άλλαξε | `Incorrect!` | 255 |

Εμφάνιση της ανακτημένης σημαίας και της καταγεγραμμένης εξόδου

REA · έξοδος αρχικού προγράμματος

```
What is the flag? DUCTF{ezzzpzzz_07bcda7bfe81faf43caa}
Correct!
```

Η ανακτημένη τιμή συμφωνεί επίσης με τη σημαία στα δημοσιευμένα μεταδεδομένα της πρόκλησης των διοργανωτών, τα οποία ελέγχθηκαν μετά την επίλυση του δυαδικού αρχείου.


Πηγή, ταυτότητα στόχου και λεπτομέρειες ανάλυσης

Νέα ανάλυση και δύο καταγραφές διεργασίας στις 8 Οκτωβρίου 2026, με REA 4.1.0 και Ghidra 12.1.4 σε Linux x64. Το δυαδικό αρχείο είναι ELF x86-64 χωρίς σύμβολα, 15,248 byte.

Αρχικό εκτελέσιμο · SHA-256

```
dcd3bec4f608e11f3a12ce461100aaf5f621851ee63a1f870d7c90d4e3dd51ae
```

Οι αναφορές συμβολοσειρών, οι συναρτήσεις και οι σταθερές εξετάστηκαν πριν διαβαστεί ο πηγαίος κώδικας ή η λύση των διοργανωτών. Ο λύτης Python και το διάγραμμα δημιουργήθηκαν από αυτά τα αποτελέσματα του REA.

[Συγκρίνετε με τον πηγαίο κώδικα των διοργανωτών](https://github.com/DownUnderCTF/Challenges_2023_Public/blob/b48f83db2984bc7fa2ec7879a32d7efb1be8d333/rev/masked-squares-flag-checker/src/ms_flag_checker.c) · [Μεταδεδομένα και σημαία της πρόκλησης](https://github.com/DownUnderCTF/Challenges_2023_Public/blob/b48f83db2984bc7fa2ec7879a32d7efb1be8d333/rev/masked-squares-flag-checker/ctfcli.yaml) · [Σημειώσεις στοιχείων REA](https://github.com/morluto/rea/blob/main/website/evidence/ctf-masked-squares.md)

## Δοκιμάστε το μόνοι σας

Κατεβάστε την αρχική πρόκληση και τον λύτη σε έναν φάκελο. Χρησιμοποιήστε την παραπάνω προτροπή για να διερευνήσετε με τον βοηθό σας ή εκτελέστε το παρεχόμενο script.

[Λήψη της αρχικής πρόκλησης](https://raw.githubusercontent.com/DownUnderCTF/Challenges_2023_Public/b48f83db2984bc7fa2ec7879a32d7efb1be8d333/rev/masked-squares-flag-checker/publish/ms_flag_checker)[Λήψη λύτη](https://rea.tools/showcase/ctf/solve.py)

Τερματικό · επίλυση και εκτέλεση

```
python3 -m venv .venv
.venv/bin/python -m pip install z3-solver
.venv/bin/python solve.py

chmod +x ms_flag_checker
./ms_flag_checker
```

Το script τυπώνει μια υποψήφια σημαία· επικολλήστε τη στην προτροπή του προγράμματος. Η επίλυση απαιτεί Python και `z3-solver`. Η εκτέλεση του αρχικού εκτελέσιμου απαιτεί Linux x86-64.

[Ρυθμίστε το REA με τον βοηθό προγραμματισμού σας](https://rea.tools/get-started/)
