세미나/우아한테크

우아한테크 세미나 8월 애플리케이션 보안 백엔드 쪽 메모

비뀨_ 2022. 9. 1. 00:16

출처 : 우아한 Tech Youtube

취약점 진단 VS 모의해킹

취약점 진단 모의 해킹
체크리스트 기반으로 항목별 취약점이 존재하는지 파악하는 작업 실제로 공격한다 가정하고 진행
위협이 될 수 있는 취약점을 찾아내고, 이를 통한 공격이 가능한지를 확인하는 수준의 작업 대상 시스템에 대한 정보를 수집
  대상 시스템에 대한 취약점을 찾아내고, 이를 통한 공격 시나리오 수립
  권한 획득, 권한 상승, 정보 탈취, 시스템 장악, 시스템 파괴, 장애 유발 등 취약점을 통해 어떤 공격이 가능한지 구체적으로 확인하는 작업

 

주관적인 최근 서비스 개발 트렌드

  • 서버 부하를 줄이기 위해 클라이언트에서 처리하는 기능이 증가
    • 서버에서 처리해야 하는 기능을 클라이언트에서 처리해서 취약점 발생
  • 효율적인 개발을 할 수 있게 도움을 주는 Framework 사용
    • Framework 설정을 부적절하게 해서 취약점 발생
    • Framework 자체에서 발생하는 취약점으로 인한 영향력이 매우 커짐
  • On-Premise 환경보다 클라우드 환경 이용
    • 클라우드 환경 특성으로 인한 공격이 유입

 

OWASP TOP 10 

OWASP(Open Web Application Security Project)는 비영리 단체로 소프트웨어 보안의 발전을 위한 노력을 함.

3-4년 주기로 가장 위협적인 웹 취약점 10개를 선정

 

2021년에 발표된 OWASP TOP 10

 

취약점

IDOR ( Insecure Direct Object Reference )

안전하지 않은 직접 객체 참조라고 한다.

국내에서는 부적절한 인가라고도 표현한다.

OWASP TOP 10 1위인 Broken Access Control과 연관이 있는 취약점

 

서버에서 수행해야 할 권한 검증 및 접근 제어를, 클라이언트에서 수행하는 경우가 잦아지며, 많이 발견되는 추세

(실제로 꽤 많이 나옴)

수평적/ 수직적 권한 상승이 발생하며, 이를 통해 타 사용자의 객체에 접근하여 정보를 유출시키거나, 기존 권한만으로는 사용이 불가한 기능을 멋대로 이용할 수 있음. ( 관리자에 접근해서 정보 탈취 )

 

수평적 권한 상승

 

동일한 권한을 가진 다른 사용자의 객체에 접근할 수 있을 때

 

예시 : 

1,2번은 해커 본인의 계정임. 문제없이 정보를 가져오는 것이 가능함.

3,4번은 해커 본인의 계정이 아닌, 다른 사람의 계정에 접근하는 것

 

수직적 권한 상승

본인의 권한보다 높은 권한의 기능을 수행할 수 있을 때

 

 

수직적 권한상승은 인가(Authorization) 문제.

 

조치

Client Side에서 검증을 수행할 경우 공격자가 모두 우회 가능하기 때문에, 검증은 반드시 Session이나 Server에서 발급한

 Token을 통해 서버에서 검증을 수행해야 함.

 

SSRF ( Server-Side Request Forgery )

서버단에서 요청을 발생시켜 내부 시스템에 접근하는 취약점이다.

내부 데이터를 외부로 유출시킬 수 있는 공격 방법.

OWASP TOP 10에 새롭게 등재됨.

서비스에서 URI를 전달받고, 서버에서 해당 URI에 직접 요청해서 데이터를 받아오는 형태의 기능에서 주로 발생

( 외부 이미지 불러오기 기능 )

 

Public Cloud 환경에서는 가상 서버의 Meta Data를 확인할 수 있는 API가 있어 SSRF를 통해 해당 API를 요청해 가상 서버의 정보를 확인할 수 있음.

 

