본문 바로가기
  • True knowledge exists in knowing that you know nothing. -Socrates-
web/웹 해킹 및 보안

WEB XSS || CSRF 문제를 만들자.

by intadd 2020. 9. 7.

안녕하세요.

 

오늘은 몇 주 전  몇 달 전에 어떤 집단의(비공개) 웹해킹 교육(비영리)에 활용하기 위해 만들었던 문제를 가져왔습니다. (허락 받음)

나이가 어리고 초심자 대상입니다. 

 

끄적끄적 

 

뭐 아무튼 컴퓨터를 처음 공부하는 친구도 있고, 웹해킹을 공부했던 친구들도 있습니다.

그래서, 난이도에 맞는 문제를 만드는게 가장 어려웠습니다.

 

온라인으로 약 2시간 설명 + 과제를 진행했습니다. 

 

뭘 가르칠려고 하냐 (니가..?)

웹해킹의 관심도(흥미)를 높이자. 

사실 국내 특성상 버그바운티를 제외한 서비스 중인 서버의 공격이 금지되어 있습니다.

그러므로 제가 하나 만들어 주기로 했습니다. (좋은 wargame 들도 많습니다.)

 

1. 공격 벡터를 스스로 찾을 수 있는가. (HTML 코드를 수정하거나 Proxy 툴을 이용) 

2. 공격 벡터를 활용해 실질적으로 Session을 탈취할 수 있는가? (XSS, CSRF )

 

아무래도 Client Side에서 발생하는 취약점이기 때문에,  웹 데이터 저장 및 출력  과정 중 "검증" 단계가 

서버 쪽에 있는지 단순 Client에 붙어 있는지를 좀 파악할 수 있으면 참 좋을것 같다..? 정도 입니다. 

 

그래서 뭘 준비 했냐

사실 XSS Session Hijacking에 대한 문제를 만들고 과제로 줄려고 했으나, 

생각해보니 대상자들이 서버가 없을 것 같았습니다.  없습니다.

그래서 XSS 혹은 CSRF 이용하여 Session hijacking 문제를 만들었습니다. 

(CSRF 를 통해 개인 서버가 없어도 풀이가 가능하도록, 혹은 개인 서버가 있으면 xss )

서버 없는 웹해커는 항상 고난해

풀이 대상자의 난이도를 고려하여 공격 벡터에 별도의 필터를 걸지 않았습니다.

<script> 태그와  html  javascript event 등을 자유롭게 사용할 수  있도록 했습니다.

다만, 3개의 데이터 입력 벡터 중 공격 벡터를 찾도록 유도했습니다.

 

환경 구성 및 구현 기능 

Server AWS ec2. ubuntu, apache2, django

domain : 개인 도메인

django 의 소스코드: github 에서 sample postboard 를 검색하고 Star 많은 거 그냥 가져와서 수정했습니다.

 

1. 로그인 & 회원 가입

2.  글쓰기 및 글 보기. 

3.  GET 파라미터 내용을 원하는 이메일로 발송하는 기능. 

 

이것만 봐도 대충 페이로드가 그려질 것으로 생각됩니다. 

2 번 기능에서 XSS or CSRF 벡터를 찾고, 

서버가 없을 경우 3번 기능을 사용하여 이메일로 Session을 넘깁니다. (CSRF)

 

구현 방법론  

로그인  & 회원 가입.

로그인
회원가입

django 에서 기본으로 지원하는 User model로 구현했습니다. (구현이라는 단어를 사용해도 되는가?)

 

https://docs.djangoproject.com/en/3.0/ref/contrib/auth/

 

 

공격 벡터 생성

제목, 본문, number 를 입력하는 기능을 추가합니다.  (WRITE)

모델은 github 에서 참고하여 만들었습니다. (copy)

내가 젛아하는 VIM. (필드를 잘 보시면 Price가 charField 입니다.)

위는 간단한 모델을 보여준 것이고, 

아래는 해당 모델에 데이터를 전달할 HTML 입니다. 

러시아어 ㅋㅋㅋㅋㅋ, 가져온겁니다 ㅎ,, 머쓱

해당 글을 작성하면 게시판 목록에서 아래와 같이 출력됩니다.  (main page)

POST Lists

해당 글을 확인해보면, 아래와 같이 잘 출력됩니다. 

특정 게시글 출력

 

이제, 취약점을 강제로 발생시켜야 합니다. Price 필드를 CharField로 만들었으니 해당 부분을 취약하게 만들 것 입니다. ( 출력 기능에서)

저는 장고를 사용 했기 때문에, 해당 데이터를 출력할 때 데이터를 렌더링하여 전달하도록  구현했습니다. 

 

