in Exploit

Belajar Membuat Shellcode (II): Remote Exploit Shellcode

Dalam artikel sebelumnya saya sudah menjelaskan dasar-dasar pembuatan shellcode. Saya sudah menjelaskan pembuatan shellcode untuk local exploit. Nah kali ini saya akan lanjutkan lagi untuk membuat shellcode yang dipakai untuk exploit secara remote.

Remote Exploit

Remote exploit adalah teknik exploitasi yang dilakukan secara remote melalui jaringan. Exploit jenis ini biasanya menyerang server/daemon yang sedang “LISTEN” di port tertentu.

Perbedaan utama antara local exploit dan remote exploit adalah pada kondisi awalnya. Pada local exploit, sejak awal attacker sudah memiliki shell access baik melalui ssh, telnet atau remote desktop connection, namun dengan hak akses terbatas (sebagai normal user). Sedangkan pada remote exploit, kondisi awal attacker adalah tidak memiliki akses shell. Akses shell yang saya maksud adalah kemampun untuk execute suatu file executable.

Jadi pada local exploit, tujuannya adalah privilege escalation atas hak akses yang terbatas tersebut menjadi tidak terbatas (root/administrator). Sedangkan pada remote exploit, karena pada awalnya tidak punya akses shell, maka remote exploit berusaha mendapatkan akses shell, baik sebagai user biasa maupun sebagai super user (root/administrator).

Remote Shellcode

Dalam artikel ini saya akan menjelaskan tentang pembuatan 2 jenis remote shellcode, yaitu:

  • Port Binding Shellcode

Shellcode jenis ini bertujuan untuk memberikan shell yang bisa diakses dari jauh melalui port tertentu. Attacker bisa mengakses shell tersebut dengan membuka koneksi ke IP komputer target pada port yang sudah ditentukan sebelumnya.

port binding

Port binding shellcode tidak berguna bila komputer target dilindungi dengan firewall yang memblok inbound koneksi ke port di luar port yang diijinkan.

Firewall yang ditakutkan bukan firewall yang berada di komputer target sebab attacker bisa juga menambahkan rutin untuk mendisable firewall di komputer target. Tetapi firewall yang berada di luar komputer target tidak bisa dimatikan dari komputer target.

  • Reverse Connecting Shellcode

Reverse connecting shellcode mirip dengan port binding shellcode namun arah koneksinya terbalik. Dalam shellcode ini justru komputer target yang membuka koneksi ke attacker. Kenapa diperlukan shellcode seperti ini? Dalam banyak kasus orang sangat paranoid terhadap koneksi yang masuk ke komputernya, namun tidak terlalu paranoid untuk koneksi keluar.

reverseconnecting

Port yang biasanya diijinkan untuk diakses adalah port untuk http, yaitu 80 dan 443 (SSL) karena ini adalah layanan yang paling banyak dipakai sehingga kecil kemungkinan ada admin yang memblok koneksi ke web server luar

Socket Programming

Apa itu socket? Socket merupakan salah satu metode IPC (inter process communication), yaitu komunikasi antar proses (running program) di komputer yang sama maupun di komputer lain (melalui jaringan). Dalam kasus ini kita membicarakan mengenai internet socket, yaitu socket yang digunakan untuk berkomunikasi melalui jaringan baik dengan komputer yang sama (localhost) maupun dengan komputer lain.

Ada dua jenis internet socket, yaitu datagram socket dan stream socket. Datagram socket digunakan untuk berkomunikasi menggunakan protokol UDP. Protokol UDP tidak cocok dipakai untuk kasus ini karena protokol ini tidak reliable. Stream socket adalah socket yang memakai protokol TCP, protokol inilah yang akan dipakai dalam shellcode ini.

Sebelum bisa memakai fungsi-fungsi socket, program harus meng-include header file berikut:

Network Byte Order vs Host Byte Order

Dalam komputer, ada aturan bagaimana data secara internal disimpan. Ada dua kubu aturan penyimpanan yang dipakai: little endian dan big endian. Ada beberapa arsitektur komputer yang memakai little endian seperti Intel, dan ada juga yang memakai big endian seperti Motorola dan PowerPC.