공식 문서에 정의가 되어있음. 어떤 주소로 어떤 API를 호출하면 정보가 어떤 게 나온다라는 게 명시되어 있기 때문에

공격자는 바로 Cloud 사용시 정보 뽑아올 수 있음,

 

 

해커가 SSRF 취약점 발견하면 서비스를 통해서 내부 시스템에 접근해서 정보를 탈취

 

/getdata를 호출할 때 Scheme에 대해서 검증 안 하면 passwd를 가져갈 수 있음.

 

Meta Data 를 뽑아내는 API를 URI에 넣었음을 볼 수 있는데 이건 AWS 공식문서에 작성.

공격하기 편함.

서비스가 동작하는 실제 서버 AWS Instance의 Meta Data를 뽑아낼 수 있음. 2차 공격에 도움이 됨.

 

조치 방안

  • 접근 가능한 주소를 whitelist 방식으로 필터링
  • 반드시 필요한 URI Scheme만을 사용하도록 whitelist 방식으로 필터링
  • Localhost, 127.0.1 등의 Loopback URI가 들어올 경우 필터링
  • Private IP, Link-local address 형태의 URI가 들어올 경우 필터링
  • 불필요한 특수문자가 URI에 포함되어 있을 때 필터링

기능에 따라서 주소를 whitelist로 사용할 수 없는 경우가 있음.

빨간색은 우회를 시도해 볼 수 있음. blacklist 또는 필터링하는 방식으로 적용해야 됨. 

 

가능하면 whitelist, 불가능하다면 blacklist를 사용

 

JWT를 이용한 인증의 문제점

JWT ( Json Web Token)은 통신을 수행하는 두 대상이 서로 보낸 데이터에 대해 신뢰할 수 있게 Data가 Encoding 된 Token을 의미

 

JWT는 Header, Payload, Signature로 이루어지는데

  • Header : Token의 타입, 서명에 사용된 암호화 알고리즘
  • Payload : 전달하고자 하는 데이터
  • Signature : Header에 명시된 암호화 알고리즘과 secret key를 이용해 Header와 Payload를 서명한 값

 

장점 

Stateless Token으로 서버가 인증 작업을 수행하지 않는다.

여러 명의 사용자가 요청했을 때 인증하지 않아서 서버의 부하를 줄일 수 있음.

단점

Stateless Token으로 서버가 인증 작업을 수행하지 않는다.

제어권을 잃어 관리할 방법이 도저히 없다.

 

기존 Session / Stateful Token 방식

logout 요청하면 Session이 만료되면서 로그인 페이지로 Redirect

로그아웃을 한 상태에서 3번을 호출하면 로그인 페이지를 호출

 

JWT Token 방식 예시

logout을 하고서 3번을 호출하면 4번처럼 글 쓰기가 가능해짐.

그 이유는 서버 입장에서는 Token을 즉시 만료할 수 없기 때문에 만료시간이 지나지 않으면 로그아웃이 되지 않음.

 

Token이 탈취되었을 경우 임의로 서버에서 Token을 만료시킬 수 없음

JWT Token을 JS를 이용해 Base 64로 Decoding 해서 사용해야 하다 보니, Token을 쿠키로 받을 경우 httponly 옵션을 추가할 수 없으며, 쿠키가 아닌 경우 localstorage와 같은 브라우저 내장 storage를 사용해야 하기 때문에 XSS로 인한 Token 탈취 가능성이 높아짐.

Refresh Token은 stateful Token이기 때문에 서버에서 관리 가능.

 

JWT 문제 조치 방안

  • JWT BlackList를 구현하여  같이 운영함으로써, 서버에서 Token에 대한 제어를 수행할 수 있도록 구현한다.
  • JWT Payload내 stateful 한 token을 추가하여, 서버에서 stateful token을 통해 제어를 수행할 수 있도록 구현

Token에 대한 유효성 검증 로직이 서버에 추가됨에 따라 기존 JWT에 비해 서버 부하가 조금 증가하지만, Stateful token만을 이용한 방식보다는 부하가 적음.

 

