정보보안 공부/웹

[웹] CRLF HTTP Splitting 공격 실습 (WebGoat v5.4)

pxatd 2021. 5. 26. 20:13
728x90


이 글의 계획을 바탕으로 진행한 실습입니다.
2021.04.15 - [정보보안 공부/웹, 네트워크, 보안, 해킹] - [웹] CRLF 취약점 (HTTP 응답 분할 공격)

[웹] CRLF 취약점 (HTTP 응답 분할 공격)

1. 사전조사 클라이언트와 서버 간의 HTTP request와 response Message를 살펴보면 헤더와 바디 사이 CRFL 공백이 존재하는 것을 볼 수 있다. 이 HTTP Response CRLF 공백에 악의적인 코드나 스크립트를 삽입하

cordingdiary.tistory.com


1. 서론

1.1 취약점 개요 (취약성)

CRLF - HTTP 응답 분할 공격(CWE-113)은 OWASP Top 10 2017에 선정되지는 않았지만, 응답에 줄 바꿈 문자 CR / LF가 포함되면 HTTP응답이 분리되는 경우를 응용한 공격이다. 줄 바꿈 문자를 삽입해 여러 개의 HTTP 응답을 만들어 냄으로써 캐시 서버(Cache Server)나 프록시 서버(Proxy Server)에 변조된 컨텐츠를 전송해 다른 사용자에게 영향을 준다.
- CR(Carriage Return: \r) : 커서의 위치를 현재 줄의 맨 처음으로 보내는 기능
- LF(Line Feed: \n) : 커서를 다음 줄로 옮기는 기능

CRLF를 이용하여 응답 패킷을 두 개 이상으로 분리하면서 원래의 HTTP Response와 별개로 새로운 HTTP Response를 만들어 조작할 수 있다는 점에서 취약성이 드러난다.

위 그림과 같이 user_id를 그대로 넘겨준 후 CRLF를 이용해 새로운 라인을 만들어 Header을 조작할 수 있다.
New Header 부분에 새로운 Header를 추가하게 된다면 HTTP Response에서는 헤더 조작이 된 Response가 오게 될 것이다.

1.2 진단개요

-스캔한 취약점 : CR/LF HTTP 응답 분할 공격 (HTTP Splitting)
-진단 수행 일정 : 2021.04.13 ~ 2021.05.26
-사용 환경 : OWASP WebGoat v5.4
: OWASP에서 배포한 WebGoat의 최신 버전인 v8.0.0에는 상대적으로 위험이 적은 CR/LF와 관련한 문제가 제외되었다. 따라서, 해당 실습을 진행하기 위해 따로 v5.4를 설치하여 실습환경을 구축하였다.

-사용 프로그램 : Burp Suite v.2021.5.1
: WebGoat와 연동하여 HTTP의 요청과 응답 패킷을 확인할 때 사용한다. HTTP의 응답 상태 코드 확인한다.
-취약점이 있다고 판단한 이유
: 웹 페이지에 URI로 인코딩 된 개행문자를 넣었을 때 그 값을 필터링 하지 않고 그대로 받아서 처리하였다.

2. 본론

2.1 실험 계획과 예상 결과

1.이 문제에 취약점이 존재하는지 파악하기 위해 우선 아무 내용의 문자를 입력하여 서버로 요청한다.
->CR/LF구문이 아닌 다른 내용을 입력했으므로, Response 패킷에서 줄 바꿈 현상이 나타나지 않을 것이다.

2. 간단한 CR/LF구문(en%0d%0a)을 입력하여 서버로 요청한다.
->Response 패킷에서 줄 바꿈 현상이 나타날 것이다. 즉, 서버 측에서 CR/LF문자열을 필터링하지 않는다는 것을 알 수 있다.

3. 문제에 맞는 Request 공격코드를 정하고, 인코딩 사이트를 통해 변환 시킨다.

4. 인코딩 시킨 값을 입력하고 서버에 Request 패킷을 보낸다.
->Response 패킷을 확인해보면, 응답 헤더가 2개 존재하는 것을 확인할 수 있을 것이다.

5. WebGoat에서 공격이 잘 실행된 것을 확인한다.

2.2 실험과정

1. HTTP 응답 분할 취약점 테스트를 위해 웹 서버 WebGoat v 5.4 실습환경을 사용한다.
주어진 문제는 HTTP Splitting 취약점을 이용하여 "200 OK" 라는 문자를 출력하는 것이다.

2. 우선, 이 문제에 취약점이 존재하는지 파악하기 위해 아무 내용의 문자를 입력하여 서버로 요청한다.

3. 입력한 값이 Language 파라미터로 들어간 것을 확인할 수 있다.
CR/LF구문이 아닌 다른 내용을 입력했으므로, Response 패킷에서 줄 바꿈 현상이 나타나지 않았다.

4. 이 공격의 핵심인 CR(%0d)/LF(%0a)는 URI 인코딩 된 문자로서, HTTP 패킷 내 포함될 경우 줄 바꿈이 가능하다.
Dos/Window 계열에서는 %0d%0a , Unix/Linux 계열에서는 %0a로 사용방법이 다르다.
본인의 실습환경은 Windows10 이므로 %0d%0a를 사용했다.
따라서, 간단한 CR/LF구문(en%0d%0a)을 입력하여 서버로 요청한다.

