본문 바로가기

4-5. 2022-2 심화 스터디/버그 헌팅과 모의 해킹

[2022.11.12] sql injection + Oauth 취약점

SQL injection

 

SQL이란?

관계형 데이터베이스 관리 시스템의 데이터를 관리하기 위해 설계된 특수 목적 의 프로그래밍 언어 

 

 

SQL 인젝션 공격의 원리

 

1. 공격자가 sql 구문을 주입

2. 사용자 입력 값과 미완성된 Sql 구문이 합쳐져 완성된 sql문으로 작동

3. 데이터베이스는 이 SQL 구문을 정상이라고 인식하고 요구하는 값을 반환

 

별도의 입력값 검증을 거치지 않아 취약점이 발생

 

  • 사용자가 url?name=peter에 방문한 이후 MySQL 명령을 민들기 위한 서버의 PHP 코드

    1. $_GET[]을 사용해 URL 파라미터에서 name 값에 액세스, 이 값을 $name에 저장
    2. 입력 값을 검증하지 않고 $query 변수로 전달
    3. 쿼리는 $query 변수를 PHP 함수 mysql_query에 전달해 실행
  •   만약 name에 일반적인 텍스트가 아닌, 악의적인 입력 값을 전달하면 이를 SQL 문법으로 인식해 완성된 쿼리문을 실행함. 이는 where 절을 항상 참으로 만들며, 의도하지 않은 작업을 수행하게 함

  •  SQL은 조건부 연산자로 ANDOR을 사용하며, 이 경우 SQLi는 방정식이 true를 반환하는 레코드를 검색하도록 WHERE절을 수정함
  • 다음의 경우엔 사용자가 파라미터를 제어할 수 있지만, 입력 값을 검증하고 있음.

  • 이런 경우엔 name에 악의적인 입력 값을 전달하면 되는데, ;-- 또는 test’ OR 1=’1’ ;-- 등을 추가해 password 파라미터를 제거하면 참을 반환하도록 할 수 있음. 이때, 대시 두 개는 주석 처리를 의미함.

 

대표적인 공격 대상

사용자 로그인 부분, 게시물 검색 부분, 우편번호 검색 부분, 자료실

 

SQLi 보안 대책
    • 준비된 명령문: 반복되는 쿼리를 실행하는 데이터베이스 명령문으로, 동적으로 실행되지 않도록 만들어 SQLi로부터 보호해 줌
    • 내장 보호 기능: 루비 온 레일즈, 장고, 심포니 등의 웹 프레임워크에서 제공하는 기능으로, SQLi 방지 가능

 


SQL 인젝션 사례 - 야후 스포츠 블라인드 SQLi

블라인드 SQLi
  • sql문에 쿼리를 삽입할 수 있지만 직접적으로 출력결과를 얻을 수 없을 때 발생
  • 공격 방식: 수정된 커리와 수정되지 않은 쿼리의 결과를 비교해 정보를 유추
공격 과정

 

  • 위의 url에서 - 두개를 추가하니 다음과 같이 출력된 결과가 달랐음

 

  • 쿼리가 다른 결과를 반환한 것을 알고, year 파라미터로 다음들 전달해 사용 중인 데이터베이스 버전 유추를 시도함.

  • MySQL의 version() 함수는 사용 중인 MYSQL의 현재 버전을 반환함. 만약 데이터베이스 버전이 5라면 and 연산에 의해 2010년의 선수를 반환할 것이고, 5가 아니라면 전체가 false가 되기 때문에 아무것도 반환하지 않을 것.

  • 아무것도 반환하지 않는 것으로 보아, 버전이 5가 아닌 것을 알 수 있으며, 이와 같은 방법으로 사이트에서 추가적인 정보를 얻어낼 수 있을 것임
시사점

Blind SQLi를 항상 악용할 수 있는 것은 아니지만, URL 파라미터를 테스트하고 쿼리 결과에 대한 미묘한 변경사항을 찾아내면 취약점을 찾아낼 수 있음

 

SQL 인젝션 사례- 우버 블라인드 SQLi

공격 과정
  • 오렌지 차이라는 사람은 우버의 이메일 광고를 받음. 이때 구독 취소 링크에 base64로 인코딩된 문자열이 URL 파라미터로 포함되어 있었음.

    • 디코딩 결과, ‘{"user_id":"5755", "receiver":"orange@mymail")’ 이라는 JSON 문자열을 발견할 수 있었고, 이곳에 디코딩된 문자열에 코드를 인코딩한 파라미터를 추가하자 사이트에서 해당 코드를 실행하는 것을 확인함.
    • 야후 스포츠 블라인드 SQLi와 마찬가지로, 조건부 검사를 수행하는 쿼리를 통해 브루트 포스 공격을 하고, 데이터베이스 사용자와 호스트 이름, 데이터베이스 이름을 알아냄
