#rev #dotnet
Part of the [[CSAW 2022 Qualifier]] CTF.
# Description
Can you recover my files :( my grandson downloaded a binary from a .pcap to send to a consultant...
Files: [Conti.exe](https://mega.nz/file/fgFSgTLR#W6997tEkmN1_QvA3i78wwfopqRWiKDTTve2ZPdSzMME) [encryptedFiles.zip](https://mega.nz/file/KhtCXQBZ#5yyOMf7X7X7qGqPAXz5GkgIlC5gr_sg5K_TipAhZX4c)
# Analysis
The ZIP archive contains 12 files ending with `.EXTEN`. If we load the executable into ILSpy, the `Encrypt` method reveals how these files were created:
```csharp
private static void Encrypt(string filename)
{
Random random = new Random(1337);
byte[] array = new byte[32];
byte[] array2 = new byte[12];
random.NextBytes(array);
random.NextBytes(array2);
byte[] array3 = File.ReadAllBytes(filename);
byte[] array4 = new byte[array3.Length];
ChaCha7539Engine chaCha7539Engine = new ChaCha7539Engine();
chaCha7539Engine.Init(forEncryption: true, new ParametersWithIV(new KeyParameter(array), array2));
chaCha7539Engine.ProcessBytes(array3, 0, array3.Length, array4, 0);
string text = Path.GetDirectoryName(filename) + "\\encrypted\\";
if (!Directory.Exists(text))
{
Directory.CreateDirectory(text);
}
File.WriteAllBytes(text + Path.GetFileName(filename).Replace(Path.GetExtension(filename), ".EXTEN"), array4);
}
```
We can see that:
- A new pseudo-random number generator (`random`) is created with the seed `1337`.
- Two arrays (`array` and `array2`) are created and populated using `random`. Since it is always seeded with the same number, these two arrays will always be the same.
- `array3` is created and populated with the data of the file to be encrypted.
- `array4` is created with the same length as `array3`.
- A new instance of the ChaCha cipher (`chaCha7539Engine`) is created and initialised with `array` as the key and `array2` as the IV (both of which we can predict).
- `chaCha7539Engine` is used to encrypt `array3` (the file contents) and store the results in `array4`.
- `array4` is written to disk.
These observations mean that we need to:
- Recreate the PRNG to get the key and IV arrays.
- Use the key and IV to decrypt the files.
# Solution
## PRNG
While compiling a new .NET executable can be a rather cumbersome process, PowerShell lets use interact with .NET libraries quickly and easily.
We'll start by creating the PRNG instance, along with the two arrays:
```powershell
$random = [System.Random]::new(1337)
$key = New-Object byte[] 32
$iv = New-Object byte[] 12
```
Next we'll populate the arrays using the PRNG:
```powershell
$random.NextBytes($key)
$random.NextBytes($iv)
```
Finally we'll output them so that they can be loaded into Python:
```powershell
$key -join ", "
$iv -join ", "
```
Here is the output:
```plain
104, 0, 244, 199, 67, 94, 2, 170, 194, 124, 79, 217, 39, 252, 34, 39, 106, 137, 84, 178, 229, 18, 239, 30, 154, 247, 34, 126, 240, 54, 227, 40
165, 116, 212, 193, 23, 186, 227, 105, 199, 86, 230, 13
```
## Decryption
We could do the decryption in PowerShell but it is easier with Python and PyCryptodome.
We'll start by copying in the key and IV (along with the directory containing the encrypted files):
```python
KEY = bytes([104, 0, 244, 199, 67, 94, 2, 170, 194, 124, 79, 217, 39, 252, 34, 39, 106, 137, 84, 178, 229, 18, 239, 30, 154, 247, 34, 126, 240, 54, 227, 40])
IV = bytes([165, 116, 212, 193, 23, 186, 227, 105, 199, 86, 230, 13])
ENCRYPTED_FILES = Path(__file__).parent / "conti"
```
Next we will iterate over the files and read each one:
```python
for file in ENCRYPTED_FILES.iterdir():
encrypted = file.open("rb").read()
```
After that we'll create an instance of the ChaCha cipher using the arrays and use it to decrypt the files' contents:
```python
chacha = ChaCha20.new(key=KEY, nonce=IV)
decrypted = chacha.decrypt(encrypted)
```
Finally we will write each decrypted file back to disk with a `.dec` extension:
```python
(ENCRYPTED_FILES / f"{file.name}.dec").open("wb").write(decrypted)
```
After running the script the flag `flag{Cyb3r_Pun4_!$_n0W1}` could be found at the bottom of the PDF file `manifesto.EXTEN.dec`.
# Full Scripts
## PowerShell
```powershell
$random = [System.Random]::new(1337)
$key = New-Object byte[] 32
$iv = New-Object byte[] 12
$random.NextBytes($key)
$random.NextBytes($iv)
$key -join ", "
$iv -join ", "
```
## Python
```python
from pathlib import Path
from Crypto.Cipher import ChaCha20
KEY = bytes([104, 0, 244, 199, 67, 94, 2, 170, 194, 124, 79, 217, 39, 252, 34, 39, 106, 137, 84, 178, 229, 18, 239, 30, 154, 247, 34, 126, 240, 54, 227, 40])
IV = bytes([165, 116, 212, 193, 23, 186, 227, 105, 199, 86, 230, 13])
ENCRYPTED_FILES = Path(__file__).parent / "conti"
for file in ENCRYPTED_FILES.iterdir():
encrypted = file.open("rb").read()
chacha = ChaCha20.new(key=KEY, nonce=IV)
decrypted = chacha.decrypt(encrypted)
(ENCRYPTED_FILES / f"{file.name}.dec").open("wb").write(decrypted)
```