본문 바로가기

Webhacking/WebGoat

[WebGoat] Broken Access Control-Missing Function Level Access Control 풀이

728x90
반응형

이번 챕터는 Missing Function Level Access Control 에 관련한 것이다.
보통 대부분의 pentester들은 IDOR와 Missing Function Level Access Control 을 동일하게 취급한다. 
하지만 세부적으로 따지면 조금은 다르다보니, webgoat에서는 그 차이를 알려주기 위한 챕터를 따로 만들어 두었다고 한다.

IDOR는 수직적 또는 수평적 권한상승이 핵심이라면, Missing Function Level Access Control은 권한상승이라기보다는, 기능 접근제어 미비로 보아야한다. IDOR는 내가 아닌 타 사용자에 포커싱이 맞추어져 있다면 Missing Function Level Access Control은 사용 불가능한 기능을 사용할 수 있는 경우에 포커싱이 맞추어져 있다는 설명이다.

그럼 문제풀이 가보자.

이번 문제는 실제로 현업에서도 많이 발생하는 이슈이다. 
바로 사용하지 않는 기능이나, 또는 사용할 수 없어야하는 기능에 대해서 프론트엔드에서 숨김처리했을때 발생할 수 있는 취약점에 관련한 것이다. 이번 문제는 눈에 보이지 않는 2개의 메뉴를 찾으라고 하는데, 개발자 도구를 이용해서 찾으면 된다.

개발자 도구를 이용해 확인해보니 Messages 메뉴 옆에 숨겨진 메뉴 Admin메뉴가 있으며, 그 하위에 3개의 메뉴가 있다.
다만 문제에서 숨겨진 메뉴는 2개라고 했기때문에 아무래도, Users라는 이름을 가진 메뉴 2개는 같은 메뉴로 취급하는것으로 보인다.

찾은 Users 메뉴와 Config 메뉴를 입력하고 Submit 하자.

다음문제로 넘어가자

다음 문제는 이전 문제에서 얻은 정보를 토대로 Jerry라는 사용자의 hash 데이터를 얻어내라는 문제이다.
이것저것 힌트를 주는데, 딱히 크게 중요하지는 않다. 우선 얻어낸 정보를 토대로 공격을 진행해보자.

얻어낸 정보는 총 3개의 API URI이다. 하나씩 테스트해보도록 하자.
다만 WebGoat에서 모든 API는 WebGoat/ 하위로 쭉 이어지는데, 확인된 API는 그렇지 않기때문에, 그냥 접속하면 분명 페이지를 찾을수 없다고 나올것이다.
/access-control 앞에 WebGoat를 붙여서 /WebGoat/access-control/ 이런식으로 접근하도록 하자.

Burpsuite repeater를 이용하여 /WebGoat/access-control/users API로 request를 보내보았는데... 500에러가 뜬다.
뭔가 template에서 렌더링을 할때 오류가 나는것 같다... 뭐가 빠진걸까?

사실 이부분은 조금은 문제를 위한 문제라고 생각한다. 조금은 억지스러우나 Content-Type: application/json이 없기 때문이다. 

MissingFunctionACUsers.java 의 코드를 보면 Content-Type을 application/json으로 주어야만 Response를 통해 데이터를 응답해줌을 알 수 있다.

다만 이 부분은 추측이 필요한 부분이기때문에, 그냥 API에 공격을 시도할때는 다양한 Content-Type을 이용하여 시도해야한다는 것만 기억하고 넘어가면 된다.

Content-Type을 잘 넣어주면 데이터가 잘 나오게 된다.
찾아낸 데이터를 넣고 Submit을 눌러 문제를 해결한다.

이제 다음 문제로 넘어가자

다음 문제는 뭔가 취약점이 수정되었는데, 다른 취약점으로 인해 우회가 가능한 상황이라고 설명하고 있다. 
그리고 힌트로 데이터를 임의로 밀어넣을 수 있는지를 확인하라고 하고있다.
아마도 조치된 API는 users-admin-fix 이 API인것 같으니 어떻게 조치가 되었는지부터 확인해보자.

오... Forbidden이 응답된다.
내가 현재 로그인한 사용자의 권한을 확인하여 접근을 제어하는것으로 보인다.

이 데이터는 아까 users API를 호출했을때 나온 데이터이다.
여기서 admin이라는 부분이 아마 권한 관련한 부분이 아닐까 추측이 된다. 
그렇다면 내가 지금 로그인해 있는 계정의 admin 여부를 true로 업데이트할 수 있다면? 권한 검증을 통과할 수 있지 않을까?

