[PHASE 1. Sample Dasar LKM pada Kernel 2.6x]

Loadable kernel module adl bagian dari kernel linux yang kita tambahkan ke 
base kernel (kode kernel linux dasar) secara on the fly. dengan adanya
lkm keunggulanya adl lebih hemat memori dan kita gak perlu repot 2 
recompile kernel kita klo kita mao nambahin modul ke dalem kernel. 
Kali ini kita akan bermain main dengan loadable kernel module untuk kernel 
2.6x , pada contoh kali ini menggunakan kernel 2.6.35-22-generic
untuk menyisipkan suatu modul baru ke kernel gunakan perintah insmod, 
contoh:

============
#insmod nama_modul.ko
============

n.b: harus dilakukan sebagai root.

Untuk melihat kernel2 modul yg sedang diload bisa diliat di /proc/modules
=============
ev1lut10n@ev1l:~$ cat /proc/modules
binfmt_misc 6599 1 - Live 0xf8195000
parport_pc 26058 0 - Live 0xf8170000
ppdev 5556 0 - Live 0xf80be000
snd_hda_codec_realtek 217980 1 - Live 0xf82c4000
joydev 8735 0 - Live 0xf8097000
snd_hda_intel 22107 4 - Live 0xf8cb2000
snd_hda_codec 87552 2 snd_hda_codec_realtek,snd_hda_intel, Live 0xf8c82000
snd_hwdep 5040 1 snd_hda_codec, Live 0xf8afd000
snipped======

misal kita lihat yg binfmt_misc:
binfmt_misc--  nama lkm
6599 -- ukuran lkm yg diload ke memori dalam byte
1 --- banyaknya dependensi
Live --- berarti module sudah diload setelah init modul
0xf8195000 -- merupakan alamat memori di kernel space (offset module 
diload)

Sebelum mulai install kernel header (linux kernel header dibutuhkan untuk 
mengkompile lkm kita nanti)

============
apt-get install kernel-headers-$(uname -r)
============

misal :
=============
#uname -r
2.6.35-22-generic
#apt-get install linux-headers-2.6.35-22-generic
cek setelah instalasi:
#ls /lib/modules/2.6.35-22-generic/build
arch           drivers   init    lib             net       sound   usr
block          firmware  ipc     Makefile        samples   source  virt
crypto         fs        Kbuild  mm              scripts   tools
Documentation  include   kernel  Module.symvers  security  ubuntu
=============


struktur dasar lkm:
 - init_module ---- modul diinisialisasi 
int init_module(void)
{
}

 - cleanup_module ----------unload modul secara clean saat exit
 
int cleanup_module(void)
{
}

- entry dan exit function:
module_init(init_module);
module_exit(cleanup_module);


Contoh lkm di sini kita pakai struktur dasar  :
=======================
#include <linux/module.h>
MODULE_LICENSE("GREY HAT");
MODULE_AUTHOR("ev1lut10n");
int init_modulku( void )
{
  printk(KERN_INFO "hai dmesg ini fungsi init\n");
  return 0;
}
void cleanup_modulku( void )
{
  printk(KERN_INFO "see u dmesg ini fungsi cleanup\n");
  return;
}

module_init(init_modulku);
module_exit(cleanup_modulku);
=====================

selanjutnya misal simpan dengan nama : ev1lut10n.c

siapkan suatu Makefile dengan isi misal (sesuaikan versi kernel):
===================
obj-m += ev1lut10n.o
 
all:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
 
clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
===================

selanjutnya ketikkan make:

=====================================
# make
make -C /lib/modules/2.6.35-22-generic/build M=/home/mywisdom/www/artikel 
modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.35-22-generic'
  CC [M]  /home/mywisdom/www/artikel/ev1lut10n.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/mywisdom/www/artikel/ev1lut10n.mod.o
  LD [M]  /home/mywisdom/www/artikel/ev1lut10n.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.35-22-generic'
# 
=======================================

