Utilizando expressões regulares para auxiliar no seu pentest white box, OSWE e AppSec

Seu cliente te contratou para um pentest white box? Está analisando o código fonte de uma aplicação? Fazendo uma exame em que scanners de código não são permitidos? Ou você trabalha com AppSec? Neste artigo irei demonstrar formas simples de procurar por vulnerabilidades em códigos fontes através de expressões regulares.

Afinal, o que são expressões regulares?

Expressões regulares ou regex são algoritmos que servem para buscar por palavras indefinidas durante o runtime de uma aplicação. Por exemplo, vamos supor que o desenvolvedor quer extrair de um texto todas as palavras que estão dentro de aspas, a sintaxe seria: /"[^"]*"/g. Perceba que neste algoritmo citado anteriormente existem duas aspas e dentro delas tem [^"]*, isso significa que será extraído todas as palavras dentro de aspas e que não possuem aspas na própria palavra.

As palavras e termos que serão extraídos vão de acordo com a vontade e necessidade do desenvolvedor. Existem também diversas outras sintaxes. Por exemplo, para extrair tags, atributos e elementos XML, Type Juggling, queries MySQL entre outras.

Trabalhando com regex em Python

No Python iremos trabalhar com a biblioteca “re”, que é a engine responsável por interpretar e processar expressões regulares.

import re

Podemos salvar o nosso texto e o regex em uma variável. O regex será responsável por extrair todas as palavras que estão dentro de aspas.

txt = 'Esta frase contém palavras entre aspas "boia", "carro", "veiculo"!'

regex = '"[^"]*"'

E então podemos utilizar a função “findall” para extrairmos e exibirmos todos os resultados do texto.

resultado = re.findall(regex, txt)

print(resultado)

E então executamos o nosso script:

Foi possível notar que o resultado foi uma lista de strings contendo todas as palavras dentro de aspas do texto. O funcionamento do regex é basicamente esse.

Em seguida, vamos desenvolver nossos próprios algoritmos para detectar vulnerabilidades comuns em PHP.

Entendendo e preparando um regex para detectar vulnerabilidades Type Juggling

Começaremos desenvolvendo um regex para extrair linhas de código possivelmente vulneráveis à Type Juggling. Basicamente, uma vulnerabilidade de Type Juggling é quando o desenvolvedor usa dois sinais de igual (==) para fazer uma comparação, ao invés de três (===). Isso faz com que, em determinadas combinações, o resultado da comparação seja true, ou seja, mesmo sabendo-se que os dois objetos são diferentes, a linguagem entende como se fossem iguais. Isso acontece porque usando dois sinais de igual o PHP não compara o tipo de objeto, apenas o valor do objeto.

Abaixo podemos ver uma tabela de comparações e seus respectivos valores booleanos.

Isso significa que, se fizermos if ( "php" == 0 )teremos um true como valor, já se fizermos if ( "1" == 1 ) também teremos true como valor.

E qual é o perigo disso?

Imagine que o atacante tenha controle do valor “senha” em um sistema de autenticação básica em PHP.

$user = "joao";

$senha = <entrada_atacante>; // Esperado uma string

if ( $user == "joao" && $senha == "myPassword123456" ){

echo "login efetuado!";

}

Se o atacante de alguma forma conseguir fazer com que a variável “$senha” seja o número 0, será feita uma autenticação com sucesso, já que qualquer string comparada com 0 terá o valor booleano true como resultado.

A solução para essa vulnerabilidade seria usar três sinais de igual (===), assim, o PHP vai comparar o valor e também o tipo do objeto.

if ( $user === "joao" && $senha === "myPassword123456" )

Seguindo estes critérios, podemos concluir que queremos extrair apenas linhas vulneráveis à Type Juggling. Então, como desenvolvemos a nossa expressão regular?

Primordialmente, você deverá fazer os testes no seu regex através de um site online. Particularmente, recomendo este site para você realizar os seus testes: https://regex101.com/. Nesse site você pode testar seu regex em diferentes linguagens, já que cada linguagem tem sua sintaxe. No caso, trabalharemos com a sintaxe em Python.

Desenvolvendo o nosso regex

Vamos utilizar o seguinte pseudocódigo como exemplo:

// Type Juggling Regex

if ( "0" == 0 )

if ( "0" === 0 )

Neste código fonte, temos uma linha vulnerável a Type Juggling e outra invulnerável, assim podemos nos certificar de que o regex detectará apenas o texto correto.

Começaremos detectando a keyword “if” + os possíveis espaços que poderiam ter após a keyword.

Observe que foi marcado a keyword “if” + 2 possíveis espaços antes do primeiro parêntese. Como isso aconteceu?

if[\s]{0,}

A expressão [\s]{0,} significa que será marcado 0 espaços ou mais depois do “if”, isso significa que independentemente da quantidade de espaços que o desenvolvedor coloca depois do “if” será marcado normalmente.

Em seguida, detectamos tudo oque estiver dentro dos dois parênteses, e, somente se, tiver dois sinais de igual (==) fazendo a comparação.

\([\s]{0,}.*[^=]==[^=].*\)

A expressão \([\s]{0,} serve para marcar o parêntese e todo espaço que vier depois, já que isso é algo indefinido e escolhido pelo próprio desenvolvedor do código fonte.

A expressão .*[^=]==[^=].* serve para marcar todo o conteúdo antes e depois dos dois sinais de igual (==) se, e somente se, for dois sinais de igual, nem mais, nem menos.

Obviamente não é possível explicar toda a expressão neste artigo, mas você pode dar uma olhada na documentação de RegEx do Python e praticar: https://www.w3schools.com/python/python_regex.asp

Aplicando no Python:

Código:

import re


txt2 = '''
// Type Juggling Regex
if  ( "0" == 0 )
if  ( "0" === 0 )
'''

print(re.findall('if[\s]{0,}\([\s]{0,}.*[^=]==[^=].*\)', txt2))

Algumas outras vulnerabilidades:

Hard-Coded Credentials:

Regex: (?<=.*(Password|Secret|Key).*(:|=)).*

Texto: AWS_SECRET_TEST=s23042e,0ddasd

Insecure HTTP Connection:

Regex: http:\/\/.*

Texto: http://user123:senha123@registry.com/project123/

SQL Injection:

Regex: \$query[\s]{0,}=[\s]{0,}['"].*['"] ou \$query[\s]{0,}=[\s]{0,}.*;

Texto: $query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";

Regex: \$query[\s]{0,}=[\s]{0,}['"].*\$.*['"]

Texto: $query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;"

Type Juggling:

Regex: if[\s]{0,}\([\s]{0,}.*[^=]==[^=].*\)

Texto: if ( "0" == 0 )

XSS:

Regex: echo[\s]{0,}.*\$.*

Texto: echo "xss vuln: ". $paramVulneravel . "test";

Agora que você entendeu como funciona as expressões regulares, recomendo praticar bastante e tentar fazer em outras vulnerabilidades.

JWT Secret Leak:

Regex: ((jwt.*key)|(key.*jwt)|(jwt.*secret)|(secret.*jwt))\s*=\s*["'].*["']

Texto: $jwt_key = "DJS83JSJS92JS93";

Bom desenvolvimento!

Leave a Reply

Your email address will not be published. Required fields are marked *

Copyright © 2024, Decripto.