SQL injection
SQL이란?
관계형 데이터베이스 관리 시스템의 데이터를 관리하기 위해 설계된 특수 목적 의 프로그래밍 언어
SQL 인젝션 공격의 원리
1. 공격자가 sql 구문을 주입
2. 사용자 입력 값과 미완성된 Sql 구문이 합쳐져 완성된 sql문으로 작동
3. 데이터베이스는 이 SQL 구문을 정상이라고 인식하고 요구하는 값을 반환
별도의 입력값 검증을 거치지 않아 취약점이 발생
- 사용자가 url?name=peter에 방문한 이후 MySQL 명령을 민들기 위한 서버의 PHP 코드
- $_GET[]을 사용해 URL 파라미터에서 name 값에 액세스, 이 값을 $name에 저장
- 입력 값을 검증하지 않고 $query 변수로 전달
- 쿼리는 $query 변수를 PHP 함수 mysql_query에 전달해 실행
- 만약 name에 일반적인 텍스트가 아닌, 악의적인 입력 값을 전달하면 이를 SQL 문법으로 인식해 완성된 쿼리문을 실행함. 이는 where 절을 항상 참으로 만들며, 의도하지 않은 작업을 수행하게 함
- SQL은 조건부 연산자로 AND와 OR을 사용하며, 이 경우 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란?
- 웹, 모바일, 애플리케이션의 보안 인증을 단순화하고, 표준화하는 개방형 프로토콜
- 사용자가 아이디나 비빌번호를 만들지 않고도 웹사이트에서 계정을 만들 수 있다.
OAuth 흐름
- 자원 소유자((resource owner)
OAuth를 이용해 로그인 시도하는 사용자 - 자원 서버(resource server)
자원소유자를 인증하는 제 3자 API이다. ex) 페이스북, 구글.. - 클라이언트(client)
자원소유자가 방문하는 제 3자 애플리케이션 클라이언트는 자원서버의 DB에 접근 가능
OAuth의 파라미터
- client_id: 자원서버가 클라이언트를 식별할 수 있게 해줌
자원서버가 자원 소유자의 정보에 대한 요청을 시작하는 애플리케이션을 식별할 수 있다. - redirect_uri: 자원 서버가 자원 소유자를 인증하고, 자원 서버가 자원 소유자의 브라우 저를 리디렉션 해줄 위치를 식별해줌.
- response_type: 제공할 응답 유형 식별해줌.
토큰 응답: 즉시 액세스 가능
코드 응답: 추가 프로세스 필요 - 상태(state): 교차 사이트 요청 권한을 방지하는 추측할 수 없는 값
자원서버로 보내는 HTTP요청에 포함되어야 하며, 유효성을 검사해야 함.
공격 과정
- OAuth를 통해 자원 소유자가 로그인 시도
- 클라이언트가 자원 서버에 정보 접근 요청, 자원 소유자에게는 데이터 접근 승인 요청
( 이 때 범위는 scope로 정의) - 클라이언트가 자원 서버에 리디렉션 응답 수신 후 브라우저가 get 요청을 자원 서버로 보냄
- 자원 소유자가 액세스 요청 승인시 자원 서버에서 redirect_uri 파라미터로 정의된 URL로 브라우저를 리디렉션하는 응답 반환
- 토큰 응답/ 코드 응답 둘 중 하나의 결과
- 코드 반환의 경우
- 클라이언트는 자원 서버에서 정보를 쿼리, 해당 코드를 액세스 코드로 교환
- 토큰을 얻기 위해 클라이언트는 세 가지 URL 파라미터(액세스 코드, client_id, client_secret)를 포함하는 자체 http 요청을 자원 서버에 보냄
- 자원 서버는 값을 확인하고 액세스 토큰을 반환. OAUTH 프로세스 종료
해당 과정은 자원 소유자의 브라우저를 거치지 않고 오직 클라이언트와 자원 서버간 교류
- 액세스 토큰 반환의 경우
- 클라이언트가 액세스 토큰 가질 시 자원 서버의 API에 직 접 조회.
- 자원 소유자는 클라이언트와 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 취약점 사례 - 로그인 토큰 사용
- wreply 파라미터를 다른 도메인으로 변경하면 프로세스 오류가 반환됐다. 이중 인코딩된 URL로 변경하면 유효한 URL이 아니라는 오류 반환
- 위의 이중 인코딩된 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를 방문한 모든 사용자의 액세스 코튼을 기록해 전체 페이스북 계정에 액세스 접근 가능해짐
'4-5. 2022-2 심화 스터디 > 버그 헌팅과 모의 해킹' 카테고리의 다른 글
[2022.11.26] SSRF (0) | 2022.12.02 |
---|---|
[2022.11.19] 원격코드실행(RCE) (0) | 2022.11.25 |
[2022.10.08] 메모리 취약점 문제 풀이 - LOB (1) | 2022.10.14 |
[2022.10.1] 메모리 취약점 (0) | 2022.10.07 |
[2022.09.17] 크로스 사이트 스크립팅(xss) (0) | 2022.09.23 |