Init. Commit
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
<h1 align="center">PYZ Sidecar</h1>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/category-Reverse-blueviolet" alt="Reverse"/>
|
||||
<img src="https://img.shields.io/badge/difficulty-easy-brightgreen" alt="easy"/>
|
||||
</p>
|
||||
|
||||
В раздатке есть файл `LineSigner.bin` с Python-утилитой для подписи отчётов. Файл начинается со строк `#!/bin/sh` и `exit 1`. Ищем данные утилиты после этой shell-обёртки.
|
||||
|
||||
## Решение
|
||||
|
||||
Находим маркер `PYZSIDECARv1\x00`. После него записаны длина блока в формате `u32 LE` и zlib-поток. Распаковываем блок и получаем сериализованный через `marshal` объект Python-кода.
|
||||
|
||||
Артефакт собран под **Python 3.13**, эту же версию используем для разбора. У `marshal` нет совместимости байткода между произвольными версиями интерпретатора.
|
||||
|
||||
```python
|
||||
from pathlib import Path
|
||||
import dis
|
||||
import marshal
|
||||
import zlib
|
||||
|
||||
data = Path("public/LineSigner.bin").read_bytes()
|
||||
pos = data.index(b"PYZSIDECARv1\x00") + len(b"PYZSIDECARv1\x00")
|
||||
size = int.from_bytes(data[pos:pos + 4], "little")
|
||||
code = marshal.loads(zlib.decompress(data[pos + 4:pos + 4 + size]))
|
||||
dis.dis(code)
|
||||
```
|
||||
|
||||
Внутри видна функция `verify(report_id)`. Она собирает результат из трёх строковых констант:
|
||||
|
||||
```python
|
||||
"caplag{pyz_o" + "ffset_showed_" + "the_signing_secret}"
|
||||
```
|
||||
|
||||
Соль `line-signer-2025` к этим кускам не относится. Можно восстановить строку по константам и дизассемблированию. Приложенный солвер выполняет извлечённый код и вызывает `verify("report-17")`.
|
||||
|
||||
[Солвер](solve/solve.py).
|
||||
|
||||
## Флаг
|
||||
|
||||
`caplag{pyz_offset_showed_the_signing_secret}`
|
||||
Reference in New Issue
Block a user