Archive for the ‘Code Analysis’ Category
CVE-2009-2698
It’s been sometimes ago, sejak terakhir kalinya isi blog ini bernuansa informasi teknikal, selebihnya bersifat informasi seperti berita dsb. Bukan sesuatu yang buruk kok, tapi seperti biasa, alasan klasik, real world, school, work, family, well…you know. Semakin sulit untuk tetap berkontribusi pada komunitas seiring pertambahan usia, sementara harapan untuk anggota baru yang lebih muda cukup miris, mereka lebih senang bertanya “bagaimana caranya untuk join?!” sementara telah tertulis jelas pada content blog procedure praktis untuk bisa join. I mean, c’mon guys, how can you write ’bout something while you can’t read properly?
Well, klo kata anak muda jaman sekarang ini adalah ‘curcol’, so…enough. Let’s talk something fishy.
Julien dan Taviso sepertinya akhir-akhir ini melakukan auditing terhadap kode-kode pada kernel linux khususnya yang berhubungan dengan implementasi networking. Sebelumnya kita telah melihat bug CVE-2009-2692, kali ini kita akan melihat lebih dalam bug CVE-2009-2698. Penjelasan singkat namun informatif dapat dilihat pada blognya Julien Tinnes.
Julien dan Taviso menemukan bahwa linux kernel < 2.6.19 memiliki masalah NULL pointer dereference pada implementasi protocol UDP, sebetulnya bug ini tidaklah terlalu bermasalah karena telah di patch oleh Herbert Xu pada bulan oktober 2006. Namun jika kalian menemukan server dengan spesifikasi kernel < 2.6.19 maka bug ini layak untuk dicoba
.
Permasalahan terdapat pada routine / fungsi udp_sendmsg, lebih spesifik lagi pada implementasi suatu variable pointer yang disebut rt. rt merupakan variable pointer yang memiliki tipe data struktur rtable (routing table). Sebagai informasi, routine udp_sendmsg merupakan implementasi pengiriman paket udp melalui socket pada linux. Variable pointer rt didefinisikan sebagai NULL pada bagian awal routine udp_sendmsg, pada implementasi routine udp_sendmsg tersebut ditemukan cara agar variable rt tetap bernilai NULL saat memanggil fungsi ip_append_data dan ini disebabkan oleh bagian kode berikut ini:
if (up->pending) {
/*
* There are pending frames.
* The socket lock must be held while it's corked.
*/
lock_sock(sk);
if (likely(up->pending)) {
if (unlikely(up->pending != AF_INET)) {
release_sock(sk);
return -EINVAL;
}
goto do_append_data;
}
release_sock(sk);
}
Kode diatas seharusnya dieksekusi ketika terdapat pending frame yang akan di transmit, dan pada routine ip_append_data tidak terdapat pengecekan apakah variable pointer rt bernilai NULL karena secara logic kode berikut ini akan dijalankan:
794 if (skb_queue_empty(&sk->sk_write_queue)) {
795 /*
796 * setup for corking.
797 */
798 opt = ipc->opt;
...
...
} else {
820 rt = inet->cork.rt;
821 if (inet->cork.flags & IPCORK_OPT)
822 opt = inet->cork.opt;
823
824 transhdrlen = 0;
825 exthdrlen = 0;
826 mtu = inet->cork.fragsize;
827 }
Jadi jika alur program datang ke routine ip_append_data ketika variable rt bernilai NULL maka telah diasumsikan bahwa sebelumnya telah terdapat corking pada socket sehingga logic “else” yang akan dijalankan. Kita bisa lihat pada logic “else” variable pointer rt akan di-berikan inisialisasi dengan nilai dari variable inet->cork.rt, penjelasan singkat telah diberikan oleh Herber Xu walaupun pada saat patch kemungkinan dia tidak menyadari masalah security di bagian kode tersebut. Herber Xu lebih melihat dari sisi developer dengan memberikan statement:
UDP tracks corking status through the pending variable. The
IP layer also tracks it through the socket write queue. It
is possible for the two to get out of sync when MSG_PROBE is
used.This patch changes UDP to check the write queue to ensure
that the two stay in sync.
Julien dan Taviso menemukan cara agar routine ip_append_data diatas (kernel < 2.6.19) dapat dieksekusi dengan variable pointer tetap bernilai NULL dan masuk pada logic “if”, dimana pada logic tersebut terdapat beberapa kode yang melakukan pointer dereference terhadap variable rt. Misalnya pada bagian berikut:
... 809 dst_hold(&rt->u.dst); 810 inet->cork.fragsize = mtu = dst_mtu(rt->u.dst.path); 811 inet->cork.rt = rt; ...
Dan pada blog Julien diberikan cara untuk men-trigger bug tersebut:
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
int main(int argc, char **argv)
{
int fd = socket(PF_INET, SOCK_DGRAM, 0);
char buf[1024] = {0};
struct sockaddr to = {
.sa_family = AF_UNSPEC,
.sa_data = "TavisIsAwesome",
};
sendto(fd, buf, 1024, MSG_PROXY | MSG_MORE, &to, sizeof(to));
sendto(fd, buf, 1024, 0, &to, sizeof(to));
return 0;
}
Masalah NULL ptr dereference kali ini berbeda dengan bug sebelumnya dimana kernel dapat langsung dibawa ke lokasi page 0 untuk mengesekusi kode-kode yang ditentukan oleh user. Bug NULL ptr deference memiliki beberapa sub-class, diantaranya tipe dereference (data read, data write, code execution) dan lokasi pointer ketika di-dereference (memory under direct userland control, kernel memory under indirect userland control, kernel memory under kernel control). Seperti yang dijelaskan oleh PaX team pada forum grsecurity, bug sock_sendpage merupakan “code execution” dan “memory under direct userland”. Sedangkan bug yang saat ini kita bahas masuk pada class “data read” dan “memory under direct userland control”.
Ada 3 buah public exploit yang beredar ketika bug tersebut dirilis, yang pertama dari p0c73n1, yang kedua oleh spender dan terakhir oleh andi@void.at. Implementasi exploit dari p0c73n1 cukup sederhana, dia melemparkan lokasi dari kernel_code pada lokasi page 0 dan mentrigger bug NULL ptr, kemudian berharap bahwa eksekusi kernel akan membaca / mengeksekusi lokasi page 0. Spender melakukan analisis yang lebih mendalam, dan exploit andi merupakan penyederhanaan dari exploit spender dengan memfokuskan pada proses exploitasi, namun intinya satu yaitu memanfaatkan (*output)(struct sk_buff*) dari dst_pointer yang digunakan oleh rtable sebagai callback pada exploit, posisi tersebut terdapat pada offset +0×74 dari rtable.
Variable pointer rt memiliki tipe data rtable, yang definisinya sebagai berikut:
...
50struct rtable
51{
52 union
53 {
54 struct dst_entry dst;
55 struct rtable *rt_next;
56 } u;
57
58 struct in_device *idev;
59
60 unsigned rt_flags;
61 __u16 rt_type;
62 __u16 rt_multipath_alg;
63
64 __u32 rt_dst; /* Path destination */
65 __u32 rt_src; /* Path source */
66 int rt_iif;
67
68 /* Info on neighbour */
69 __u32 rt_gateway;
70
71 /* Cache lookup keys */
72 struct flowi fl;
73
74 /* Miscellaneous cached information */
75 __u32 rt_spec_dst; /* RFC1122 specific destination */
76 struct inet_peer *peer; /* long-living peer info */
77};
78
...
Struktur rtable mendefinisikan union yang salah satu anggotanya bertipe struct dst_entry. Berikut ini definisi struktur dst_entry:
...
38struct dst_entry
39{
40 struct dst_entry *next;
41 atomic_t __refcnt; /* client references */
42 int __use;
43 struct dst_entry *child;
44 struct net_device *dev;
45 short error;
46 short obsolete;
47 int flags;
48#define DST_HOST 1
49#define DST_NOXFRM 2
50#define DST_NOPOLICY 4
51#define DST_NOHASH 8
52#define DST_BALANCED 0x10
53 unsigned long lastuse;
54 unsigned long expires;
55
56 unsigned short header_len; /* more space at head required */
57 unsigned short trailer_len; /* space to reserve at tail */
58
59 u32 metrics[RTAX_MAX];
60 struct dst_entry *path;
61
62 unsigned long rate_last; /* rate limiting for ICMP */
63 unsigned long rate_tokens;
64
65 struct neighbour *neighbour;
66 struct hh_cache *hh;
67 struct xfrm_state *xfrm;
68
69 int (*input)(struct sk_buff*);
70 int (*output)(struct sk_buff*);
71
72#ifdef CONFIG_NET_CLS_ROUTE
73 __u32 tclassid;
74#endif
75
76 struct dst_ops *ops;
77 struct rcu_head rcu_head;
78
79 char info[0];
80};
...
Pada baris ke-70 terdapat suatu variable pointer dengan tipe data struct sk_buff yang nantinya akan digunakan sebagai callback oleh fungsi NF_HOOK. Sehingga oleh exploit (setelah di-mapping pada page 0) pada posisi tersebut (NULL+0×74) akan dimasukan lokasi dari fungsi own_the_kernel (fungsi ini pada tiap exploit berbeda-beda namanya, namun intinya adalah memerintahkan kernel untuk memberikan uid=0 / root pada proses exploit). Ketika NF_HOOK mengakses lokasi callback tersebut maka secara tidak langsung akan dibawa untuk mengakses page 0 offset +0×74, dari sinilah kernel akan dituntun untuk mengeksekusi fungsi own_the_kernel dan memberikan rootshell pada kita.
Penjelasan mengenai fungsi NF_HOOK dapat dilihat disini. Secara singkat kita bisa mengatakan bahwa fungsi NF_HOOK akan selalu di eksekusi ketika kernel linux hendak mengirimkan data melalui jaringan. Linux mendukung beragam NIC (Network Interface Card) melalui bergam device drivers, dan NF_HOOK merupakan salah satu fungsi standard high level routing yang digunakan oleh linux dalam hal memanage networking.
Julien dan Taviso mengakhiri advisories mereka dengan menambahkan patch berupa proses checking terhadap variable pointer rt dalam fungsi ip_append_data, hal ini untuk mencegah NULL ptr deref dari variable rt dalam fungsi tersebut dengan anggapan bahwa fungsi ip_append_data memang tidak akan pernah mengakses variable rt dalam kondisi NULL.
DNS, the betrayer!
Lucu juga jika melihat tulisan fazed di blog GNUCITIZEN berikut ini, memainkan informasi DNS untuk menguasai WIFI connection (yeah…yeah…wifi-ownage, wahoooo?!). Jadi teringat dengan blog ini yang membicarakan mengenai tehnik pengubahan informasi DNS pada modem speedy dapat digunakan untuk mendapatkan informasi rahasia dari seluruh koneksi yang melewati modem speedy tersebut.
Jika melihat referrer pada blog tersebut, saya suka tersenyum sendiri karena ternyata banyak yang mencari tahu informasi untuk ‘hacking modem speedy’. Namun yang membuat kecewa karena umumnya pertanyaan yang diajukan dengan harapan dapat memanfaatkan modem speedy tersebut untuk koneksi internet gratisan. C’mon, jika diperhatikan lebih lanjut lagi, hacking modem speedy tersebut bukan ditujukan untuk mendapatkan koneksi internet gratis, tapi yang lebih jauh lagi…mendapatkan berbagai macam informasi penting dari koneksi-koneksi pengguna modem speedy tersebut, seperti informasi login pada situs per-bankan, ebay, amazon, dll.
[PHP] Image Photo Gallery
Ipen wrote tutorial about how-to create Image Photo Gallery using PHP on forum Kecoak Elektronik Indonesia, check his code and tutorial here.
Exploit wordpress oleh LMH
Pada salah satu sesi chatting, ada pertanyaan yang cukup menarik:
anon: mas, tau gak tentang pwnpress?
h3b: apa tuh?
anon: exploit untuk wordpress, yang buat LMH
h3b: oya?biasa nya tools buatan LMH menarik tuh
anon: iya, cuman ada yang aneh…kok sering failed nya ya?
h3b: emang gak ada manual help nya?
anon: ada sih help nya, cuma sring failed dan kyk nya gak stabil…coba dech lihat, ada di milw0rm tuh
h3b: liat dulu ya…jd penasaran
Exploit pwnpress nya LMH dapat download di sini . Tools-tools dari LMH biasa nya unik, dan untuk pwnpress ini sendiri juga cukup unik, salah satu yang unik nya…untuk menjalankan exploit ini harus menggunakan nama pwnpress.rb. Disatu sisi, ada sebagian pihak yang berpendapat hal ini menunjukan betapa lamme nya si pembuat exploit, padahal kan bisa di buat agar code di eksekusi dengan menggunakan nama apapun (kadang kita copy-paste source dari milw0rm dan save-as dengan nama yang sesuai kehendak) dan tidak masalah, namun untuk pwnpress dari LMH ini code exploit harus di simpan sebagai pwnpress.rb, dan eksekusi program harus menggunakan nama ini. Ini bisa kita lihat dari source code nya:
if $0 =~ /pwnpress.rb/
require ‘optparse’OPTIONS = {}
def vputs(msg)
if OPTIONS[:verbose]
puts “+> #{msg}”
end
end
Pada bagian inilah proses exploitasi akan dimulai, dan bagi yang tidak membaca source code nya akan mengalami kebingungan sesaat (including me, LOL). Tapi di sisi lain, ini salah satu tipikal seseorang yang memiliki keunikan tersendiri dengan tujuan agar code buatan nya tidak cuma di jalankan begitu saja (script kiddies style), namun kita harus membaca source code nya terlebih dahulu sebelum menggunakan code exploit tersebut. Saya tidak tahu LMH masuk pada bagian yang mana, namun yang pasti…tools-tools buatan LMH selain unik juga terstruktur dengan sangat rapih dan apik, pada pwnpress bisa kita lihat bagaimana source code program nya yang terstruktur dengan baik, plus komentar-komentar men-detail dengan mencantumkan referensi-referensi berdasarkan hole wordpress yang telah ditemukan sebelumnya, serta efisiensi penggunaan source code (penggunaan symbol sebagai variable di ruby sebagai contoh, menunjukan bahwa code program tersebut lebih efisien dibandingkan penggunaan string yang menghabiskan lebih banyak resource memory). Walaupun LMH terkenal dengan underground style nya, namun kemampuan coding nya setipe dengan coder profesional, well…security profesional
.
Oke, enough, kembali ke topik. Jika kita coba praktekan exploit tersebut, memang akan muncul keanehan seperti yang dirasakan oleh lawan bicara saya di chat tersebut, dimana kadang exploit mengalami kegagalan dengan pesan error yang gak jelas, kadang dia gagal melakukan fingerprinting, kalaupun berhasil cuma menampilkan informasi yang kesan nya lamme, apabila target merupakan blog wordpress yang telah hardly customize maka pwnpress tidak bisa melakukan apapun, dsb. Benarkah?!yup, apabila dilihat sepintas memang seperti itu, namun sekali lagi…jika kita memperhatikan source code nya maka pwnpress lebih dari sekedar exploit biasa (yang diasumsikan sebagai exploit sekali jalan, eksekusi dan dapat hasil). Dari source code tersebut, saya melihat pwnpress merupakan suatu template, atau lebih tepat nya…framework untuk exploitasi wordpress. Ada 2 bagian besar pada pwnpress, yaitu scanning (lebih tepat nya adalah, fingerprinting) serta exploitasi. Disamping itu juga terdapat cukup banyak method-method menarik yang digunakan untuk proses scanning dan exploitasi tersebut, diantara nya adalah menambahkan method baru untuk salah satu class utama ruby, Class Array dan Class String.
Kita dapat memahami proses kerja nya yang dijelaskan dengan mendetail (ini tipikal seorang coder yang baik dan profesional) pada exploit tersebut, metode-metode yang digunakan untuk fingerprinting versi wordpress target (via meta_generator, rss_feed_links, rss2_generator, atom_generator, serta isi page yang biasa nya terdapat “powered by wordpress”), metode exploitasi dengan mengacu pada “known vulnerablities” di wordpress, randomisasi user agent, randomisasi ip_address penyerang, dsb. Hal-hal inilah yang membuat pwnpress bukan sekedar exploit biasa, namun lebih kepada framework. Dengan menggunakan pwnpress, kita dapat menambahkan sendiri tipe fingerprinting untuk bisa mendapatkan versi wordpress yang diinginkan, menambahkan jenis exploit berdasarkan hole yang telah diketahui maupun yang belum diketahui, menambahkan metode-metode tambahan, dll. Pwnpress dapat di-customize sesuai dengan perkembangan wordpress serta pengetahuan kita untuk melakukan eksploitasi pada target, inilah seni dari exploit pwnpress milik LMH.
LMH mencuat nama nya berkat MoAB (Month Of Apple Bugs), beberapa waktu lalu pun sempat terjadi debat pendapat mengenai identitas LMH, jika dilihat sepintas mengenai variasi bidang yang disentuh oleh LMH maka tidak heran ada yang berpendapat bahwa LMH hanyalah nick yang digunakan oleh beberapa orang. Namun penguasaan beberapa bidang bukan sesuatu yang aneh dikalangan underground, terlepas dari hal itu…saya pribadi salut dengan keunikan code-code yang dihasilkan oleh LMH dimana disertai dengan dokumentasi singkat dan efisien namun padat sehingga mempermudah kita mencerna proses kerja code-code tersebut, paling tidak kita bisa melihat hasil nya dari interface web metasploit (msfweb) yang merupakan salah satu hasil kerja LMH
.
Oh iya, tidak perlu dijelaskan panjang lebar mengenai isi code pwnpress.rb, silahkan baca sendiri karena dokumentasi proses kerja nya sudah akurat, bahasa pemrograman yang digunakan adalah ruby. Ruby menggunakan pendekatan “bahasa manusia” dengan konsep “bahasa inggris (english)” sehingga cukup mudah mencerna code-code tersebut. Sisa nya adalah kemauan untuk membaca.