안녕하세요.
해킹과 방어 시리즈를 연재하고 있는 Ziqon입니다.
이번엔 그 세번째 공격과 방어를 해보겠습니다.
CRLF는 Carriage Return (ASCII 13, \r) Line Feed (ASCII 10, \n)의 줄임말로 HTTP응답분할이라고도 합니다.
HTTP Request에 있는 파라미터가 HTTP Response의 응답헤더로 다시 전달되는 경우 파라미터 내 개행문자 ㅊCR, LF 가 존재하면 HTTP 응답이 분리될 수 있습니다. 이러한 취약점을 통해 응답 메시지에 악성 코드를 주입함으로써 XSS 및 캐시를 훼손합니다.
유형은 4가지 정도 사례가 있습니다.
쿠키값(cookieSink)을 응답헤더에 추가하는 경우
response.addCookie(cookieSink);헤더값에 외부 입력값(data 변수)을 추가하는 경우
response.addHeader("Location", "/author.jsp?lang="+data);헤더값에 외부 입력값(data)을 덮어쓰는 경우
response.setHeader("Location", "/author.jsp?lang="+data);로그에 외부 변수 정보를 삽입하는 경우
logger.info("Previous page from request was: " + previousPage)
그럼 공격을 먼저 해보겠습니다.
HTTP Splitting 메뉴를 선택합니다.
HTTP 200 OK를 강제로 보내고 개행문자로 split할 수 있도록 먼저 string 문자를 웹서버가 이해할 수 있는 아스키코드로 인코딩합니다. 인코딩 사이트인 http://yehg.net/encoding/ 로 들어가 아래 문자를 인코딩 시켜 보겠습니다.
HTTP/1.1 200 OK
If-Modified-Since : Fri, 30 Dec 2099 18:40:22 GMT
Last-Modified: Fri, 30 Dec 2099 18:40:22 GMT
인코딩된 값으로 아래 값이 도출됩니다
HTTP%2F1.1%20200%20OK%0D%0AIf-Modified-Since%20%3A%20Fri%2C%2030%20Dec%202099%2018%3A40%3A22%20GMT%0D%0ALast-Modified%3A%20Fri%2C%2030%20Dec%202099%2018%3A40%3A22%20GMT다시 webgoat로 가서 인코딩된 값을 입력합니다.
search버튼을 누르면!!!
성공했습니다! 자 이번엔 이 공격을 방어할 수 있는 코드을 짜보겠습니다. 이클립스로 들어가 BugExplorer창에 관련 취약점이 2개가 탐지되었습니다.
해당 소스에 들어가보면 아래와 같이 if ~ else ~ 문에 각기 사이좋게 모여있음을 확인할 수 있습니다.
여기서 실제 수정해야 할 취약점 원인이 되는 코드는 String cookie = s.getCookie(UNIQUE2U); 에서 쿠키값을 읽어 바로 response.setHeader메소드의 변수값으로 넣어버리는 부분입니다.
자 이제 필터를 하나 만들어서 CR, LF가 들어올 경우 치환을 해볼까요? 역시나 SecurityFilter.java에 메소드를 추가해 봅니다. CRLFFilter를 아래와 같이 개행문자를 ""로 변환하는 메소드로 작성합니다.
이제 다시 문제가 되는 코드로 돌아가서 아래와 같이 cookie변수를 필터링합니다.
- findbugs를 다시 한번 돌려보면 해당 취약점이 여전히 남아 있게 된다. findbugs가 CRLF Filter 툴을 분석하지 못했기 때문이면 이러한 경우 취약점이 제거되었다라고 예외처리하면 된다.
예외처리 방법은 아래와 같이 처리한다.
이상 CRLF Injection 공격과 방어를 살펴보았습니다.
다같이 힘을 내어 열공!열공!
잘 읽었습니다. 유익한 정보를 이제야 봤네요.
kr-dev
태그도 등록하면 좋겠어요~😊아 그런 태그도 있었군용 +o+