시사점
  • 인코딩한 파라미터를 허용하는 HTTP 요청을 유심히 살펴보고, 서버가 예상하는 인코딩과 완전히 동일하게 만드는 것이 좋음.
  • 버그 바운티에 사용하는 프로그램은 모두 동일하지 않으며, 자체 제작한 스크립트를 사용할 수도 있지만 자동화 도구를 사용하는 방법도 있음

 

SQL 인젝션 사례- 드루팔  SQLi

드루팔이란?
  • 워드프레스 등과 유사하게 웹 사이트 구축을 위해 널리 사용되는 오픈소스 콘텐츠 관리 시스템으로, 드루팔 설치 시 플랫폼을 실행하는 모듈인 드루팔 코어가 포함되어 있음. 이러한 핵심 모듈은 MySQL 같은 데이터베이스에 연결해 사용해야 함.
취약점
  • 임의 사용자가 모든 드루팔 사이트를 대상으로 손쉽게 공격할 수 있는 SQLi 취약점이 발견되었는데, IN절을 사용하는 드루팔 쿼리에 SQL문을 삽입해 취약점을 유발할 수 있음. 이는 드루팔 로그인 기능에 영향을 미쳤으며, 로그인에 활용할 수 있는 관리 사용자도 만들 수 있었음.
시사점
  • 사이트로 전달되는 입력 구조를 변경할 수 있어야 함. 예를 들어, 파라미터에 []를 추가해 배열로 변경하고 사이트에서 이를 처리하는 방법을 고민해야 함.

SQL 인젝션 사례- 숙박 서비스 '여기어때' 개인정보 유출 침해사고

공격 포인트
  • 공격 대상이 된 ㈜위드이노베이션 홈페이지에는 비정상적인 DB 질의에 대한 검증절차가 없어 SQL 인젝션 공격에 취약한 웹페이지가 존재
  • 탈취된 관리자 세션값을 통한 우회접속을 탐지·차단하는 체계가 없었음
공격 과정
  • 공격자는 SQL 인젝션을 통해 DB에 저장된 관리자 세션 값을 탈취.
  • 외부에 노출된 '서비스 관리 웹페이지'를 관리자 권한으로 우회 접속해 각종 정보를 유출했음
피해내역 
  •  제휴점 정보, 예약내역, 회원의 이메일, 전화번호 이름을 포함해 중복 제외 총 99만 854건
  • 약 4천여명에게 수치심을 유발하는 협박성 문자 전송됨

 


요약

    • SQLi는 사이트에 심각한 취약점이 될 수 있으며, 굉장히 위험할 수 있음
    • 드루팔의 사례처럼, 경우에 따라 공격자가 데이터베이스에 데이터를 삽입해 권한 상승을 노릴 수 있음. 이런 경우 시스템을 장악할 수 있게 되므로 굉장히 위험함.
    • 작은 따옴표나 큰 따옴표를 쿼리에 전달하지 못하도록 해야 하며, 예기치 않은 방식으로 데이터를 전달할 수 있는 위치가 있는지 확인해야 함

 

OAuth 취약점

OAuth란?
  • 웹, 모바일, 애플리케이션의 보안 인증을 단순화하고, 표준화하는 개방형 프로토콜
  • 사용자가 아이디나 비빌번호를 만들지 않고도 웹사이트에서 계정을 만들 수 있다.

Aouth 서비스의 예시

 

 

 

OAuth 흐름

  • 자원 소유자((resource owner)
    OAuth를 이용해 로그인 시도하는 사용자
  • 자원 서버(resource server)
    자원소유자를 인증하는 제 3자 API이다. ex) 페이스북, 구글..
  • 클라이언트(client)
    자원소유자가 방문하는 제 3자 애플리케이션 클라이언트는 자원서버의 DB에 접근 가능
OAuth의 파라미터
  • client_id: 자원서버가 클라이언트를 식별할 수 있게 해줌
    자원서버가 자원 소유자의 정보에 대한 요청을 시작하는 애플리케이션을 식별할 수 있다.
  • redirect_uri: 자원 서버가 자원 소유자를 인증하고, 자원 서버가 자원 소유자의 브라우 저를 리디렉션 해줄 위치를 식별해줌.
  • response_type: 제공할 응답 유형 식별해줌.
    토큰 응답: 즉시 액세스 가능
    코드 응답: 추가 프로세스 필요
  • 상태(state): 교차 사이트 요청 권한을 방지하는 추측할 수 없는 값
    자원서버로 보내는 HTTP요청에 포함되어야 하며, 유효성을 검사해야 함.
