Cara menggunakan what is php stdin

Laravel PHPUnit Remote Code Execution. Sebenarnya ini bug sudah lama banget. Tapi jujur saja saya juga gak tau karena memang sudah jarang banget update masalah exploit. Nah karena exploit ini kembali rame, akhirnya saya coba share aja deh di blog barangkali ada yang belum tau. Celah ini sebenarnya terletak pada vendor third party yakni PHPUnit, bukan dari Laravelnya.

  • Vuln: eval-stdin.php
  • Full Path Exploit : http://target/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
  • Affected versions : Before 4.8.28 and 5.x before 5.6.3

Disini kalian bebas untuk mengirim datanya menggunakan Burp Suite, Postman, atau curl pun bisa. Disini saya share yang pake curl dulu karena menurut saya ini yang paling simple.

Dulu, di awal belajar pemrograman, biasanya yang dibuat adalah program teks berbasis perintah baris. Peralatannya sendiri yang umum digunakan adalah bahasa C, Pascal, atau pun Basic.

Nah, kali ini kita akan mencoba membuat program perintah baris sederhana dengan memafaatkan bahasa PHP. Ya. PHP yang sering kita dengar untuk membuat aplikasi berbasis web itu yang akan kita gunakan. Tentu saja untuk program ini kita tidak memerlukan aplikasi pelayan web.


Secara sederhana, program yang kita buat akan meminta input dari pengguna dan menampilkannya kemudian. Input dari pengguna ini ditangkap melalui standar input (stdin). Di PHP kita menggunakan protokol php:// dan menangkapnya dengan fungsi fgets().

Berikut kode programnya :

$fp = fopen('php://stdin', 'r');
echo "Masukkan nama : ";
$a = trim(fgets($fp));
echo "Nama saya : $a\n";

Simpan kode tersebut dengan nama “prog_nama.php” lalu eksekusi melalui perintah baris :

php -f /path/to/prog_nama.php

Yang perlu diingat disini adalah kita harus tahu lokasi eksekutable PHPnya. Di Linux, misalnya, lokasi executable PHP yang aseli dari repositori terletak di /usr/bin/php. Atau di terminal cukup ketik php saja.

Bukan barang baru sebenarnya, tapi saya baru tahu sekarang 😳 PHP yang selama ini saya kenal sebagai bahasa pemrograman untuk web development ternyata bisa digunakan juga dalam CLI (Command Line Interface). Sebagai bahasa pemrograman web, tadinya saya pikir untuk menjalankan script PHP harus dari browser. Sehingga untuk membuat contoh kode sumber sederhana yang membutuhkan interaktifitas user, paling tidak harus membuat dalam bentuk form HTML yang menggunakan metode Submit dan/atau GET / POST. Tapi itu ribet! Paling tidak harus menggunakan sekali refresh di web browser untuk mendapatkan hasilnya.

Setelah Googling sedikit ke sana dan kemari akhirnya ketemu juga cara untuk menjalankan PHP lewat console (Command Prompt kalau di Windows). 😉 Cukup mudah ternyata. Jika kita sudah memiliki PHP yang terinstal di Windows, otomatis kita bisa langsung memakainya. Untuk catatan, fitur CLI ini sudah ada di PHP sejak versi 4.2.0 (masih berupa eksperimen). Dan mulai ada secara default sejak versi 4.3.0 dan berlanjut hingga PHP 5. Bagi yang tertarik untuk mempelajari lebih lanjut, bisa melihat sumber-sumber yang saya cantumkan di bawah. Untuk mengujinya, saya coba menjalankan contoh script berikut ini.

	$stdin = fopen('php://stdin', 'r');
	echo 'Input a Name : ';
	$name = fgets($stdin);
	echo 'n';
	$greeting = '';
	
	while (!($greeting == 1 || $greeting == 2 || $greeting == 3)) {
		echo 'Choose a greeting:n';
		echo '1. Sugeng enjangn';
		echo '2. Sugeng awann';
		echo '3. Sugeng dalunn';
		$greeting = fgets($stdin);
	}
	if ($greeting == 1) {
		$greeting = 'Sugeng enjang';
	} else if ($greeting == 2) {
		$greeting = 'Sugeng awan';
	} else if ($greeting == 3) {
		$greeting = 'Sugeng dalu';
	}

	echo 'n' . $greeting . ' ' . $name . 'n';
	fclose($stdin);

Simpan script di atas, misal dengan nama answer22.php. Karena saya menggunakan XAMPP untuk instalasi PHP dan Apache, maka saya harus menaruh script di atas di direktori ../xampp/php. Selanjutnya, untuk menjalankan script tersebut, buka Command Prompt di Windows dan ketikkan:

C:xamppphp>php answer22.php

Hasilnya? Silakan lihat sendiri. 😛

Script di atas sekaligus untuk menjawab tantangan teman saya yang baik-hati-dan-tidak-sombong-tapi-suka-menantang-itu… 🙄

The following code shows how to test for input on STDIN.  In this case, we were looking for CSV data, so we use fgetcsv to read STDIN, if it creates an array, we assume CVS input on STDIN, if no array was created, we assume there's no input from STDIN, and look, later, to an argument with a CSV file name.

Note, without the stream_set_blocking() call, fgetcsv() hangs on STDIN, awaiting input from the user, which isn't useful as we're looking for a piped file. If it isn't here already, it isn't going to be.

stream_set_blocking(STDIN, 0);
$csv_ar = fgetcsv(STDIN);
if (is_array($csv_ar)){
  print "CVS on STDIN\n";
} else {
  print "Look to ARGV for CSV file name.\n";
}
?>