sweetchip's blog

ASAN - AddressSanitizer




https://github.com/google/sanitizers/wiki/AddressSanitizer


구글의 깃허브에 정의된 ASAN 은 c/c++로 제작된 프로그램에서 버그를 디텍션 해주는 툴 이라고 보면 된다.


따로 설치해서 해야 하는건 없고 컴파일러 Clang 을 설치한뒤 컴파일 할때 -fsanitize=address 옵션만 붙여주도록 하자.


맨 위의 사진은 ASAN을 적용해서 디텍션할 수 있는 버그들의 목록이다.


Sanitizer 시리즈로는 아래와 같은 것들이 있다.


AddressSanitizer (detects addressability issues) - https://github.com/google/sanitizers/wiki/AddressSanitizer

LeakSanitizer (detects memory leaks) - https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer

ThreadSanitizer (detects data races and deadlocks) for C++ and Go - https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual

MemorySanitizer (detects use of uninitialized memory) - https://github.com/google/sanitizers/wiki/MemorySanitizer


사용법은 위 링크에 모두 나와있으니 ASAN과 MSAN만 사용해보도록 하자.


우선 위 기능을 사용하기 위해서 Clang을 설치한다.


sudo apt install clang


*참고 - 기준은 ubuntu 16.04 server *bit LTS 버전이다.


#include <stdlib.h>

// clang -fsanitize=address -O1 -fno-omit-frame-pointer uaf.c -o uaf

int main() {

  char *x = (char*)malloc(10 * sizeof(char*));

  free(x);

  return x[5];

}



위의 예제 코드를 보면 malloc으로 메모리를 할당하고 바로 Free시킨다. 그 이후 Free된 메모리 x를 접근하는데 이는 Free된 메모리를 재 사용하는


Use-After-Free라고 볼 수 있다.


이를 2번째 줄에 있는 커맨드로 컴파일 해보자.


이때 -fsanitize=address 는 ASAN을 사용하겠다는 것이고, -O1은 최적화 (옵션, 아래 페이지에 있어서 그냥 붙임.)


-fno-omit-frame-pointer는 더 좋은 스택트레이스 결과를 보기위해 붙이라고 한다.


각각의 옵션에 대한 정보는 https://github.com/google/sanitizers/wiki/AddressSanitizer#using-addresssanitizer 을 참고하도록 하자.


[sweetchip@ubuntu sanitizer]$ clang -fsanitize=address -O1 -fno-omit-frame-pointer uaf.c -o uaf

[sweetchip@ubuntu sanitizer]$ ./uaf 

=================================================================

==10400==ERROR: AddressSanitizer: heap-use-after-free on address 0x60700000dfb5 at pc 0x0000004e9bbe bp 0x7ffd5c55f6f0 sp 0x7ffd5c55f6e8

READ of size 1 at 0x60700000dfb5 thread T0

    #0 0x4e9bbd  (/home/sweetchip/sanitizer/uaf+0x4e9bbd)

    #1 0x7f031f59582f  (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

    #2 0x418518  (/home/sweetchip/sanitizer/uaf+0x418518)


0x60700000dfb5 is located 5 bytes inside of 80-byte region [0x60700000dfb0,0x60700000e000)

freed by thread T0 here:

    #0 0x4b84c0  (/home/sweetchip/sanitizer/uaf+0x4b84c0)

    #1 0x4e9b8a  (/home/sweetchip/sanitizer/uaf+0x4e9b8a)

    #2 0x7f031f59582f  (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)


previously allocated by thread T0 here:

    #0 0x4b8648  (/home/sweetchip/sanitizer/uaf+0x4b8648)

    #1 0x4e9b7f  (/home/sweetchip/sanitizer/uaf+0x4e9b7f)

    #2 0x7f031f59582f  (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)


SUMMARY: AddressSanitizer: heap-use-after-free (/home/sweetchip/sanitizer/uaf+0x4e9bbd) 

Shadow bytes around the buggy address:

  0x0c0e7fff9ba0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

  0x0c0e7fff9bb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

  0x0c0e7fff9bc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

  0x0c0e7fff9bd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

  0x0c0e7fff9be0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

=>0x0c0e7fff9bf0: fa fa fa fa fa fa[fd]fd fd fd fd fd fd fd fd fd

  0x0c0e7fff9c00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

  0x0c0e7fff9c10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

  0x0c0e7fff9c20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

  0x0c0e7fff9c30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

  0x0c0e7fff9c40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