공격 과정
  1. OAuth를 통해 자원 소유자가 로그인 시도
  2. 클라이언트가 자원 서버에 정보 접근 요청, 자원 소유자에게는 데이터 접근 승인 요청
    ( 이 때 범위는 scope로 정의)
  3. 클라이언트가 자원 서버에 리디렉션 응답 수신 후 브라우저가 get 요청을 자원 서버로 보냄
  4. 자원 소유자가 액세스 요청 승인시 자원 서버에서 redirect_uri 파라미터로 정의된 URL로 브라우저를 리디렉션하는 응답 반환
  5. 토큰 응답/ 코드 응답 둘 중 하나의 결과
    • 코드 반환의 경우
      1. 클라이언트는 자원 서버에서 정보를 쿼리, 해당 코드를 액세스 코드로 교환
      2. 토큰을 얻기 위해 클라이언트는 세 가지 URL 파라미터(액세스 코드, client_id, client_secret)를 포함하는 자체 http 요청을 자원 서버에 보냄
      3. 자원 서버는 값을 확인하고 액세스 토큰을 반환. OAUTH 프로세스 종료
        해당 과정은 자원 소유자의 브라우저를 거치지 않고 오직 클라이언트와 자원 서버간 교류
    • 액세스 토큰 반환의 경우
      1. 클라이언트가 액세스 토큰 가질 시 자원 서버의 API에 직 접 조회.
      2. 자원 소유자는 클라이언트와 API간의 상호작용을 의식할 필요가 없음

 

 


OAuth 취약점 사례  - OAuth 토큰 훔치기

OAuth 토큰 훔치기
  • 개발자가 허용된 redirect_uri를 부적절하게 구성하거나 비교하여 공격자가 OAuth 토 큰을 훔칠 수 있는 경우
사례
  • 슬랙(사이트)의 화이트리스트인 redirect_uri에 임의 사항을 추가하여 redirect_uri제한 사항 우회.
  • 슬랙은 redirect_uri 파라미터의 시작부분만 검증하고 있었음.
  • 화이트리스트 에 URL 값을 등록하여 자원 소유자가 의도하지 않은 곳으로 리디렉트 시킴.
    ex)
    redirect_uri=https://www..com을 전달하도록 하는 것은 거부
    redirect_uri=https://www..com.mx을 전달하도록 하는 것은 허용

 

OAuth 취약점 사례 -  디폴트 비밀번호로 인증전달

  • Flurry와 야후가 OAuth토큰을 교환하고 마지막으로 야후에서 Flurry로 요청을 전달할 때 “password”: “not-rovided”인 경우, OAuth를 사용하지 않고, 아이디 및 비번을 사 용하지 않아도 Flurry에 로그인할 수 있었다.

 

OAuth 취약점 사례 -  로그인 토큰 사용

  1. wreply 파라미터를 다른 도메인으로 변경하면 프로세스 오류가 반환됐다. 이중 인코딩된 URL로 변경하면 유효한 URL이 아니라는 오류 반환
  2. 위의 이중 인코딩된 URL에 example.com을 더한 경우 오류X

 

OAuth 취약점 사례 -  액세스 토큰 전환

 

초기 공격자의 목표
  • 공격 대상 사용자의 페이스북 토큰을 수집한 후 개인정보에 접근하는 것
    -> 페이스북의 정교한 Oauth 구현으로 인해 공격 실패
2차 시도
        • 페이스북 소유의 앱을 포함한 주요 페이스북 기능이 Oauth를 사용 중이며, 모두 페이스북 계정에서 자동인가 받는 것을 활용해 사전 승인을 받았고, 사용할 수 있는 페이스북 애플리케이션 찾아냄.
        •  페이스북에서 더 이상 도메인을 소유하고 사용하고 있지 않지만 인가를 받은 애플리케이션을 발견
        • 화이트 리스트에 등록된 도메인을 redirect_uri의 파라미터로 등록해 Oauth 인증 엔드포인트를(https://facebook.com/v2.5/dialog/oauth?response_fype:token&display=popup&Client_ID=APP_ID&REDIRECT_URI=REDIRECT_URI) 방문한 대상사용자의 페이스북 토큰을 수신
        •  애플리케이션은 모든 페이스북 사용자에게 이미 권한을 부여받았기 때문에 임의의 공격 대상 사용자는 요청된 범위를 승인할 필요가 없다는 것을 활용. 해당 애플리케이션 페이스북 OAuth URL을 방문하면 사용자는 자동으로 (http://REDlRECT_URl/#*token:access_token_appended_here/)로 리디렉션
        •  Redirect_uri의 주소를 등록해 url를 방문한 모든 사용자의 액세스 코튼을 기록해 전체 페이스북 계정에 액세스 접근 가능해짐