확장 가능한 parallel fuzzing 인프라 구축 및 성능 비교 분석 (3-1) 실제 소프트웨어 Fuzz

OOSUlZ·2023년 2월 24일
0

이 게시글의 fuzzing 실습은 대부분 https://github.com/antonio-morales/Fuzzing101/tree/main/ 를 참고하였다.

3. 기타 소프트웨어 Fuzz


0) Google Bug Hunter

Fuzz를 하기 이전에 Google Bug Hunters에 Reports가 된 사례를 보고 따라해보고, Fuzz할만 한 것들이 있는지 살펴보았으나, Fuzz의 대상으로 적절치 못하여 조사만 실시하였다.

Google Auth Bypass in ads.google.com

Auth Bypass in ads.google.com | Google Bug Hunters

💡 Auth Bypass (Authentication Bypass Vulnerability)란? 로그인과 같은 과정을 거치지 않고 취약한 파일 등의 경로를 통해 로그인하여 권한을 행사하는 것을 말한다.주로 관리자가 충분히 보안을 해놓지 않거나 사용자가 비밀번호를 자주 바꾸지 않은 경우 발생할 수 있는 문제이다.

XSS in https://mail.google.com (Gmail)

XSS in https://mail.google.com/mail/u/0/#inbox | Google Bug Hunters

💡 **XSS 란?** XSS 는 Cross-site Scripting의 약자로 SQL Injection처럼 취약한 코드에 공격자의 스크립트를 넣어서 공격하는 것을 말한다. SQL Injection과 달리 XSS 는 주로 프론트엔드의 Javascript 에서 이루어진다. 게시판과 같이 여러 사용자가 접근할 수 있는 곳에 스크립트를 심어 사용자의 개인정보를 빼가는 방식이 많다. 또는 위와 같이 mail을 타고 접근할 수도 있다.

1) CVE-LIST

CVE(Common Vulnerabilities and Exposures)는 공개적으로 알려진 컴퓨터 보안 결함 목록이다. CVE는 보통 CVE ID 번호가 할당된 보안 결함을 뜻한다.

이 결함이 속한 소프트웨어들을 Fuzz 해보며 실습을 하려 한다.

(1) XPDF

CVE-2019-13288 : In Xpdf 4.01.01, the Parser::getObj() function in Parser.cc may cause infinite recursion via a crafted file. A remote at

Xpdf 4.01.01 버전에서 Parser.cc의 Parser::getObj() 함수는 제작된 파일을 통해 무한 재귀를 유발할 수 있음.
프로그램에서 호출된 각 함수는 스택에 스택 프레임을 할당하므로 함수가 반복적으로 여러 번 호출되면 스택 메모리 고갈 및 프로그램 충돌로 이어진다. (DoS 공격에 활용가능성) 
이는 CVE-2018-16646과 유사하다.
CVE-2019-13288

fuzz에 앞서 ..

AFL은 비결정론적 테스트 알고리즘을 사용하기 때문에 고정 시드값(-s123)을 설정하여 FUZZ를 진행할 예정이다.

그리고 문제가 되는 Xpdf는 3.02 버전으로 설치해 줄 예정이다.

XPDF 설치 전 사전 작업 및 테스트

  1. xpdf fuzz를 위한 폴더 생성
cd $HOME
mkdir fuzzing_xpdf && cd fuzzing_xpdf/
  1. make와 gcc를 위한 툴 설치
sudo apt install build-essential
  1. Xpdf 3.02버전 다운후 압축 해제
wget https://dl.xpdfreader.com/old/xpdf-3.02.tar.gz
tar -xvzf xpdf-3.02.tar.gz
  1. Xpdf 빌드
cd xpdf-3.02
sudo apt update && sudo apt install -y build-essential gcc
./configure --prefix="$HOME/fuzzing_xpdf/install/"
make
make install
  1. 빌드 한 Xpdf 테스트를 위한 PDF 예제들 다운받기
