
변이 기능을 갖춘 문법 기반 HTTP/1 퍼저
T-Reqs(Two Requests)는 논문의 일부로 작성된 문법 기반 HTTP 퍼저입니다. 해당 논문의 제목은 "T-Reqs: HTTP Request Smuggling with Differential Fuzzing"이며, ACM CCS 2021에서 발표되었습니다.
BibTeX of the paper:
@inproceedings{ccs2021treqs,
title={T-Reqs: HTTP Request Smuggling with Differential Fuzzing},
author={Jabiyev, Bahruz and Sprecher, Steven and Onarlioglu, Kaan and Kirda, Engin},
booktitle={Proceedings of the 2021 ACM SIGSAC Conference on Computer and Communications Security},
pages={1805--1820},
year={2021}
}
T-Reqs는 버전 1.1 및 그 이전의 변형된 HTTP 요청을 전송하여 HTTP 서버를 퍼징하기 위한 도구입니다. 세 가지 주요 구성 요소가 있습니다: 1) 입력 생성, 2) 생성된 입력 변형, 3) 대상 서버로 전달.
퍼저에 입력되는 CFG 문법은 HTTP 요청을 생성하는 데 사용됩니다. 아래에 표시된 예시 문법은 요청 라인 퍼징에 맞춰져 있으므로, 각 요청 라인 구성 요소와 그 구성 요소별 가능한 값이 명시적으로 지정되어 있습니다. 이를 통해 다양한 형태의 요청 라인으로 유효한 요청을 생성할 수 있으며, 변형 관점에서 각 요청 라인 구성 요소를 별도의 단위로 처리할 수 있습니다.
'<start>':
['<request>'],
'<request>':
['<request-line><base><the-rest>'],
'<request-line>':
['<method-name><space><uri><space><protocol><separator><version><newline>'],
'<method-name>':
['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH'],
'<space>':
[' '],
'<uri>':
['/_URI_'],
'<protocol>':
['HTTP'],
'<separator>':
['/'],
'<version>':
['0.9', '1.0', '1.1'],
'<newline>':
['\r\n'],
'<base>':
['Host: _HOST_\r\nConnection:close\r\nX-Request-ID: _REQUEST_ID_\r\n'],
'<the-rest>':
['Content-Length: 5\r\n\r\nBBBBBBBBBB'],
각 구성 요소는 두 가지 방식으로 표시될 수 있습니다: 문자열 변형 가능(string mutable) 및 트리 변형 가능(tree mutable) (예시 구성 참조). 구성 요소가 문자열 변형 가능인 경우, 무작위 위치의 문자를 삭제하거나, 대체하거나, 삽입할 수 있습니다. 아래 예시(왼쪽)에서는 프로토콜 버전의 마지막 문자(1)가 삭제되고, 메서드 이름의 세 번째 문자(S)가 R로 대체되며, URI 시작 부분에 슬래시가 삽입됩니다. 반면, 구성 요소가 트리 변형 가능인 경우, 해당 구성 요소 아래의 무작위 위치에서 무작위 구성 요소를 삭제, 대체 또는 삽입할 수 있습니다. 아래 예시(오른쪽)는 요청 라인 구성 요소에 적용된 세 가지 트리 변형을 보여줍니다: 1) method가 protocol로 대체, 2) 현재 URI 뒤에 추가 URI 삽입, 3) 기존 proto 삭제.

퍼저는 입력 생성 및 변형에 대한 사용자 선호도를 알아야 합니다. 보다 구체적으로, 입력 문법, 변형 가능 구성 요소, 변형 선호도 등을 구성 파일에 지정해야 합니다 (예시 구성 참조).
각 반복에서 생성되고 변형된 입력을 재현할 수 있도록 시드 번호가 사용됩니다. 실제로 이 시드 번호는 입력 형성 및 변형 중 난수 생성의 시드 역할을 합니다. 이러한 시드가 퍼저에 제공되는 방식에 따라 퍼저는 개별(individual) 모드와 벌크(bulk) 모드 중 하나로 실행됩니다. 개별 모드에서는 사용자가 지정한 시드를 기반으로 입력이 생성되고 변형됩니다. 아래 명령어에서는 단일 시드(예: 505)가 지정되었습니다. 또는 -f 옵션을 사용하여 시드 목록을 지정할 수 있습니다 (자세한 내용은 도움말 페이지 참조).
python3 main.py -i -c config -s 505
반면, 벌크 모드(기본값)에서는 시드 값을 0부터 시작하여 종료 번호에 도달할 때까지 각 반복마다 증가시킵니다. 시작 및 종료 번호는 사용자 정의할 수 있습니다.
python3 main.py -c config
또한 t-reqs 코드를 실행할 수 있도록 Dockerfile을 제공합니다. 다음 명령어를 실행하여 시작할 수 있습니다:
# run the command below under the directory which has the Dockerfile
docker build -t test/treqs .
# create a container after you built the image using the command above
docker run -ti test/treqs bash
# run the commands below in the started docker shell
cd t-reqs/
python3 code/main.py -c config -n -i -s90
HTTP 요청 스머글링은 서버 간의 다른 본문 구문 분석 동작에 의존합니다. 여기서 한 서버는 Transfer-Encoding 헤더를 사용하고 다른 서버는 Content-Length 헤더를 선호하여 요청 본문의 경계를 결정하거나, 한 서버는 요청 본문을 무시하는 반면 다른 서버는 처리합니다.
다양한 형태의 HTTP 요청에서 다양한 변형에 대한 서버의 본문 구문 분석을 분석하려면, 해당 서버에 본문 구문 분석 동작을 알려주는 피드백 메커니즘을 설치해야 합니다. 서버에 피드백 메커니즘을 설치하는 한 가지 방법은 서버를 리버스 프록시 모드로 실행하고 서비스로 실행되는 "피드백 제공자(feedback provider)" 스크립트로 요청을 전달하는 것입니다. 이 서비스는 수신된 요청의 본문 길이를 측정하고 이를 저장하여 나중에 다른 서버와 비교합니다.
이 저장소에는 "feedback provider" 스크립트 예시가 포함되어 있습니다. 그러나 이 스크립트는 이 정보가 클라이언트 측에 저장된다고 가정하고 응답으로 본문 길이 정보를 다시 보냅니다.
T-Reqs는 MIT 라이선스로 라이선스가 부여되었습니다.