요즘 대부분의 프레임 워크는  default로  데이터를 렌더링하게 되면, 자동으로 html encode 처리해줍니다.

 

예를 들어 글 제목과 본문에 <img src=@> 라는 html 코드를 기입해도, 렌더링 과정에서 html encode 되기 때문에 아래와 같이 html 코드로 인식되지 않습니다. (즉 태그가 동작하지 않는다.)

 

출력화면
&lt; 로 < 를 html encode 한 결과 값

 

그러므로 원하는 데이터를 출력할 때, 렌더링 과정에서 html encode 를 제외해주어야 합니다.

 

그러면 Django 프레임워크를 사용하는 서비스들은 XSS 와 CSRF 가 모두 불가능 한가?

어떻게 보면 맞고 어떻게 보면 틀린 것 같습니다. 

 

만약 해당 서비스가 데이터를 장고에서 제공하는 기본 렌더링을 통해 제공하면 문제가 없습니다. (취약점 발생하지 않음)

하지만 이러한 기능 구현이 아닌, 해당 데이터를 api 형식으로 데이터를 송수신 할 때에 발생할 수 있습니다.

 

예를들어 게시판 내용을 json 형태로 반환해주는 장고의 기능을 구현했다고 가정한다면,

장고는 데이터를 렌더링하는 것이 아니라 db에서 조회 한 데이터를 html encode 없이 그대로 return 해주고 ,

수신 받은 front (JS 예를 들어 AJAX )에서 별도 처리없이 데이터를 출력하면  XSS 나 html injection 이 가능합니다. 

 

즉, Back과 Front를 구분하였을 때 별도 처리가 없을 경우에 XSS나 CSRF가 발생할 수 있습니다. 

 

 

아무튼, 다시 본문으로 돌아와.

취약점을 강제로 만들어줘야합니다. 

취약점의 벡터는 number (price)로 했습니다. 

 

price 데이터 출력 부분에 safe 옵션 적용. 

price 에 데이이터를 출력해줄 때, |safe 옵션을 주면, html encode 처리를 하지 않습니다. 

이 기능은 html 데이터를 출력해주는데에 자주 사용합니다. 

https://docs.djangoproject.com/en/3.0/ref/templates/builtins/

그러므로 강제로 취약점을 만들어 주었습니다. 

 

취약점 테스트

number(출력 이름)에 데이터 Input type 은 number 입니다. 

정상적이라면, 숫자만 입력할 수 있습니다. 

 

input type "number"

 

Proxy 툴을 이용하여 중간에 데이터를 수정할 수 있지만, 사용자가 input type을 수정하여 숫자가 아닌 문자도 작성할 수 있습니다. 

 

개발자 도구 > input type 을 지워버림.

개발자 도구를 통해 해당 INPUT TAG의 속성을 지운 뒤,  number(price) input 란에 

값을 입력합니다. 

 

이후 작성한 글을 확인하면 아래와 같습니다. 

 

짠-

 

자, 이제 공격 벡터를 만들었습니다.

여기까지만 구현해도 공격자들은 XSS session hijacking 페이로드를 기입하면 됩니다. 

 

XSS POC 

해커 서버로 GET 파라미터를 이용하여 Session hijacking

 

문제는 서버가 없는 환경의 친구들입니다.

 

CSRF 공격 벡터도 하나 만들어줍니다.

GET 파라미터를 통해 원하는 메시지를 메일로 전송하는 기능을 하나 만들어 줍니다. 

 

import EmailMessage
GET 파라미터를 통해 이메일을 전송하는 간단한 로직.  술먹고 짰나 생각이 들었는데 생각해보니 술먹고 짠ㄱ ㅓ같기도,,

음 사실 EmailMessage 는 시간이 조금 걸립니다. 약 3초 정도, 

효율적이게 할려면 아마 비동기로 처리해줘야 하는데,, 뭐,, 

 

확인할 수 있도록 페이지도 하나 만듭니다.

Email 정상 작동 테스트.

Get 파라미터를 통해 전송할 데이터 (message), 전송할 이메일 (email) 데이터 전송. Send Status로 확인.
정상적으로 메일이 수신됨.

이렇게 하면, CSRF 벡터도 만들어 줬습니다. 

 

CSRF POC 

Write By Miminshin7.

이미지 태그를 생성하여 SRC에 공격 POC를 주입했습니다.

 

위와 같이 작성할 경우, 페이지 이동 없이 공격을 수행할 수 있습니다.   (img src에 공격 POC가 있을 경우  해당 POC로 HTTP Request 발생, --> 브라우저 형이 알아서 해줍니다. )

 

끝.

 

그럼 저는 이만.

댓글