cd $HOME/fuzzing_xpdf
mkdir pdf_examples && cd pdf_examples
wget https://github.com/mozilla/pdf.js-sample-files/raw/master/helloworld.pdf
wget http://www.africau.edu/images/default/sample.pdf
wget https://www.melbpc.org.au/wp-content/uploads/2017/10/small-example-pdf-file.pdf
  1. pdfinfo test
$HOME/fuzzing_xpdf/install/bin/pdfinfo -box -meta $HOME/fuzzing_xpdf/pdf_examples/helloworld.pdf 

XPDF AFL++로 빌드하기

소스 코드를 사용할 수 있는 경우 AFL은 각 기본 블록(함수, 루프 등)의 시작 부분에 함수 호출을 삽입하여 instrumentation 을 사용할 수 있음

  1. 빌드 다시하기 위한 사전 작업
    이전에 컴파일된 모든 개체 파일 및 실행 파일을 정리
cd ..rm -r $HOME/fuzzing_xpdf/install
cd $HOME/fuzzing_xpdf/xpdf-3.02/
make clean
  1. afl-clang-fast 컴파일러를 사용해 Xpdf 빌드
export LLVM_CONFIG="llvm-config-11"
CC=$HOME/AFLplusplus/afl-clang-fast CXX=$HOME/AFLplusplus/afl-clang-fast++ ./configure --prefix="$HOME/fuzzing_xpdf/install/"
make
make install
  1. afl-fuzz 실행 (시드값 123 사용)
afl-fuzz -i $HOME/fuzzing_xpdf/pdf_examples/ -o $HOME/fuzzing_xpdf/out/ -s 123 -- $HOME/fuzzing_xpdf/install/bin/pdftotext @@ $HOME/fuzzing_xpdf/output

이 오류가 뜨면 다음과 같이 실행한다.

sudo su
echo core >/proc/sys/kernel/core_pattern
exit

정상적으로 Fuzz가 되어, 1개의 crash 파일을 찾은 것을 확인했다.
(1~2시간은 돌려야 하지만, 시간 관계상 crash를 찾았으므로 임의로 중단하였다)

$HOME/fuzzing_xpdf/out/default/crashes 폴더에 가면 id:000000,sig:11,src:000855,time:244130,execs:97311,op:havoc,rep:16 라는 크래시 파일이 생성되어 있는데 이 파일을 pdftotext 바이너리에 input으로 넣으려고 한다.

$HOME/fuzzing_xpdf/install/bin/pdftotext $HOME/fuzzing_xpdf/out/default/crashes/id:000000,sig:11,src:000855,time:244130,execs:97311,op:havoc,rep:16 $HOME/fuzzing_xpdf/output

segmentation error가 발생한 것을 확인 할 수 있다.
왜 이런 오류가 발생하는지는 gdb란 프로그램을 활용해서 살펴보려 한다.

보통은 GDB라고 부르는 GNU 디버거는 GNU 소프트웨어 시스템을 위한 기본 디버거이다. GDB는 다양한 유닉스 기반의 시스템에서 동작하는 이식성있는 디버거로, 에이다, C, C++, 포트란 등의 여러 프로그래밍 언어를 지원함

Call stack 확인해서 알려진 오류와 동일한지 확인하기

rm -r $HOME/fuzzing_xpdf/install
cd $HOME/fuzzing_xpdf/xpdf-3.02/
make clean
CFLAGS="-g -O0" CXXFLAGS="-g -O0" ./configure --prefix="$HOME/fuzzing_xpdf/install/"
make
make install

GDB를 실행하는 명령어는 다음과 같다

gdb --args $HOME/fuzzing_xpdf/install/bin/pdftotext $HOME/fuzzing_xpdf/out/default/crashes/id:000000,sig:11,src:000855,time:244130,execs:97311,op:havoc,rep:16 $HOME/fuzzing_xpdf/output

여기서 run 을 실행하면

seg fault가 발생한 것을 확인 할 수 있다.
backtracking 을 실시하는 bt 명령어를 통해 backtrace를 하면 다음과 같다

"Parser::getObj” method가 반복적으로 무한 재귀 호출이 되는 것을 확인 할 수 있다.

이 오류는 xpdf 4.0.2 버전에서 디버깅 되었다고 한다.

