본문 바로가기
프로그램 (PHP,Python)

[Paros] 개발자가 알아야 할 웹 보안

by 날으는물고기 2009. 2. 27.

[Paros] 개발자가 알아야 할 웹 보안

SQL Injection, 파라미터 변조, 쿠키 변조, 세션 변조 공격 등으로부터 필자가 개발 중인 블로그 형태의 "바투"라는 웹 사이트가
얼마나 안전한지, 문제점은 무엇인지에 대해 알아보자.

 

1.    SQL Injection

 

SQL Injection 공격으로부터 사이트를 보호하기 위해서는 우선적으로 다음 3가지 과정을

지켜야 한다.

 

DB 최소권한으로 웹 사이트를 운영한다.

② 입력값 검증( ' " ) # || + > )을 통해 SQL Injection 공격을 대비한다.

③ 저장 프로시저(Stored Procedure)를 이용한다.

 

바투 웹 사이트에서 테스트 결과 SQL Injection에 대한 공격이 발생하지 않는다.

 

모든 데이터 처리를 저장 프로시저로 처리하기 때문에 ' or 1=1 등과 같은 공격이 프로시저에서 에러를 발생시키거나
varchar
타입이라 제대로 수행되지 않기 때문에 문제가 없는 것으로 여겨진다.

하지만 이러한 SQL 인젝션을 유발시키는 문자열( ' " ) # || + > )은 결국 DB통신을 하기 때문에 서버 사이드에서 막아
프로시저로 호출하지 않도록 처리해야 할 것이다.

 

2.    파라미터 변조

 

바투 웹 사이트에는 비동기 통신을 위해 ATLAS라는 AJAX 기반 서버 통신으로 데이터를 처리하고 있다.

ATLAS Client에서 Server로 데이터를 요청하기 때문에 요청 시점을 얼마든지 가로챌 수 있다.

바투 웹 사이트에서 사용하는 대부분의 ATLAS 통신은 파라미터 변조가 가능하다.

어떻게 파라미터 변조를 하는지 알아보자.

 

우선 파라미터 변조를 위한 웹 프록시 툴을 설치해야 한다.

설치와 관련된 정보는 웹 사이트에 검색하면 많이 나오니 생략하도록 하겠다.

Paros 설치 및 매뉴얼 링크

http://tt.co.kr/~antihong/documents/paros_proxy.pdf

 

아래 [그림 1]과 같이 인터넷 옵션-연결-LAN설정-프록시서버 영역에 localhost(127.0.0.1) 8080포트로 설정을 하고
Paros
툴을 실행시키면 모든 웹 요청이 Paros Proxy Tool을 거쳐서 웹 사이트로 요청을 보내게 되고 서버에서 받은 응답 또한

Paros
를 거쳐서 Client로 내려받게 된다
.


[그림 1] 웹 프록시 Paros의 작동 원리

 

이제 파라미터 변조를 위한 모든 준비를 마쳤으니 테스트를 시작해 보자.

 

2.1.                   댓글 삭제

 

바투 웹 사이트의 개인 락커룸 영역에서 다른 사용자가 작성한 댓글을 삭제해 볼 것이다.

웹에서 댓글 삭제시 보여지는 영역은 아래 [그림 2]와 같다.

 

[그림 2] 개인 락커룸 댓글 삭제시 UI

 

[그림 2]에서 확인 버튼을 누른 후 Paros 툴을 살펴보자.

 

[그림 3] 댓글 삭제시 Request 정보

 

[그림 3]을 보면 댓글 삭제시 Paros 툴의 아래 history 영역에

http://www.batoo.com/AjaxService.asmx/OnDeleteComment HTTP/1.1

와 같은 내용이 있다.(파란색 선택화면)

이 영역을 클릭하게 되면 [그림 3]의 윗부분 Request 요청 정보와 가운데 영역의 파라미터 정보가 노출된다.

삭제하려고 한 정보는 297번 댓글 임을 알 수 있다.

Paros Tools 메뉴에 Menual Request Editor를 클릭하면 [그림 3]의 가운데 팝업이 나타나게 되는데 팝업의 위쪽 영역에
Request
요청 정보를 복사하여 붙여넣고 아래 파라미터 정보에 297대신 다른 사용자가 남긴 댓글 번호 290번을 입력한 후
아래 Send 버튼을 눌러 보자.

 

그럼 [그림 4]와 같이 응답 정보를 확인 할 수 있다.

 

[그림 4] 댓글 삭제시 Response 정보

 

[그림 4]를 보게 되면 Main 화면은 [그림 3]에 대한 응답 정보를 보여준다.

297번 댓글에 대한 삭제가 SUCCESS했다는 의미를 나타낸다.

[그림 4]의 팝업 창은 [그림 3]의 팝업 창에 대한 응답 정보를 보여준다.

다른 사용자가 작성한 290번 댓글에 대한 삭제가 성공했음을 알 수 있다.

 

댓글 번호로만 파라미터로 전달하는 것은 개발 관점에서 문제가 있다고 봐야 할 것이다.

위 테스트와 같이 웹 서비스 통신 시 무작위로 댓글 번호를 입력하여 변조가 가능하기 때문이다.

 

2.2.                   포스트 삭제

 

그럼 사용자 번호와 포스트 번호를 파라미터로 넘겨 통신하는 포스트 삭제 에 대한 테스트도 진행해 보자.

 

웹에서 포스트 삭제시 보여지는 영역은 아래 [그림 2]와 같다.

 

[그림 5] 개인 락커룸 포스트 삭제시 UI

 

삭제 버튼에 마우스 오버를 하면 왼쪽 아래 상태바에 포스트번호(‘232’), 회원번호(‘8’)가 나타난다.

[그림 5]에서 확인 버튼을 누른 후 Paros 툴을 살펴보자.

 

[그림 6] 포스트 삭제시 Request 정보

 

[그림 6]을 보면 포스트 삭제시 Paros 툴의 아래 history 영역에

http://www.batoo.com/AjaxService.asmx/DeletePost HTTP/1.1

와 같은 내용이 있다.(파란색 선택화면)

이 영역을 클릭하게 되면 [그림 6]의 윗부분 Request 요청 정보와 가운데 영역의 파라미터 정보가 노출된다.

삭제할 포스트 번호는 232이고 회원번호는 8임을 알 수 있다.

Menual Request Editor를 실행하여 팝업의 위쪽 영역에 Request요청 정보를 복사하여 붙여넣고 아래 파라미터 정보에
포스트번호를 233, 회원번호를 임의의 번호 85로 입력한 후 아래 Send 버튼을 눌러 보자.

 

그럼 [그림 7]와 같이 응답 정보를 확인 할 수 있다.

 

[그림 7] 포스트 삭제시 Response 정보

 

[그림 7]을 보게 되면 Main 화면은 [그림 6]에 대한 응답 정보를 보여준다.

웹에서 정상적으로 요청한 정보이므로 포스트를 삭제하였습니다.’ 라는 성공적인 메시지를 받는다.

[그림 7]의 팝업 창은 [그림 6]의 팝업 창에 대한 응답 정보를 보여준다.

다른 사용자가 작성한 233번 포스트와 회원번호 85번에 대한 삭제가 실패했음을 알 수 있다.

이는 저장 프로시저에서 포스트 번호와 회원 번호가 일치하는 로직이 들어 있기 때문에 실패한 것이다.

 

하지만 불법 사용자가 포스트 번호와 회원 번호 모두를 알게 된다면 포스트 삭제가 성공할 것이다.

그리고 DB통신을 수행하기 때문에 DOS(Deny Of Service)로 공격을 하게 될 경우 DB서버의 부하가 불가피 해진다.

 

2.3.                  해결 방안

 

처리방법 1

웹 메소드에서 현재 세션인증 값(Context.User.Identity.Name)을 얻어서 DB통신시 댓글번호와 유저번호를 파라미터로 넘겨
일치 여부를 확인한다.

이 방식은 웹 서비스를 호출하는 웹 페이지들을 수정하지 않아도 되므로 수정작업을 쉽게 할 수 있다.
하지만 파라미터 변조로 들어온 요청값들은 DB통신을 하게 되는 문제점이 있다.

 

[WebMethod]

public string OnDeleteComment(string commentGuid)

{

             string msg = string.Empty;

             string memberGuid = Context.User.Identity.Name;

             PostManager manager = new PostManager();

             if (manager.DeleteComment(commentGuid, memberGuid) == 0)

             {

                           msg = "SUCCESS";

             }

             else

             {

                           msg = "FAIL";

             }

             return msg;

}

 

처리방법 2

회원번호를 파라미터로 받아 회원 번호 값과 세션인증 값을 비교하여 일치하면 DB통신을 수행하고
일치하지 않으면 에러 메시지를 리턴해 준다.

파라미터 변조로 들어온 요청 값들은 결국 세션인증 값과 다르기 때문에 DB통신을 수행하지 않아도 된다.

 

[WebMethod]

public string OnDeleteComment(string memberGuid, string commentGuid)

{

             string msg = string.Empty;

             if(memberGuid == Context.User.Identity.Name)

             {

                           PostManager manager = new PostManager();

                           if (manager.DeleteCommentReply(commentReplyGuid, memberGuid) == 0)

                           {

                                        msg = "SUCCESS";

                           }

                           else

                           {

                                        msg = "DBERROR";

                           }

             }

             Else

             {

                           msg = "FAIL";

             }

             return msg;

}

 

이 방법 외에도 개발 방법이 복잡해지는 단점이 있지만 파라미터 정보들을 암호화하는 방법을 사용할 수도 있을 것이다.

 

3.    쿠키 변조

 

Paros 툴을 이용하여 쿠키 값을 수정하거나 삭제하여 악의적인 공격을 할 수 있다.

 

3.1.                  방문자 수 변경

 

개인 락커룸의 방문 수 쿠키를 삭제하여 개인 락커룸 조회 수를 증가시키는 테스트를 해보자.

락커룸 메인 페이지의 UI는 아래 [그림 8]과 같다.

 

[그림 8] 개인 락커룸 메인 페이지

 

[그림 8]에서 오늘 방문수는 4이고 총 방문수는 723임을 알 수 있다.

아래 [그림 9] Paros 툴에서 [그림 8] 페이지에 접속했을 때 요청 정보이다.

 

[그림 9] 개인 락커룸 메인 페이지 Request 정보

 

빨간 색으로 체크된 부분에 대한 설명은 다음과 같다.

 

(1)   방문 정보 쿠키 v_lockerroomlist=51|55| 51번 락커룸과 55번 락커룸에 방문했다는 정보를 나타낸다.

(2)   Manual Request Editor에서 Request 탭에 (1)의 쿠키정보를 복사하여 v_lockerroomlist 값에 51을 삭제한다.(v_lockerroomlist=55|)

(3)   현재 요청 페이지의 주소를 나타낸다.

 

Manual Request Editor에서 Send로 정보를 송신하면 아래 [그림 10]처럼 응답을 받는다.

 

[그림 10] 개인 락커룸 메인 페이지 Response 정보

 

[그림 10]을 보면 응답이 성공했음을 알 수 있다.

[그림 10]Request 탭에 Send 버튼을 한번 더 눌러 조회수의 변화를 살펴보자.

 

[그림 11] 개인 락커룸 메인 페이지

 

[그림 11]을 보면 오늘 방문자 수가 6이고 총 725이다.

이렇게 쿠키를 변조 함으로서 시스템에 악의적인 공격을 할 수 있게 된다.

 

3.2.                  해결 방안

 

쿠키변조와 같은 공격은 Client에서 Server로 요청 직전에 변조하여 통신하기 때문에 서버에서 모든 Client의 쿠키에 대한 정보를
가져서 변조 여부를 체크한다면 시스템에 많은 부하가 걸릴 것이다.

결국 많이 알려진 방법이지만 가장 확실한 방법이 쿠키 정보를 암호화하여 서버에서 복호화 하여 처리하는 방법일 것이다.

 

4.    Session 변조

 

4.1.                   ASP.NET에서의 세션

 

바투 웹 사이트에서 세션 변조로 공격하기 위해서는 먼저 ASP.NET에서의 세션에 대한 매커니즘을 이해해야 한다.

유저가 ASP.NET으로 구축된 웹 페이지에 최초 접근 시 쿠키 값을 보면 ASP.NET_SessionId 이라는 암호화된 값이 있음을 알 수 있다.

웹 서버는 다수의 웹 페이지 요청자를 구별하기 위하여 각각의 사용자의 세션에 대해서 임의의 긴 문자열 값인 Session ID를 부여한다.

 

Ex) ASP.NET_SessionId=p0rbg2nhepm0ejzvyzmnfd45;

 

유저가 최초로 웹 사이트에 접근 시 서버에서 유저의 정보를 받아 Session ID값을 발급하여 서버에 저장하고
클라이언트에 쿠키로 저장하는 과정이다.

추후에 재 요청시에는 이 ASP.NET_SessionId 값을 비교하여 요청을 수행하게 되는 것이다.

 

ASP.NET에서 구동된 사이트에 로그인을 하게 되면 .ASPXAUTH 쿠키가 생성된 것을 볼 수 있다.
이것 역시 세션이며 인증세션을 암호화한 값을 나타낸다.

 

Ex).ASPXAUTH=DC3748B2F50FD47FA0FE54A84CD08FA26B67074134BE18A7CF878C4E55F9E6697460A17E06C7F454
B34E9039BEC72F12A4FC5AEA26A63F627F296099542CA821;

 

