2016년 11월 22일 화요일

MySQL MyISAM Type의 데이터 파일 구조 분석과 삭제된 레코드의 복구 방안


[Tech Report] MySQL MyISAM Type의 데이터 파일 구조 분석과 삭제된 레코드의 복구 방안



  • AhnLab


  • 2014-01-29

손상된 데이터에도 '의미'는 있다

 

MyISAM은 InnoDB와 더불어 MySQL의 대표적인 저장방식 중 하나이다. 모든 테이블과 데이터를 하나의 파일로 통합하여 관리하는 InnoDB와는 달리 MyISAM은 테이블별로 파일을 생성하여 해당 테이블과 관련된 모든 데이터를 각각의 테이블별 파일에 저장한다. 이처럼 테이블과 파일이 1:1 대응의 형태를 갖는 MyISAM은 데이터 관리가 매우 우수하며 데이터 처리 속도도 빠르다. 그러나 데이터 삭제 시, 관리 성능 및 빠른 처리 속도를 유지하기 위해 데이터가 존재했던 영역 일부에 삭제를 표시하기 위한 다른 값을 덮어쓴다. 결국 MyISAM은 완벽한 절차를 수행하더라도 삭제된 데이터를 온전히, 또는 모두 복구하기가 어렵다.



디지털 포렌식 관점에서는 비록 일부만 복구된 데이터라 할지라도 상당한 의미가 될 수 있기 때문에 이에 대한 복구 방안 마련이 필요하다. 이와 관련해 이번 호에서는 MyISAM 저장방식에서의 데이터 접근 방법을 살펴보고 삭제된 데이터의 복구 방안에 대해 알아본다.

 

 

<연재 목차>

1부_MySQL의 현황 및 포렌식적 의미(2013년 12월 호)

2부_MySQL InnoDB Type의 데이터 파일 구조 분석과 삭제된 레코드의 복구 방안(2014년 1월 호)

3부_MySQL MyISAM Type의 데이터 파일 구조 분석과 삭제된 레코드의 복구 방안(이번 호)

 

 

지난 월간 안 1월호에서 살펴보았던 InnoDB 저장방식에 비해 MyISAM 저장방식은 빠른 속도로 대용량의 데이터를 처리할 수 있는 장점을 갖고 있다. MyISAM은 MySQL의 초기 버전부터 메인 저장방식으로 사용되었으며, MySQL 5.5 버전 출시 이후 InnoDB 저장방식으로 변경되기 전까지 MySQL의 기본 저장방식으로 사용되었다.



MyISAM은 트랜잭션 기능을 지원하지 않으며 외래 키(Foreign Key)를 지원하지 않기 때문에 시스템이 손상되었을 경우 데이터의 복구가 어렵고 데이터의 품질을 향상시키기 어렵다는 단점이 있다. 그러나 이 같은 단점에도 불구하고 대다수의 MySQL 사용자는 MyISAM의 빠른 속도와 사용상의 편의성 때문에 여전히 이를 기본 저장방식으로 사용하고 있다. 이 같은 MyISAM의 높은 사용률때문에라도 이에 대한 분석 및 복구 방안 연구는 디지털 포렌식 관점에서 상당히 중요한 의미를 갖는다.

 

 

MyISAM의 구조적 특징



MyISAM은 테이블의 구조 정보와 인덱스 정보, 테이블 내부에 저장될 데이터 등을 각각의 정해진 파일에 분할하여 저장한다. 각각의 파일은 저장된 정보를 통하여 데이터 관리의 효율을 높이기 위한 역할을 수행한다. 일반적으로 MySQL은 [그림 1]과 같이 사용자 또는 시스템이 데이터베이스를 생성하는 경우 기 설정된 저장경로에 데이터베이스명의 디렉터리를 생성한다.

 

ㅇㄴㄹㄴㅇㄹ

 

 

이후 생성한 데이터베이스 내부에서 [그림 2]와 같은 쿼리를 이용해 MyISAM 저장방식의 테이블을 생성하면 데이터베이스명의 디렉터리 내부에 테이블명의 MYD 파일과 MYI, FRM 파일을 동시에 생성된다([그림 3]).

 

