[논문 리뷰] 디지털 포렌식 소프트웨어의 처리되지 않은 예외 분석에 있어서 타입 정보 기반 정교화

2024. 2. 2. 14:33논문 리뷰/보안-디지털포렌식

*본 글의 모든 내용, 그림, 표 출처는 논문 원문에 있습니다.

논문 전문 : https://www-dbpia-co-kr.libproxy.dankook.ac.kr/journal/articleDetail?nodeId=NODE11646283

[출처] 이서우, 이동권 and 김세훈. (2023). 디지털 포렌식 소프트웨어의 처리되지 않은 예외 분석에 있어서 타입 정보 기반 정교화. 정보과학회논문지, 50(12), 1071-1082.


* 포렌식 과정의 신뢰성을 높이기 위하여 파이썬으로 작성된 디지털 포렌식 소프트웨어의 처리되지 않은 예외를 사전에 검출하는 기법을 설계

* 디지털 매체마다 수집할 수 있는 디지털 증거들의 속성이 달라 디지털 증거를 확보하는 방법 또한 달라질 수 밖에 없으며 각 디지털 매체에 맞는 디지털 포렌식 소프트웨어 개발이 요구된다.

 디지털 증거를 추출하는데 있어서 진정성이 요구되는데, 이 진정성의 기준은 무결성, 동일성, 신뢰성을 기준으로 한다.

무결성 : 디지털 매체로부터 데이터를 수집하여 법원에 증거로 제출되기까지 데이터의 훼손 및 조작이 없어야 함

동일성 : 디지털 매체로부터 수집된 데이터의 내용과 법원에 제출된 디지털 증거의 내용이 다르지 않아야 함

신뢰성 : 디지털 증거를 획득하고 분석하는 소프트웨어 자체의 신뢰성 및 정확성

-> 데이터 수집 및 분석, 출력 하는 전체적인 과정이 전문적인 기술을 가진 주체에 의해서 이루어져야 한다는 것을 내포한다. 

-> 의도치 않은 오류로 놓치게 되는 디지털 증거가 발생하면 안 된다.

디지털 포렌식 소프트웨어들의 부분은

1) 디지털 매체에서 데이터들을 추출하는 부분

2) 추출된 데이터를 DB등의 데이터 저장 매체에 저장하는 부분

3) 저장된 데이터들을 분석하면서 디지털 증거들을 확보하는 부분

으로 나뉜다. 

1) -> NULL 값이나 쓰레기값이 수집되어 디지털 증거 오염 가능성 존재

2) -> 데이터 매체와의 연결에 오류가 생겨 데이터 일부 유실 가능

3) -> 예외가 정확히 처리되지 않아 데이터의 누락 및 훼손이 발생 가능


집합 제약식 기반 분석

처리 되지 않은 예외와 분석

처리되지 않은 예외 : 프로그램 내에서 어떠한 오류로 예외가 발생하여 프로그램이 비정상 종료가 되는 상황을 의미

DB에 저장된 데이터를 출력하는 파이썬 예시 코드

-name열에 있는 데이터들의 수가 6개보다 작으면 line7 에서 배열이 할당된 범위에서 첨자범위 오류가 생길 수 있음.

-line 1에서 DB와 연결을 시도할 때 연결에 실패하면 pymysql.err.OperationalError가 발생 가능

try문으로 예외 처리를 일부 추가한 코드

-line 1에서 try와 line 9와 10에서 except문을 추가하여 DB와의 연결에 실패할 경우에 대한 예외 처리를 정의 -> 이 코드에서는 DB와의 연결에 실패하여도 프로그램이 비정상적으로 종료되지 않음

n번째 줄, try문, 전체 프로그램에서 발생 가능한 예외들의 집합을 L(n)(아래첨자를 여기선 괄호로 대신 표현하겠다.), L(try), L(prog)라고 나타낼 예정이다. 

L(1) : {ZeroDivisionError}

L(7) : {NameError}

=> 발생 가능한 예외들 사이의 포함관계를 기반으로 제약식으로 나타내면 try문(3-7번째 줄)에서 발생 가능한 예외들의 집합을 구하는 제약식은 

L(try) = L(4) - {ZeroDivisionError} ∪ L(6) ∪ L(7)

 전체 프로그램에서의 예외 집합은 

L(prog) = L(1)∪L(2)∪L(try)

결국 {NameError}를 산출한다.

 

집합 제약식 기반 분석

-본 연구에선 파이썬을 사용하였고, 파이썬은 변수에 값이 할당될 때 변수 타입이 결정된다는 특성을 가지고 있으나, 더 정확한 예외 분석을 위해 선언 기능을 가진 let문을 IR에 추가함