Dalam socket programming kita akan berkomunikasi dengan komputer lain yang tidak selalu sejenis arsitekturnya dengan yang kita pakai. Mungkin di komputer kita memakai little endian, berkomunikasi dengan komputer yang memakai big endian. Karena ada variasi ini, maka protokol IP mendefinisikan istilah network byte order dan host byte order.

Network byte order adalah byte order dari protokol network yaitu memakai big endian byte ordering.

Host byte order adalah byte order yang dipakai client/server, bisa little atau big endian tergantung arsitektur komputernya.

Host byte order mungkin sama atau berbeda dengan host byte order.

Pada notasi little endian, byte rendah ditulis duluan, baru kemudian byte tinggi. Sedangkan pada notasi big endian, byte tinggi ditulis duluan, baru kemudian byte tinggi. Perhatikan gambar di bawah ini untuk melihat perbedaan little dan big endian.

Pada gambar di atas IP address 192.168.0.14 dalam hexa adalah C0.A8.00.0E disimpan dalam notasi little endian dan big endian. Byte paling rendah, yaitu 0x0E disimpan di alamat memori paling rendah pada sistem little endian. Sedangkan pada big endian, byte paling tinggi 0xC0 disimpan di alamat memori paling rendah.

Dalam kasus arsitektur Intel IA32, terdapat perbedaan endianness antara host byte order yang memakai little endian, dengan network byte order protokol network yang memakai big endian. Perbedaan ini membuat data yang diterima dari protokol harus dikonversi dulu ke notasi little endian, bila tidak akan terjadi mis-interpretasi data. Contohnya data yang diterima dari network 0xABCD, bila tidak dikonversi maka data tersebut dikira sebagai 0xCDAB pada komputer yang memakai little endian.

Karena protokol network memakai big endian, maka data yang ditulis dalam paket yang dikirim ke jaringan harus dalam notasi big endian. Contohnya dalam protokol IP, field source address harus ditulis dalam notasi big endian. Perhatikan contoh sniffing network packet berikut:

Perhatikan pada gambar di atas, field destination IP adalah 192.168.0.14 yang bila ditulis dalam bentuk dotted hexadecimal adalah C0.A8.00.0E. Dalam network packet, IP tersebut ditulis dalam bentuk C0.A8.00.0E, yaitu notasi big endian untuk C0.A8.00.0E. Bila menggunakan notasi little endian, nilai tersebut akan disimpan sebagai 0E.00.A8.C0.

Pada gambar di atas juga terlihat bahwa field destination port dan source port juga ditulis dalam notasi big endian. Jadi jelas secara internal kita sudah melihat raw packet data yang diambil dari network, semua nilai ditulis dalam notasi big endian. Sekarang tinggal komputer yang terlibat dalam komunikasi harus menyesuaikan diri dengan notasi tersebut. Bila arsitekturnya juga memakai big endian, maka tidak ada yang perlu dikonversi.

Karena host byte order di komputer yang saya pakai (IA32) memakai little endian, sedangkan network byte order memakai big endian, maka diperlukan konversi dari little endian ke big endian. Ada banyak fungsi untuk melakukan konversi ini, antara lain:

  • htons() dan htonl()
  • Mengubah host byte order ke network byte order. Fungsi ini dipakai untuk mengirimkan paket, sebelum data ditulis dalam paket dan dikirim ke jaringan harus dikonversi dulu dalam bentuk network byte order.

    Bagaimana menuliskan port 80 dalam network byte order? Pertama 80 dalam hexa adalah 0x0050. Karena host (IA32) memakai little-endian, dan network memakai big endian, maka 0x0050 ini perlu dibalik dulu menjadi 0x5000. Kenapa harus dibalik? Ingat dalam IA32, nilai 0x5000 di memori komputer host akan tersimpan sebagai 0x00 0x50 dan dituliskan dalam paket jaringan dalam urutan yang sama 0x00 0x50. Bila 0x0050 tidak dibalik, maka di memori komputer host (IA32) akan tersimpan sebagai 0x50 0x00, sehingga dalam paket jaringan tertulis port 0x50 0x00 yang berarti port 20.480 bila diartikan memakai big endian, bukan port 80.

  • ntohs() dan ntohl()
  • Mengubah network byte order ke host byte order. Fungsi ini dipakai ketika menerima paket dari jaringan. Dalam paket tersebut data ditulis dalam notasi big endian, sehingga perlu dikonversi ke host byte order yang sesuai (dalam kasus IA32 adalah little endian).