ㄴㅇㄹㅇㄴㄹ

 

 

ㄴㅇㄹㄴ 

 

 

일반적으로 대부분의 DB는 [그림 4]와 같은 구조로 이루어져 있다. 따라서 원하는 위치의 데이터에 접근하기 위해서는 원하는 데이터베이스와 테이블을 알아야 한다. 특히 MySQL에서는 접근하고자 하는 테이블이 MyISAM 또는 InnoDB 중 어느 것인지를 구분하는 절차가 필요하다.

 

ㄴㅇㄹ

 

  

MyISAM 구성 파일

 

앞서 설명한 바와 같이 MySQL은 사용자 또는 시스템이 데이터베이스를 생성할 때 지정된 저장경로에 데이터베이스명의 디렉터리를 생성한다. 또한 MySQL의 MyISAM 저장방식은 데이터베이스 내부에 테이블을 생성하는 경우, 데이터베이스명의 디렉터리 안에 테이블 정보와 인덱스 정보, 테이블에 저장될 데이터를 각각 테이블명의 파일로 저장한다. 일반적으로 테이블의 구조 정보는 FRM 파일에 저장되고 인덱스 정보는 MYI 파일에 저장되며 실제 데이터에 해당하는 레코드들은 MYD 파일에 저장된다. 포렌식을 위해 삭제된 데이터를 복구하는 경우에는 테이블의 구조를 저장하고 있는 FRM 파일과 데이터를 저장하고 있는 MYD 파일을 반드시 수집해야 한다. 물론 MYI 파일까지 모두 수집할 수 있다면 보다 효과적인 복구가 가능하다. 따라서 삭제된 데이터를 복구할 경우, FRM 파일과 MYD 파일을 손상 없이 수집할 수 있는 여러 가지 방안 및 대안이 필요하다.

 

ㅇㄹㄴㅇ

 

1. MYD 파일

 

MySQL의 MyISAM 저장방식은 FRM 파일에 저장된 테이블 스키마 정보를 참조하여 데이터를 레코드 단위로 MYD 파일에 저장한다. MYD 파일의 저장방식은 해당 테이블의 필드가 가변 길이의 데이터 타입을 포함하고 있는지의 여부에 따라 Fixed 포맷과 Dynamic 포맷, 두 가지로 구분된다. MySQL은 가변길이를 위한 데이터 타입으로 VARCHAR, TEXT, BLOB 등의 타입을 제공하고 있으며 테이블이 해당 데이터 타입을 포함하는 경우 Dynamic 포맷으로 분류된다.

 

 

 MYD 파일에 저장되는 레코드는 Fixed 포맷 또는 Dynamic 포맷의 여부에 따라 저장방식에 큰 차이가 있으며 헤더 값 또한 다르다. 따라서 완성도 있는 복구를 위해서는 Fixed 포맷과 Dynamic 포맷에 대한 철저한 분석이 필요하다.

 

1) Fixed 포맷

 

MYD 파일은 테이블이 가변 길이 데이터 타입을 포함하지 않을 경우 데이터를 Fixed 포맷으로 저장한다.

 

 

 

[그림 5]는 Fixed 포맷으로 저장된 MYD 파일로, Fixed 포맷의 MYD 파일은 레코드 단위의 데이터를 순차적으로 저장한다. 또한 데이터 저장 시, 하나의 레코드당 하나의 헤더 값을 부여한다. 헤더 값은 레코드의 속성을 표현하며, 테이블 내부의 필드 개수가 많지 않은 경우 일반적으로 총 1 바이트의 길이다. 필드의 개수가 많아지는 경우 헤더의 길이도 늘어난다.

 

 

헤더 값은 비트 단위로 해당 레코드의 속성을 나타내며, 해당 레코드의 최하위 비트가 1이면 정상 레코드이다. 헤더 값의 최하위 비트가 0인 경우, 해당 레코드는 삭제된 레코드이다. [그림 5]의 경우, 현재 총 3개의 레코드가 해당 테이블에 저장되어 있음을 알 수 있으며 색깔에 따라 레코드가 구분되어 있음을 확인할 수 있다. 첫 번째 레코드와 세 번째 레코드의 헤더 값은 0xF1 (2진수 값: 1111 0001)을 나타내고 있으며 최하위 비트가 1 이기 때문에 정상적으로 저장되어 있는 레코드 임을 알 수 있다.

 