- 각 프로그램의 지점마다 발생 가능한 예외와 연관된 제약식의 생성 규칙을 정의

- 본 연구에서 대상으로 하는 분석 예외로 집합 제약식 생성 규칙에 나타나는 예외는 다음과 같다.

E(name) : 잘못된 변수 이름 예외

E(attribute) : 잘못된 속성 이름 예외

E(index) : 잘못된 인덱스 예외

E(key) : 잘못된 키 예외

E(zeroDiv) : 0으로 나누기 예외

- 분석 대상에서 타입 안전성을 위해 TypeError가 발생하지 않는다고 가정

- 제약식 생성 규칙을 표현하기 위해 아래와 같이 기호를 정의

X(e) : 식 e에서 발생할 수 있는 예외들의 집합

X(s) : 문장 s에서 발생할 수 있는 예외들의 집합

C : 제약식 집합

E(c) : 예외 클래스 c

식에 대한 기본적인 집합 제약식 생성 규칙

1) 정수, 실수, 문자열, 불리안 등의 상수식 자체에서는 예외가 발생하지 않아 상수에서 생성되는 제약식들의 집합은 공집합

2) 변수나 함수, 객체에 바인딩된 식별자 식에서는 부적절한 식별자를 사용하면 정의되지 않은 변수 사용 오류가 발생 가능

3) 객체의 속성값에 접근 시 속성없는 오류 및 e(1)에서 예외가 발생할 수 있음

4) 속성값에 접근할 때 e(1)에서 생성되는 제약조건 집합인 C(1) 의 원소들은 모두 속성값의 제약식 집합에 해당

 

식에서 발생 가능한 예외들의 집합을 구하는 제약식들의 생성 규칙

expr:C ) 식 expr에서 발생 가능한 예외들의 집합들을 구하는 제약식들의 집합은 C라는 의미

라이브러리 함수 = list() 등 파이썬 내장 및 외부 라이브러리 함수 의미

라이브러리 함수 호출에서는 예외가 발생하지 않는다고 가정

예외 클래스를 추가적으로 정의 (여기서는 Except(c)(e)이 해당하고 식별자가 가리키는 값이 예외 클래스인 경우)

문장에서 발생 가능한 예외들의 집합을 구하는 제약식들의 생성 규칙

stmt:C ) 문장 stmt에서 발생 가능한 예외들의 집합들을 구하는 제약식들의 집합은 C

*실행 흐름 제어문인 break, pass, continue에서는 예외가 발생하지 않음

각각의 구문 = S(i)

제약조건 집합 = C(i)

객체의 프로그램식 = e(i)

*a의 값이 0 -> line 5에서 0으로 나누기 오류가 난다고 해도 line 4에서 예외가 발생하지 않고 line 5에서 처리되지 않은 오류가 발생 (pass제어문 때문)

*식만으로 구성된 식 실행문에서는 e(1)을 실행하는 구문에서는 해당 식에서 발생할 수 있는 예외가 그대로 발생 가능->이때 연관되는 제약식의 집합은 C(1)

*구문 연결문(sequence statement)에서는 연결되는 S(1), S(2)에서 발생할 수 있는 예외가 발생 가능

=> 이 실행문에서 집합 제약식들의 집합은 S(1), S(2)에서 생성하는 제약 원소들을 포함하여 C(1) ∪ C(2)가 됨.

기본 문장 ) 할당문에서는 변수 e(1)와 식 e(2)에서 발생할 수 있는 예외가 모두 포함하기에 할당문에서의 제약식의 집합은 위와 같이 C(1) ∪ C(2)가 됨.

if문 )

조건식 e(1)과 조건이 만족할 때 실행되어야 할 S(1) 그리고 만족하지 않을 때 실행되어야 할 S(2)에서 발생할 수 있는 예외 발생 가능

제약식들의 집합은 e(1)과 S(1), S(2)에서 생성되는 C(1), C(2), C(3)의 원소들로 구성

함수 정의문 )

함수 본문의 모든 구문 S(1)에서 발생할 수 있는 예외 발생 가능

제약식들의 집합은 S(1)에서 생성되는 C(1)을 기본적으로 포함하며, return문에서는 반환되는 e(1)에 관련된 예외 발생 가능

try문 )

try 블록 안의 실행문 S(1)에서 발생가능한 E(c)가 포함됨

--S(1)에서 발생할 수 있지만 처리되지 않은 예외

--예외를 처리할 때 실행하는 S(2)

--예외 처리 후에 실행되는 S(3), S(4) 예외 상황 포괄

raise 문) 