Shadow byte legend (one shadow byte represents 8 application bytes):

  Addressable:           00

  Partially addressable: 01 02 03 04 05 06 07 

  Heap left redzone:       fa

  Heap right redzone:      fb

  Freed heap region:       fd

  Stack left redzone:      f1

  Stack mid redzone:       f2

  Stack right redzone:     f3

  Stack partial redzone:   f4

  Stack after return:      f5

  Stack use after scope:   f8

  Global redzone:          f9

  Global init order:       f6

  Poisoned by user:        f7

  Container overflow:      fc

  Array cookie:            ac

  Intra object redzone:    bb

  ASan internal:           fe

  Left alloca redzone:     ca

  Right alloca redzone:    cb

==10400==ABORTING



그리고 위처럼 디버그 정보가 쭉 출력되고 스택트레이스 정보가 출력된다.





이번엔 MSAN을 사용해보자.


Asan처럼 그냥 옵션만 추가해주면 사용할 수 있기 떄문에 우선 Clang을 설치한 상태여야 한다.


[sweetchip@ubuntu sanitizer]$ cat umr.cc 

#include <stdio.h>

//clang -fsanitize=memory -fPIE -pie -fno-omit-frame-pointer -g -O2 umr.cc -o umr -fsanitize-memory-track-origins

int main(int argc, char** argv) {

  int a[10];

  a[5] = 0;

  if (a[argc])

    printf("xx\n");

  return 0;

}


이때 -fsanitize=memory 는 MSan을 사용하겠다는 것이고, -fPie -pie는 예제에 붙어있길래 같이 붙였다. 안붙여도 결과만 보는데는 크게 문제가 없는듯 하다.


-fsanitize-memory-track-origins 는 어느 함수에서 메모리를 할당시켰는지 추적할 수 있는 기능이다. 


-fno-omit-frame-pointer 는 ASAN과 같이 스택 트레이서 기능이다.



위 예제 코드를 보면 a배열을 초기화하지 않은 것에 문제가 발생한다.


이 경우 a[argc]로 접근하게 될 경우 여러 문제가 발생할 수 있다.


[sweetchip@ubuntu sanitizer]$ ./umr 5

==10456==WARNING: MemorySanitizer: use-of-uninitialized-value

    #0 0x563e3030d568  (/home/sweetchip/sanitizer/umr+0x87568)

    #1 0x7fd85136082f  (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

    #2 0x563e3029ff88  (/home/sweetchip/sanitizer/umr+0x19f88)


  Uninitialized value was created by an allocation of 'a' in the stack frame of function 'main'

    #0 0x563e3030d430  (/home/sweetchip/sanitizer/umr+0x87430)


SUMMARY: MemorySanitizer: use-of-uninitialized-value (/home/sweetchip/sanitizer/umr+0x87568) 

Exiting


[sweetchip@ubuntu sanitizer]$ ./umr 100

==10457==WARNING: MemorySanitizer: use-of-uninitialized-value

    #0 0x56272224f568  (/home/sweetchip/sanitizer/umr+0x87568)

    #1 0x7f0f5626782f  (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

    #2 0x5627221e1f88  (/home/sweetchip/sanitizer/umr+0x19f88)


  Uninitialized value was created by an allocation of 'a' in the stack frame of function 'main'

    #0 0x56272224f430  (/home/sweetchip/sanitizer/umr+0x87430)


SUMMARY: MemorySanitizer: use-of-uninitialized-value (/home/sweetchip/sanitizer/umr+0x87568) 

Exiting



MSan 은 위처럼 결과가 나온다.


잘만 사용하면 써먹을 곳이 꽤나 많을듯 하다.

저작자 표시 비영리 변경 금지
신고

Comment 3

  • 세종대 컴공
    2016.06.29 05:23 신고 수정 답글

    얼마전 세종대 ssg 동아리 세미나에서 발표하신거 잘들었습니다. 좋은주제로 재밌는 발표해주셔서 감사해요 그냥 돌아다니다가 우연히 낯익은 닉네임을 발견해서 들어와보니 맞았네요ㅎㅎ 다음에도 좋은주제 기대하겠습니다 참고로 저는 그때 외부인으로 참석하였었습니다.

  • 2016.07.17 22:32 수정 답글

    비밀댓글입니다