docs: restructure bootstrap section with two extraction methods
Method A (two-step): extract unpacker first, then run it. Method B (direct): extract file with single one-liner using rfind/LastIndexOf — bypasses Windows Execution Policy.
This commit is contained in:
@@ -38,32 +38,34 @@ powershell -File unpack.ps1 packed.png -All
|
|||||||
|
|
||||||
На целевой машине есть только `bootstrap.png` (созданный с `-SelfExtract`) и PowerShell.
|
На целевой машине есть только `bootstrap.png` (созданный с `-SelfExtract`) и PowerShell.
|
||||||
|
|
||||||
### 1. Извлечь unpack.ps1 однострочником
|
Два способа извлечения. Замените `IMG` на имя вашего файла.
|
||||||
|
|
||||||
Замените `IMG` на имя вашего файла:
|
### Способ A: двухшаговый (распаковщик → файл)
|
||||||
|
|
||||||
|
**Шаг 1.** Извлечь `unpack.ps1` — ищет **первый** payload:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
$d=[IO.File]::ReadAllBytes('IMG');$t=[Text.Encoding]::GetEncoding(28591).GetString($d);$s='PNGZIP';$i=-1;do{$i=$t.IndexOf($s,$i+1,[StringComparison]::Ordinal)}while($i-ge0-and($d[$i+6]-ne0-or$d[$i+7]-ne1));$p=$i+8;$nl=$d[$p]*256+$d[$p+1];$p+=2;$n=[Text.Encoding]::UTF8.GetString($d,$p,$nl);$p+=$nl;$pl=[uint64]0;for($k=0;$k-lt8;$k++){$pl=$pl*256+$d[$p+$k]};$p+=8;$ms=New-Object IO.MemoryStream;$ms.Write($d,$p+2,$pl-6);[void]$ms.Seek(0,0);$ds=New-Object IO.Compression.DeflateStream($ms,[IO.Compression.CompressionMode]::Decompress);$os=New-Object IO.MemoryStream;$ds.CopyTo($os);[IO.File]::WriteAllBytes($n,$os.ToArray());Write-Host "Extracted: $n"
|
$d=[IO.File]::ReadAllBytes('IMG');$t=[Text.Encoding]::GetEncoding(28591).GetString($d);$s='PNGZIP';$i=-1;do{$i=$t.IndexOf($s,$i+1,[StringComparison]::Ordinal)}while($i-ge0-and($d[$i+6]-ne0-or$d[$i+7]-ne1));$p=$i+8;$nl=$d[$p]*256+$d[$p+1];$p+=2;$n=[Text.Encoding]::UTF8.GetString($d,$p,$nl);$p+=$nl;$pl=[uint64]0;for($k=0;$k-lt8;$k++){$pl=$pl*256+$d[$p+$k]};$p+=8;$ms=New-Object IO.MemoryStream;$ms.Write($d,$p+2,$pl-6);[void]$ms.Seek(0,0);$ds=New-Object IO.Compression.DeflateStream($ms,[IO.Compression.CompressionMode]::Decompress);$os=New-Object IO.MemoryStream;$ds.CopyTo($os);[IO.File]::WriteAllBytes($n,$os.ToArray());Write-Host "Extracted: $n"
|
||||||
```
|
```
|
||||||
|
|
||||||
Ищет первый `PNGZIP` с байтами `\x00\x01` после — это встроенный `unpack.ps1`.
|
**Шаг 2.** Извлечь основной файл:
|
||||||
|
|
||||||
**Windows CMD** — готовый EncodedCommand-однострочник (с уже подставленным именем файла) выводится при паковке и сохраняется в метаданных PNG. Скопируйте из консоли или из свойств файла (Details → Comments).
|
|
||||||
|
|
||||||
### 2. Извлечь основной файл
|
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
powershell -File unpack.ps1 bootstrap.png
|
powershell -File unpack.ps1 bootstrap.png
|
||||||
```
|
```
|
||||||
|
|
||||||
### Однострочник (без bootstrap)
|
### Способ B: прямое извлечение файла (без распаковщика)
|
||||||
|
|
||||||
Извлечь последний payload напрямую (если self-extract не использовался). Замените `IMG` на имя файла:
|
Ищет **последний** payload — это сам файл. Не нужен `unpack.ps1`, обходит Execution Policy:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
$d=[IO.File]::ReadAllBytes('IMG');$t=[Text.Encoding]::GetEncoding(28591).GetString($d);$s='PNGZIP';$i=$d.Length;do{$i=$t.LastIndexOf($s,$i-1,[StringComparison]::Ordinal)}while($i-ge0-and($d[$i+6]-ne0-or$d[$i+7]-ne1));$p=$i+8;$nl=$d[$p]*256+$d[$p+1];$p+=2;$n=[Text.Encoding]::UTF8.GetString($d,$p,$nl);$p+=$nl;$pl=[uint64]0;for($k=0;$k-lt8;$k++){$pl=$pl*256+$d[$p+$k]};$p+=8;$ms=New-Object IO.MemoryStream;$ms.Write($d,$p+2,$pl-6);[void]$ms.Seek(0,0);$ds=New-Object IO.Compression.DeflateStream($ms,[IO.Compression.CompressionMode]::Decompress);$os=New-Object IO.MemoryStream;$ds.CopyTo($os);[IO.File]::WriteAllBytes($n,$os.ToArray());Write-Host "Extracted: $n"
|
$d=[IO.File]::ReadAllBytes('IMG');$t=[Text.Encoding]::GetEncoding(28591).GetString($d);$s='PNGZIP';$i=$d.Length;do{$i=$t.LastIndexOf($s,$i-1,[StringComparison]::Ordinal)}while($i-ge0-and($d[$i+6]-ne0-or$d[$i+7]-ne1));$p=$i+8;$nl=$d[$p]*256+$d[$p+1];$p+=2;$n=[Text.Encoding]::UTF8.GetString($d,$p,$nl);$p+=$nl;$pl=[uint64]0;for($k=0;$k-lt8;$k++){$pl=$pl*256+$d[$p+$k]};$p+=8;$ms=New-Object IO.MemoryStream;$ms.Write($d,$p+2,$pl-6);[void]$ms.Seek(0,0);$ds=New-Object IO.Compression.DeflateStream($ms,[IO.Compression.CompressionMode]::Decompress);$os=New-Object IO.MemoryStream;$ds.CopyTo($os);[IO.File]::WriteAllBytes($n,$os.ToArray());Write-Host "Extracted: $n"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Работает и для обычных packed-образов (без self-extract).
|
||||||
|
|
||||||
|
**Windows CMD** — готовые EncodedCommand-однострочники для обоих способов выводятся при паковке и сохраняются в метаданных PNG. Скопируйте из консоли или из свойств файла (Details → Comments).
|
||||||
|
|
||||||
## Очистка PNG
|
## Очистка PNG
|
||||||
|
|
||||||
Удалить все встроенные данные (payload, bootstrap-метаданные eXIf/tEXt):
|
Удалить все встроенные данные (payload, bootstrap-метаданные eXIf/tEXt):
|
||||||
|
|||||||
43
README.md
43
README.md
@@ -111,38 +111,53 @@ python3 pack.py --self-extract --self-extract-ps cover.png secret.tar.gz -o boot
|
|||||||
|
|
||||||
Это валидный PNG — пройдёт любую проверку на изображение.
|
Это валидный PNG — пройдёт любую проверку на изображение.
|
||||||
|
|
||||||
### 3. На VM — извлекаем распаковщик однострочником
|
### 3. На VM — два способа извлечения
|
||||||
|
|
||||||
Однострочник извлекает **первый** встроенный файл (распаковщик). Замените `IMG` на имя вашего файла:
|
#### Способ A: двухшаговый (распаковщик → файл)
|
||||||
|
|
||||||
**Python (Linux / macOS / PowerShell):**
|
**Шаг 1.** Извлечь распаковщик — однострочник ищет **первый** payload. Замените `IMG` на имя файла:
|
||||||
|
|
||||||
|
**Python:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 -c "d=open('IMG','rb').read();i=d.find(b'PNGZIP\x00\x01');nl=int.from_bytes(d[i+8:i+10],'big');n=d[i+10:i+10+nl].decode();pl=int.from_bytes(d[i+10+nl:i+18+nl],'big');import zlib;open(n,'wb').write(zlib.decompress(d[i+18+nl:i+18+nl+pl]));print('Extracted:',n)"
|
python3 -c "d=open('IMG','rb').read();i=d.find(b'PNGZIP\x00\x01');nl=int.from_bytes(d[i+8:i+10],'big');n=d[i+10:i+10+nl].decode();pl=int.from_bytes(d[i+10+nl:i+18+nl],'big');import zlib;open(n,'wb').write(zlib.decompress(d[i+18+nl:i+18+nl+pl]));print('Extracted:',n)"
|
||||||
```
|
```
|
||||||
|
|
||||||
**PowerShell (без Python):**
|
**PowerShell:**
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
$d=[IO.File]::ReadAllBytes('IMG');$t=[Text.Encoding]::GetEncoding(28591).GetString($d);$s='PNGZIP';$i=-1;do{$i=$t.IndexOf($s,$i+1,[StringComparison]::Ordinal)}while($i-ge0-and($d[$i+6]-ne0-or$d[$i+7]-ne1));$p=$i+8;$nl=$d[$p]*256+$d[$p+1];$p+=2;$n=[Text.Encoding]::UTF8.GetString($d,$p,$nl);$p+=$nl;$pl=[uint64]0;for($k=0;$k-lt8;$k++){$pl=$pl*256+$d[$p+$k]};$p+=8;$ms=New-Object IO.MemoryStream;$ms.Write($d,$p+2,$pl-6);[void]$ms.Seek(0,0);$ds=New-Object IO.Compression.DeflateStream($ms,[IO.Compression.CompressionMode]::Decompress);$os=New-Object IO.MemoryStream;$ds.CopyTo($os);[IO.File]::WriteAllBytes($n,$os.ToArray());Write-Host "Extracted: $n"
|
$d=[IO.File]::ReadAllBytes('IMG');$t=[Text.Encoding]::GetEncoding(28591).GetString($d);$s='PNGZIP';$i=-1;do{$i=$t.IndexOf($s,$i+1,[StringComparison]::Ordinal)}while($i-ge0-and($d[$i+6]-ne0-or$d[$i+7]-ne1));$p=$i+8;$nl=$d[$p]*256+$d[$p+1];$p+=2;$n=[Text.Encoding]::UTF8.GetString($d,$p,$nl);$p+=$nl;$pl=[uint64]0;for($k=0;$k-lt8;$k++){$pl=$pl*256+$d[$p+$k]};$p+=8;$ms=New-Object IO.MemoryStream;$ms.Write($d,$p+2,$pl-6);[void]$ms.Seek(0,0);$ds=New-Object IO.Compression.DeflateStream($ms,[IO.Compression.CompressionMode]::Decompress);$os=New-Object IO.MemoryStream;$ds.CopyTo($os);[IO.File]::WriteAllBytes($n,$os.ToArray());Write-Host "Extracted: $n"
|
||||||
```
|
```
|
||||||
|
|
||||||
**Windows CMD** — готовые однострочники с base64/EncodedCommand (не нужно менять имя файла) выводятся при паковке и сохраняются в метаданных PNG. Скопируйте из:
|
**Шаг 2.** Извлечь основной файл:
|
||||||
- Вывода `pack.py` / `pack.ps1` в консоли
|
|
||||||
- Свойств файла: правый клик → Свойства → Details → Comments
|
|
||||||
|
|
||||||
### 4. Извлекаем основной файл
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Python
|
python3 unpack.py bootstrap.png # Python
|
||||||
python3 unpack.py bootstrap.png
|
powershell -File unpack.ps1 bootstrap.png # PowerShell
|
||||||
|
|
||||||
# PowerShell
|
|
||||||
powershell -File unpack.ps1 bootstrap.png
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Дальше распаковщик уже есть на VM и можно передавать обычные packed-образы.
|
Дальше распаковщик уже есть на VM и можно передавать обычные packed-образы.
|
||||||
|
|
||||||
|
#### Способ B: прямое извлечение файла (без распаковщика)
|
||||||
|
|
||||||
|
Однострочник ищет **последний** payload — это сам файл. Не нужен `unpack.py` / `unpack.ps1`, обходит Windows Execution Policy. Замените `IMG` на имя файла:
|
||||||
|
|
||||||
|
**Python:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 -c "d=open('IMG','rb').read();i=d.rfind(b'PNGZIP\x00\x01');nl=int.from_bytes(d[i+8:i+10],'big');n=d[i+10:i+10+nl].decode();pl=int.from_bytes(d[i+10+nl:i+18+nl],'big');import zlib;open(n,'wb').write(zlib.decompress(d[i+18+nl:i+18+nl+pl]));print('Extracted:',n)"
|
||||||
|
```
|
||||||
|
|
||||||
|
**PowerShell:**
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$d=[IO.File]::ReadAllBytes('IMG');$t=[Text.Encoding]::GetEncoding(28591).GetString($d);$s='PNGZIP';$i=$d.Length;do{$i=$t.LastIndexOf($s,$i-1,[StringComparison]::Ordinal)}while($i-ge0-and($d[$i+6]-ne0-or$d[$i+7]-ne1));$p=$i+8;$nl=$d[$p]*256+$d[$p+1];$p+=2;$n=[Text.Encoding]::UTF8.GetString($d,$p,$nl);$p+=$nl;$pl=[uint64]0;for($k=0;$k-lt8;$k++){$pl=$pl*256+$d[$p+$k]};$p+=8;$ms=New-Object IO.MemoryStream;$ms.Write($d,$p+2,$pl-6);[void]$ms.Seek(0,0);$ds=New-Object IO.Compression.DeflateStream($ms,[IO.Compression.CompressionMode]::Decompress);$os=New-Object IO.MemoryStream;$ds.CopyTo($os);[IO.File]::WriteAllBytes($n,$os.ToArray());Write-Host "Extracted: $n"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Windows CMD** — готовые однострочники с base64/EncodedCommand (не нужно менять имя файла) для обоих способов выводятся при паковке и сохраняются в метаданных PNG. Скопируйте из:
|
||||||
|
- Вывода `pack.py` / `pack.ps1` в консоли
|
||||||
|
- Свойств файла: правый клик → Свойства → Details → Comments
|
||||||
|
|
||||||
### Очистка PNG от встроенных данных
|
### Очистка PNG от встроенных данных
|
||||||
|
|
||||||
Удалить все payload'ы (append, chunk) и bootstrap-метаданные (eXIf, tEXt) из PNG:
|
Удалить все payload'ы (append, chunk) и bootstrap-метаданные (eXIf, tEXt) из PNG:
|
||||||
|
|||||||
Reference in New Issue
Block a user