PHP heeft een aantal input/output wrappers, deze zijn
hier te vinden.
Ik zat vanmiddag met deze wrappers te spelen en kwam tot een leuke conclusie.
Laten we beginnen met het uitleggen wat wrappers precies zijn. Streams zijn een interface voor schrijven en lezen van data uit een bron. Een enkele interface voor verschillende data zorgt voor herbruikbare code: een web applicatie kan data halen uit verschillende bronnen van een lokale bestand of van een externe web pagina. Streams zijn pas echt toegevoegd vanaf PHP 4.3.0. Ze zijn niet goed gedocumenteerd en daarom zijn hun capaciteiten niet volledig uitgebuit. Vanaf PHP5 zijn nieuwe stream extensies toegevoegd. Daarover zometeen meer.
Een extensie die voor een een stream interface zorgt wordt een
wrapper genoemd. The SimpleXML extensie is geschreven die gebruikt maakt van een stream interface. De functie
simplexml_load_file() bijvoorbeeld kan XML data lezen vanuit een lokale bestand, externe webserver of FTP.
PHP ondersteunt ook filters, deze kunnen streams van data wijzigen. De filter zit als het ware tussen de stream wrapper en de PHP code dat leest of schrijft uit een stream.
Er zijn verschillende wrappers die PHP ondersteunt, hieronder staat een lijst:
-file
-php
-ftp
-http
Er zijn nog andere, maar deze zul je het vaakst tegenkomen.
Om te kijken welke wrappers er worden ondersteunt, kun je de volgende code gebruiken.
PHP:
<?php
print_r( stream_get_wrappers() );
?>
Ik zat te experimenteren met wrappers en kwam leuke dingen tegen. Zo kun je php://input gebruiken om RAW POST data te lezen. Dit bied potentie voor kwaadwillende. In de PHP manual staat er dit over php://input:
php://input allows you to read raw POST data. It is a less memory intensive alternative to $HTTP_RAW_POST_DATA and does not need any special php.ini directives. php://input is not available with enctype="multipart/form-data".
Stel we hebben de volgende code:
PHP:
<?php
include($_GET['p']. '.php');
?>
Het is duidelijk dat dit geen veilige code is. Als allow_url_fopen op
off staat, kunnen we vrij weinig mee (tenzij jij php bestanden kan uploaden op de server). Echter moet magic_quotes_gpc op off staan, want dan kunnen we namelijk nog leuke dingen doen. Met magic_quotes_gpc op off, kunnen we code uitvoeren die eindigt met een ASCIIZ karakter. Dankzij de ASCIIZ 'terminator' karakter, wordt er geen '.php' achter geplakt aan $_GET['p'].
Dus we hebben dan dit: index.php?p=php://input%00
(dit werkt op besturingssystemen die C stijl strings gebruiken, daar is een binair 0 een terminator).
Het maakt NIKS UIT of allow_url_fopen on of off staat. Zoals we al lazen, leest php://input POST data. Door nu zelf een POST request te maken, kunnen we willekeurige code uitvoeren. Best evil of niet?
Vanaf PHP5 hebben we een andere gevaarlijke wrapper, namelijk php://filter. LET OP: deze heeft lees EN schrijf rechten. Dat laatste maakt het nog gevaarlijker. Ook maakt de configuratie van allow_url_fopen niks uit!
PHP:
<?php
file_put_contents
("php://filter/write=string/resource=te_schrijven_bestand.php",
"Gevaarlijke code!");
?>
Oeioeioei.....
Op de weblog van Tri Pham vinden we vandaag een interessant verhaal over hoe PHP stream wrappers veiligheids lekken kunnen veroorzaken bij includes die gegenereerde bestandsnamen gebruiken. Als er niet voldoende gecontroleerd wordt op de bestandsnaam z...
Tracked: Feb 08, 16:54
Tripham schreef in Februari over de potentiele gevaren van de PHP stream wrappers. Zo kun je, als je bepaalde includes niet goed zou afschermen, via POST data PHP code kunnen “injecteren”. In PHP6 zal dit niet meer mogelijk zijn, daarvoo...
Tracked: Mar 11, 10:20