Sulley 는 TrippingPoint 의 패드램 아미니와 아론 포트노이가 개발한 파이썬 기반의 강력한 퍼징 프레임워크로써 Sulley 라는 이름은 영화 몬스터 주식회사에 나오는 크고 푸른 괴물인 Sulley 의 이름을 따서 지은 것이다. Sulley 는 단순한 퍼저가 아닌 퍼저 그 이상이다. 패킷을 캡쳐할 수 있고 광범위한 에러 보고 기능과 VMware 자동화를 제공한다. 또한 퍼징 대상 애플리 케이션에서 에러가 발생하면 해당 애플리케이션을 재시작 시켜 버그를 발견하기 위한 퍼징 세션을 다시 시작시킬 수 있다.
Sulley 는 블록 기반의 퍼징을 수행한다. 블록 기반 퍼징 방법은 데이브 아이텔이 개발한 SPIKE 에서 처음으로 사용됐다. 블록 기반 퍼징에서는 퍼징을 수행할 프로토콜이나 파일 형식 등을 일반화 시키는데, 그것은 데이터의 각 필드에 길이와 데이터 타입을 할당함으로써 이뤄진다. 그런 다음에 퍼저는 내부적인 테스트 케이스를 만들어 그것을 다양한 방법으로 일반화 시킨 프로토콜에 적용한다. 이 방법을 사용하면 퍼저는 퍼징을 수행할 프로토콜에 대해 미리 내부적인 정보를 알고 있으므로 매우 효과적으로 버그를 찾아낼 수 있다.
1) Sulley 설치
Sulley 를 살펴보기 전에 설치를 먼저 해야 한다.
http://www.nostarch.com/ghpython.htm 을 통해 소스코드가 압축된 파일을 받을 수 있다.
압축 해제후 sulley, utils, request 폴더를 파이썬 Lib/site-packages 로 복사한다.
그후 필수 패키지 몇개를 설치해야 한다.
1. WinPcap
--> pcapy, impacket 도 설치해야 한다.
pcapy 는 WinPcap에 대한 파이썬 인터페이스
impacket 은 패킷 인코딩과 생성을 가능하게 하는 파이썬 라이브러리
Sulley 프리미티브
퍼징을 수행할 애플리케이션을 선택한 다음에는 퍼징 프로토콜을 나타내는 데이터 형식을 정의해야 한다. Sulley 는 이런 데이터 형식을 아주 많이 제공하기 때문에 간단한 것 뿐만 아니라 복잡한 프로토콜도 빠르게 만들 수 있다. 이런 각 데이터 컴퍼넌트 들을 프리미티브(primitive) 라 부른다. 여기서는 WarFTPD 서버를 철저히 퍼징하기 위해 필요한 프리미티브를 간단히 살펴볼 것이다. 일단 기본적인 프리미티브들의 사용법을 확실히 알게 되면 다른 프리미티브들도 쉽게 이해할 수 있다.
문자열은 가장 자주 사용하게 되는 프리미티브다. 즉, 사용자 이름,IP,주소,디렉토리,기타 많은 것이 문자열로 표현된다. Sulley 는 s_string() 지시어를 사용해 프리미티브 안에 포함되어 있는 데이터가 문자열이라는 것을 나타낸다. s_string() 지시어에는 문자열이 주요 인자로 사용되며, 해당 문자열은 프로토콜에 일반적인 입력으로 전달되는 올바른 형태의 문자열이다. 예를 들어 이메일 주소를 퍼징한다면 s_string() 은 다음과 같이 사용된다.
s_string("hyunwoo@kim82536.pe.kr")
이렇게 하면 Sulley 에게 hyunwoo@kim82536.pe.kr 이 올바른 이메일 주소라는 것을 알려주며, Sulley 는 이를 이용해 모든 가능한 변형을 만들어 퍼징을 수행한다. 그리고 맨 마지막에는 원래의 올바른 이메일 주소를 사용한다. 다음은 Sulley 가 입력된 이메일 주소를 이용해 퍼징에 사용할 새로운 이메일 문자열을 만든 예이다.
hyunwoo@kim82536.pe.krAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
hyunwoo@%n%n%n%n%n%n%n.pe.kr
%d%d%d%d%d@kim82536.pe.krAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
구분자
구분자는 긴 문자열을 처리하기 쉽게 여러 개의 문자열로 나누는 데 사용되는 짧은 문자열이다. s_delim() 지시어를 사용해 앞의 이메일 주소를 다음과 같이 여러 개의 문자열로 나눌 수 있다.
s_string("hyunwoo")
s_delim("@")
s_string("immunityinc")
s_delim(".",fuzzable=False)
s_string("pe.kr")
이처럼 이메일 주소를 여러 개의 짧은 문자열로 나눌 수 있다. 위 예에서는 '.' 에 대해 퍼징을 수행하지 않게 설정했고, @ 구분자에 대해 퍼징을 수행하게 설정했다.
정적, 랜덤 프리미티브
Sulley 에서는 변경되지 않는 정적 Static 문자열이나 임의의 데이터로 변경되는 랜덤 문자열을 전달할 수 있다. 정적 문자열을 사용하려면 다음과 같은 형태로 사용한다.
s_static("Hello,world!")
s_static("\x41\x41\x41")
길이가 유동적인 랜덤 데이터는 s_ramdom() 지시어를 이용해 만들어 낸다. Sulley 가 랜덤 데이터를 어떻게 만들어야 하는지 알려주기 위해 s_ramdom() 지시어에는 몇 개의 인자가 사용된다. min_length 와 max_length 인자는 Sulley 가 만들어 내는 랜덤 데이터의 최소, 최대 길이를 나타낸다. 그 외에 추가적으로 num_mutations 인자를 사용할 수 있는데, 원래의 데이터를 사용하기 전까지 Sulley 가 문자열을 변형하는 횟수를 나타내며, 디폴트 값은 25다. 다음은 랜덤 문자열을 만들어 내는 예다.
s_ramdom("hyunwoo",min_length=6,max_length=256,num_mutations=10)
길이가 6바이트보다 크고 256 바이트 보다는 작은 랜덤 문자열을 만들어 내며, 원래 문자열인 hyunwoo 을 사용하기 전까지 문자열을 10번 변형한다.
바이너리 데이터
Sulley 에서 바이너리 데이터(Binary Data) 프리미티브는 데이터 표현에 있어 스위스 군용 칼과 같다. 어떤 바이너리 데이터든 복사해 사용할 수 있으며, Sulley 는 그런 바이너리 데이터를 이용해 퍼징을 수행한다. 이는 알려지지 않은 프로토콜의 패킷을 캡쳐할 때나 완전하게 갖춰지지 않은 데이터에 대해 서버가 단지 어떻게 응답하는지 보고자 할때 특히 유용하다. 바이너리 데이터의 경우에는 s_binary() 지시어를 사용한다.
s_binary("0x00 \\x41\\x42\\x43 0d 0a 0d 0a")
Sulley 는 바이너리 데이터 형식을 제대로 인식해 다른 문자열과 마찬가지로 해당 바이너리 데이터를 퍼징에 사용한다.
정수
정수는 어디서나 사용된다. 텍스트나 바이너리 프로토콜 모두에서 길이를 판단하거나 데이터 구조체를 표현하기 위해, 그 밖의 모든 종류의 작업을 수행하기 위해 정수가 사용된다. Sulley 는 리스트 9-1 과 같이 주요 정수형을 모두 지원한다.
1 byte s_byte(), s_char()
2 bytes s_word(), s_short()
4 bytes s_dword(), s_long(), s_int()
8 bytes s_qword(),s_double()
모든 정수 표현은 옵션 키워드와 함께 사용된다. endian 키워드는 정수가 little_endian(<) 방식인지 big_endian(>) 방식인지 여부를 나타낸다. 디폴트 값은 little_endian 이다. format 키워드는 ascii 와 binary 두 가지 값을 가질 수 있으며, 정수가 사용되는 방법을 결정한다. 예를 들어 정수 1을 ASCII 형으로 선언했다면 바이너리 값인 \x31 로 표현된다. signed 키워드는 정수가 부호있는 정수인지 아니면 부호 없는 정수인지 여부를 지정한다. 이는 format 키워드의 값을 ascii 로 지정했을 경우에만 사용 가능하며, 디폴트 값은 False 다. 마지막으로 불린 값으로 표현되는 Full_range 키워드가 있다. Full_range 는 Sulley 가 정수에 대한 모든 간으한 값을 사용해 반복적으로 퍼징을 수행할 지 여부를 지정한다. 모든 가능한 정수를 이용해 반복적으로 퍼징을 수행하는 데에는 상당히 오랜 시간이 소요되며, 정수를 사용할 때 Sulley 는 경계 값 (최솟값이나 최댓값에 매우 근접하거나 동일한 값)을 이용할 수 있을 정도로 지능적이기 때문에 full_range 키워드의 사용 여부를 합리적으로 판단해야 한다. full_range 의 기본 값은 false 이다.
블록과 그룹
블록과 그룹은 프리미티브들을 구조적인 방법으로 연결하기 위해 Sulley 가 제공하는 강력한 특징이다. 블록은 각 프리미티브 들의 집합을 하나의 구조 안으로 모으는 것이고, 그룹은 특정 프리미티브가 주기적으로 퍼징에 사용되게 하는 것이다.
'스터디 > 파이썬 해킹 프로그래밍' 카테고리의 다른 글
윈도우 드라이버 퍼징 (0) | 2015.02.23 |
---|---|
질문정리 (0) | 2015.02.16 |
퍼징 (0) | 2015.02.16 |
백도어 제작 (0) | 2015.02.16 |
코드 인젝션 (0) | 2015.02.16 |