두 번째 레코드는 0x00(2진수 값: 0000 0000)의 헤더 값을 가지고 있으며 최하위 비트가 0 이므로 삭제된 레코드 임을 알 수 있다. 또한 레코드 앞부분의 일정 부분은 0xFF 값의 일부가 덮어 쓰여져 있으므로 원본 데이터가 영구 삭제되었음을 알 수 있다.

 

 

[표 3]은 Fixed 포맷의 헤더 구조를 나타내는 것이다. 레코드 헤더를 통해 해당 레코드의 삭제 여부를 판단할 수 있다. 삭제된 레코드를 복구하기 위해서는 각 레코드의 헤더 값에 어떠한 속성이 부여 되었는지를 파악할 수 있어야 한다.

 

2) Dynamic 포맷

MYD 파일은 테이블이 가변 길이 데이터 타입(BLOB, VARCHAR, TEXT 등)을 포함하는 경우, Dynamic 포맷으로 데이터를 저장한다.

 

 

 

[그림 7]은 Dynamic 포맷으로 저장된 MYD 파일이다. Dynamic 포맷의 MYD 파일은 Fixed 포맷과 마찬가지로 데이터를 레코드 단위로 순차적으로 저장하며 하나의 레코드 당 하나의 헤더 값을 포함한다. 그러나 Dynamic 포맷은 Fixed 포맷과는 달리 가변된 길이에 대한 정보를 헤더에 따로 포함하고 있고 데이터의 얼라이먼트(alignment)를 유지하기 위해 패딩(padding)된 길이 정보도 포함한다. 또한 Dynamic 포맷은 하나의 레코드 길이가 가변 길이와 상관없이 최소 20 바이트를 유지하고 있다. 하나의 레코드 길이가 20 바이트를 채우지 못하는 경우에는 나머지 공간을 Null 값으로 채운다.

 

 

 

 

Fixed 포맷의 파일은 최상위 비트 하나만으로 레코드의 삭제 여부를 판단할 수 있었던 것과 달리 Dynamic 포맷의 파일은 헤더의 첫 번째 바이트에 레코드의 속성을 부여한다. 일반적으로 헤더의 첫 번째 바이트의 값이 0x00 인 경우 해당 레코드는 삭제된 레코드로 표현된다. 헤더의 첫 번째 바이트 값이 0x00 보다 큰 경우에는 정상 레코드로 분류된다. 따라서 Dynamic 포맷의 파일의 삭제된 레코드를 복구하기 위해서는 첫 번째 바이트의 속성 값을 파악하는 것이 중요하다.

 

2. FRM 파일

사용자나 시스템에 의해 생성된 테이블 스키마 정보는 테이블명으로 생성된 FRM 파일에 저장된다. MySQL은 FRM 파일의 테이블 스키마를 통해 데이터를 저장 및 관리할 수 있는 정보를 제공한다.

 

 



 

[그림 8]은 FRM 파일을 통하여 테이블이 어떠한 형태로 구성되어 있는지를 보여준다. FRM 파일을 통하여 해당 테이블의 필드명과 데이터 타입, 할당된 길이 정보 등을 파악할 수 있다. 데이터 타입은 숫자형, 문자형, 날짜형 등 다양한 타입이 존재한다.

 

MYD 파일은 문자형의 가변 길이 데이터 타입이 테이블에 포함되는 경우 Dynamic 포맷으로 데이터를 저장한다. FRM 파일은 InnoDB와 동일한 형태로 테이블 스키마가 저장된다. 즉, InnoDB 역시 MyISAM와 마찬가지로 FRM 파일을 통해 테이블의 정보를 확인한다. 따라서 완성도 높은 레코드 복구를 위해서는 FRM 파일을 통해 필드명과 데이터 타입 등을 확인해야 한다.

 

 

 

MyISAM의 삭제된 레코드 복구

 

