Oh! JUN
[WebGoat] Cross Site Request Forgeries - 3 본문
[WebGoat] Cross Site Request Forgeries - 3
Kwon Oh! JUN 2023. 12. 23. 17:141. 문제설명
CSRF 및 Content-Type
이전 섹션에서 우리는 Content-Type 에 의존하는 것이 CSRF에 대한 보호가 아니라는 것을 보았습니다. 이 섹션에서는 CSRF로부터 보호되지 않는 API에 대해 CSRF 공격을 수행할 수 있는 또 다른 방법을 살펴보겠습니다.
이 과제에서는 다음 JSON 메시지를 엔드포인트에 게시해야 합니다.
2. 문제풀이
name, email, subject, message에 dummy값 넣어서 burp로 요청을 캡쳐해서 살펴봤습니다.
Content-Type : application/Json로 되어있는걸로 봐서 Content-Type을 변경해서 CSRF공격을 수행하는것 같습니다.
Content-Type을 enctype="text/plain"로 변경해주고
JSON 형태의 데이터를 name='{"name":"asd","email":"asd@asd","subject":"service","message":"asd"}'
로 지정해주고 burp를 다시 잡아줬습니다.
Content-Type : text/plain는 정상적으로 변경되었는데 JSON 형태의 끝에 '='이 있는것을 확인할 수 있습니다.
그래서 이를 제거하기 위해서는 다음과 같은 방법을 사용해야합니다.
dummy 키를 만들고 키에 해당하는 value 값에 '='이 들어가도록 설정하였습니다.
다시 burp를 잡고 확인해보겠습니다.
정상적으로 JSON 형태의 데이터가 만들어진것과 응답값을 확인할 수 있습니다.
3. 코드분석
//CSRFFeedback.java
boolean correctCSRF = requestContainsWebGoatCookie(request.getCookies()) && request.getContentType().contains(MediaType.TEXT_PLAIN_VALUE);
correctCSRF &= hostOrRefererDifferentHost(request);
if (correctCSRF) {
String flag = UUID.randomUUID().toString();
userSessionData.setValue("csrf-feedback", flag);
return success(this).feedback("csrf-feedback-success").feedbackArgs(flag).build();
}
return failed(this).build();
requestContainsWebGoatCookie(request.getCookies())는 요청헤더에서
WebGoat 쿠기값이 포함되는지 확인합니다.
request.getContentType().contains(MediaType.TEXT_PLAIN_VALUE)는 요청헤더에서
Content-Type인 text/plain이 포함되어 있는지 확인합니다.
그리고 hostOrRefererDifferentHost 함수를 참고하는데 아래에서 설명하겠습니다.
//CSRFFeedback.java
private boolean hostOrRefererDifferentHost(HttpServletRequest request) {// 원래의 호스트인지 타호스트 인지 확인하는 함수
String referer = request.getHeader("Referer");
String host = request.getHeader("Host");
if (referer != null) {
return !referer.contains(host);// referer가 null이 아니면 referer에 host가 포함되어 있으면 return false 출력 (원래 호스트)
} else {
return true; //referer = null 이면 return true 출력 (타 호스트)
}
}
hostOrRefererDifferentHost 함수는 서버에 요청하는 호스트가 원래 호스트인지 타 호스트인지 확인하는 함수입니다.
//CSRFFeedback.java
boolean correctCSRF = requestContainsWebGoatCookie(request.getCookies()) && request.getContentType().contains(MediaType.TEXT_PLAIN_VALUE);
correctCSRF &= hostOrRefererDifferentHost(request);
if (correctCSRF) {
String flag = UUID.randomUUID().toString();
userSessionData.setValue("csrf-feedback", flag);
return success(this).feedback("csrf-feedback-success").feedbackArgs(flag).build();
}
return failed(this).build();
그래서 결과적으로 요청헤더에서 WebGoat 쿠기값과 Content-Type인 text/plain이 포함되면서 referer가 null이면 flag값이 랜덤으로 지정되면서 문제를 해결할 수 있습니다.
'웹 해킹 > Request Forgeries(CSRF)' 카테고리의 다른 글
[개인 공부] JSESSIONID와 CSRF 토큰 (0) | 2024.01.17 |
---|---|
[WebGoat] Cross Site Request Forgeries - 2 (0) | 2023.12.23 |
[WebGoat] Cross-Site Request Forgeries - 1 (0) | 2023.12.23 |