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 은 위처럼 결과가 나온다.
잘만 사용하면 써먹을 곳이 꽤나 많을듯 하다.
멀티 아키텍쳐 지원 어셈블러 Keystone (0) | 2016.06.08 |
---|---|
윈도우 XP, 7에서의 WINDBG 를 이용한 Kernel Debugging (커널 디버깅) (3) | 2015.06.21 |
IOS 앱 원본 바이너리 추출 및 복호화 - dumpdecrypted (10) | 2015.03.09 |
[Fuzzer 만들기 프로젝트!] Pydbg 한번에 설치하기 (2) | 2013.10.04 |
NewHeart 2013 Write ups - reversing (1) | 2013.05.29 |