4.2.                  세션 공격

 

암호화된 세션 정보들은 현재까지 복호화가 불가능한 것으로 알려지고 있다.

그렇다면 어떻게 세션 변조가 가능한 것인지 알아보도록 하자.

 

세션공격 유형은 2가지로 분류할 수 있다.

 

(1)   Cookie Sniffing 을 통한 Session ID 도용

(2)   XSS 공격으로 Session ID 취득하여 공격

 

위 공격 유형에 대한 공격을 2단계로 분류할 수 있다.

먼저 1단계는 Session ID를 취득하는 단계이고,

2단계는 취득한 Session ID를 공략하는 단계가 필요하다.

이 세션 공격 2단계에 대한 공격 흐름도는 아래 [그림 12]로 표현할 수 있다.

[그림12] HTTP Session 변조 공격 흐름도

 

공격자는 Session ID를 취득하기 위하여 웹 서버와 웹 클라이언트의 트래픽을 직접적으로 스니핑하거나(1),
웹 서버 상에 공격 코드를 삽입하여 두고 사용자가 클릭할 때 Cookie, Session ID 값을 전송 받을 수 있도록 한다(2).

ASP.NEThidden필드로는 세션 값을 저장하지 않기 때문에 [그림 12](3)은 무시하고 넘어가도록 한다.