개인적으로는 JWT를 이용해서 인증 작업을 수행하지 않음. JWT 자체가 JWT.io 사이트에 들어가서 명세를 보면 알지만 Authorization을 위해서 만들어진 것은 아님. 신뢰할 수 있는 데이터를 보내는 방법임.

때문에 인증으로 쓰지 않아도 됨. 쓰는 이유는 편리하고 서버에 부하가 적어지니까 사용

완벽한 Stateless 환경에서 사용하는 것보다, 조금은 Stateful 하게 같이 쓰는 것이 좋다.

 

In-Memory DB인 Redis를 통해서 서버에서 Token에 대한 제어를 수행할 수 있도록 구현

JWT Payload안의 Stateful 한 토큰을 구현해서 (UUID 등) 서버에서 Token에 대해 Stateful 하게 구현할 수 있게 한다.

 

1 : 로그인을 함

2 : JWT Token을 발급 받음

3 : 글을 쓸 수 있음

4 : blacklist : Redis를 통해 Token이 blacklist에 있는지 확인하고

5 : 그 결과를 서버에 반환해 검증

6 : 인증이 되면 글을 등록시킴

 

Token이 blacklist에 등록되었을 때

  • 로그아웃 되었을 때
  • Server에서 임의로 만료시키고 싶을 때

Actuator Misconfiguration 

Actuator 설정을 잘못했을 경우에 나타남.

 

Spring boot Framework의 Sub-project로써 운영되는 Service를 모니터링하고 관리하기 위한 기능들을 포함하고 있음.

HTTP 방식과 JMX (Java Management eXtensions)라는 Java API를 이용하는 방식이 있으며, 보통은 HTTP 방식으로 함.

다양한 역할을 지닌 EndPoint들이 존재함 ( health, metrics : 지표 , prometheus :프로메테우스 Agent , etc... ) 

 

불필요한 EndPoint를 활성화시켜두어, 예상치 못한 Actuator의 기능으로 서비스 기밀성, 무결성, 가용성을 침해당할 수 있음.

  • 환경 변수로 중요 정보를 저장해 둔 경우
    • Actuator env endPoint를 사용할 경우, 환경변수에 저장되어 있는 중요 정보를 확인할 수 있음.
    • 아래의 이미지는 env라는 endPoint
    • access fee를 넣어놨다던가, id/pwd, master key 등을 넣어놨을 때 노출 가능

예시 이미지

  • 중요정보가 메모리에 올라가 있는 경우
    • Actuator Heapdump endPoint를 사용할 경우, 현재 서비스가 점유 중인 heap 메모리 내 존재하는 데이터를 확인할 수 있음.

예시 이미지

 

Actuator 조치 방안

 

1. Actuator endpoint는 필요한 것만 enable 처리한다.

  • Actuator는 shutdown endpoint 제외한 나머지는 Default로 enable 되어있음.
    • Actuator는 shutdown을 제외한 나머지는 Default로 활성화되어있음.
    • Default을 그대로 따르면 불필요한 endpoint를 사용해 잠재적 위협이 될 수 있음.
  • Default 설정은 불필요한 endpoint가 활성화되어 잠재적 위험이 될 수 있음.
  • Default 설정을 따르지 않고, 모든 endpoint들을 disable 상태로 유지해야 함.
  • 필요한 endpoint 만을 enable 해줘야 함.

2. Actuator endpoint는 필요한 것만 expose( 노출 ) 한다.

Actuator는 활성화와 expose를 둘 다 해야 함.

  • JMX는 기본적으로 모든 endPoint가 expose 되어있으며, HTTP는 반대로 health endpoint만이 기본적으로 expose 되어있음.
  • 불필요한 endpoint를 expose 할 경우 잠재적 위험이 될 수 있다.
  • JMX형태로 Actuator 사용이 필요하지 않을 경우 모든 endpoint가 JMX를 통해 사용 불가하게 설정해야 함.
  • 사용이 필요한 endpoint를 노출할 때는 Wildcard 문자인 Asterisk(*)를 사용하지 않아야 함.

