기본 콘텐츠로 건너뛰기

build with Address sanitizer

Address Sanitizer와 함께 빌드하기

GCC와 CLANG로 빌드 시 Adress sanitizer를 구성하는 예시이다. 오브젝트 코드 주소를 소스 코드 행 번호와 파일 이름으로 변환하려면 ASAN_OPTIONS=symbolize=1옵션이 필요하다. GCC 사용 시 권장 방법은 -static-libasan을 사용하여 ASAN에 정적으로 링크하는 것이다. (ldd 명령어를 이용하여 이를 확인해보자.)

ldd
ldd(List Dynamic Dependencies)는 프로그램이나 공유 라이브러리들이 요구하는 공유 라이브러리(shared libraries)를 출력하는 명령 행(Command Line)프로그램이다.
–version : ldd의 버전을 출력한다.
-v, –verbose : 심볼 버전 정도등 모든 정보를 출력한다.
-d, –data-relocs
-r, –function-relocs
–help : 사용방법을 출력한다.
출처 : joinc - ldd

main.cpp

다음은 스택 오버플로우 취약점이 있는 간단한 소스코드이다.

int main(int argc, char **argv) {
  int stack_array[100];
  stack_array[1] = 0;
  return stack_array[argc + 100];  // BOOM
}

Makefile

.PHONY: using-gcc using-gcc-static using-clang

using-gcc:
    g++-4.8 -o main-gcc -lasan -O -g -fsanitize=address -fno-omit-frame-pointer main.cpp && \
    ASAN_OPTIONS=symbolize=1 ASAN_SYMBOLIZER_PATH=$(shell which llvm-symbolizer) ./main-gcc

using-gcc-static:
    g++-4.8 -o main-gcc-static -static-libstdc++ -static-libasan -O -g -fsanitize=address -fno-omit-frame-pointer main.cpp && \
    ASAN_OPTIONS=symbolize=1 ASAN_SYMBOLIZER_PATH=$(shell which llvm-symbolizer) ./main-gcc-static

using-clang:
    clang -o main-clang -x c++ -O -g -fsanitize=address main.cpp && \
    ASAN_OPTIONS=symbolize=1 ASAN_SYMBOLIZER_PATH=$(shell which llvm-symbolizer) ./main-clang

clang

$ make using-clang 
clang -o main-clang -x c++ -O -g -fsanitize=address main.cpp && \
    ASAN_OPTIONS=symbolize=1 ASAN_SYMBOLIZER_PATH=/usr/local/bin/>llvm-symbolizer ./main-clang

=================================================================
==25497==ERROR: AddressSanitizer: stack-buffer-overflow on address >0x7fffaeb43014 at pc 0x4b7453 bp 0x7fffaeb42e50 sp 0x7fffaeb42e48
READ of size 4 at 0x7fffaeb43014 thread T0
#0 0x4b7452 in main /home/kkleine/Development/asan-test/main.cpp:5
#1 0x2af489d27ec4 in __libc_start_main /build/buildd/eglibc-2.19/csu/>libc-start.c:287
#2 0x4b720c in _start (/home/kkleine/Development/asan-test/>main-clang+0x4b720c)

Address 0x7fffaeb43014 is located in stack of thread T0 at offset 436 in >frame
#0 0x4b72ef in main /home/kkleine/Development/asan-test/main.cpp:2

