linux kernel 2.6.38.8 system call wrapping

2011. 10. 14. 23:49·【Fundamental Tech】/Linux
반응형
◈ 원문 출처: http://www.troot.co.kr/tc/2649


Exploiting races in system call wrappers
http://lwn.net/Articles/245630/

뭐 대충 시스템 콜 상속에 관한 논문.
http://www.seclab.cs.sunysb.edu/anupam ··· erit.pdf

원래 참고한 블로그 글 (감사합니다!)
http://blog.naver.com/postview.nhn?blo ··· 11928670

시스템 콜 하이재킹
http://securex0.tistory.com/entry/linu ··· 582%25b7

하이재킹은 여러 가지 방법으로 시도했지만.. sys_call_table 내용을 엎어치기 하는 트릭으로.. 
최근 커널에는 cr0 트릭이 먹힌다.
http://www.troot.co.kr/tc/2644

뭐 커널 소스 직접 건든다면 바로 익스포트
http://blog.naver.com/parkys1982?redir ··· 03953701

이렇게 테이블 위치를 찾을 수도 있다. 
http://teamcrak.tistory.com/50

비슷한 글 마구 레퍼런스
http://www.mareq.com/2008/05/linux-uni ··· ing.html

이건 libc 레벨에서의 꼼수. 그러니까 libc를 preload 하고 심볼 찾아서 내 함수로 대치하면 libc에서 커널 쪽으로 안 보내고 내 함수를 부른다.

http://kldp.org/node/83447
물론 시스템 병신 만들기 싫으면 내 함수 호출 후 원래 함수도 호출해야 함 (래핑)

사실 libc 래핑도 할 수 있음. gcc 기능으로.
http://www.troot.co.kr/tc/2641


해킹하려고 찾은게 아니라서.. 
시스템 콜 실험을 할 때 매번 재빌드 하기 귀찮아서 디벼봤음;;

해킹 기법이 아니라 슈퍼유저 권한을 사용한다.
뭐... 사용하지 않고도 할 수 있음. 하지만 보통 상용 서버라면 중요 툴 실행 권한을 안 줌;

진짜 해킹을 해서 루트킷을 심고 싶다면.. 피싱 홈페이지나 dns 스푸핑으로 최신 (가짜) 디바이스 드라이버 설치하도록 삥쳐야 함.


sys_call_table은 정의된 부분은.
arch/x86/kernel/syscall_table_32.S 

이걸 딴 데서 가져다 써야하므로, EXPORT 해야 한다. 파일 찾아서 추가.
kernel/i386_ksyms_32.c:EXPORT_SYMBOL(sys_call_table);

extern void *sys_call_table; 도 써줘야 한다. void **가 맞겠군. 아무렇게나 써도 됨.

하지만 이건 어디까지나 슈퍼유저의 방법이므로..
아까 본 sys_call_table_32.S의 맨 앞 함수를 찾는다.

cat /proc/kallsyms > ddd 한 후 ddd 파일에서 sys_restart를 찾는다.
어라 .. 사용자 계정으로 보니까 주소가 모두 000 이네?


그렇다면 방법이 또 있다.
grep sys_restart /boot/System... 뒤에 버전은 uname -r 을 하든지 해서 붙임.

여긴 제대로 나옴 ㅋㅋㅋㅋㅋ
이 주소를 직빵 지정하면 됨.