5. Request 패킷을 살펴보면 입력 값이 제대로 전달되었으며, Response 패킷에서는 줄 바꿈 현상이 나타났다.
즉, 서버 측에서 CR/LF문자열을 필터링하지 않는다는 것을 확인할 수 있다.

6. 공격 코드는 HTTP body부분에 포함되며, 서버로부터 응답 받을 페이지에 문자열 길이를 의미하는
Content-Length라는 속성을 0으로 바꾸고자 한다. 따라서 첫 번째 그림과 같이 작성할 수 있다.
Request 공격코드를 정했으면, 문제에 주어진 인코딩 사이트를 통해 변환한다.

7. 인코딩 한 값을 입력하고 BurpSuite를 통해 Request 패킷을 확인한다.

HTTP 응답 분할 공격 코드를 삽입하여 전송하면
서버 측에서 공격코드에 있는 파라미터를 그대로 받아서 처리한다.
그러므로, Response 패킷을 확인해보면 응답 헤더가 2개 존재하는 것을 확인할 수 있다.

8. WebGoat에서 HTTP Splitting 공격이 잘 실행된 것을 확인하면, 이 실습은 성공이다.

3. 결론

3.1 결과 분석

1. 줄 바꿈 코드(CR + LF)를 입력한 후 응답 패킷을 확인해보았을 때, 줄 바꿈 현상이 나타난 것으로 보아, 이 웹 서버는 CR/LF문자열을 필터링하지 않는다는 것을 확인할 수 있었다. 즉, CRLF-HTTP Splitting 취약점을 가지고 있다고 판단된다.

2. 문제가 요구하는 정답인 HTTP 프로토콜 상태 메세지 “200 OK”를 출력하기 위해 공격코드를 작성하고 인코딩한다. 그 값을 입력하여 서버에 요청한 후 응답 패킷을 확인해보면 원래의 값과 사용자가 입력한 값, 2개의 응답 헤더가 존재하는 것을 확인할 수 있었다.

3. 이 웹 서버는 외부에서 입력한 값의 CR LF 등의 줄 바꿈 코드를 제거하지 않은 채 HTTP 응답 헤더에 전달했기 때문에 이러한 취약점이 존재한다고 결론지을 수 있다. 따라서, 이러한 취약점은 개행 문자를 삭제하는 코드를 추가하면 안전하게 서버를 이용할 수 있다.

3.2 실습에서 개선할 점 & 취약점 대응 방안

실습에서 개선할 점
중간 과제로 제출했던 계획서에서는 직접 웹서버 (Microsoft-IIS/5.1)를 사용하여 게시판에 있는 글을
조회하는 모듈을 구현할 계획이었지만, 본인의 능력 부족에 따라 어쩔 수 없이 웹 서버가 미리 구축된
WebGoat를 실습에 사용하게 되었다. 따라서, CRLF에 취약한 웹서버를 수정하지 못 했고, 웹 보안 기법의
효과를 입증하지 못한 점이 아쉽다. 기회가 된다면, 직접 웹서버를 구축하여 다시 실습 해 보고 싶다.

CRLF 취약점 대응 방안
그럼에도, CRLF 취약점에 대응하기 위한 방안을 적어보자면, HTTP 응답 헤더에 입력되는 값에 대하여
CR(%0d) / LF(%0a) 를 제거하는 등 입력에 대한 유효성 검사를 실시함으로써 헤더가 두 개 이상 분리되는
것을 방지할 수 있다.

예) String test = test.replaceAll(“\r”,” “).replaceAll(“\n”,” “);


간단해 보이지만 1주일 반을 꼬박 밤을 새서 완성한 실습이다. 저번 글에서 계획했던 것 처럼 Microsoft-IIS로 서버를 구축하고자 했으나 능력부족으로 실패.. 그 후 html로 간단하게 웹 서버를 만들었지만, CRLF 공격이 들어가지 않아 실패
실패 실패...
결국 교수님께서 알려주신 WebGoat로 실습을 진행할 수 밖에 없었다. 게다가 CRLF는 OWSAP TOP10에도 들어가지 않아 최근 버전(8.0.0)에는 문제가 빠졌다고 한다. 구글링 해서 관련 문제가 있는 5.2버전으로 다운 그레이드시키고, 실습을 진행했는데 아무리 진행해도 Success 문구가 안나오길래 싹 다 밀고 5버전 중 가장 최신 버전 5.4버전으로 구축했더니 겨우 성공할 수 있었다.
실습 자체는 별로 오래걸리지 않았는데 앞에서 서버구축하려고 한 노력들이.. 시간을 많이 잡아먹었다. 게다가 원래 하려고 했던 실습을 진행하지 못했다는 것에 아쉬움이 크게 남았다.
그래도 긍정적으로 생각할 부분은, CRLF 실습을 진행하면서 기본지식이 뒷받침되어야 겠다고 생각해 웹 프로토콜의 기본 공부와 HTTP와 TCP/IP의 관계, HTTP Request Response 패킷 구조를 스스로 찾아보고 자세하게 공부할 수 있었다는 것이다.

21.06.09 추가
단순히 웹고트를 사용해서 실습을 진행했기에 당연히 높은점수를 기대하지 않고 있었는데 의외로 학과 내 2등을 하였다. 실험과정은 만점, 결과분석과 취약점분석에서 각 1점씩 감점된 58/60 점인데 후에 교수님께 어떤 부분에서 점수를 이렇게 주신건지 여쭤 볼 생각이다.

728x90