본문 바로가기
웹 모의해킹/웹 취약점 진단 실습

웹 취약점 진단 - 인증처리미흡

by Nighthom 2023. 1. 16.

목차

    1. 인증처리미흡 개요

    그림 1 OWASP Top 10

    인증처리미흡(Broken Authentication)2017OWASP Top 10에서는 A02에 해당하고, 2021OWASP Top 10에서는 A08로 내려갔지만 여전히 10위권 내에 들어가는 빈도수가 상당히 높은 취약점이다.

     

    인증처리미흡은 인증이 필요한 페이지 및 관리자 페이지 등의 페이지에 인증처리 소스코드 로직의 결함으로 인해 공격자가 적절한 인증처리를 수행하지 않고 접근할 수 있게 되는 취약점이다. 해당 취약점이 발생하는 구간은 여러 곳이 있을 수 있는데, 일반적으로 서버로 전달되는 인증 데이터를 적절히 검증하지 않음으로써 발생한다.

     

    해당 취약점은 따로 악의적인 패킷을 전송하는 것이 아니라 인증처리 로직의 결함을 이용하는 취약점이기 때문에, 정상적인 패킷을 전송한다. 따라서 인증처리미흡은 어떠한 보안관제 솔루션으로 잡아내기 힘든 취약점에 해당한다. 

    2. 인증처리미흡 실습 진행

    2-1. 1:1 문의게시판에서 타인의 1:1 문의글 조회/수정/삭제

    1:1 문의게시판(ask_view.php)에서는 data 파라미터의 idx값을 통해서 게시물에 접근한다. 해당 페이지의 idx값에 자신의 게시물의 idx값이 아닌 다른 idx값을 입력해도 게시물에 접근 가능한지 점검한다. 이후 접근한 게시물에서 문의글을 수정 및 삭제가 가능한지 점검한다.

    그림 1 공격자가 작성한 임의의 게시물

    공격자는 본인이 작성한 임의의 게시글에 접근한 뒤 URL에 포함된 idx를 확인한다.

    그림 2 URL  내부  idx

    이후 URLidx값을 144로 수정한 뒤, 엔터를 눌러 해당 URL로 접근을 시도한다.

     

    그림 3 공격자가  victim 의 게시물에 접근 성공

    공격자가 victim1:1 문의글에 접근하는데 성공했다. 이후 공격자는 접근한 게시물 수정을 시도한다.

    그림 4 공격자가 victim의 게시물 수정 성공

    공격자가 victim의 게시물을 수정하는데 성공했다. 이후 게시물 삭제가 되는지 확인해 볼 것이다.

    그림 5 1대1 문의게시판 글 삭제 성공

    성공적으로 victim의 게시물을 삭제했다.

    2-2. 1:1 문의게시판을 이용해 자유게시판의 비밀글 조회

    자유게시판(board_view.php)1:1문의게시판이랑 똑같이 idx값을 이용해서 게시물에 접근한다. idx값이 1:1문의게시판 idx값과 연속되는 값이기 때문에 1:1 문의게시판과 자유게시판의 idx값이 서로 공유된다고 추측된다. 해당 추측을 기반으로 1:1 문의게시판에서 idx값을 조작해 자유게시판 비밀글에 접근한다.

    그림 6 victim의 비밀글

    공격자는 victim의 비밀글을 확인한 뒤, 해당 게시물에 접근하고자 한다. 해당 게시물을 클릭한다.

    그림 7 victim 의 비밀글 url 내 파라미터  idx  확인

    그림 7에서 victim의 비밀글 idx값이 146임을 확인했다. 해당 idx값을 기반으로 1:1 문의게시판에서 접근을 시도한다.

    그림 8 공격자의 1:1 게시물

    해당 게시물의 URL에서 idx파라미터의 값을 146으로 수정한 뒤 엔터를 눌러 접속을 시도한다.

     

    그림 9 victim 의 게시물 접근 성공

    1:1 문의게시판에서 일반게시판에 있는 victim의 비밀글에 접근하는데 성공했다. 본래 일반게시판의 게시물은 수정 및 삭제를 하는데 작성자가 작성한 비밀번호를 요구하지만, 해당 방식으로 조회한 게시물은 1:1 문의게시판의 게시물처럼 비밀번호 없이 수정 및 삭제가 가능하다.

    2-3. 게시물 수정 시 타인의 비밀글에 접근

    그림 10 공격자의 자유게시판 게시물 수정 페이지

    그림 10은 공격자의 자유게시판 게시물 수정 페이지로, 해당 부분에 접근할 때 이용되는 파라미터 정보를 얻기 위해 Burpsuite로 해당 페이지의 정보를 Intercept한다.

    그림 11 공격자의 게시물 수정 페이지  Request

    그림 11의 Request를 확인한 결과, Request Body값에 idx 파라미터의 존재를 확인할 수 있다. 해당 파라미터의 값을 146으로 조작해서 victim의 비밀글에 접근을 시도한다.

     

    그림 12 victim의 비밀글 수정 페이지 접근 성공

    victim의 비밀글 수정 페이지에 접근했으면 해당 페이지에서 글 수정이 가능한지 점검한다.

    그림 13 victim의 글 수정 성공

    victim의 게시물 수정에 성공했다.

     

    2-4. 타인의 주문내역 조회

    그림 14 주문내역조회 위치

    우선 공격자의 ID로 로그인한 뒤, 주문조회를 클릭한다.

    그림 15 상세 주문내역 진입

    주문조회를 클릭해 주문내역조회로 들어간 뒤, 주문코드를 클릭한다.

    그림 16 공격자의 주문내역 확인

    공격자의 상세 주문내역 페이지로 들어온 뒤, 해당 주문내역의 URL을 확인한다.

    그림 17 공격자 주문내역  URL

    공격자의 주문내역 페이지의 URL 확인 결과, 해당 페이지는 idx 기반으로 접근을 하는 것을 알 수 있다. 해당 페이지에서 idx값을 조작하여 다른 주문내역을 조회할 수 있는지 확인한다. 해당 idx값을 2로 조작한 뒤 접근을 시도해본다.

    그림 18 공격자 계정으로 희생자의 주문내역 접근 성공

    공격자의 계정으로 희생자의 주문내역에 접근하는데 성공했다.

     

    2-5. 회원가입 필수입력항목 인증 우회

    회원가입 페이지의 필수 입력 항목에 관한 인증을 클라이언트에서 처리하면 발생할 수 있는 취약점이다. 해당 취약점을 통해서 공격자는 기존 사용자와 중복되는 아이디를 생성해 기존 사용자의 계정을 탈취하는 시도를 하거나, 존재하지 않는 신상 정보를 회원 가입 페이지에 기입할 가능성도 있다.

     

    그림 19 회원가입 페이지  Response

    그림 19는 회를 시도할 회원가입 페이지의 Response, 해당 Response에 회원가입 필수항목 인증 코드가 있다면 해당 코드를 지우고 회원가입 필수항목 인증을 우회할 수 있다.

    그림 20 회원가입 페이지 인증 코드 (joinSendit 메서드)

    그림 20은 회원가입 페이지의 인증처리 코드 joinSendit() 함수이다. 해당 부분에 있는 인증처리 코드를 전부 삭제한다.

    그림 21 수정한  joinSendit 메서드

    그림 21처럼 joinSendit() 함수를 수정한 뒤, 해당 Response를 보내준다.

     

    그림 22 회원가입 필수항목 인증처리 우회성공

    그림 22처럼 필수입력 항목을 공란으로 한 뒤, 회원가입을 누르면 회원가입에 성공하는 것을 볼 수 있다.

    2-6. 투표 인증 우회

    본 사이트의 메인 페이지(index.php)에서 투표 기능에 바로 접근할 수 있다. 해당 투표에는 유효기간/투표 가능 횟수가 지정되어 있는데, 해당 부분의 소스 코드가 클라이언트 사이드에 구현되어 있다면 공격자는 간단하게 해당 부분을 우회할 수 있다. 해당 취약점이 존재한다면 공격자는 유효기간이 끝난 투표를 시도하거나, 투표를 제한횟수 이상 할 수 있다.

    그림 23 메인페이지 (index.php) response

    그림 23은 index.phpresponse, 해당 페이지에 투표 관련 기능이 존재한다. 해당 페이지에서 투표 관련 인증처리 코드(투표 기간 인증처리, 중복투표 관련 인증처리)가 존재하는지 확인한다.

    그림 24 투표 관련 메서드  pollWrite

    pollWrite() 함수의 인증처리 소스코드가 노출되어 있음을 알 수 있고, 해당 함수의 인증처리를 우회하면 투표기간을 무시하고 투표를 수행하거나, 비회원임에도 회원제 투표를 하거나, 중복 투표를 할 수 있는 등 여러 취약점이 발생할 수 있다.

     

    1번 주석에 해당하는 부분은 메서드 인자들의 의미를, 2번 주석에 해당하는 부분은 인증처리를 하는 코드다. 본 점검에서는 인증처리를 하는 코드를 모두 삭제할 것이다.

    그림 25 인증처리코드 삭제

    이후 Response를 보낸 뒤 투표가 가능한지 점검한다.

    그림 26 투표 성공

    기간이 만료된 투표였음에도 불구하고 성공적으로 투표를 했음을 알 수 있다. 투표 이후, 중복 투표가 가능한지 여부도 살펴보도록 한다.

     

    그림 27 투표하기 버튼 메서드 확인

    이미 한번 투표를 수행한 뒤 다시 한번 투표하기 버튼에 커서를 올릴 경우, pollWrite() 함수가 아닌 pollErr()함수를 호출하는 것을 알 수 있다. 해당 함수에서 pollWrite() 함수를 호출하면 중복투표를 수행할 수 있을 것으로 보인다.

    원본
    수정본

     

    수정된 pollErr() 함수는 pollWrite() 함수의 Statusnow, bPlu10, reCan1로 각각 지정한 뒤, pollWrite()를 호출한다.

    그림 28 중복투표 성공

    이후 투표를 진행하면 다시 한번 투표가 가능함을 알 수 있다.

    2-7. 필드 값 조작에 따른 검증 여부 (가격조작 포함)

    해당 취약점은 RequestBody에 들어가는 파라미터를 조작함으로써 공격자가 수정이 허용되지 않은 특정한 값을 조작할 수 있는 취약점이다. 해당 취약점이 상품값 전달하는 부분에 발생한다면, 공격자는 상품값을 조작하여 0원으로 수정해서 무료로 물품을 주문할 가능성이 존재한다.

    그림 29 구입할 상품

    상품 구입을 위해서 주문하기 버튼을 누른다.

    그림 30 주문하기 누르고 주문자정보를 채운 모습

    주문하기 버튼을 누른 뒤 주문자 정보를 적당한 값으로 채운다. 이후 확인 버튼을 눌러 주문한다.

    그림 31 결제 창

    결제 창을 확인했다면, 여기서 최종적으로 결제금액 조작을 수행할 것이다. 해당 페이지에서 소스 코드를 확인하려고 View Page Source를 누르려고 했으나, 비활성화되어 있다. Burp Suite로 직접 Response를 인터셉트해서 확인한다.

     

    인터셉트한 Response에서 최종 결제금액 5000을 검색한다.

    그림 32 결제금액 값

    실제 결제금액 폼에 입력되어 있는 5000이라는 값을 확인할 수 있다. 해당 부분을 수정해서 상품의 가격을 0원으로 조작하고, 실제 주문이 되는지 확인한다.

    그림 33 상품 가격 조작 성공

    이후 무통장입금으로 결제를 진행하면 실제 0원으로 상품을 주문하는데 성공하게 된다.

    그림 34 조작된 가격으로 주문 성공

    3. 대응 방안

    3-1. 1:1 문의 게시판(ask_view.php)

    1:1 문의게시판은 기본적으로 본인과 관리자 이외에는 접근할 수 없도록 인증 코드를 추가해야 한다. 관리자는 관리자 페이지를 통해서 따로 접근이 가능하므로, 본 대응에서는 글을 작성한 사용자만 접근 가능하도록 인증처리를 한다. 실제 소스 코드인 board_view.php의 앞 부분에 본인이 아닌 사용자는 접근이 불가능하도록 ID를 검증하는 코드를 추가했다.

    그림 35 1:1 문의게시판 인증 처리 추가 코드

    우선 db에서 idx에 해당하는 게시물의 컬럼을 view_row에 가져온다. 그 다음 세션의 GOOD_SHOP_USERIDview_rowuser_id를 비교해서 서로 다르다면 접근을 차단한다.

    3-2. 자유게시판 수정 페이지(board_edit.php)

    해당 페이지의 취약점은 board_pwd_chek.php에서는 인증처리를 수행하지만 board_edit.php에서는 인증처리를 진행하지 않기 때문에 생긴 취약점이다. 해당 취약점을 수정하려면 board_pwd_chek.php에서 진행한 인증처리가 실제 진행된 인증처리인지 board_edit.php에서 확인해야 한다.

     

    시큐어코딩 적용한 코드
    board_pwd_chek.php37~48번 라인

    board_edit.php1~12번 라인

     

    우선 board_pwd_chek.php에 비밀번호가 적절히 검증되었음을 확인하는 값을 세션의 IS_VALID_PWD에 저장한다. 그리고 board_edit.php에서 세션에 IS_VALID_PWD가 존재하면 세션에 IS_VALID_PWD를 삭제한 뒤 정상적으로 게시물 수정 페이지로 접근하고, 존재하지 않는다면 비밀번호가 잘못되었다는 메시지와 함께 이전 페이지로 이동한다.

    3-3. 상세 주문내역(mypage_order_detail.php)

    1:1 문의게시판 ID 검증 대응과 똑같이, 현재 세션의 ID와 주문정보 상의 ID를 비교해서 서로 다르다면 접근을 차단하는 방식으로 처리하면 간단하게 대응할 수 있다.

    3-4. 회원가입 페이지(member_join_ok.php)

    회원가입 페이지의 인증 처리는 Javascript에서 처리되고 있다. 회원가입을 처리하는 서버사이드 스크립트인 member_join_ok.php에도 관련 인증 처리를 추가하면 간단하게 해당 페이지의 인증 우회를 막을 수 있다.

     

    아래 그림 36은 member_join_ok.php에 추가한 소스 코드로, member_join.php Javascript에서 수행하는 인증 처리와 똑같은 코드를 PHP의 문법에 맞게 수정해서 추가했다.

    그림 36 회원가입 페이지 인증처리 추가 코드

    3-5. 투표 인증

    투표 기능을 수행하는 코드는 poll_ok.php에 존재하고, 투표 기능을 웹 페이지에 보여주는 부분은 left_menu.php에 존재한다. 현재 소스 코드에서는 left_menu.php에서 인증을 진행하고 있다. 하지만, poll_ok.php에서는 인증을 진행하지 않고 left_menu.php에서 유효기간 만료 여부, 중복 투표 가능 여부, 회원 투표 및 비회원 투표 여부를 클라이언트로 전달한 다음 클라이언트 스크립트(Javascript)에서 검증 로직이 작동하고 있어 공격자는 간단하게 해당 스크립트를 우회할 수 있다. 본 대응에서는 세션을 이용해서 인증에 사용한 값을 전달하고, 실제 투표가 수행되는 페이지에서 세션을 통해 값을 전달받아 인증처리를 수행하도록 코드를 수정하였다.

     

    left_menu.php 580~599번 라인
    poll_ok.php 5~17번 라인

     

    우선 left_menu.php에서 세션을 통해 poll_status, poll_bPlu, poll_reCan을 전달한다. 이후 poll_ok.php에서 statuslast인지 검증하여 만료된 설문조사인지 아닌지를 인증한다. 그리고 reCan 2라면 GOOD_SHOP_PARTmember인지를 검토하여 비회원 이용자가 회원 전용 투표에 투표하는지를 검사한다.

    3-6. 가격값 조작

    해당 취약점은 order_table.php에서 card_update.php로 결제 가격, 배송비, 전체 가격을 전달할 때 발생한다. 해당 부분에서 전달하는 payM, transM, totalM과 같은 가격값을 보내는데, 공격자는 해당 값을 임의로 수정해서 보낼 수 있다.

    그림 37 order_table.php의  769 번 라인

    그림 37은 order_table.php769번 라인으로, 해당 코드는 payM, transM, totalM에 해당하는 값을 내부 DB trade 테이블로 보내고 있음을 의미한다. , 클라이언트에서 보내는 파라미터 값을 card_update.php에서 상품 결제 시 이용할 이유는 어디에도 없다.

    그림 38 card_update.php에서  trade  테이블 참조

    card_update.php에서 trade 테이블의 정보를 직접 참조해서 해당 값들을 이용하게 하면 클라이언트에서 가져온 값이 아닌 내부 DB로 전달된 값을 이용하게 된다. 따라서 클라리언트의 값을 아무리 조작해도 실제 가격값은 조작되지 않는다.

    그림 39 가격값 조작 실패

     

    댓글