PHP Tricks
Powszechne lokalizacje plików cookies:
To również dotyczy plików cookies phpMyAdmin.
Lokacje:
Ominięcie porównań w PHP
Luźne porównania/Type Juggling ( == )
Jeśli w PHP używane jest ==
, mogą wystąpić 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ć, czy typ porównywanych danych jest taki sam, musisz użyć ===
.
Tabele porównań w PHP: https://www.php.net/manual/en/types.comparisons.php
"string" == 0 -> True
Ciąg znaków, który nie zaczyna się od liczby, jest równy liczbie"0xAAAA" == "43690" -> True
Ciągi złożone z liczb w formacie dziesiętnym lub szesnastkowym można porównać z innymi liczbami/ciągami z wynikiem True, jeśli liczby były takie same (liczby w ciągu znaków są interpretowane jako liczby)"0e3264578" == 0 --> True
Ciąg znaków rozpoczynający się od "0e" i poprzedzony czymkolwiek będzie równy 0"0X3264578" == 0X --> True
Ciąg znaków rozpoczynający się od "0" i poprzedzony dowolną literą (X może być dowolną literą) oraz poprzedzony czymkolwiek będzie równy 0"0e12334" == "0" --> True
Jest to bardzo interesujące, ponieważ w niektórych przypadkach można kontrolować wejściowy ciąg znaków "0" oraz pewne treści, które są haszowane i porównywane do niego. Dlatego jeśli można podać wartość, która spowoduje utworzenie hasza zaczynającego się od "0e" i bez żadnej litery, można ominąć porównanie. Można znaleźć już zahaszowane ciągi w tym formacie tutaj: https://github.com/spaze/hashes"X" == 0 --> True
Dowolna litera w ciągu znaków jest równa liczbie całkowitej 0
Więcej informacji na stronie https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09
in_array()
Type Juggling również wpływa na funkcję in_array()
domyślnie (trzeba ustawić na true trzeci argument, aby dokonać ścisłego porównania):
strcmp()/strcasecmp()
Jeśli ta funkcja jest używana do jakiejkolwiek weryfikacji uwierzytelniania (takiej jak sprawdzanie hasła) i użytkownik kontroluje jedną stronę porównania, może wysłać pusty ciąg zamiast ciągu znaków jako wartość hasła (https://example.com/login.php/?username=admin&password[]=
) i ominąć tę weryfikację:
Suwałe występuje z strcasecmp()
strcasecmp()
Ścisłe rzutowanie typów
Nawet jeśli jest używany operator ===
, mogą wystąpić błędy, które sprawiają, że porównanie jest podatne na manipulację typami. Na przykład, jeśli porównanie konwertuje dane na inny typ obiektu przed porównaniem:
preg_match(/^.*/)
preg_match()
może być używane do sprawdzania poprawności danych wprowadzanych przez użytkownika (sprawdza, czy jakiekolwiek słowo/wyrażenie regularne z czarnej listy jest obecne w danych wprowadzanych przez użytkownika, a jeśli nie, kod może kontynuować swoje wykonanie).
Ominięcie nowej linii
Jednakże, gdy ograniczamy początek wyrażenia regularnego, preg_match()
sprawdza tylko pierwszą linię danych wprowadzonych przez użytkownika, więc jeśli w jakiś sposób można przesłać dane wejściowe w kilku liniach, można ominięć tę kontrolę. Przykład:
Aby ominąć tę kontrolę, możesz wysłać wartość z zakodowanymi znakami nowej linii (%0A
) lub jeśli możesz wysłać dane JSON, wyślij je w kilku wierszach:
Znajdź przykład tutaj: https://ramadistra.dev/fbctf-2019-rceservice
Bypassowanie błędu długości
(Ten bypass został wypróbowany na PHP 5.2.5 i nie udało mi się go uruchomić na PHP 7.3.15)
Jeśli możesz przesłać do preg_match()
bardzo duże dane wejściowe, nie będzie w stanie ich przetworzyć, co pozwoli Ci obejść sprawdzenie. Na przykład, jeśli jest na czarnej liście JSON, możesz przesłać:
Przejś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
W skrócie problem występuje, ponieważ funkcje preg_*
w PHP opierają się na bibliotece PCRE. W PCRE pewne wyrażenia regularne są dopasowywane poprzez dużą liczbę wywołań rekurencyjnych, co zużywa dużo miejsca na stosie. Możliwe jest ustawienie limitu na ilość dozwolonych rekursji, ale w PHP ten limit domyślnie wynosi 100 000, co jest więcej niż mieści się na stosie.
Wątek na Stackoverflow został również podlinkowany w poście, gdzie bardziej szczegółowo omówiono ten problem. Naszym zadaniem było teraz jasne:
Wysłać dane wejściowe, które sprawią, że wyrażenie regularne wykona 100 000+ rekursji, powodując SIGSEGV, sprawiając, że funkcja preg_match()
zwróci false
, co sprawi, że aplikacja uzna, że nasze dane wejściowe nie są złośliwe, rzucając niespodziankę na końcu ładunku w postaci czegoś takiego jak {system(<bardzozła_komenda>)}
aby uzyskać SSTI --> RCE --> flaga :).
Cóż, w terminach wyrażeń regularnych, faktycznie nie wykonujemy 100 tys. "rekursji", ale zamiast tego liczymy "kroki wstecz", które, jak dokumentacja PHP podaje, domyślnie wynoszą 1 000 000 (1M) w zmiennej pcre.backtrack_limit
.
Aby to osiągnąć, 'X'*500_001
spowoduje 1 milion kroków wstecz (500 tys. do przodu i 500 tys. do tyłu):
Typowanie dynamiczne dla zaciemniania PHP
Wykonaj Po Przekierowaniu (EAR)
Jeśli PHP przekierowuje do innej strony, ale nie jest wywoływana funkcja die
lub exit
po ustawieniu nagłówka Location
, PHP kontynuuje wykonywanie i dołącza dane do ciała strony:
Wykorzystanie Traversal Path i Inkluzji Plików
Sprawdź:
pageFile Inclusion/Path traversalWięcej sztuczek
register_globals: W PHP < 4.1.1.1 lub gdy jest błędnie skonfigurowany, register_globals może być aktywny (lub ich zachowanie jest imitowane). Oznacza to, że w zmiennych globalnych jak $_GET, jeśli mają wartość np. $_GET["param"]="1234", można uzyskać do niej dostęp za pomocą $param. Dlatego, wysyłając parametry HTTP, można nadpisać zmienne używane w kodzie.
Ciasteczka PHPSESSION z tej samej domeny są przechowywane w tym samym miejscu, dlatego jeśli w obrębie domeny używane są różne ciasteczka w różnych ścieżkach, można sprawić, że ścieżka uzyska dostęp do ciasteczka z innej ścieżki, ustawiając wartość ciasteczka z innej ścieżki. W ten sposób, jeśli obie ścieżki uzyskują dostęp do zmiennej o tej samej nazwie, można sprawić, że wartość tej zmiennej w ścieżce 1 będzie stosowana w ścieżce 2. Następnie ścieżka 2 będzie uznawać zmienne ścieżki 1 za ważne (nadając ciasteczku nazwę odpowiadającą ścieżce 2).
Gdy masz nazwy użytkowników użytkowników maszyny. Sprawdź adres: /~<USERNAME> aby zobaczyć, czy katalogi php są aktywowane.
password_hash/password_verify
Te funkcje 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 jest często takie samo jak PASSWORD_BCRYPT. Aktualnie PASSWORD_BCRYPT ma ograniczenie rozmiaru wejścia do 72 bajtów. Dlatego, gdy próbujesz zahashować coś większego niż 72 bajty tym algorytmem, użyte zostaną tylko pierwsze 72B:
Bypassowanie nagłówków HTTP poprzez nadużycie błędów PHP
Jeśli strona PHP drukuje błędy i echo zwraca pewne dane wprowadzone przez użytkownika, użytkownik może sprawić, że serwer PHP zwróci pewne treści wystarczająco długie, aby gdy próbuje dodać nagłówki do odpowiedzi, serwer wyrzuci błąd. W następującym scenariuszu atakujący sprawił, że serwer zwrócił duże błędy, i jak widać na ekranie, gdy PHP próbowało zmodyfikować informacje nagłówka, nie mogło (więc na przykład nagłówek CSP nie został wysłany do użytkownika):
Wykonanie kodu
system("ls"); `ls`; shell_exec("ls");
Sprawdź to dla bardziej przydatnych funkcji PHP
RCE za pomocą preg_replace()
Aby wykonać kod w argumencie "replace", wymagane jest co najmniej jedno dopasowanie. Ta opcja preg_replace została zdeprecjonowana od PHP 5.5.0.
RCE za pomocą Eval()
RCE za pomocą Assert()
Ta funkcja w php pozwala ci wykonać kod napisany w postaci ciągu znaków, aby zwrócić true lub false (i w zależności od tego zmienić wykonanie). Zazwyczaj zmienna użytkownika zostanie wstawiona w środku ciągu znaków. Na przykład:
assert("strpos($_GET['page']),'..') === false")
--> W tym przypadku, aby uzyskać RCE, możesz:
Będziesz musiał przerwać składnię kodu, dodać swój payload, a następnie ponownie to naprawić. Możesz użyć operacji logicznych, takich jak "and" lub "%26%26" lub "|". Należy zauważyć, że "or" lub "||" nie działają, ponieważ jeśli pierwszy warunek jest prawdziwy, nasz payload nie zostanie wykonany. Podobnie nie działa ";", ponieważ nasz payload nie zostanie wykonany.
Inną opcją jest dodanie do ciągu znaków wykonania polecenia: '.highlight_file('.passwd').'
Inną opcją (jeśli masz dostęp do kodu źródłowego) jest zmodyfikowanie pewnej zmiennej w celu zmiany wykonania: $file = "hola"
RCE za pomocą usort()
Ta funkcja służy do sortowania tablicy elementów za pomocą określonej funkcji. Aby nadużyć tej funkcji:
Możesz również użyć // aby skomentować resztę 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. Wygląda na to, że jest to prawidłowe.?order=id));}//
: otrzymujemy komunikat o błędzie (Parse error: syntax error, unexpected ')' i
). Prawdopodobnie mamy za dużo zamykających nawiasów.
RCE za pomocą .httaccess
Jeśli możesz załadować plik .htaccess, możesz skonfigurować kilka rzeczy, a nawet wykonać kod (konfigurując pliki z rozszerzeniem .htaccess do wykonywania).
Różne powłoki .htaccess można znaleźć tutaj
RCE za pomocą zmiennych środowiskowych
Jeśli znajdziesz podatność, która pozwala ci modyfikować zmienne środowiskowe w PHP (i inną do wgrywania plików, chociaż po dokładniejszym zbadaniu może to zostać obejścione), możesz wykorzystać to zachowanie do uzyskania RCE.
LD_PRELOAD
: Ta zmienna środowiskowa pozwala na ładowanie dowolnych bibliotek podczas wykonywania innych binariów (choć w tym przypadku może nie działać).PHPRC
: Wskazuje PHP, gdzie znajduje się plik konfiguracyjny, zwykle nazywanyphp.ini
. Jeśli możesz wgrać swój własny plik konfiguracyjny, użyjPHPRC
, aby wskazać PHP na niego. Dodaj wpisauto_prepend_file
określający drugi wgrany plik. Ten drugi plik zawiera normalny kod PHP, który jest następnie wykonywany przez środowisko PHP przed jakimkolwiek innym kodem.
Wgraj plik PHP zawierający nasz kod powłoki
Wgraj drugi plik zawierający dyrektywę
auto_prepend_file
instruującą preprocesor PHP do wykonania pliku wgraliśmy w kroku 1Ustaw zmienną
PHPRC
na plik wgrany w kroku 2.
Uzyskaj więcej informacji na temat wykonania tego łańcucha z oryginalnego raportu.
PHPRC - kolejna opcja
Jeśli nie możesz wgrywać plików, możesz użyć w FreeBSD pliku "file"
/dev/fd/0
, który zawierastdin
, będący 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.
Analiza statyczna PHP
Sprawdź, czy możesz wstawić kod w wywołania tych funkcji (z tutaj):
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
Odszyfrowywanie kodu PHP
Możesz użyć strony www.unphp.net do odszyfrowania kodu PHP.
PHP Wrappery i Protokoły
Wrappery i protokoły PHP mogą pozwolić Ci obejść zabezpieczenia przed zapisem i odczytem w systemie i go skompromitować. Aby uzyskać więcej informacji, sprawdź tę stronę.
Xdebug nieuwierzytelniona RCE
Jeśli zauważysz, że Xdebug jest włączony w wyniku phpconfig()
, powinieneś spróbować uzyskać RCE za pomocą https://github.com/nqxcode/xdebug-exploit
Zmienne zmiennych
Wykorzystywanie RCE poprzez nowe $_GET["a"]($_GET["b"])
Jeśli na stronie możesz utworzyć nowy obiekt dowolnej klasy, możesz uzyskać zdalne wykonanie kodu (RCE). Sprawdź poniższą stronę, aby dowiedzieć się jak:
pagePHP - RCE abusing object creation: new $_GET["a"]($_GET["b"])Wykonanie PHP bez liter
https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/
Użycie liczby ósemkowej
XOR
Kod powłoki XOR
Zgodnie z tym opisem, można wygenerować prosty kod powłoki w ten sposób:
Więc jeśli możesz wykonać dowolne PHP bez liczb i liter, możesz wysłać żądanie, jak poniżej, nadużywając tego ładunku, aby wykonać dowolne PHP:
Dla bardziej szczegółowego wyjaśnienia sprawdź https://ctf-wiki.org/web/php/php/#preg_match
Kod powłoki XOR (wewnątrz eval)
Podobne do Perla
Last updated