jika berhasil maka akan tercipta file ev1lut10n.ko
===============
# ls -la  *.ko
-rw-r--r-- 1 root root 2787 2011-09-13 01:51 ev1lut10n.ko
# modinfo ev1lut10n.ko
filename:       ev1lut10n.ko
author:         ev1lut10n
license:        GREY HAT
srcversion:     0A941DA1D5AC55B86B25E1B
depends:        
vermagic:       2.6.35-22-generic SMP mod_unload modversions 686 
=================

selanjutnya untuk meload lkm tadi dengan insmod:
=============
# insmod ev1lut10n.ko
==============

untuk melihat hasil printk di kernel space bisa dengan dmesg:
===============
# dmesg | tail
[   32.112080] Skipping EDID probe due to cached edid
[   32.593054] Skipping EDID probe due to cached edid
[   37.344059] Skipping EDID probe due to cached edid
[  116.906126] warning: `proftpd' uses 32-bit capabilities (legacy support 
in use)
[ 2289.736043] Skipping EDID probe due to cached edid
[ 6153.780062] device eth0 entered promiscuous mode
[ 6195.524833] teredo: Disabled Privacy Extensions
[ 6204.544338] teredo: no IPv6 routers present
[ 6383.024787] device eth0 left promiscuous mode
[16824.579333] hai dmesg ini fungsi init 
=================

[16824.579333] hai dmesg ini fungsi init  ---- printk(KERN_INFO "hai dmesg 
ini fungsi init\n");

untuk melihat module yang tadi kita load:
=====================
# cat /proc/modules | grep ev1l
ev1lut10n 702 0 - Live 0xf8179000 (P)
=====================

* PRINTK
printk merupakan fungsi yang bisa dipakai untuk kernel debugging mode 
dikombinasikan dengan perintah dmesg.

berikut ini beberapa level debugging dari printk:
====================
# cat /usr/include/linux/kernel.h | grep 'printk(K'
        printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__) --------pesan 
emergency biasanya muncul sebelum crash wkwkwkwk
        printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__) ------- butuh 
tindakan secepatnya
        printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__) -------pesan kritis 
biasanya berhubungan dengan kegagalan hardware atau software (critical 
damage)
        printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)       ------- kondisi 
error
        printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__) ------------ 
peringatan
        printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)        
-----------notice
        printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)          ---informasi
	printk(KERN_CONT fmt, ##__VA_ARGS__)            ------- 
melanjutkan baris yang sudah dimulai sebelumnya
	printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) ----- digunakan utk 
pesan pada debugging
=====================



[PHASE 2. Simbol Kernel]

simbol kernel akan banyak dipakai oleh programmer linux kernel.  Daftar2 
simbol kernel yang diload bisa didapatkan pada file2 
berikut ini (baik secara plain maupun binary)
====================
/proc/kallsyms (kernel 2.6.x)
/proc/ksyms (kernel 2.4.x)
/boot/System.map*
/usr/src/linux/System.map
/lib/modules/*/System.map
/boot/vmlinux
/boot/vmlinuz
and so on....bla bla bla
====================

misal untuk melihat simbol2 kernel yang diload :
================
ev1lut10n@ev1l:~$ cat /proc/kallsyms | grep cred
c016c300 T override_creds
c016c3a0 T get_task_cred
c016c3f0 T __put_cred
c016c440 t release_tgcred_rcu
c016c480 t put_cred_rcu
c016c520 T revert_creds
c016c560 T abort_creds
c016c590 T prepare_creds
c016c640 T copy_creds
c016c830 T commit_creds
==========cuted cuted cuted===========
=======================

daftar2 di atas merupakan nama 2 fungsi maupun variabel global.  Simbol2 
kernel di atas merujuk pada alamat2 memori kernel space. Jadi bisa 
dibilang 
simbol kernel 
sbg nama 2 yang merujuk pada alamat2 memori kernel space yang berisi 
variabel global maupun suatu fungsi pada suatu loadable kernel module.

mari kita lihat dari lkm yg di atas kita buat tadi:
================
# cat /proc/kallsyms | grep modulku
f80b9000 t cleanup_modulku	[ev1lut10n]
================

f80b9000 --- merupakan alamat memori kernel space  yang merujuk pada 
fungsi cleanup_modulku
t - merupakan tipe simbol kernel

pada banyak exploit2 kernel untuk escalate privilege kernel simbol ini 
biasanya akan dibaca untuk mendapatkan alamat memori fungsi 2 yang 
dibutuhkan 
untuk eksploitasi berikut ini potongan kode dari fungsi yang berjalan di 
userspace untuk mendapatkan kernel simbol yang dicomot dari salah satu 
local 
root exploit:
=================
    f = fopen("/proc/kallsyms", "r"); ---------membaca dari /proc/kallsyms
    if (f == NULL) { ----------jika tidak bisa 
        f = fopen("/proc/ksyms", "r"); -----------------baca dari 
/proc/ksyms
        if (f == NULL) { 
            goto fallback;    
        }
        oldstyle = 1; ------------jika /proc/ksyms bisa dibaca berarti 
versi kernel di bawah kernel 2.6
    }
    --------------biasanya setelah ini diikuti rutin untuk membaca 
/boot/System.Map***bla***bla**
==================

sebenernya pada setiap local root exploit kekuranganya adl tidak adanya 
metode pembacaan kernel simbol secara lengkap, Untuk membuat local root 
exploit
dengan metode pengambilan kernel  simbol secara lebih lengkap bisa 
menggunakan ksymhunter yang bisa diambil dan bisa kita modifikasi dari:
https://github.com/jonoberheide/ksymhunter

untuk menggunakanya sangat mudah:
========================
root@ev1l:/home/ev1lut10n/jonoberheide-ksymhunter-2570d5b# ./ksymhunter
usage: ./ksymhunter symbol_name
root@ev1l:/home/ev1lut10n/jonoberheide-ksymhunter-2570d5b# ./ksymhunter 
cleanup_modulku
[+] trying to resolve cleanup_modulku...
[+] resolved cleanup_modulku using /proc/kallsyms
[+] resolved cleanup_modulku to 0xf80b9000
root@ev1l:/home/ev1lut10n/jonoberheide-ksymhunter-2570d5b# 
========================

di atas kita bisa melihat fungsi cleanup_modulku berada pada alamat memori 
kernel space :  0xf80b9000


[PHASE 3. Userspace dan Kernel Space]

Kernel space kita analogikan saja sbg tempat kernel dieksekusi dan user 
space tempat semua program buatan si user di sistem linux berjalan.
suatu program yang berjalan di userspace tidak bisa seenaknya mengakses  
kernel space, user space bisa mengontak kernel space melalui syscall.

Berikut ini diagram cara kerja user space saat menggunakan syscall pada 
suatu program C:

[User Space ]							                   									  
[Kernel Space]
[./exploit]                                  [c library]												      
[kernel] 
---------------setuid(0);--------->>>   |  ---argumen eax=__NR_setuid lalu 
panggil kernel dengan int 
80h----->>>|----system_call_table[eax]-->>>|--->>> 
(sys_setuid())	          
																												
																											

* SYSCALL
syscall merupakan penghubung antara aplikasi yang berjalan di user space 
dan layanan2 yang disediakan oleh kernel.

pada linux kernel 2.6.35-22-generic, daftar syscall bisa dilihat di 
/usr/include/bits/syscall.
==============================
root@ev1l# cat /usr/include/bits/syscall.h | grep define
#define SYS__sysctl __NR__sysctl
#define SYS_access __NR_access
#define SYS_acct __NR_acct
#define SYS_add_key __NR_add_key
#define SYS_adjtimex __NR_adjtimex
#define SYS_afs_syscall __NR_afs_syscall
#define SYS_alarm __NR_alarm
#define SYS_brk __NR_brk
#define SYS_capget __NR_capget
#define SYS_capset __NR_capset
#define SYS_chdir __NR_chdir
#define SYS_chmod __NR_chmod
#define SYS_chown __NR_chown
#define SYS_chroot __NR_chroot
#define SYS_clock_getres __NR_clock_getres
#define SYS_clock_gettime __NR_clock_gettime
#define SYS_clock_nanosleep __NR_clock_nanosleep
#define SYS_clock_settime __NR_clock_settime
#define SYS_clone __NR_clone
#define SYS_close __NR_close
#define SYS_creat __NR_creat
------------------cuted--------------
===================================