이전에도 했듯, 수정에는 주로 PUT method를 사용한다.
하지만 지금의 경우 users를 통해 조회해본 결과 내가 로그인한 계정은 리스트에 없음을 알 수 있다. 이러한 경우 수정이 아니라 신규추가이기 때문에 POST method를 이용하여 공격을 수행해보았다.

users API를 통해서 Content-Type이 application/json 인것을 확인했고, 또 users API를 통해 조회된 내용도 json 형태였기 때문에, 그 내용을 토대로 username은 내가 현재 로그인한 계정 이름인 'testtest'로, 제일 주요한 admin은 true로, 마지막으로 password는 그냥 아무거나 입력했다.

입력하고 나니 정상적으로 등록이 된것으로 보이는 OK 응답이 왔다. 그렇다면 이제 나도 권한 검증을 통과하여 데이터를 조회할 수 있지 않을까?

성공이다...!

응답의 맨 아래를 보면 내가 등록한 testtest가 정상적으로 admin 권한을 가지고 등록되었음을 알 수 있다.
그리고 admin 권한을 임의로 얻어냈기에, 정상적으로 권한검증을 통과하여 사용자들의 정보를 조회할 수 있었다.
조회된 정보를 가지고 답을 인증하자.

자 그러면 Missing Function Level Access Control 취약점은 어떻게 조치하면 될까?
생각보다 간단하다. 권한검증을 잘 넣어주면 된다.
마지막 문제 4번의 경우 권한 검증을 잘 넣어줬으나, GET Method로 들어오는 Controller에만 넣어주었기에 문제가 되었다. 특정 Method에 대해서만 권한 검증을 넣는것이 아닌, 다른 Method에 대해서도 권한 검증을 넣어주면 조치가 가능하다.

그렇다면 직접 조치를 진행해보자.

MissingFUnctionACUsers.java 파일의 내용 중 users-admin-fix를 GET으로 호출했을때를 담당하는 controller이다.
보면, 현재 로그인한 세션을 가지고 로그인한 사용자의 정보를 가져오며, 해당 사용자가 userRepository 리스트에 존재하면서 동시에 isAdmin 메서드를 통해 admin의 권한이 있는지를 확인하여 권한이 있는 경우에만 정보를 응답해주는 구조로 이루어져 있다.

 

이 부분은 users-admin-fix에 POST 방식으로 요청을 보냈을때를 담당하는 controller이며 동일한 MissingFUnctionACUsers.java에 있는 부분이다.
조금 독특한 것은 users API와 users-admin-fix API 2개 API에 대한 처리를 하나의 Controller에서 수행하고 있다. 아마 우리가 아까 했던 POST 방식으로 계정을 추가하는 공격은 users API를 이용했어도 가능했을것이라 생각한다.

내용을 보면 조건문이 전혀 없다. 
그냥 POST로 요청이 들어오면 전달받은 데이터를 토대로 userRepository에 저장시켜버린다. 이러다보니 임의로 관리자 권한을 가진 계정을 추가하여 문제를 풀 수 있었던 것이다.

조치하는 방법은 매우 간단하다. 위에서 권한 검증을 수행하던 부분을 복사해서 취약한 코드에 붙여넣기 하면된다.

위에서 사용된 변수와 조건문 그대로 복사해서 userRepository.save 메서드를 호출하기 전 조건문으로 사용하면 되며, 만약 그 조건을 통과하지 못했을 경우에는 403 에러를 return하도록 하면 된다.

이제 저장하고 다시 테스트 해보자.

혹시 maven 빌드중 이런 오류가 난다면... 시키는 대로 ./mvnw spotless:apply 를 해주고 다시 빌드해보자.

반드시 테스트하기 전에 Reset lesson 버튼을 눌러 초기화 하고 테스트를 진행한다.
보면 동일한 POST request지만, 응답이 조금 다르다. OK가 나오나, 디테일한 정보가 나오지 않는다. 
이것만 가지고는 방어가 된건지 확인이 어려우니, 이렇게 POST 요청을 보낸뒤, GET 요청으로 정보조회가 가능한지 확인해보자.

Forbidden이 응답되는것을 알 수 있다.
즉 아까 시도한 POST request는 권한 제어로 인해 실패한 것이다.

이렇게 조치를 완료할 수 있다.


728x90
반응형