웹 서버와 웹 클라이언트 사이의 트래픽을 직접적으로 스니핑하는 방법은 일반적인 네트워크 트래픽 스니핑 기법을 통해 가능하다.

[그림 12](4)를 통해 공격자는 취득한 타인의 Session ID 값을 웹 서버에 요청함으로써 HTTP Session 변조 공격을 시도할 수 있다.

 

4.3.                  대응방안

 

바투 웹 사이트는 HTML코드를 포함한 스크립트와 파일업로드를 제공하는 페이지가 존재하지만,
악의적인 스크립트의 공격을 필터링하고, 업로드의 경우 서버에서 처리할 수 있는 확장자를 가진 파일들의 업로드를 막고 있다
.
또한 업로드한 파일들은 이미지 서버에 업로드되므로 XSS공격을 통해 세션 변조가 될 소지는 적어 보인다
.

하지만 좀 더 사용자의 입력 값의 유효성 체크와 HEX값에 대한 필터링 등 구체적인 테스트를 통해 세션 공격에 대응해야 할 것이다.

 

직접적인 웹 서버와 웹 클라이언트 트래픽을 sniffing하는 방법은 Cookie가 전달되는 방식을 SSL로 구현함으로써
sniffing 공격에 대응할 수도 있다.

그러나 직접적인 sniffing공격을 위한 조건으로는 바투 웹이 아닌 메신저로 바이러스에 감염되거나 유저 PC의 보안에 위험성이
있는 사용자에 한해 공격이 이루어지기 때문에 이러한 공격의 대응을 개발자가 직접 해줘야 하는지 고민해야 할 부분이다.



출처 : http://securecode.tistory.com/

728x90

댓글