This frame has 1 object(s):
[32, 432) ‘stack_array’ <== Memory access at offset 436 overflows >this variable
HINT: this may be a false positive if your program uses some custom stack >unwind mechanism or swapcontext
(longjmp and C++ exceptions are supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /home/kkleine/Development>/asan-test/main.cpp:5 main
Shadow bytes around the buggy address:
0x100075d605b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100075d605c0: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
0x100075d605d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100075d605e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100075d605f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x100075d60600: 00 00[f3]f3 f3 f3 f3 f3 f3 f3 f3 f3 00 00 00 00
0x100075d60610: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100075d60620: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100075d60630: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100075d60640: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100075d60650: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
ASan internal: fe
==25497==ABORTING
make: * [using-clang] Error 1

gcc

$ make using-gcc
g++-4.8 -o main-gcc -lasan -O -g -fsanitize=address >-fno-omit-frame-pointer main.cpp && \
    ASAN_OPTIONS=symbolize=1 ASAN_SYMBOLIZER_PATH=/usr/local/bin/>llvm-symbolizer ./main-gcc

=================================================================
==25394== ERROR: AddressSanitizer: stack-buffer-overflow on address >0x7fffd708a284 at pc 0x40080d bp 0x7fffd708a0c0 sp 0x7fffd708a0b8
READ of size 4 at 0x7fffd708a284 thread T0
#0 0x40080c in main /home/kkleine/Development/asan-test/main.cpp:5
#1 0x2b9e16013ec4 in __libc_start_main /build/buildd/eglibc-2.19/csu/>libc-start.c:287
#2 0x400688 in _start (/home/kkleine/Development/asan-test/>main-gcc+0x400688)
Address 0x7fffd708a284 is located at offset 436 in frame of T0’s >stack:
This frame has 1 object(s):
[32, 432) ‘stack_array’
HINT: this may be a false positive if your program uses some custom stack >unwind mechanism or swapcontext
(longjmp and C++ exceptions are supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /home/kkleine/Development>/asan-test/main.cpp:5 main
Shadow bytes around the buggy address:
0x10007ae09400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10007ae09410: 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00
0x10007ae09420: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10007ae09430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10007ae09440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10007ae09450:[f4]f4 f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00
0x10007ae09460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10007ae09470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10007ae09480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10007ae09490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10007ae094a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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 righ 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
ASan internal: fe
==25394== ABORTING
make: * [using-gcc] Error 1

gcc static

$ make using-gcc-static 
g++-4.8 -o main-gcc-static -static-libstdc++ -static-libasan -O -g >-fsanitize=address -fno-omit-frame-pointer main.cpp && \
ASAN_OPTIONS=symbolize=1 ASAN_SYMBOLIZER_PATH=/usr/local/bin/>llvm-symbolizer ./main-gcc-static

=================================================================
==25464== ERROR: AddressSanitizer: stack-buffer-overflow on address >0x7fff8f79d214 at pc 0x41ab0b bp 0x7fff8f79d050 sp 0x7fff8f79d048
READ of size 4 at 0x7fff8f79d214 thread T0
#0 0x41ab0a in main /home/kkleine/Development/asan-test/main.cpp:5
#1 0x2b4b32bdaec4 in __libc_start_main /build/buildd/eglibc-2.19/csu/>libc-start.c:287
#2 0x402116 in _start (/home/kkleine/Development/asan-test/>main-gcc-static+0x402116)
Address 0x7fff8f79d214 is located at offset 436 in frame of T0’s >stack:
This frame has 1 object(s):
[32, 432) ‘stack_array’
HINT: this may be a false positive if your program uses some custom stack >unwind mechanism or swapcontext
(longjmp and C++ exceptions are supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /home/kkleine/Development>/asan-test/main.cpp:5 main
Shadow bytes around the buggy address:
0x100071eeb9f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100071eeba00: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
0x100071eeba10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100071eeba20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100071eeba30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x100071eeba40: 00 00[f4]f4 f3 f3 f3 f3 00 00 00 00 00 00 00 00
0x100071eeba50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100071eeba60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100071eeba70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100071eeba80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100071eeba90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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 righ 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
ASan internal: fe
==25464== ABORTING
make: * [using-gcc-static] Error 1

ldd

$ ldd main-*
main-clang:
linux-vdso.so.1 => (0x00007fff2a1fe000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (>0x00007ff4eb80a000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007ff4eb602000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff4eb2fb000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff4eb0f7000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (>0x00007ff4eaee1000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff4eab1a000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff4eba63000)
main-gcc:
linux-vdso.so.1 => (0x00007fffe6bae000)
libasan.so.0 => /usr/lib/x86_64-linux-gnu/libasan.so.0 (>0x00007f8b44a0e000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8b44648000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (>0x00007f8b44429000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f8b44225000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8b479d8000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (>0x00007f8b4400f000)
main-gcc-static:
linux-vdso.so.1 => (0x00007fffd615b000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f29984f3000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (>0x00007f29982d5000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (>0x00007f29980be000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2997cf8000)
/lib64/ld-linux-x86-64.so.2 (0x00007f2998732000)

원본 자료 : Github - kwk/Makefile

이 블로그의 인기 게시물

데일 카네기 인간관계론 정리

Remove-Server-Header

응답 메시지 내 서버 버전 정보 제거 1. Apache 1) 조치 방법 “/etc/htpd/conf/httpd.conf” 파일 안에서 1. ServerTokens OS → ServerTokens Prod 2. ServerSignature On → ServerSignature Off 로 변경한 후 아파치를 재시작하면 헤더 값의 아파치 버전 정보 및 OS 정보를 제거할 수 있다. 2) 참고 URL http://zetawiki.com/wiki/CentOS_ 아파치_보안권장설정_ServerTokens_Prod,_ServerSignature_Off 2. IIS 1) 조치 방법 IIS 6.0 urlscan_setup 실행. 설치. \windows\system32\inetsrv\urlscan\urlscan.ini 파일을 열어 다음 수정(RemoveServerHeader=0 을 RemoveServerHeader=1 로 변경) 서비스에서 IIS Admin Service 재시작. IIS 7.0 IIS 관리자를 열고 관리하려는 수준으로 이동합니다. 기능 보기에서 HTTP 응답 헤더를 두 번 클릭합니다. HTTP 응답 헤더 페이지에서 제거할 헤더를 선택합니다. 작업 창에서 제거를 클릭하고 예를 클릭합니다. 2) 참고 URL IIS 6.0 : http://gonnie.tistory.com/entry/iis6- 응답헤더-감추기 IIS 7.0 : https://technet.microsoft.com/ko-kr/library/cc733102(v=ws.10).aspx 3. jetty 1) 조치 방법 “jetty.xml” 파일에서 jetty.send.server.version=false 설정 2) 참고 URL http://attenuated-perspicacity.blogspot.kr/2009/09/jetty-61x-hardening.html 4. Nginx ...

CVE-2017-11352

CVE-2017-11352 ImageMagick 에서 발생했던 CVE-2017-9144 취약점의 미흡한 조치로 인하여 동일한 취약점이 다시 발생되었다. 재 발생된 취약점 CVE-2017-11352은 coders/rle.c 에서 RLE 이미지에 대한 부적절한 EOF 처리가 원인이었다. EOF 란? 파일의 끝(End of File, EOF)으로 데이터 소스로부터 더 이상 읽을 수 있는 데이터가 없음을 나타낸다. ImageMagick Github Page 에 들어가보면 해당 이슈를 상세히 확인할 수 있다. 부적절한 EOF 처리 원인은 소스 코드 수정 시 유사한 코드를 복사 붙여넣기 하는 과정에서 검증해야할 변수 명을 고치지 않고 그대로 적용해서 발생했다. operand=ReadBlobByte(image); if (opcode == EOF) ThrowRLEException(CorruptImageError, "UnexpectedEndOfFile" ); 이로 인해서 조치 완료된 줄 알았던 CVE-2017-9144 취약점은 CVE-2017-11352이라는 새로운 취약점 명으로 다시 조치 되었다. case SkipLinesOp: { operand=ReadBlobByte(image); - if (opcode == EOF) + if (operand == EOF) ThrowRLEException(CorruptImageError, "UnexpectedEndOfFile" ); if (opcode & 0x40 ) { operand=ReadBlobLSBSignedShort(image); - if (opcode == EOF) + if (operand == EO...