MyISAM 저장방식은 레코드가 삭제되는 경우 포맷에 따라 헤더 값의 표기가 다르다. Fixed 포맷은 해당 레코드 헤더의 최하위 비트를 0으로 표기하며, Dynamic 포맷은 헤더의 첫 번째 바이트의 값을 0x00으로 표기한다. 따라서 삭제된 레코드를 복구하는 방법도 포맷에 따라 각기 다르다.

 

Fixed 포맷의 경우, FRM 파일에 저장된 테이블 스키마를 통해 하나의 레코드가 차지하는 길이를 계산하여 레코드 단위로 MYD 파일 내부의 모든 레코드들을 순차적으로 읽으면서 삭제 여부를 파악한다. 삭제된 레코드는 테이블 구조에 맞게 각 필드의 데이터 값을 잘라서 복구한다. Dynamic 포맷의 경우에는 각 레코드마다 가변 길이로 저장된 필드의 길이와 고정 길이로 저장된 필드의 길이를 더하여 하나의 레코드가 차지하는 길이를 계산한다. 그후 Fixed 포맷과 같은 방식으로 순차적으로 읽으면서 복구를 진행할 수 있다.

 

결국 테이블의 구조를 얼만큼 정확하게 파악하느냐에 따라 데이터를 구분이 수월하며, 각 레코드의 헤더 값을 얼마나 정확하게 파악하느냐에 따라 복구할 수 있는 데이터의 양이 많아진다. 그러나 MyISAM 저장방식은 레코드를 삭제한 후 새로운 레코드를 저장하면 이 새로운 레코드가 삭제된 레코드가 존재하는 위치를 덮어쓰게 된다. 데이터 저장의 공간적인 측면에서는 덮어쓰는 방식이 유용하지만 삭제된 레코드의 복구 관점에서는 기존의 삭제된 데이터가 다른 데이터로 덮어 쓰여지면 해당 영역에 대한 데이터 복구는 불가능하다. 데이터베이스에서 레코드의 생성 및 삭제는 빈번히 발생하기 때문에 레코드의 삭제 시점이 오래될수록 레코드의 복구 확률은 낮아진다고 볼 수 있다. 또한 앞서 살펴본 바와 같이 MyISAM 저장방식에서는 레코드 삭제 시 Fixed 포맷은 4 바이트, Dynamic 포맷은 20 바이트 길이만큼 삭제 관련 정보로 덮어쓴다. 따라서 MyISAM 저장방식에서는 데이터를 복구하더라도 일부 데이터의 손상을 막을 수는 없다.



지금까지 3회에 걸쳐 MySQL에서의 삭제된 레코드에 대한 복구 방안에 대하여 알아보았다. 복구 방법을 파악했으니 이제 실제로 복구하는 과정을 살펴볼 차례다. 다음 '월간 안'을 통해 간단한 테스트 데이터와 함께 삭제된 레코드의 실제 복구 과정에 대하여 소개할 예정이다.@










  • AhnLab 로고



  • 클라우드분석팀 남궁재웅 연구원




이 정보에 대한 저작권은 AhnLab에 있으며 무단 사용 및 도용을 금합니다.

단, 개인이 비상업적인 목적으로 일부 내용을 사용하는 것은 허용하고 있으나, 이 경우 반드시 출처가 AhnLab임을 밝혀야 합니다.

기업이 이 정보를 사용할 때에는 반드시 AhnLab 의 허가를 받아야 하며, 허가 없이 정보를 이용할 경우 저작권 침해로 간주되어 법적인 제재를 받을 수 있습니다. 자세한 내용은 컨텐츠 이용약관을 참고하시기 바랍니다.

정보 이용 문의 : contents@ahnlab.com


홈페이지 jQuery 라이브러리에서 CVE-2019-11358 취약점 패치 여부 확인 방법

현재 홈페이지에서 사용 중인 jQuery 라이브러리가 CVE-2019-11358 취약점 패치를 적용했는지 확인하는 방법은 다음과 같습니다. 1. jQuery 버전 확인 홈페이지 소스 코드를 확인하여 jQuery 라이브러리 버전을 직접 확인합니다. 웹 ...