SQL Injection이란 악의적인 사용자가 보안상의 취약점을 이용하여,임의의SQL문을 주입하고 실행되게 하여 데이터베이스가 비정상적인 동작을 하도록 조작하는 행위 입니다.인젝션 공격은OWASP Top10중 첫 번째에 속해 있으며,공격이 비교적 쉬운 편이고 공격에 성공할 경우 큰 피해를 입힐 수 있는 공격입니다.
여기어때 해킹 사건
2017년3월에 일어난“여기어때”의 대규모 개인정보 유출 사건도SQL Injection으로 인해 피해가 발생하였습니다.
SQL공격 기법은 여러 가지가 있는데 논리적 에러를 이용한SQL Injection은 가장 많이 쓰이고,대중적인 공격 기법입니다.
Error based SQL Injection
위의 사진에서 보이는 쿼리문은 일반적으로 로그인 시 많이 사용되는SQL구문입니다.해당 구문에서 입력값에 대한 검증이 없음을 확인하고,악의적인 사용자가 임의의SQL구문을 주입하였습니다.주입된 내용은‘ OR 1=1 --로WHERE절에 있는 싱글쿼터를 닫아주기 위한 싱글쿼터와OR 1=1라는 구문을 이용해WHERE절을 모두 참으로 만들고, --를 넣어줌으로 뒤의 구문을 모두 주석 처리 해주었습니다.
매우 간단한 구문이지만,결론적으로Users테이블에 있는 모든 정보를 조회하게 됨으로 써 가장 먼저 만들어진 계정으로 로그인에 성공하게 됩니다.보통은 관리자 계정을 맨 처음 만들기 때문에 관리자 계정에 로그인 할 수 있게 됩니다.관리자 계정을 탈취한 악의적인 사용자는 관리자의 권한을 이용해 또 다른2차피해를 발생 시킬 수 있게 됩니다.
Union based SQL Injection
Union명령어를 이용한SQL Injection
SQL에서Union키워드는 두 개의 쿼리문에 대한 결과를 통합해서 하나의 테이블로 보여주게 하는 키워드 입니다.정상적인 쿼리문에Union키워드를 사용하여 인젝션에 성공하면,원하는 쿼리문을 실행할 수 있게 됩니다. Union Injection을 성공하기 위해서는 두 가지의 조건이 있습니다.하나는Union하는 두 테이블의 컬럼 수가 같아야 하고,데이터 형이 같아야 합니다.
Union based SQL Injection
위의 사진에서 보이는 쿼리문은Board라는 테이블에서 게시글을 검색하는 쿼리문입니다.입력값을title과contents컬럼의 데이터랑 비교한 뒤 비슷한 글자가 있는 게시글을 출력합니다.여기서 입력값으로Union키워드와 함께 컬럼 수를 맞춰서SELECT구문을 넣어주게 되면 두 쿼리문이 합쳐서서 하나의 테이블로 보여지게 됩니다.현재 인젝션 한 구문은 사용자의id와passwd를 요청하는 쿼리문 입니다.인젝션이 성공하게 되면,사용자의 개인정보가 게시글과 함께 화면에 보여지게 됩니다.
물론 패스워드를 평문으로 데이터베이스에 저장하지는 않겠지만 인젝션이 가능하다는 점에서 이미 그 이상의 보안위험에 노출되어 있습니다.이 공격도 역시 입력값에 대한 검증이 없기 때문에 발생하게 되었습니다.
Blind SQL Injection
Boolean based SQL
Blind SQL Injection은 데이터베이스로부터 특정한 값이나 데이터를 전달받지 않고,단순히 참과 거짓의 정보만 알 수 있을 때 사용합니다.로그인 폼에SQL Injection이 가능하다고 가정 했을 때,서버가 응답하는 로그인 성공과 로그인 실패 메시지를 이용하여, DB의 테이블 정보 등을 추출해 낼 수 있습니다.
Blind SQL Injection – Boolean based
위의 그림은Blind Injection을 이용하여 데이터베이스의 테이블 명을 알아내는 방법입니다. (MySQL)인젝션이 가능한 로그인 폼을 통하여 악의적인 사용자는 임의로 가입한abc123이라는 아이디와 함께abc123’ and ASCII(SUBSTR(SELECT name From information_schema.tables WHERE table_type=’base table’ limit 0,1)1,1)) > 100 --이라는 구문을 주입합니다.
해당구문은MySQL에서 테이블 명을 조회하는 구문으로limit키워드를 통해 하나의 테이블만 조회하고, SUBSTR함수로 첫 글자만,그리고 마지막으로ASCII를 통해서ascii값으로 변환해줍니다.만약에 조회되는 테이블 명이Users라면‘U’자가ascii값으로 조회가 될 것이고,뒤의100이라는 숫자 값과 비교를 하게 됩니다.거짓이면 로그인 실패가 될 것이고,참이 될 때까지 뒤의100이라는 숫자를 변경해 가면서 비교를 하면 됩니다.공격자는 이 프로세스를 자동화 스크립트를 통하여 단기간 내에 테이블 명을 알아 낼 수 있습니다.
Blind SQL Injection
Time based SQL
Time Based SQL Injection도 마찬가지로 서버로부터 특정한 응답 대신에 참 혹은 거짓의 응답을 통해서 데이터베이스의 정보를 유추하는 기법입니다.사용되는 함수는MySQL기준으로SLEEP과BENCHMARK입니다.
Blind SQL Injection - Time based
위의 그림은Time based SQL Injection을 사용하여 현재 사용하고 있는 데이터베이스의 길이를 알아내는 방법입니다.로그인 폼에 주입이 되었으며 임의로abc123이라는 계정을 생성해 두었습니다.악의적인 사용자가abc123’ OR (LENGTH(DATABASE())=1 AND SLEEP(2)) –이라는 구문을 주입하였습니다.여기서LENGTH함수는 문자열의 길이를 반환하고, DATABASE함수는 데이터베이스의 이름을 반환합니다.
주입된 구문에서, LENGTH(DATABASE()) = 1가 참이면SLEEP(2)가 동작하고,거짓이면 동작하지 않습니다.이를 통해서 숫자1부분을 조작하여 데이터베이스의 길이를 알아 낼 수 있습니다.만약에SLEEP이라는 단어가 치환처리 되어있다면,또 다른 방법으로BENCHMARK나WAIT함수를 사용 할 수 있습니다. BENCHMARK는BENCHMARK(1000000,AES_ENCRYPT('hello','goodbye'));이런 식으로 사용이 가능합니다.이 구문을 실행 하면 약4.74초가 걸립니다.
Stored Procedure SQL Injection
저장된 프로시저 에서의SQL Injection
저장 프로시저(Stored Procedure)은 일련의 쿼리들을 모아 하나의 함수처럼 사용하기 위한 것입니다.공격에 사용되는 대표적인 저장 프로시저는MS-SQL에 있는xp_cmdshell로 윈도우 명령어를 사용할 수 있게 됩니다.단,공격자가 시스템 권한을 획득 해야 하므로 공격난이도가 높으나 공격에 성공한다면,서버에 직접적인 피해를 입힐 수 있는 공격 입니다.
Mass SQL Injection
다량의SQL Injection공격
2008년에 처음 발견된 공격기법으로 기존 SQL Injection 과 달리 한번의 공격으로 다량의 데이터베이스가 조작되어 큰 피해를 입히는 것을 의미합니다. 보통 MS-SQL을 사용하는 ASP 기반 웹 애플리케이션에서 많이 사용되며, 쿼리문은 HEX 인코딩 방식으로 인코딩 하여 공격합니다. 보통 데이터베이스 값을 변조하여 데이터베이스에 악성스크립트를 삽입하고, 사용자들이 변조된 사이트에 접속 시 좀비PC로 감염되게 합니다. 이렇게 감염된 좀비 PC들은 DDoS 공격에 사용됩니다.
SQL Injection에서 사용되는 기법과 키워드는 엄청나게 많습니다.사용자의 입력 값에 대한 검증이 필요한데요.서버 단에서 화이트리스트 기반으로 검증해야 합니다.블랙리스트 기반으로 검증하게 되면 수많은 차단리스트를 등록해야 하고,하나라도 빠지면 공격에 성공하게 되기 때문입니다.공백으로 치환하는 방법도 많이 쓰이는데,이 방법도 취약한 방법입니다.예를 들어 공격자가SESELECTLECT라고 입력 시 중간의SELECT가 공백으로 치환이 되면SELECT라는 키워드가 완성되게 됩니다.공백 대신 공격 키워드와는 의미 없는 단어로 치환되어야 합니다.
Prepared Statement구문사용
Prepared Statement구문을 사용하게 되면,사용자의 입력 값이 데이터베이스의 파라미터로 들어가기 전에DBMS가 미리 컴파일 하여 실행하지 않고 대기합니다.그 후 사용자의 입력 값을 문자열로 인식하게 하여 공격쿼리가 들어간다고 하더라도,사용자의 입력은 이미 의미 없는 단순 문자열 이기 때문에 전체 쿼리문도 공격자의 의도대로 작동하지 않습니다.
Error Message노출 금지
공격자가SQL Injection을 수행하기 위해서는 데이터베이스의 정보(테이블명,컬럼명 등)가 필요합니다.데이터베이스 에러 발생 시 따로 처리를 해주지 않았다면,에러가 발생한 쿼리문과 함께 에러에 관한 내용을 반환헤 줍니다.여기서 테이블명 및 컬럼명 그리고 쿼리문이 노출이 될 수 있기 때문에,데이터 베이스에 대한 오류발생 시 사용자에게 보여줄 수 있는 페이지를 제작 혹은 메시지박스를 띄우도록 하여야 합니다.
웹 방화벽 사용
웹 공격 방어에 특화되어있는 웹 방화벽을 사용하는 것도 하나의 방법입니다.웹 방화벽은 소프트웨어 형,하드웨어 형,프록시 형 이렇게 세가지 종류로 나눌 수 있는데 소프트웨어 형은 서버 내에 직접 설치하는 방법이고,하드웨어 형은 네트워크 상에서 서버 앞 단에 직접 하드웨어 장비로 구성하는 것이며 마지막으로 프록시 형은DNS서버 주소를 웹 방화벽으로 바꾸고 서버로 가는 트래픽이 웹 방화벽을 먼저 거치도록 하는 방법입니다.
예전부터 postman을 사용하여 만든 api를 호출하고 테스트 해왔는데 생각보다 기능들이 많고 손쉽게 만들 수 있어서 아래와 같이 정리를 합니다. 여기서 설명할 내용은 mock server와 api 문서를 만드는 방법입니다. mock server를 만들면서 api 문서화를 같이 진행할 수 있고 그 반대의 경우도 가능하므로 개발자에게 아주 편리한 기능을 제공합니다.
1. Mock server 생성하기
이미지의 좌측 상단에 있는 New 버튼을 누르면 팝업이 뜨는데 여기서 Mock Server를 눌러줍니다.
누르면 다음 화면이 위와 같이 나오는데 Request Path 부분에 경로를 입력하면 우측 하단의 Next가 활성화가 됩니다. 위에서 지정한 Request Path는 나중에 수정이 가능하므로 일단 test라는 경로로 지정하고 다음으로 넘어갑니다.
Mock server의 이름을 지정해주면 위 경우와 마찬가지로 우측 하단의 Create 버튼이 활성화가 됩니다. 이름은 역시 나중에 수정이 가능하므로 Test mock server로 임시 지정해 줍니다. 여기서는 설명하지 않지만 만약 이미 존재하는 Collection에 Mock Server를 추가하는 경우라면 Name 아래의 Use an environmnet에서 선택하면 됩니다. 없을 경우 위와 같이 아무 것도 선택하지 않으면 됩니다.
Create를 누르면 위처럼 Mock Server가 생성됩니다. 빨간색 박스로 가린 부분에 생성된 Mock Server URL이 발급됩니다.
위와 같이 Mock Server만 생성하면 Collection이 같이 만들어 집니다. 여기서 한 가지 확인해야 되는 부분은 {{url}}은 postman의 환경 변수를 타기 때문에 우측 상단에 있는 No Environment 상태에서 호출하면 호출이 되지 않습니다.
위처럼 생성한 Test mock server를 설정해야 위에서 생성된 mock server url이 {{url}} 변수에 연결됩니다.
2. mock api 반환 형태 설정하기
위의 /test/ api가 호출됐을 때 어떤 response를 줄지 구성해야 하기 때문에 우측 상단쪽에 있는 Examples에서 Default를 누릅니다.
위와 같이 아래쪽 EXAMPLE RESPONSE를 원하는 대로 꾸며줍니다.
저장을 한 다음, 해당 API를 호출하면 설정한 대로 나오는 것을 확인할 수 있습니다.
3. API 문서 만들기
/test/ API의 request와 respoonse에 대한 설명 뿐만 아니라 해당 collection에 대한 설명을 작성할 수 있습니다. postman은 markdown 문법을 지원하므로 테이블 형태로 작성하는 것이 아니라면 손쉽게 꾸밀 수 있습니다.
문서를 추가하고자 하는 api 목록에서 오른쪽 마우스 또는 우측 ... 을 클릭하여 Edit을 눌러줍니다.
위와 같이 설명을 추가한 다음 Update를 누릅니다.
생성한 API 문서를 확인하기 위해 Test mock server 리스트에 마우스를 올려놓으면 화살표가 보이는데 해당 화살표를 누른 다음 View in web버튼을 누릅니다.
그러면 위와 같이 웹이 호출되고 위와 같이 작성한 API 문서를 확인할 수 있습니다.
요약
위와 같은 방법으로 손쉽게 API 문서와 Mock server를 생성하고 모니터링이나 변경로그 기능도 제공합니다. 또한 하나의 collection에 여러 mock server url을 가질 수 있고, 환경변수를 사용하여 mock server 별로 파라미터를 다르게 지정할 수도 있습니다. 무료 버전에서는 생성할 수 있는 collection과 request 등이 제한되어 있지만 유료 버전이 비싼 편에 속하지 않기 때문에 협업 도구로 충분히 고려할 만합니다.
장점
Mock Server를 위한 서버 구성이 필요가 없음
특별한 코딩이 필요 없고 단순한 클릭 몇 번으로 손쉽게 생성 가능
또한 API 문서도 쉽게 생성 가능
환경 별로 변수의 값을 다르게 설정할 수 있음
CORS가 설정되어 있음
단점
호출 횟수에 제한이 있음 (1분당 60회)
특정 API의 Example에 Path, Header, Params, Body가 같은 것이 있으면 최근에 추가된 Example가 호출됨