소프트웨어에 있어서 보안 문제는 매우 위협적이고, 이를 대응하기 위한 비용도 상당히 많이 소요된다. 2008년 CSI의 연례 보고서에 따르면, Computer 이용 범죄 및 보안에 관한 조사에서 평균 289,000 달러의 손실이 수반된다고 판시하였다. 이를 막기위해 취하는 조치가 바로 ‘보안 테스팅’이다. 소프트웨어 취약점을 조기에 발견하기 위해 사용하는 여러가지 기술이 있으며, 퍼징은 그 중 하나다. 임의의 데이터 입력값을 자동으로 생성하여 충돌 또는 예기치 않은 동작을 발생시킴으로써 잠재적인 소프트웨어 취약점을 찾아내는 기법이다. 결국, Fuzz 테스팅은 취약점을 노출시키기 위해 소프트웨어 시스템에 대해 랜덤한 데이터 input을 자동으로 주입하는 기법이다.


Fuzzing은 최초에 누가 발명하였는가?

Miller, Barton P., Louis Fredriksen, and Bryan So 등이 발표한 "An empirical study of the reliability of UNIX utilities."(1990)에서 최초로 언급된 것으로 알려져 있다. 소프트웨어 신뢰도를 테스트하는 수단으로서의 퍼지(fuzzing)를 사용하였다고 한다. 그러나 이것은 '단어'를 사용했다는 의미이며 따라서 최초 탄생에 관해서는 논란의 여지가 있다. 이보다 선행된 연구인 1972년 Purdom, Paul.의 “A sentence generator for testing parsers” 논문이 있었다. 파싱 기능을 테스트 하기 위해 문장을 생성하는 방법을 논하고 있는데, 결국 이러한 알고리즘이 지금의 퍼저 기능을 의미하므로 시초가 되었다고 볼 수 있다. 어쨌든, 실존하는 real-world의 소프트웨어(어플리케이션, 프로그램)에 대해서 구체적인 퍼징을 시도한 첫 사례는 Miller의 논문이 최초라고 볼 수 있다.


비하인드 스토리

Fuzzing은 사실 굉장히 우연한 방법으로 알게된 기법이다. 논문의 저자 중 한명이 장마철 폭우가 치는 날, 컴퓨터를 사용하던 중 전자기 간섭(electro-magnetic interference)이 발생하였고, 이로인해 사용자가 입력하지 않은 임의의 값들이 무작위로 command-line에 삽입되어버려서, 사용중이던 응용 프로그램에 Crash가 발생하는 기묘한 일을 겪었다고 한다. 이를 경험한 저자는 Miller 등과 함께 '무작위로 손상된 입력을 적절하게 처리하지 못하는 대부분의 응용프로그램은 취약한 것이 아닐까?' 라는 고민을 시작하게 되었다. 결국, 소프트웨어의 강건성(robustness)을 테스트하기 위한 무작위 입력을 생성하는 방법을 고안하게 되었다. 그들은 다음 두가지 프로그램을 제시하였다.


Fuzz와 Ptyjig

Miller는 실제로 Fuzz 와 Ptyjig라는 두개의 샘플 프로그램을 공개하였다. Fuzz는 대상 프로그램에서 적용 할 임의의 문자 스트림을 자동으로 생성하고, Ptyjig는 fuzz의 결괏값을 대화식 유틸리티 프로그램에 전달하는 방식으로 테스트하기 위해 작성되었다. (예시 :   fuzz 100000 -o outfile |  ptyjig vi )


왼쪽이 Fuzz, 오른쪽이 Ptyjig
왼쪽이 Fuzz, 오른쪽이 Ptyjig


이들은 이 도구를 사용해서 실제 UNIX 시스템의 다양한 Utilities의 취약점 및 버그를 발견하는 성과를 얻었다고 한다. 실제로 테스트한 환경은 88개의 Unix 응용프로그램이며, 퍼징 도구에 의해 입력값이 주입되면 25~33%의 유틸에서 Crash가 발생하는 버그가 발견되었다. 

테스트에 사용된 시스템 목록
테스트에 사용된 시스템 목록
각 시스템에서 테스트 된 유틸리티의 목록. 검은 점으로 표시된 항목은 crash가 발생한 것이다.
각 시스템에서 테스트 된 유틸리티의 목록. 검은 점으로 표시된 항목은 crash가 발생한 것이다.


fuzz는 기본적으로 random한 문자열을 생성해내는 것이다. 따라서 사용자는 얼마만큼의 input을 생성하기 원하는지를 지정해야 한다. 또한, 특정 문자는 사용하지 말아야한다거나 등의 제약조건을 고민하고 적절히 설정하여야 한다. 그리고 fuzz로 인한 생성 결괏값을 단지 화면에 출력하도록 하거나, File에 기록하여 저장하거나, 또는 직접 해당 응용프로그램에 pipe로 전달할 수 있다. 이러한 작업에 의사난수생성기를 활용한다면 사용자는 seed만 설정함으로써 반복적으로 테스팅을 재수행하는 방식으로 자동화할 수 있다.


Miller 등은 가능한 많은 테스트를 자동화하기 위해 스크립트를 작성하여 구동하였다. 응용프로그램이 예기치 않은 오류로 인해 여러번 강제종료될 때, 각각의 core dump를 확인하여 해당 오류를 자세히 검사하면 된다. 그러므로 그 원인이 된 입력값과 그로인한 core dump를 저장하는 과정을 자동화하면 된다. 


결론

Miller 등은 우연히 발견한 퍼지(Fuzz)를 실용적으로 전환시키는 발상의 전환을 통해 소프트웨어의 테스트 요구사항을 정의하고 이를 충족시키는지 확인하는 기법으로써의 실용적인 Fuzzer 모델을 제시하였다. 또한, Fuzzer의 구성요소, 제공해야 할 기능 등에 대한 최초의 정의를 확립하였다. 지난 30년 동안 퍼징 기법은 꾸준히 발전해오고 있지만, Fuzzer의 모델은 Miller가 제시한 항목들로 꾸준히 유지되고 있다. 역시 사람은 이름을 남기는 것이다.


참고문헌 : 

[1] Clarke, Toby. "Fuzzing for software vulnerability discovery." Department of Mathematic, Royal Holloway, University of London, Tech. Rep. RHUL-MA-2009-4 (2009).

[2] Sutton, Michael, Adam Greene, and Pedram Amini. Fuzzing: brute force vulnerability discovery. Pearson Education, 2007.

[3] Prof. Barton P Miller's Home Page : http://pages.cs.wisc.edu/~bart/


CPUU님의 창작활동을 응원하고 싶으세요?