# RefinedPool

Então, este post vai ser uma atualização do meu post anterior: [carregamento-por-proxy](https://vith0r.gitbook.io/public/malware-dev/posts/stack/carregamento-por-proxy "mention"), onde eu mostrei a técnica do **Paranoid Ninja** de carregamento de DLL por *proxy*. Mas, como já era de se esperar, já existem regras para detectar esse tipo de técnica.

Eu já tinha usado essa técnica do **Paranoid Ninja** em um projeto meu: [hell-code-loader](https://vith0r.gitbook.io/public/malware-dev/posts/injecao-de-processo/hell-code-loader "mention"), porque carregar a `amsi.dll` no processo “do jeito normal”, **no meu caso**, acabava fazendo o processo ser detectado como malicioso.

Eu não imaginava que já existisse algum outro projeto que refinasse essa técnica. E, de fato, quando eu fiz o projeto, eu não tinha encontrado nada nesse nível. Só que, há alguns dias, eu me deparei com este artigo: [evading-elastic-callstack-signatures](https://offsec.almond.consulting/evading-elastic-callstack-signatures.html), graças a um usuário aleatório do servidor do [yurirdev](https://github.com/yurirdev) ([link](https://discord.com/invite/websec)):

<figure><img src="https://3487725980-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fx3knx0LN2gJjRbyd1ua9%2Fuploads%2Fosq74rO7EfqW95TPghbv%2Fimage.png?alt=media&#x26;token=7df6b1e1-703f-4298-a21a-40aa4100c2db" alt=""><figcaption></figcaption></figure>

Eu não achava que esse projetinho ia virar um post, mas como estou meio pobre de ideias… melhor isso do que nada. 😅\
E sim: eu reaproveitei partes do meu próprio [**README**](https://github.com/Vith0r/RefinedPool/blob/main/README.md) do projeto ao longo do post, então não estranhe.

{% hint style="danger" %}
As informações que você encontrar neste post, técnicas, códigos, provas de conceito ou qualquer outra coisa são estritamente para fins educacionais.
{% endhint %}

***

### Trabalho original

Basicamente, o [trabalho/pesquisa](https://github.com/AlmondOffSec/LibTPLoadLib) realizado pelo [@SAERXCIT](https://github.com/SAERXCIT) possibilita inserir mais um “elemento” na **call stack**, quebrando assim a regra de detecção. É bem simples de entender.

A técnica original do **LibTPLoadLib** (detalhada [neste post](https://offsec.almond.consulting/evading-elastic-callstack-signatures.html)) funciona assim:

![diagrama](https://offsec.almond.consulting/images/evading-elastic-callstack-signatures/callback2_0_diagram.png)

* Isso quebra o [padrão de detecção do Elastic](https://github.com/elastic/protections-artifacts/blob/6e9ee22c5a7f57b85b0cb063adba9a3c72eca348/behavior/rules/windows/defense_evasion_library_loaded_via_a_callback_function.toml), que procura **call stacks** suspeitas durante o carregamento de bibliotecas.

**A abordagem original exigia:**

* Carregar uma DLL específica e *hardcoded* (`dsdmo_10.0.26100.1882.dll`) que contém o gadget.
* A DLL precisava ser colocada manualmente em `C:\dsdmo_10.0.26100.1882.dll`.
* Isso cria uma dependência meio “circular”: carregar uma DLL “suspeita” para evadir a detecção de carregamento de DLLs.

Eu vi isso mais como um obstáculo logo de cara. Com todo o respeito ao dono original do projeto, mas, para mim, publicar um PoC é algo que, quando você baixa, deveria ser só compilar e executar. Só que, nesse caso, você fica “obrigado” a procurar DLLs que tenham o gadget.&#x20;

No próprio README está escrito:

> **WARNING ⚠️**: This project is not usable as-is. The call gadget used for this PoC is no longer available in current versions of Windows. You'll have to find your own. [Read the blogpost for more info](https://offsec.almond.consulting/evading-elastic-callstack-signatures.html).

Tudo bem: o cara é o dono do projeto, e eu tenho mais é que agradecer do que reclamar. Mas, na minha cabeça, eu pensei:

> “Então, para carregar uma DLL, eu vou ter que já ter carregado na memória do processo atual uma DLL que tenha o gadget necessário?”

Aí eu pensei: “Beleza… então vamos escrever o gadget dentro de um *code cave* existente em alguma DLL que já esteja carregada na memória do processo.” Claro que isso tem vários pontos negativos (você vai estar escrevendo na memória de outra DLL já carregada), mas a vida é assim, né? 😄

***

### “Inovação”

Eu coloco entre aspas porque, sendo sincero, eu não inovei em nada. Eu só eliminei a necessidade de DLLs externas. Para fazer isso, eu implementei **injeção dinâmica em&#x20;*****code caves***.

Então, em vez de procurar gadgets pré-existentes em DLLs *hardcoded*, o [RefinedPool](https://github.com/Vith0r/RefinedPool):

1. **Enumera os módulos carregados** no processo atual.
2. **Localiza&#x20;*****code caves*** dentro de seções executáveis, especificamente:
   * Procura dentro dos limites de funções existentes usando o *Exception Directory* (`.pdata` / tabela `RUNTIME_FUNCTION`).
   * Busca sequências contínuas de bytes nulos ou instruções `INT3` (`0xCC`).
   * Garante que a *cave* tenha pelo menos 10 bytes para comportar o gadget.
3. **Escreve o gadget dinamicamente** no *code cave* descoberto:

   ```asm
   41 FF D2        ; call r10
   33 C0           ; xor eax, eax
   48 83 C4 28     ; add rsp, 0x28
   C3              ; ret
   ```
4. **Usa o gadget injetado** no *callback* do Thread Pool, assim como na técnica original.

***

### Vantagens

* **Sem dependências de DLLs externas**: funciona com módulos já carregados em memória.
* **Mais furtivo**: não há operações suspeitas de carregamento de DLL que possam disparar alertas.
* **Mais prático**: não depende de versões específicas do Windows nem de arquivos pré-posicionados.
* **Adaptação dinâmica**: pesquisa automaticamente em múltiplos módulos candidatos.
* **Ciente de funções (*****function-aware*****)**: prioriza posicionar gadgets dentro de limites legítimos de funções para “melhor furtividade”.

### Resultado na call stack

![resultado da execução do programa normal](https://i.imgur.com/sluvimD.png)

![resultado da execução transformando o projeto em shellcode RDI](https://i.imgur.com/OPocl8J.png)

***

### PIC shellcode?

Eu sou muito desatento e percebi que o projeto que eu fiz fugia um pouco da “IDEIA” que os projetos originais buscavam. Basicamente, se a gente ler o README do [LibTPLoadLib](https://github.com/AlmondOffSec/LibTPLoadLib), ele menciona o uso do [Crystal Palace](https://tradecraftgarden.org/crystalpalace.html).

O ponto que eu deixei passar é que o Crystal Palace é um *linker* especializado em criar **PIC (Position-Independent Code)** a partir de arquivos **COFF**. Ou seja:

* Aqueles projetos foram feitos para serem **bibliotecas (libs)**.
* Eles são “peças” que você encaixa em um *loader* de shellcode maior.

Então, eu não segui esse padrão de “lib modular para linker de shellcode”, e só fui perceber depois (TOP 10 TDAH). Mas isso não quer dizer que o projeto não possa ser aprimorado para virar algo do tipo!

Então eu decidi fazer um PoC só para mim kkkk e gerei uma shellcode PIC do projeto em si.\
Claro: eu tive que modificar "**bastante"** o código para conseguir fazer isso. No final, eu consegui gerar a shellcode PIC do projeto:

<figure><img src="https://3487725980-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fx3knx0LN2gJjRbyd1ua9%2Fuploads%2F8zJ0rx3f4rWk3hj404p0%2Fimage.png?alt=media&#x26;token=55a97e30-3189-4c42-ab40-a6d7c3f6576a" alt=""><figcaption></figcaption></figure>

Observando a print, dá para ver que não muda quase nada kk. A diferença real é que agora não foi executado uma SRDI como na print anterior. Então sim: dá para implementar e deixar esse código PIC, e não é nada difícil. Eu só não vou publicar o PIC dele porque vou usar esse mesmo código em outro projeto no futuro.

Você pode ver este vídeo para acompanhar a técnica e também para ver como ficaria o projeto caso fosse usado como uma shellcode PIC:

{% embed url="<https://youtu.be/Wc1keaCBuPI?si=V7ggncpYjbNw2ZgJ>" %}

***

### Agradecimentos

E, claro, eu tenho que deixar os meus mais sinceros agradecimentos ao [@AlmondOffSec](https://github.com/AlmondOffSec) e ao [@SAERXCIT](https://github.com/SAERXCIT) pela pesquisa e implementação originais, que tornaram este “aprimoramento” possível.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://vith0r.gitbook.io/public/malware-dev/posts/stack/refinedpool.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
