PHP – File descriptors

PHP – File descriptors

In dit artikel wil ik een CTF opdracht als voorbeeld gebruiken om het een en ander te gaan uitleggen en beschrijven. Bij de opdracht kreeg ik de volgende code gedeelte voor mijn neus.

<?php
  $fp = fopen("/tmp/flag.txt", "r");
  if($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['include']) && strlen($_GET['include']) <= 10) {
    include($_GET['include']);
  }
  fclose($fp);
  echo highlight_file(__FILE__, true);
?>

Zoals altijd was het de bedoeling om de flag te bemachtigen. Het eerste wat opviel was de lange if statement, deze statement doet het volgende:

  • De request methode moet een GET Request zijn
  • Om de vlag te bemachtigen moet de include worden toegevoegd aan de request
  • De waarde van de (include) mag niet langer dan 10 zijn, zoals te zien is aan de <= 10 gedeelte.

Ook was het opvallend dat de flag al ingeladen was in de variable ($fp), wat ik als eerst had geprobeerd was het volgende:

GET /?include=$fp

Dit werkte helaas niet, daarna had ik het volgende geprobeerd

GET /?include=flag.txt

Wederom werkte dit ook niet. De bedoeling van deze challenge was om met behulp van ‘file descriptors’ te werk te gaan.

File descriptors

Huh, een file descriptor? wat is dit nou weer dan, is wat jij jezelf afvraagt. Een file descriptor is niks meer dan een verwijzing naar een bestand op de hoofd operating systeem. Stel jezelf eens voor dat jij 10 bestanden open hebt staan op jouw computer. Deze bestanden krijgen een nummer van 1 tot en met 10.

1.txt = 1
2.txt = 2
3.txt = 3
4.txt = 4
5.txt = 5
6.txt = 6
7.txt = 7
8.txt = 8
9.txt = 9
10.txt = 10

Hierboven is het even wat duidelijker gemaakt, zoals je ziet heeft bestand 7.txt de file descriptor van 7. In dit geval is het nummer 7 een verwijzing naar 7.txt.

File descriptor - Wikiwand

In bovenstaande afbeelding nogmaals ter verduidelijking van het princiepe. File descriptor 0 hoort bij /etc/passwd. Zoals je kunt zien in de afbeelding en bij het volgen van de pijlen.

De php bug?

In php was er een bug die het toe liet dat bestanden gelezen konden worden die open stonden door een bepaalde path mee te geven aan in ons geval de (include) parameter in de request. Het was mogelijk om een bestand op te roepen met behulp van

GET /?include=/dev/fd/<een nummer> 
of 
GET /?include=/proc/self/fd/<een nummer>

De oplossing

Terug naar de opdracht, zoals te zien was in de code mag de waarde van de include parameter niet langer zijn dan 10.

if($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['include']) && strlen($_GET['include']) <= 10)

Toen ik de bovenstaande bug aan het onderzoeken was kwam ik tot een oplossing om de opdracht te kunnen voltooien. Door de volgende request te versturen had ik de opdracht kunnen voltooien.

GET /?include=/dev/fd/10

Waarom 10? Dit omdat het dan precies 10 karakters lang is.

/ = 1
d = 2
e = 3
v = 4
/ = 5
f = 6
d = 7
/ = 8
1 = 9
0 = 10

En als wij even terugkijken naar de code mocht het niet langer zijn dan 10, dit is precies 10 karakters en valt dus nog binnen de if statement. De resultaat was de vlag die tevoorschijn kwam.

De code

In dit hoofdstuk wil ik de code even goed uitleggen en wat er precies gebeurt.

$fp = fopen("/tmp/flag.txt", "r");

In bovenstaande code wordt er een variable gemaakt genaamd $fp en deze krijgt de waarde van het bestand ‘flag.txt’ dat zich bevind in ‘/tmp/’. Vervolgens de ‘r’ die aan het eind van de code zit, vertelt dat het bestand geopend word in de lees mode.

if($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['include']) && strlen($_GET['include']) <= 10)

Bovenstaande if statement doet het volgende:

  • De $_SERVER[‘REQUEST_METHOD’] === ‘GET’ controleert of de request een GET reqeust is.
  • Dit gedeelte ‘isset($_GET[‘include’])’ kijkt of de include parameter is toegevoegd.
  • de laatste gedeelte ‘strlen($_GET[‘include’]) <= 10′ kijkt of de lengte van de waarde die aan de include parameter wordt toegekend niet langer dan 10 karakters is.
include($_GET['include']);

Bovenstaande code voegt vervolgens het bestand toe aan de pagina, in ons geval de flag.txt.

fclose($fp);

Bovenstaande code sluit vervolgens het bestand.

Completed photos, royalty-free images, graphics, vectors & videos ...

Please share and spread
5 2 stemmen
Artikelbeoordeling
Abonneer
Laat het weten als er
guest
0 Reacties
Inline feedbacks
Bekijk alle reacties
NederlandsEnglish
0
Zou graag je gedachten willen weten, s.v.p. laat een reactie achter.x
()
x