Dalam contoh sebelumnya, port 80 dalam paket jaringan tertulis dalam urutan 0x00 0x50. Nilai ini ketika diterima oleh komputer host juga tersimpan di memori dalam urutan yang sama. Urutan dua byte 0x00 0x50 dalam host yang memakai little endian diartikan sebagai 0x5000 yaitu 20.480. Oleh karena itu perlu dikonversi dulu menjadi notasi little endian, menjadi 0x50 0x00. Dua byte 0x50 0x00 dalam sistem little endian diartikan sebagai nilai 0x0050 yaitu port 80.

Gambar di atas mengilustrasikan pemakaian fungsi untuk konversi endianness antara host dan network. Dalam membua shellcode nanti kita tidak akan memakai fungsi itu, kita akan langsung menuliskan dalam bentuk network byte order.

Socket Address Structure

Dalam pemrograman socket, sebuah proses akan memakai IP address dan port tertentu yang disimpan dalam struktur data bernama socket address yang strukturnya seperti di bawah ini:

sin_family adalah jenis alamat yang dipakai dalam socket, dalam kasus ini kita isi dengan 2 atau AFINET, yaitu IP (internet protocol) address. sin_addr adalah IP address yang bertipe struct in_addr yang hanya memiliki satu field yaitu s_addr bertipe integer. Dalam kasus port binding shellcode, sin_addr.s_addr diisi dengan 0 atau INADDR_ANY yang berarti kita menggunakan semua IP di localhost (tidak hanya 127.0.0.1 tapi semua IP address di komputer tersebut). sin_port adalah port yang akan dipakai untuk LISTEN, silakan mengisi dengan port apa saja yang tidak dipakai.

Ingat menuliskan IP address dan port harus dalam bentuk network byte order

Client Server Socket Programming

Socket programming melibatkan dua pihak, yaitu client dan server. Hubungan antara client dan server serta fungsi yang dipakai dapat dilihat pada gambar di atas.

Pada sisi server, fungsi yang dipakai adalah:

  1. socket()
  2. Ini adalah fungsi untuk membentuk socket baik di sisi server maupun client. Pertama kali yang harus dilakukan dalam socket programming adalah membuat socket dengan fungsi ini.

  3. bind()
  4. Ini adalah fungsi untuk memakai IP address dan port tertentu dalam socket yang sudah dibuat dengan fungsi socket() sebelumnya.

  5. listen()
  6. Ini adalah fungsi untuk LISTEN atau menunggu permintaan koneksi dari client.

  7. accept()
  8. Ini adalah fungsi untuk menerima koneksi dari client.

  9. read()
  10. Ini adalah fungsi untuk menerima data yang dikirim client.

  11. write()
  12. Ini adalah fungsi untuk mengirim data ke client.

Sedangkan pada sisi client lebih sederhana, fungsi yang dipakai adalah:

  1. socket()
  2. Sama seperti pada server, fungsi ini adalah fungsi yang pertama dipanggil dalam socket programming.

  3. connect()
  4. Fungsi ini untuk membuka koneksi ke server.

  5. read()
  6. Fungsi ini untuk menerima data dari server.

  7. write()
  8. Fungsi ini untuk mengirim data ke server.

Socket adalah File

Di UNIX semua hal adalah file, termasuk juga socket. Setiap file setelah dibuka, dapat dioperasikan dengan memakai file handler. Ketika program memanggil fungsi socket(), maka dia akan menerima socket file handler, dan dengan handler tersebut operasi dengan socket bisa dilakukan untuk berkomunikasi melalui jaringan.

Kenapa saya perlu menjelaskan tentang ini? Sebab dalam port binding shellcode kita perlu mengarahkan file handler stdin, stdout dan stderr ke file handler socket. STDIN adalah file handler dengan nilai 0, STDOUT adalah file handler dengan nilai 1 dan STDERR adalah file handler dengan nilai 2.

Biasanya stdin adalah keyboard, sehingga dengan membaca stdin program akan menerima masukan dari user. Namun dalam shellcode ini program tidak menerima input secara langsung dari keyboard, tetapi input berasal dari client socket. Agar input dari client socket bisa diterima oleh shell yang akan kita execute, maka kita perlu melakukan cloning dari client socket ke stdin. Dengan cloning ini, kini stdin adalah client socket dan program menerima input dari client socket.