시스템 콜 후킹 하는 커널 모듈을 만들자.
view plaincopy to clipboardprint?
  1. #include <linux/init.h>  
  2. #include <linux/kernel.h>  
  3. #include <linux/module.h>  
  4. #include <linux/proc_fs.h>  
  5. #include <linux/syscalls.h>  
  6. #include <linux/kallsyms.h>  
  7. #include <linux/sched.h>  
  8. #include <asm/uaccess.h>  
  9. #include <asm/unistd.h>  
  10.   
  11. // 익스포트 안 했다면 알아서 대충 변수명 정해서 아까 얻은 주소 쓰면 됨.  
  12. // 위에 링크 글 보면 테이블 주소 찾는 법이 있는데.. 요즘은 또 바뀌었음..;;   
  13. // void **syscccc = (void *)c011111......   
  14. extern void *sys_call_table[];  
  15.   
  16.   
  17. // asmlinkage int (*orig_setuid)( uid_t ruid );    
  18. // 이 포인터는 뭐 복구용으로 알아서 잘 쓰시고..  
  19.   
  20.   
  21. asmlinkage int new_syscall(void)  
  22. {  
  23.         printk("dawnsea!!!\n" );  
  24.   
  25.         return 0;  
  26. }  
  27.   
  28. int __init m_init( void )  
  29.   
  30. {  
  31.   
  32. //      orig_setuid = sys_call_table[__NR_dawnsea_1];  
  33.   
  34.         write_cr0( read_cr0( ) & ( ~0x10000 ) );  // 이게 중요한 부분  
  35.   
  36.   
  37.         sys_call_table[__NR_dawnsea_1] = new_syscall;  
  38.   
  39.         write_cr0( read_cr0( ) | 0x10000 );  
  40.   
  41.         printk("Module init, %lx, %lx\n", (unsigned long)sys_call_table, sys_call_table[__NR_dawnsea_1] );  
  42.   
  43.         return 0;  
  44. }  
  45.   
  46. void __exit m_exit( void )  
  47. {  
  48.         printk( KERN_ALERT "Module exit\n" );  
  49. }  
  50.   
  51. module_init( m_init );  
  52. module_exit( m_exit );  

커널 모듈로 빌드하니까 빨라서 좋다. 
모듈로 빌드하자고!
http://www.troot.co.kr/tc/2591


대충 디렉토리 하나 만들고 위에 소스 때려넣고 Makefile을 만들자.

view plaincopy to clipboardprint?
  1. PWD = $(shell pwd)  
  2.   
  3. obj-m += dawnsea3.o  
  4.   
  5. all:  
  6.         make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules  
  7.   
  8. clean:  
  9.         make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean  

빌드 3초!                                                                   

아차.. 커널에 빈 시스템 콜을 하나 넣어두자.
http://www.troot.co.kr/tc/2559


빈 시스템 콜에 연결할 함수 본체는. 아래처럼 야메로 짬.

/kernel/dawnsea.c 로 만들고.
/kernel Makefile 에 
obj-y += dawnsea.o 추가하면 댐.

view plaincopy to clipboardprint?
  1. </span></font>  
  2. <font face="'맑은 고딕'">#include <linux/kernel.h>  
  3. #include <linux/sched.h>  
  4. #include <asm/types.h>  
  5. #include <asm/thread_info.h>  
  6. #include <asm/unistd_32.h>  
  7. #include <asm/syscalls.h>  
  8. #include <asm/cacheflush.h>  
  9.   
  10. asmlinkage int sys_dawnsea_1(void)  
  11. {  
  12.   
  13.         printk("dawnsea org syscall\n");  
  14.         return 0;  
  15. }</font></font>  
  16. <font size="2" color="#000000"><span style="font-family: '맑은 고딕'; line-height: 22px; ">  

인클루드가 많은 건 이런 저런 실험하다 남은 찌꺼기 ㅋㅋㅋ


시스템 콜 넘버 선언 추가하려면
arch/x86/include/asm/unistd_32.h 까보면 됨.


뭐 대충 커널을 빌드하자.
make-kpkg --initrd --append-to-version=dawnseahw1 kernel-image kernel-headers -j 4


arch/x86/include/asm/syscalls.h 에 미리 선언도 해둬야.. 나중에 어플 빌드할 때 asm에서 찾아온다.

view plaincopy to clipboardprint?
  1. ...  
  2.   
  3. asmlinkage int sys_dawnsea_1(void);  
  4. #endif /* _ASM_X86_SYSCALLS_H */  

asm 심볼릭 링크도 잘 해두잡. 즉.. arch/x86/include/asm 은 include/asm에 잘 연결되어 있어야 함..
/usr/include/asm 도 저기서 긁어오게 해둘 것~