(2) tcpdump

tcpdump (명령 줄에서 실행하는 일반적인 패킷 가로채기 소프트웨어)

CVE-2017-13028 : The BOOTP parser in tcpdump before 4.9.2 has a buffer over-read in print-bootp.c:bootp_print().

tcpdump 4.9.2 이전 버전의 BOOTP parser는 print bootp.c:bootp_print() 함수에서 버퍼 over-read 현상이 존재함

CVE-2017-13028

fuzz에 앞서 ..

AFL은 비결정론적 테스트 알고리즘을 사용하기 때문에 고정 시드값(-s123)을 설정하여 FUZZ를 진행할 예정이다.

그리고 문제가 되는 tcpdump4.9.2버전으로 설치해 줄 예정이다.

tcpdump 설치 전 사전 작업 및 테스트

  1. tcpdump fuzz를 위한 폴더 생성
cd $HOME
mkdir fuzzing_tcpdump && cd fuzzing_tcpdump/
  1. tcpdump 4.9.2버전 다운후 압축 해제
wget https://github.com/the-tcpdump-group/tcpdump/archive/refs/tags/tcpdump-4.9.2.tar.gz
tar -xzvf tcpdump-4.9.2.tar.gz
  1. TCPdump할 때 필요한 크로스 플랫폼 라이브러리 다운이 필요
wget https://github.com/the-tcpdump-group/libpcap/archive/refs/tags/libpcap-1.8.0.tar.gz
tar -xzvf libpcap-1.8.0.tar.gz
mv libpcap-libpcap-1.8.0/ libpcap-1.8.0
  1. libpcap 빌드
cd $HOME/fuzzing_tcpdump/libpcap-1.8.0/
./configure --enable-shared=no
make
  1. tcpdump 빌드
cd $HOME/fuzzing_tcpdump/tcpdump-tcpdump-4.9.2/
./configure --prefix="$HOME/fuzzing_tcpdump/install/"
make
make install
  1. 설치 확인하기

$HOME/fuzzing_tcpdump/install/sbin/tcpdump -h

정상적으로 설치가 된 것을 확인했다.

FUZZ 사전 작업

./tests 폴더에서 많은 .pcacp 예제를 찾을 수 있음


$HOME/fuzzing_tcpdump/install/sbin/tcpdump -vvvvXX -ee -nn -r ./tests/geneve.pcap

출력결과는 다음과 같이 나온다.

ASan 사용하여 FUZZ 하기

이전에 사용했던 적이 있던 ASAN을 사용해 FUZZ를 해보려 한다.

rm -r $HOME/fuzzing_tcpdump/install
cd $HOME/fuzzing_tcpdump/libpcap-1.8.0/
make clean

cd $HOME/fuzzing_tcpdump/tcpdump-tcpdump-4.9.2/
make clean

configure와 make를 하기 전 AFL_USE_ASAN=1 으로 설정한다.

cd $HOME/fuzzing_tcpdump/libpcap-1.8.0/
export LLVM_CONFIG="llvm-config-11"
CC=afl-clang-lto ./configure --enable-shared=no --prefix="$HOME/fuzzing_tcpdump/install/"
AFL_USE_ASAN=1 make

cd $HOME/fuzzing_tcpdump/tcpdump-tcpdump-4.9.2/
AFL_USE_ASAN=1 CC=afl-clang-lto ./configure --prefix="$HOME/fuzzing_tcpdump/install/"
AFL_USE_ASAN=1 make
AFL_USE_ASAN=1 make install

configure와 make를 하기 전 AFL_USE_ASAN=1 으로 설정한다.

그리고 나서 Fuzz를 pcacp 예제들을 활용해서 실행해본다.
64비트의 ASAN은 가상메모리를 엄청 많이 요구하므로 -m none 옵션을 붙여 메모리 제한 사용 안함 옵션을 명시해 주었다.

afl-fuzz -m none -i $HOME/fuzzing_tcpdump/tcpdump-tcpdump-4.9.2/tests/ -o $HOME/fuzzing_tcpdump/out/ -s 123 -- $HOME/fuzzing_tcpdump/install/sbin/tcpdump -vvvvXX -ee -nn -r @@