Stdout adalah tempat untuk menampilkan output yang biasanya adalah layar console. Namun dalam kasus ini, output harus bisa dibaca oleh attacker yang berada di komputer lain melalui jaringan. Oleh karena itu stdout juga harus dicloning ke client socket sehinga shell bisa mengirimkan output melalui jaringan. Sedangkan stderr biasanya adalah layar console, sama dengan stdout.

Cloning file handler dilakukan dengan memanggil fungsi dup2([socket handler],[stdin/stdout/stderr]). Fungsi ini membuat socket handler dan stdin/stdout/stderr adalah sama.

Membuat Port Binding Shellcode

Port binding shellcode artinya shellcode bertindak sebagai server yang menunggu koneksi dari client yaitu attacker. Sebelum kita membuat shellcode dalam bahasa assembly saya akan membuat program port binding dalam bahasa C agar lebih mudah dimengerti. Source code port binding shellcode dalam bahasa C terlihat seperti di bawah ini:

Seperti pada gambar yang telah saya jelaskan di atas, socket programming di server dimulai dari fungsi socket() untuk membuat server socket dan mendapatkan file handlernya. Setelah itu ip address dan port harus didefinisikan dalam struct sockaddr_in. Socket address ini akan dipakai dalam fungsi bind() untuk mengikat port dan ip address tersebut dengan socket yang sudah dibuat sebelumnya. Setelah ip dan port sudah terikat dengan socket, kita bisa mulai menunggu koneksi dari client dengan fungsi listen(). Program akan blocking di fungsi listen() ini. Program akan resume, mulai berjalan lagi ketika client membuka koneksi dan hubungan telah terjalin. Setelah hubungan telah terjalin, kita akan memanggil fungsi accept() untuk mendapatkan file handler socket untuk client.

Ada dua socket yang dipakai: server socket dan client socket

Port yang akan kita pakai untuk LISTEN adalah port 2396, yang dalam hexadesimal adalah 0x095C. Ingat penulisan port harus dalam bentuk network byte order (big endian), sehingga penulisannya harus dibalik menjadi 0x5C09.

Saya menggunakan IP address bernilai 0 yang artinya all local address. Local address disini tidak hanya 127.0.0.1 tetapi juga semua ip address yang terdefinisi di interface yang ada pada host tersebut. Bila dalam host tersebut ada 3 ethernet card dengan ip yang berbeda, maka dia akan listen di semua ip tersebut.

Dalam program di atas sebelum kita mengeksekusi /bin/sh, kita perlu mengarahkan stdin,stdout dan stderr ke client socket. Hal ini dimaksudkan karena program yang dieksekusi dengan execve akan mewarisi stdin, stdout dan stderr dari yang mengeksekusinya. Jadi bila tidak dicloning dulu, maka stdin,stdout,stderr akan memakai keyboard dan layar console sehingga tidak bisa dipakai untuk mengirim command dan menerima outputnya dari jarak jauh.

Test

Sekarang mari kita uji program port binding di atas. Saya memakai dua console di komputer yang sama untuk mengujinya. Pada console pertama saya akan melakukan kompilasi dan menjalankan program tersebut sebagai root.

Setelah portbind dijalankan sebagai root dengan sudo, kini di console lain saya membuka koneksi ke port 2396 dengan mamakai program netcat.

Port Binding dalam Assembly

Oke dalam pengujian di atas kita berhasil membuat program yang listen ke port tertentu dan mengeksekusi shell bila ada koneksi masuk. Sekarang kita harus membuat program sejenis namun dalam bahasa assembly. Sama seperti pembuatan local shellcode, kita menggunakan interrupt 80 hexa untuk memanggil system call. System call yang akan kita panggil adalah socket, bind, listen, accept, dup2 dan execve.

Keluarga system call socket, bind, listen dan accept adalah satu system call dengan nomor 102. Sebelum memanggil interrupt 80h kita perlu mendefinisikan dulu apa yang akan kita panggil, apakah socket, bind, listen atau accept. Pilihan tersebut harus dimasukkan dalam register EBX:

  • EBX = 1 untuk socket()
  • EBX = 2 untuk bind()
  • EBX = 3 untuk connect()
  • EBX = 4 untuk listen()
  • EBX = 5 untuk accept()