JMX와 HTTP의 expose 설정

3. Shutdown endpoint는 enable하지 않는다.

시스템을 shutdown 시킬 수 있기 때문에 서비스 가용성을 침해할 우려가 있음.

기본적으로 disable 되며, expose 설정도 되지 않기 때문에 절대!! 설정을 enable하지 않도록 신경 써야 함.

 

4. Service 운영 포트와 다른 포트를 사용한다.

Actuator가 다양한 기능을 가진 만큼, 공격자들은 웹 사이트를 공격할 때 Actuator 관련 endpoint가 존재하는지를 Scan 함.

서비스 운영 포트와 Actuator 포트를 분리할 경우, 외부에서의 접근을 차단하고 내부에서만 접근하도록 방화벽 설정이 가능하기 때문에 외부 공격자들로부터 보호를 받을 수 있음.

 

health check를 Intenal로 돌리면 됨.

 

5. Actuator에 접근할 수 있는 IP 주소를 제한한다.

접근할 수 있는 사람을 최소한으로 줄이자는 것.

Actuator의 경우 서비스 운영자, 개발자가 주로 이용하기 때문에, 오로지 인가된 사용자만이 접근 가능하도록 IP 제어를 통해 내부, 외부 공격자로부터 보호받을 수 있음.

WAF, L7 방화벽, IPS, (포트를 제한했을 경우) 방화벽 등의 방법으로도 제한 가능하며, Actuator 설정으로도 제한 가능.

 

6. Actuator 기본 경로를 변경한다.

Actuator의 경우 기본적으로 /actuator/[endpoint]와 같은 형태로 외부에 노출됨.

공격자는 이미 알려진 형태를 이용해 Actuator endpoint에 대해 Scanning 함.

Actuator 경로를 변경함으로써 공격자의 Scan을 피할 수 있음.

경로 변경 시 유추하기 어려운 문자열의 경로로 설정할 것을 권고

 

7. Actuator 접근 시 권한 검증을 수행한다.

Actuator는 많은 기능을 가지고 있는 만큼, 권한이 있는 인증된 사용자만이 다루는 게 보안상 좋음.

Session 또는 인증 Token을 이용해 접근 권한이 있는지를 검증하는 로직을 추가할 것을 권고

 

Spring Security를 사용할 경우 쉽게 적용할 수 있음.

 

Spring Security를 이용한 Actuator 설정

 

application.properties에 Actuator 설정을 진행한 경우

7번은 Security기 때문에 패스

 

 

Q&A

Spring Security는 무거운데 대규모 프로젝트에서도 사용하나요?

문제가 되는 부분이 Session인데 Scale Out 할 때 Cloud에서 안 쓰는 이유가  Session은 WAS 종속적인데, 각 WAS별로 Session이 동기화가 되지 않아서 사용하지 못하는 경우가 많음.

그래서 보통은 Redis를 운영하는 경우가 많음. Stateful Token을 각 WAS에서 가져갈 수 있도록 운영

 

Management.server.address에 대역 설정이나 여러 값 설정도 가능한가요?

 가능한 걸로 알고 있음 대역 값은 공식문서를 확인해 봐야 함.

대역 설정은 설정 파일보다 방화벽으로 만드는 게 수월할 것 같음.

 

whitelist 방식이 CORS 설정에도 해당되는 건가요?

CORS와 Actuator는 조금 별개임.

CORS도 whitelist방식이 권고됨.

 

우연히 Youtube에서 메인화면에 떠서 보게 되었는데, 모르는 부분이 대부분이었다.

실제로 Spring boot, Spring Security를 사용하고 있고, 보안적인 이슈가 중요하게 대두되기 때문에

당장에 모르는 것도 나중에 공부하면서 차근차근하면서 다시 한번 확인해 보려고 정리해 봤다.

 

정리가 부족할 수도 있기 때문에 우아한 Tech 유튜브에서 한번 보면서 이 글은 참고만 하는 식으로 가면 좋지 않을까 싶습니다.