얼마 지나지 않아 엄청난 crash들이 생성이 된다.

이 크래시들은 fuzzing_tcpdump/out/default/crashes 디렉토리에 저장이 되었다. 이중 id가 000000인 크래시파일을 ASAN을 활용해 열어보도록 한다.

$HOME/fuzzing_tcpdump/install/sbin/tcpdump -vvvvXX -ee -nn -rid:000000,sig:11,src:000179+000441,time:74534,execs:28128,op:splice,rep:16

아까 말했던 print bootp.c:bootp_print() 함수에서 버퍼 over-read 현상이 존재한다는 것을 요약파일로 확인 할 수 있다.

이 버그는 다음 버전의 tcp_dump에서 고쳐졌다고 한다

(3) LibTIFF

LibTIFF
(Tagged Image File Format 파일을 읽고 쓰기 위한 라이브러리)

CVE-2016-9297 : The TIFFFetchNormalTag function in LibTiff 4.0.6 allows remote attackers to cause a denial of service (out-of-bounds rea

조작된 TIFF_SETGET_C16ASCII 또는 TIFF_SETGET_C32_ASCII 태그 값을 통해 트리거될 수 있는 Out-of-bounds Read 취약점이 발견되었음

Out-of-Bounds Read는 프로그램이 의도한 버퍼의 끝 또는 시작 전에 데이터를 읽을 때 발생하는 취약점
결과적으로 원격 공격자가 서비스 거부를 유발하거나 프로세스 메모리에서 잠재적으로 중요한 정보를 해킹 가능함

**CVE-2016-9297**

fuzz에 앞서 ..

AFL은 비결정론적 테스트 알고리즘을 사용하기 때문에 고정 시드값(-s123)을 설정하여 FUZZ를 진행할 예정이다.

그리고 문제가 되는 LibTIFF4.0.4버전으로 설치해 줄 예정이다.

LCOV (GCOV의 reporthtml으로 보기위한 확장 함수커버리지 툴) 도 사용할 예정이다.

docker의 AFL++에서 작업할 예정이다.

LibTIFF 설치 전 사전 작업 및 테스트

  1. LibTIFF fuzz를 위한 폴더 생성
cd $HOME
mkdir fuzzing_tiff && cd fuzzing_tiff/
  1. LibTIFF 4.0.4 버전 다운후 압축 해제
wget https://download.osgeo.org/libtiff/tiff-4.0.4.tar.gz
tar -xzvf tiff-4.0.4.tar.gz
  1. LibTIFF 빌드
cd tiff-4.0.4/
./configure --prefix="/home/fuzzing_tiff/install/" --disable-shared
make
make install

Fuzz의 대상은 /bin 폴더에 있는 tiffinfo 바이너리를 fuzz할 생각이다. fuzzing의 샘플 이미지 input은 /test/images/ 폴더에 있는 것들을 활용할 예정이다.

  1. 작동이 잘되는 지 테스트
/home/fuzzing_tiff/install/bin/tiffinfo -D -j -c -r -s -w /home/fuzzing_tiff/tiff-4.0.4/test/images/palette-1c-1b.tiff

정상적으로 작동이 잘 되는 모습을 확인 할 수 있다.

"-j -c -r -s -w" 옵션은 code coverage를 향상 시키고 버그를 쉽게 찾기 위한 옵션이다.

Code Coverage 측정을 위한 LCOV 사용

code coverage는 코드의 각 줄이 얼마나 실행 되는지 발동된 횟수를 나타낸 metric이다. 또한 fuzzer가 도달한 코드를 확인하고 fuzzing process를 시각화 해준다.

  1. LCOV 설치
sudo apt install lcov
  1. —-coverage 태그를 달아 libTIFF를 다시 빌드
rm -r /home/fuzzing_tiff/install
cd /home/fuzzing_tiff/tiff-4.0.4/
make clean
  
CFLAGS="--coverage" LDFLAGS="--coverage" ./configure --prefix="/home/fuzzing_tiff/install/" --disable-shared
make
make install

LCOV 설치를 통해 얻은 code coverage 데이터는 다음과 같은 코드로 확인가능하다.

  • lcov --zerocounters --directory ./ : 이전 카운터 재설정
  • lcov --capture --initial --directory ./ --output-file app.info : 실행된 모든 라인에 대해 coverage가 0인 "베이스라인" coverage 데이터 파일을 리턴
  • /home/fuzzing_tiff/install/bin/tiffinfo -D -j -c -r -s -w /home/fuzzing_tiff/tiff-4.0.4/test/images/palette-1c-1b.tiff : 분석하려는 응용 프로그램을 실행 
    다른 입력으로 여러 번 실행도 가능
  • lcov --no-checksum --directory ./ --capture --output-file app2.info : 현재 커버리지 상태를 app2.info 파일에 저장
cd /home/fuzzing_tiff/tiff-4.0.4/
lcov --zerocounters --directory ./
lcov --capture --initial --directory ./ --output-file app.info
/home/fuzzing_tiff/install/bin/tiffinfo -D -j -c -r -s -w /home/fuzzing_tiff/tiff-4.0.4/test/images/palette-1c-1b.tiff
lcov --no-checksum --directory ./ --capture --output-file app2.info

최종적으로 이 결과 리포트를 다음 코드를 통해 html로 확인할 수 있다. 정상적으로 완료되면, html-coverage 폴더가 생겼을 것이다. 이 리포트를 통해 코드가 얼마나 실행되는지 확인 가능하다.

그림이 작지만 다음과 같이 표시된다.

Fuzzing

  1. fuzz 전 사전작업
rm -r /home/fuzzing_tiff/install
cd /home/fuzzing_tiff/tiff-4.0.4/
make clean
  1. AFL_USE_ASAN=1로 설정 후, make를 하고 빌드
export LLVM_CONFIG="llvm-config-11"
CC=afl-clang-lto ./configure --prefix="/home/fuzzing_tiff/install/" --disable-shared
AFL_USE_ASAN=1 make -j4
AFL_USE_ASAN=1 make install
  1. fuzz
afl-fuzz -m none -i /home/fuzzing_tiff/tiff-4.0.4/test/images/ -o /home/fuzzing_tiff/out/ -s 123 -- /home/fuzzing_tiff/install/bin/tiffinfo -D -j -c -r -s -w @@

fuzzing을 한시간을 돌리니, 무려 6743개, unique한 크래시는 207개나 발견하였다.

이 중 의미있는 crash를 확인하기 위해 id:000000,sig:06,src:000017,time:32396,execs:42291,op:havoc,rep:8 라는 파일을 확인해 보려고 한다. ASAN을 활용하여 다음 커맨드를 입력시키면 상세한 내역이 뜰 것이다.

/home/fuzzing_tiff/install/bin/tiffinfo -D -j -c -r -s -w '/home/fuzzing_tiff/out/default/crashes/id:000000,sig:06,src:000017,time:32396,execs:42291,op:havoc,rep:8’

위에서 언급한 조작된 TIFF_SETGET_C16ASCII 또는 TIFF_SETGET_C32_ASCII 태그 값을 통해 트리거될 수 있는 Out-of-bounds Read 취약점이 발견된 것을 확인 할 수 있다.

이 오류는 https://github.com/vadz/libtiff/commit/30c9234c7fd0dd5e8b1e83ad44370c875a0270ed 에서 fix 되었다.

아까 말했던 LCOV report는 다음과 같이 표현되었다.
도커 내에서는 html파일을 단독으로 실행을 못시키기 때문에, 다음과 같은 절차로 실행 가능하다.
원리 : 도커 내의 파일을 로컬로 복사해서 실행하는 원리

chrome을 먼저 설치하고 그 크롬 파일을 이미 환경 변수에 등록되어 있는 폴더에 옮긴다.

$ sudo ln -s /opt/google/chrome/chrome /usr/bin/chrome (보통 경로는 다음처럼 설치되어 있다)
그리고 터미널에 **$ chrome ./index.html** 을 입력하면 된다


profile
천천히,꾸준하게

0개의 댓글