Parameter untuk fungsi socket, bind, connect, listen dan accept disimpan sebagai array yang addressnya disimpan dalam register ECX. Seperti biasa register EAX harus diisi dengan nomor system call yaitu 102.

struct sockaddr_in dalam Assembly

Bagian yang rumit dalam shellcode ini adalah ketika membentuk struct sockaddr_in. Struct ini sebenarnya berukuran 16 byte, tetapi 8 byte terakhir adalah sin_zero yang tidak terpakai, jadi kita hanya fokus mengisi 8 byte pertama.

Susunan byte pada struct sockaddr_in adalah:

  • Byte ke-1 dan ke-2: sin_family yang akan diisi dengan 0x0002 (AF_INET).
  • Byte ke-3 dan ke-4: sin_port yang akan diisi dengan 0x5C09 (port 2396).
  • Byte ke-5 s/d ke-8: sin_addr.s_addr yang akan diisi dengan 0x00000000 (semua IP di interface host).

Alamat dari struct sockaddr_in ini harus disimpan dalam ECX. Kita akan memanfaatkan stack untuk membentuk struct ini. Karena stack adalah struktur data LIFO, maka kita harus push dulu 4 byte terakhir (0x00000000), kemudian diikuti dengan push 2 byte untuk sin_port dan terakhir baru push untuk sin_family. Setelah semua di-push, maka ESP menunjuk pada address struct ini sehingga harus kita salin ke ECX.

Snipped assembly di bawah ini adalah instruksi untuk membuat struct sockaddr_in. Di akhir source, ESP menunjuk pada address struct sockaddr_in.

Setelah snippet di atas dijalankan, struct sockaddr_in akan terlihat seperti di bawah ini:

0x02 0x00 adalah sin_family, hasil dari instruksi “push dx” pada saat regsiter DX bernilai 2. Byte berikutnya 0x09 0x5C adalah sin_port, hasil dari instruksi “push word 0x5C09”. Lalu 4 byte sisanya adalah sin_addr.s_addr hasil dari instruksi “push edx” pada saat EDX bernilai 0.

Source Code Assembly Port Binding Shellcode

Bila anda sudah membaca artikel sebelumnya belajar membuat shellcode part 1 anda tentu sudah mengerti tentang system call untuk mengeksekusi shell (execve), jadi tidak perlu saya jelaskan lagi di sini.

System call dup2 sangat sederhana, register yang harus diisi adalah EBX diisi dengan client socket handler, ECX diisi file handler untuk stdin,stdout dan stderr, dan terakhir adalah EAX yang harus diisi dengan nomor system call, 63.

Pada system call keluarga socket programming, socket(), bind(), listen(), accept() semua argumen disimpan dalam bentuk blok memori secara berurutan dengan alamatnya disimpan pada register ECX. Sebagai contoh, untuk socket(2,1,0), register ECX harus berisi alamat blok memori yang berisi byte berikut: 0x02 0x01 0x00.

Mengambil Opcode untuk Shellcode

Langkah berikutnya adalah kita harus compile dan link source assembly tersebut. Setelah itu baru kita disassemble dengan objdump agar bisa diekstrak opcodenya.

Byte Terlarang di Shellcode

Dari hasil objdump di atas terlihat ada byte yang terlarang, yaitu 0x00 yang merupakan bagian dari opcode instruksi: “add edx,2”. Kenapa byte 0x0 tidak boleh ada? Sebab ketika kita menginjeksi string, maka byte 0x0 akan dianggap sebagai akhir sebuah string, akibatnya shellcode kita tidak akan terinjeksi dengan lengkap dan terpotong pada byte 0x0 tersebut.

Agar byte 0x0 tidak ada, maka kita harus mengganti “add edx,2” dengan instruksi lain yang ekivalen, artinya instruksi pengganti tersebut harus berakibat pada bertambahnya nilai edx dengan 2. Saya akan mengganti instruksi “add edx,2” dengan instruksi “inc edx” sebanyak 2 kali. Mari kita lihat perbedaan antara opcode “add edx,2” dengan “inc edx”.