시스템콜이 호출이 되어야 하니까 어플도 하나 대충 만듬ㅋㅋ
view plaincopy to clipboardprint?
  1. </span></font>  
  2.   
  3. <font face="'맑은 고딕'">#include <linux/unistd.h>  
  4. #include <stdio.h>  
  5. main()  
  6. // main (int argc, char *argv[])  
  7. {  
  8.         int i;  
  9.   
  10.         i = syscall(341); // 아까 추가한 콜 번호.. include.. asm/syscalls.h 하면 NR... 아 귀찮다..  
  11.   
  12.         printf("i = %d\n", i);  
  13.         return 0;</font><span style="font-family: '맑은 고딕'; line-height: 22px; ">                    </span><font face="'맑은 고딕'">  
  14. }  
  15.                                                                                      </font>  
  16. <font face="'맑은 고딕'">  


insmod dawnsea3.ko 하면 시스템 콜이 바뀐 상태. 
즉 sys_dawnsea_1 함수가 new_syscall 로 바뀜


dmesg | tail 로 보면?


[   71.177668] dawnsea org syscall
[   80.422611] Module init, c152b220, f8d46020
[   86.237055] dawnsea!!!

바꼈네?!! 굿!
반응형

'【Fundamental Tech】 > Linux' 카테고리의 다른 글

GCC 컴파일 메시지 컬러 출력  (0) 2011.10.20
Linux miscdev simple template  (0) 2011.10.14
리눅스 컴퓨터에서 윈도우즈 컴퓨터로 원격 데스크탑 연결하는 방법 (rdesktop 사용법)  (0) 2011.10.14
Kernel 2.6 Makefile 분석  (0) 2011.10.14
ioctl() 디바이스 제어  (0) 2011.10.14
'【Fundamental Tech】/Linux' 카테고리의 다른 글
  • GCC 컴파일 메시지 컬러 출력
  • Linux miscdev simple template
  • 리눅스 컴퓨터에서 윈도우즈 컴퓨터로 원격 데스크탑 연결하는 방법 (rdesktop 사용법)
  • Kernel 2.6 Makefile 분석
[一日一學, 一日一新]
[一日一學, 一日一新]
  • [一日一學, 一日一新]
    cyber93's Blog
    [一日一學, 一日一新]
  • 글쓰기 관리
    • 분류 전체보기 (219)
      • 【Research Logs】 (4)
      • 【🌟 Awesome】 (20)
      • 【BIMMER】 (4)
      • 【Fundamental Tech】 (102)
        • Algorithm (0)
        • BIOS & UEFI (3)
        • Kali (1)
        • Linux (54)
        • MacOSX (12)
        • openSUSE (1)
        • Raspberry Pi OS (2)
        • Ubuntu (26)
        • Windows (3)
      • 【Professional Tech】 (10)
        • CXL│NVMe│PCIe (7)
        • Docker│Kubernetes (0)
        • Test Automation Fram.. (3)
      • 【Programming】 (24)
        • C (6)
        • C++ (4)
        • Go (0)
        • Java (1)
        • JSP (2)
        • Javascript (0)
        • Node.js (1)
        • Python (10)
      • 【🧰 SW Info & Tips】 (55)
        • Automake & Autoconf (6)
        • Eclipse (3)
        • Git (1)
        • Gnuplot (0)
        • LaTex (5)
        • MacOSX Apps (9)
        • Source Insight (5)
        • SVN (4)
        • Vim (7)
        • Visual Studio (9)
  • 반응형
  • 링크

    • cyber93's github
    • cyber93's github.io
    • 📚 책 읽고 정리
    • 👨‍💻 Today I Learned
    • 📖 Encyclopedia
    • 🔎 Linux Source Code
  • 인기 글

  • hELLO· Designed By정상우.v4.10.3
[一日一學, 一日一新]
linux kernel 2.6.38.8 system call wrapping
상단으로

티스토리툴바