틈틈히 리눅스 커널 익스 공부를 할 예정. 따라서 필요한 지식들을 간단히 정리해보자.
보통 리눅스 커널 CTF 문제에서 리눅스 커널모듈의 취약점을 이용해서 익스를 하는것 같다. 커널 모듈을 간단히 만들어보자.
test.c
test.c
----------------------
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
int init_module(void) {
printk(KERN_INFO "init_ test kernel module!!.\n");
return 0;
}
void cleanup_module(void) {
printk(KERN_INFO "remove test kernel module!!.\n");
}
C
복사
참고로 printk()는 커널 함수에서 사용되는 출력 함수임.
초기 init_module() 함수는 insmod 같이 커널 모듈이 올라갈때 동작되는 초기화 과정을 뜻한다. 작성한 커널 모듈이 커널에 올라갈때 "init_ test kernel module!!" 를 출력할것이다. 또한 반대로 cleanup_module() 함수는 rmmod 같이 커널 모듈이 내려갈때 수행되는 종료 루틴이라고 생각하면 된다. 우선 빌드를 수행해야 한다. 다음과 같이 makefile을 만들면 된다.
Makefile
obj-m += test.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
C
복사
•
M=$(PWD) : 외부 모듈이 위치한 디렉토리의 절대 경로
•
-C : 커널 소스 위치로, 실제 make 수행시 해당 경로로 이동해서 빌드됨. 그리고 다시 돌아옴
위와 같이 Makefile을 만들고 make를 조지면 test.ko가 생성된다. (make clean을 하면 빌드한거 정리됨.)
➜ develop_kermod make
make -C /lib/modules/5.4.0-53-generic/build M=/home/wogh8732/Desktop/kernel_study/develop_kermod modules
make[1]: Entering directory '/usr/src/linux-headers-5.4.0-53-generic'
CC [M] /home/wogh8732/Desktop/kernel_study/develop_kermod/test.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: modpost: missing MODULE_LICENSE() in /home/wogh8732/Desktop/kernel_study/develop_kermod/test.o
see include/linux/module.h for more information
CC [M] /home/wogh8732/Desktop/kernel_study/develop_kermod/test.mod.o
LD [M] /home/wogh8732/Desktop/kernel_study/develop_kermod/test.ko
make[1]: Leaving directory '/usr/src/linux-headers-5.4.0-53-generic'
C
복사
보면 '/usr/src/linux-headers-5.4.0-53-generic' 여기로 이동해서 수행하는게 보임.
이제 insmod로 커널모듈을 올려보자.
╭─wogh8732@ubuntu ~/Desktop/kernel_study/develop_kermod
╰─$ sudo insmod ./test.ko 130 ↵
╭─wogh8732@ubuntu ~/Desktop/kernel_study/develop_kermod
╰─$ dmesg | tail -1
[ 3178.151904] init_ test kernel module!!.
C
복사
init_module() 함수의 printk() 가 출력된것을 확인할 수 있다. rmmod를 하면 cleanup_module() 함수의 printk()가 호출된다.
참고로 init_module() 함수와 cleanup_module() 함수는 그대로 함수명을 써야하는데 이를 변경하고 싶으면 다음과 같이 해야한다.
test2.c
GNU nano 2.9.3 test2.c
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h>
int custom_init(void){
printk(KERN_INFO "custom init_ test kernel module!!.\n");
return 0;
}
void custom_cleanup(void) {
printk(KERN_INFO "custom remove test kernel module!!.\n");
}
module_init(custom_init);
module_exit(custom_cleanup);
C
복사
초기화 및 제거시 수행되는 함수명은 상관없이 module_init(), module_exit() 안의 인자로 각각 넣어주면 된다.
dmesg
[ 3485.369499] custom init_ test kernel module!!.
[ 3547.925718] custom remove test kernel module!!.
C
복사