Perhatikan kedua opcode di atas. Ada dua keuntungan yang kita dapatkan dengan mengganti instruksi add. Pertama adalah tidak ada lagi byte 0x0. Kedua adalah ukurannya lebih hemat, instruksi “inc edx” hanya berukuran 1 byte, jadi total berukuran 2 byte. Sedangkan instruksi “add edx, 2” berukuran 6 byte, kita hemat 4 byte untuk mendapat efek yang sama.

Oke setelah kita menyingkirkan byte terlarang, kita harus mengekstrak opcodenya untuk menjadi shellcode. Kita akan pakai lagi cara yang saya pakai di artikel part 1 untuk dengan cepat meng-ekstrak opcode dari output objdump.

Setelah kita dapatkan shellcode, mari kita coba lagi pakai perl dan ndisasm, kalau hasil disassemblernya sama dengan source assembly awal, berarti shellcode tersebut sudah benar.

Oke selamat, shellcodenya sudah benar. Setelah itu biar lebih afdol, kita harus menguji dengan program C berikut.

Jangan lupa untuk mematikan exec shield dengan cara “echo 0 > /proc/sys/kernel/exec-shield” sebelum program C di bawah ini bisa dieksekusi. Bila tidak anda akan mendapatkan segmentation fault error.

Setelah dijalankan sebagai root, di console lain saya coba koneksi dengan netcat ke port 2396.

Berhasil! Selamat, port binding shellcode kini sudah siap dipakai untuk remote exploit.

Membuat Reverse Connecting Shellcode

Baiklah kini kita menginjak pada pembuatan shellode bertipe reverse connecting. Dalam shellcode jenis ini, shellcode bertindak sebagai client dan attacker menyiapkan sebuah server yang siap dihubungi di IP dan port tertentu. Sebagai simulasi kita asumsikan IP dan port attacker adalah 192.168.0.14:27155 dan IP komputer target adalah 192.168.0.10.

Karena socket programming di sisi client lebih sederhana dan mirip dengan port binding, saya langsung saja membuat shellcode ini dalam bahasa C.

Sebelum kita compile dan eksekusi, kita siapkan dulu di komputer attacker server yang listen di port 27155 dan port 192.168.0.14. Sistem operasi komputer attacker adalah windows dan attacker memakai netcat for windows untuk membuat server sederhana seperti di bawah ini.

Oke setelah server attacker sudah listen di 192.168.0.14:27155. Kini kita compile dan eksekusi program reverse sebagai root untuk mensimulasikan exploit yang mendapatkan root shell.

Sekarang perhatikan apa yang terjadi pada komputer attacker setelah program reverse tersebut dijalankan.

Ada koneksi masuk dari ip komputer target (192.168.0.10). Setelah koneksi terbentuk, attacker bisa mulai mengirimkan command untuk dieksekusi di komputer target.

Reverse Connecting dalam Assembly

Tidak ada hal baru dalam shellcode ini dibandingkan dengan shellcode port binding sebelumnya, jadi tidak ada yang perlu dijelaskan lebih jauh lagi. Langsung saja kita membuat program yang sama dalam bahasa assembly.

Tidak ada yang perlu saya jelaskan karena sama dengan shellcode port binding dan saya juga sudah memberi komentar untuk memperjelas di source di atas. Kita langsung saja compile dan link program assembly tersebut.

Sekarang kita harus mendisassemble program tersebut dan mengambil opcodenya untuk dirangkai menjadi shellcode dengan cara yang seperti port binding shellcode sebelumnya.

Menghilangkan Byte Terlarang

Oke kini kita telah dapatkan shellcodenya. Tapi kita periksa dulu apakah ada byte terlarang di dalamnya? Ternyata ada byte 0x00 dalam shellcode tersebut yang berasal dari instruksi “push long 0x0E00A8C0”. Byte 0x00 tidak terhindarkan karena IP attacker mengandung 0, yaitu 192.168.0.14. Oleh karena itu kita harus menyiasatinya agar tidak muncul byte 0x00.

Saya akan mengganti instruksi tersebut menjadi dua push, yaitu push 0x0E00 dan push 0xA8C0. Push nilai 0x0E00 tidak bisa dilakukan secara langsung karena itu akan menghasilkan opcode yang mengandung 0x00. Oleh karena itu saya harus membuat nilai 0x0E00 tanpa melibatkan angka 00 dengan cara:

