HeartBleed는 AFL Fuzzer할 때 다뤘으니 생략하겠다.

AFL Fuzzer를 사용했던 것 처럼 libFuzzer를 이용해 HeartBleed를 찾아보자!

Build OpenSSL

afl 때와 별로 다른 건 없는데 굳이 afl-clang을 사용하지 않아도 되고 AFL_USE_ASAN의 값을 지정하지 않아도 된다. 라고 했다가 굉장히 헤맸다. CC 값 설정을 잘해줘야 libFuzzer가 잘 돌아간다.

$ git clone https://github.com/openssl/openssl.git
$ cd openssl
$ git checkout OpenSSL_1_0_1f
$ CC='clang -O2 -fno-omit-frame-pointer -gline-tables-only -fsanitize=address,fuzzer-no-link -fsanitize-address-use-after-scope' ./config -d
$ make

target.cc

// Copyright 2016 Google Inc. All Rights Reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <assert.h>
#include <stdint.h>
#include <stddef.h>

SSL_CTX *Init() {
  SSL_library_init();
  SSL_load_error_strings();
  ERR_load_BIO_strings();
  OpenSSL_add_all_algorithms();
  SSL_CTX *sctx;
  assert (sctx = SSL_CTX_new(TLSv1_method()));
  /* These two file were created with this command:
      openssl req -x509 -newkey rsa:512 -keyout server.key \
     -out server.pem -days 9999 -nodes -subj /CN=a/
  */
  assert(SSL_CTX_use_certificate_file(sctx, "runtime/server.pem",
                                      SSL_FILETYPE_PEM));
  assert(SSL_CTX_use_PrivateKey_file(sctx, "runtime/server.key",
                                     SSL_FILETYPE_PEM));
  return sctx;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
  static SSL_CTX *sctx = Init();
  SSL *server = SSL_new(sctx);
  BIO *sinbio = BIO_new(BIO_s_mem());
  BIO *soutbio = BIO_new(BIO_s_mem());
  SSL_set_bio(server, sinbio, soutbio);
  SSL_set_accept_state(server);
  BIO_write(sinbio, Data, Size);
  SSL_do_handshake(server);
  SSL_free(server);
  return 0;
}

이 코드 또한 libFuzzer 자체에서 Data를 만들어 패킷을 보내는 형식으로 생각하면 된다. 이제 컴파일만 해주면 끝이다.

아 그전에, runtime이라는 디렉토리 안에 server.key, server.pem을 생성해주자.

$ mkdir runtime
$ cd runtime
$ openssl req -x509 -newkey rsa:512 -keyout server.key -out server.pem -days 9999 -nodes -subj /CN=a/

Fuzzing!

$ clang++ -g -O1 -fsanitize=fuzzer,address target.cc openssl/libssl.a openssl/libcrypto.a -o target -I openssl/include -ldl
$ ./target
image

Heap-Buffer-Overflow가 발생했다. crash 파일을 재미삼아 afl 퍼저 실습할 때 만든 바이너리에 넣어보자.

image

동일하게 오류가 난다! 이렇게 HeartBleed까지 퍼징해보았다.


'System Hacking' 카테고리의 다른 글

libFuzzer Training - (1) Start  (2) 2020.04.18
AFL Fuzzing Training - (2) HeartBleed  (0) 2020.04.18
AFL Fuzzing Training - (1) Setup & Easy Example  (0) 2020.04.12

+ Recent posts