또다른 예외 E(c)가 발생 가능

예외 클래스에 인자로 e(1)가 있을 때에는 E(c)에 추가적으로 e(1)에 연관된 예외도 발생할 수 있음

제약식들의 집합에 추가적으로 e(1)에서 생성되는 C(1)의 원소들을 포함

분석 결과

파이썬 정적 분석기 활용방안

허위 경보 축소

-집합 제약식 생성 규칙에서는 가능한 모든 오류들이 구분 없이 모두 발생한다고 판단했기 때문에 다수의 허위 경보 발생

-Pyright로 미리 분석 대상 프로그램에서 각각의 식, 식의 타입, 식의 위치를 포함하는 테이블을 만들고 이 테이블을 참조하면서 집합 제약식을 생성할 때 타입이 정교화 됨

문제 ) 배열이나 딕셔너리에 인덱스나 키로 접근하면 첨자범위 오류와 키가 없는 오류를 모두 발생한다고 판단

-> 해결책) 인덱스나 키로 접근하는 객체의 타입 정보를 Pyright를 이용하여 구하면 해당 객체가 리스트인 경우에는 키가 없는 오류를, 딕셔너리인 경우에는 첨자 범위 오류를 무시 가능

=> 집합 제약식을 생성하기 전에 a에 대한 타입을 Pyright를 이용하여 미리 찾고 집합 제약식 생성 시점에서 이 타입에 연관된 오류들만 발생시킴

문제 ) 정의되지 않은 변수 사용 오류와 속성없는 오류의 경우

-> 해결책 ) Pyright에서는 어떤 변수의 타입을 판단할 수 있으면 해당 타입이나 Any를 출력하고 그외의 경우에는 Unknown을 출력

=>타입을 알 수 있는 변수의 경우에는 정의되지 않은 변수 사용 오류를 발생시키지 않음

=>집합 제약식 기반 분석만을 이용해서는 어떤 클래스에 어떤 속성이 정의되어 있는지 알기 어렵기 때문에 집합 제약식 생성 규칙에서는 속성값에 접근하는 경우 속성없는 오류의 가능성을 항상 열어둠.

반복된 불필요한 경보 압축

허위 경보들 사이에 종속적인 관계가 있을 때 대표적인 경보만을 출력하면 정적 분석기 결과의 가독성을 높일 수 있음

프로그램의 지점들의 종속관계와 예외들의 집합 사이의 포함 관계를 구조화하면 다음과 같다.

-중북하여 발생하는 예외들의 집합을 제거하기 위해서 프로그램의 나무 구조에서 전위 순회하면서 중복되는 예외를 제거

전위 순회 : 루트 노드를 먼저 방문한 후 이 노드의 왼쪽 서브트리를 방문하고 더 이상 방문할 왼쪽 서브트리가 없으면 오른쪽 서브트리 방문


실험 결과 및 분석

그림 3의 예시 코드에 대해 허위 경보 축소 후의 분석 결과

* 그림 8에 비해 

[41:53] can raise {NameError, IndexError}
[41:46] can raise {IndexError}
[35:53] can raise {NameError, IndexError}
-> KeyError 허위 경보 삭제

대상 디지털 포렌식 소프트웨어의 분석용 단위 모듈 9개와 분석용 단위 모듈에 라이브러리 코드를 추가한 벤치마크 1개, 데스팅용 일반 파이썬 코드 2개를 허위 경보를 축소하기 전 후로 분석기로 분석한 결과
테스트 코드의 구성 예

분석용 단위 모듈의 경우 외부 데이터베이스나 모듈들과 연동하는 부분이 많기 때문에 허위 경보 여부를 판단하기 어려움. 따라서 처리되지 않은 예외가 추가된 파이썬 코드 벤치마크 2개를 추가함.

파이썬에서 외부 라이브러리에서와 같이 변수의 값을 문자열에 나타내도록 하기 위한 방법들 중에서 f-string을 사용하면 정확도를 높일 수 있음. 또한 코드에서 재귀함수 사용을 지양하고 반복문을 사용해야함. (재귀함수는 변수들과 반환값이 저장되면서 스택 오버플로우(overflow)를 야기할 수 있음)

결론

한계점)

1. 파이썬의 경우 변수의 타입이 동적으로 결정되고 실제 클래스와는 무관하게 멤버 함수로만 타입을 판단하는 덕 타이핑 등으로 변수나 함수 인자의 타입을 정적으로 알기에는 한계를 가짐.

해결방안)

1. 클래스에 정의되어 있는 멤버 변수들을 사전 분석을 통해 미리 파악하고 이 정보를 활용하여 허위경보를 제거 가능