Init. commit
This commit is contained in:
60
reverse-ptitsa-govorun/WRITEUP.md
Normal file
60
reverse-ptitsa-govorun/WRITEUP.md
Normal file
@@ -0,0 +1,60 @@
|
||||
<h1 align="center">Птица Говорун</h1>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/category-Reverse-blueviolet" alt="Reverse"/>
|
||||
<img src="https://img.shields.io/badge/points-1000-critical" alt="1000 pts"/>
|
||||
</p>
|
||||
|
||||
Получаем на старте Windows x64 бинарь `challenge.exe`. Сначала программа проверяет окружение, потом собирает из найденных значений ключ, и только затем расшифровывает вшитый массив байт. Флаг покажется лишь если все три проверки окружения сойдутся с ожидаемыми значениями.
|
||||
|
||||
## Решение
|
||||
|
||||
Открываем в Ghidra или IDA — и видим три проверки:
|
||||
|
||||
| Артефакт | Откуда берётся | Ожидаемое значение |
|
||||
|---|---|---|
|
||||
| MAC-префикс | `GetAdaptersInfo()` | `00:0C:29` |
|
||||
| Имя компьютера | `GetComputerNameA()` | `CHALLENGE-PC` |
|
||||
| Гипервизор | `cpuid` leaf `0x40000000` | `VMwareVMware` |
|
||||
|
||||
Все три куска склеиваются в материал ключа:
|
||||
|
||||
```text
|
||||
000C29CHALLENGE-PCVMwareVMware
|
||||
```
|
||||
|
||||
От этой строки считается SHA-256, и все 32 байта хеша идут как XOR-ключ для зашифрованного флага. После расшифровки программа ещё раз считает SHA-256 от результата и сравнивает с зашитым эталоном — сошлось, печатает флаг.
|
||||
|
||||
> **CPUID leaf `0x40000000`** — стандартизованный интерфейс обнаружения гипервизора. Vendor возвращает 12 ASCII-символов в `EBX:ECX:EDX`: VMware — `VMwareVMware`, Hyper-V — `Microsoft Hv`, KVM — `KVMKVMKVM`, VirtualBox — `VBoxVBoxVBox`. На реальном железе leaf возвращает нули. Детали — в [Microsoft Hypervisor TLFS](https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/feature-discovery).
|
||||
|
||||
Предполагаемый путь — просто собрать окружение под эталон: запустить Windows внутри VMware, переименовать компьютер в `CHALLENGE-PC`, убедиться, что MAC первого адаптера начинается с `00:0C:29`, и запустить `challenge.exe`. Строку `VMwareVMware` VMware и так сама возвращает через CPUID, её отдельно подделывать не нужно. А если не повезло и MAC выпал с неправильным префиксом, его легко зафиксировать вручную в `.vmx`:
|
||||
|
||||
```text
|
||||
ethernet0.addressType = "static"
|
||||
ethernet0.address = "00:0C:29:AA:BB:CC"
|
||||
```
|
||||
|
||||
Однако, можно не возиться с виртуалкой — всё нужное уже лежит в бинарнике: и материал ключа, и сам зашифрованный массив xD
|
||||
|
||||
Воспроизводим алгоритм на Python и получаем флаг локально:
|
||||
|
||||
```python
|
||||
import hashlib
|
||||
|
||||
key_material = "000C29CHALLENGE-PCVMwareVMware"
|
||||
key = hashlib.sha256(key_material.encode()).digest()
|
||||
|
||||
enc = bytes([
|
||||
0xf9, 0x10, 0x70, 0x63, 0xa3, 0x57, 0x19, 0xb5,
|
||||
0x38, 0x6e, 0x11, 0xb1, 0xfe, 0xf6, 0x6f, 0x4c,
|
||||
0xf3, 0x07, 0x65, 0x50, 0xf3, 0x03, 0x51, 0xf4,
|
||||
0x0a, 0x50, 0x42, 0xb2, 0xb9, 0xf1, 0x3e, 0x5b,
|
||||
0xa3, 0x0c
|
||||
])
|
||||
|
||||
flag = bytes(enc[i] ^ key[i % 32] for i in range(len(enc)))
|
||||
print(flag.decode())
|
||||
```
|
||||
|
||||
## Флаг
|
||||
`caplag{vm_detective_1337_a7f3b2c9}`
|
||||
Reference in New Issue
Block a user