Dengan mengganti menjadi instruksi mov dan shl kita terhindar dari byte terlarang 0x00. Berikut adalah opcode dari instruksi pengganti “push long 0x0E00A8C0”. Pada opcode tersebut terlihat lebih banyak space yang dibutuhkan, tetapi di sana tidak mengandung byte terlarang 0x00.

Setelah mengganti “push long 0x0E00A8C0” dengan 4 baris instruksi di atas, shellcode yang baru adalah seperti di bawah ini:

Kini kita siap mengujinya dengan membuat program dalam bahasa C berikut ini:

Mari kita compile dan jalankan program dalam bahasa C di atas. Tapi jangan lupa sebelumnya di komputer attacker harus dijalankan server yang listen di 192.168.0.14:27155.

Mari kita lihat apa yang terjadi pada console attacker setelah shellcode dieksekusi.

Berhasil! Kini kita telah berhasil membuat shellcode yang bisa dipakai untuk remote shellcode. Selamat anda telah berhasil membuat 2 macam shellcode yang bisa dipakai untuk remote exploit, yaitu port binding dan reverse connecting. Dalam artikel berikutnya saya akan membahas mengenai stack based buffer overflow exploit, di sana kita bisa memakai shellcode yang kita buat di artikel ini.

Write a Comment

Comment

This site is using OpenAvatar based on

13 Comments

  1. hebat bang… hebat… tapi kok kalau kaka’ nulis semisal di majalah jasakom kok artikel nya bukan yang kayak gini bang… lain kali kalau nulis di jasakom aku boleh request tentang masalah exploit bang ya… 😀 atau sekalian bikin buku aja bang kayak mas y3dips, bukunya keren, pasti kalau abang buat buku pasti laku keras tapi level isi bukunya tingkatin, jangan cuman kayak buku mas yedips ver. 1 yah bang… cuman saran bang… bravo ilmuhacking

  2. mas mau nanya bisa ngga ini untuk remote pc di jaringan windows, misal untuk men-shutdown atau me-restart pc lain yang ada di jaringan dari pc kita?
    sekalian contoh kode bahasa C nya dong kalau ada kirim ke email saya
    thanks

  3. Nice article,,
    tulisan2 kaya gini nih, yang dibutuhin ama para IT Indonesia, biar ga cuma jadi kiddies doank,
    Terima kasih banget,
    Keep Moving…

  4. wow!abang ni keren!caranya ngeHACK pake apa c bang?software atau program apa?dari dulu aku pengen banget blajar hacking.tapi gak tau apa apa.alias nol.
    aku mohon ajari aku…T_T
    tolong jelaskan padaku software atu program apa yang di gunakan untuk para hacker,dan bagaimana cara mendapatkan software atau program itu?
    tolong balas ke emailku ya bang:jefryfirdaus14@yahoo.com
    trima kasih yang sangat

  5. artikelnya bagus, cuma yang kurang jelas adalah gimana assembly code itu relevansinya sama highlevel language c++/c diatas, kenapa ECX bertugas seperti diatas, EDX, EBX, dan lainnya. kalau diberi penjelasan sebelum kode assemblynya ditampilkan akan lebih baik lagi mungkin. IMHO

  6. saya nggak bila anda ga jelasin relevansi register itu ke hll codenya, yang saya maksud, anda menjelaskannya kurang terstruktur di bagian registernya. kalau bagian penjelasan hll dan assembly. sejauh ini saya lihat anda nomor wahid (untuk tutorial shellcodeyang berbahasa indonesia), 2 jempol.

  7. Contoh, ”
    System call dup2 sangat sederhana, register yang harus diisi adalah EBX diisi dengan client socket handler, ECX diisi file handler untuk stdin,stdout dan stderr, dan terakhir adalah EAX yang harus diisi dengan nomor system call, 63. ”

    pertanyaan saya dan mungkin yang lain:

    1. Kenapa EBX harus diisi dengan client socket handler, bisa ga kalau file handler yang diisi di EBX?
    2. Gimana logic reasoningnya dari sisi bahasa assembly, karena bisa jadi baca tutorial mas rizki, kami sekalian belajar bahasa assembly.

    atau emang udah ketentuan dari processor, kalau bus data dan instruksi nganternya untuk socket programming udah pasti ngarahnya ke register tersebut?

    maklum mas, sebagian kecil kami termasuk saya, kurang dapat akses ke informasi yang lebih technical. IMHO, CMIIW