보안 연구와 프로그램 자동 분석 기술

보안 연구와 프로그램 자동 분석 기술

개요

암호학과 같은 수학적 보안 분야와 달리 소프트웨어 보안 분야는 전통적인 컴퓨터과학 분야에 비해 그 역사가 짧은 편입니다. 초기 개척기 동안 데이터베이스, 네트워크, 운영체제, 프로그래밍 언어, 소프트웨어 공학 등 많은 다른 분야의 연구자들이 보안 연구에 유입되었고, 기존의 다양한 기술들이 소프트웨어 보안이라는 맥락 안에서 영향을 주고받으며 융합되었습니다. 특히, 프로그래밍 언어 분야에서 유래한 소프트웨어 자동분석 기술은 악성코드 분석 및 탐지, 보안취약점 탐지, 지적재산권 침해 판별 등의 분야에 많은 영향을 주었는데, 오늘은 이러한 자동분석 기술 중 가장 기본이 되는 기술이라고 할 수 있는 프로그램 슬라이싱(Program Slicing)과 테인트 분석(Taint Analysis)에 관해 알아보겠습니다.
이해를 돕기 위해, Wikipedia의 예시를 조금 변형한 아래 예시를 활용하겠습니다.

01: int i = 1 ;
02: int sum = 0 ;
03: int product = 1 ;
04: int w = 7 ;
05: while(i ⁢ N) {
06:     sum = sum + i + w ;
07:     product = product * i ;
08:     i++ ;
09: }
10: write(sum) ;
11: write(product) ;

그림 1. 앞으로 활용할 예제코드 (원본 출처: Wikipedia)

프로그램 슬라이싱(Program Slicing)

프로그램 슬라이싱은 유비쿼터스 컴퓨팅(Ubiquitous Computing)의 개척자로도 유명한 Mark Weiser가 1979년 박사학위 논문에서 처음 제안한 개념입니다. [Weiser 79] 프로그램 슬라이싱은 어떤 변수를 기준으로 그 변수의 영향 아래 있거나 그 변수에 영향을 주는 코드를 모두 찾아내는 기술로, 백워드 슬라이싱(Backward Slicing)과 포워드 슬라이싱(Forward Slicing) 기술이 대표적입니다.
백워드 슬라이싱은 프로그램의 어떤 라인에서 사용되는 특정한 변수에 대해 해당 변수에 영향을 주는 모든 코드를 찾아내는 기술로, 실행 순서의 역방향으로 코드를 잘라낸다는 의미에서 백워드 슬라이싱이라는 이름을 갖게 되었습니다.
아래는 그림 1의 라인 9에서 사용된 sum을 기준으로 백워드 슬라이싱을 적용한 결과입니다. 라인 10의 변수 sum에 기여하지 않는 라인 3과 라인 7, 라인 11이 제거됨을 알 수 있습니다. 어떤 변수에 영향을 주는 모든 코드를 찾아낸다는 점에서, 백워드 슬라이싱은 디버깅에 유용하게 사용될 수 있습니다. 예를 들어, 라인 10에서 출력되는 sum의 값이 예상과 다른 비정상 값이었다고 한다면, 우리는 라인 10의 sum에 백워드 슬라이싱을 적용함으로써 비정상 값의 원인이 될 수 있는 모든 라인을 기계적으로 추출할 수 있습니다. 또한, 슬라이싱은 코드 사이의 의존성 분석을 용이하게 하여, 컴파일러에 의한 병렬화 및 최적화 등에 활용되기도 합니다.

01: int i = 1 ;
02: int sum = 0 ;
04: int w = 7 ;
05: while(i < N) {
06:     sum = sum + i + w ;
08:     i++ ;
09: }
10: write(sum) ;

그림 2. 그림 1의 변수 sum(라인 10)에 대해 백워드 슬라이싱을 적용한 결과

백워드 슬라이싱과 유사한 기술로, 특정 변수로부터 영향을 받는 모든 프로그램 라인을 찾아내는 포워드 슬라이싱이 있습니다. 이 기술은 지정된 라인 이후의 코드를 찾는다는 의미에서 포워드 슬라이싱이라는 이름을 갖게 되었습니다. 아래는 그림 1의 라인 2에서 사용된 sum을 기준으로 포워드 슬라이싱을 적용한 결과입니다. 변수 sum의 값이 변경되었을 때 전혀 영향을 받지 않는 라인 1, 라인 3~5, 라인 7~9, 라인 11이 제거됨을 알 수 있습니다.

02: int sum = 0 ;
06: sum = sum + i + w ;
10: write(sum) ;

그림 3. 그림 1의 변수 sum(라인 2)에 대해 포워드 슬라이싱을 적용한 결과

테인트 분석(Taint Analysis)

테인트 분석은 포워드 슬라이싱과 매우 유사한 기술로, 보안 연구에 특히 잘 사용됩니다. 테인트 분석은 데이터의 흐름을 추적하는 기술로, 다음과 같은 원리로 동작합니다. 먼저, 테인트 소스(Taint Source)로 지정된 변수에 꼬리표를 붙인 뒤, 프로그램의 실행 경로(Execution Path)를 따라 그 값이 전파될 때마다 꼬리표도 함께 전파합니다. 꼬리표가 붙은 값이 최종적으로 테인트 싱크(Taint Sink)로 지정된 코드에 도달할 경우, 우리는 테인트 소스로부터 테인트 싱크 사이에 데이터 흐름이 존재한다고 합니다. 아래는 그림 1의 라인 1에서 사용된 i를 테인트 소스로 지정했을 때, 테인트된 데이터가 흘러간 경로만을 표시한 결과입니다. 굵은 글씨로 표시된 변수들이 테인트 되는 변수들입니다.

01: int i = 1 ;
06:    sum = sum + i + w ;
07:    product = product * i ;
08:    i++ ;
10: write(sum) ;
11: write(product) ;

그림 4. 그림 1의 변수 i(라인 1)에 대해 테인트 분석을 실시한 결과

보안 연구에 있어서, 테인트 분석은 테인트 소스와 테인트 싱크의 관계를 어떻게 디자인하느냐에 따라 매우 다양한 용도로 사용될 수 있습니다.
첫째로, 인젝션 공격(Injection Attack)에 취약한 코드를 탐지하는데 사용되는 대표적인 기술입니다. [Huang 04] 인젝션 공격은 SQL Injection, Code Injection, Script Injection, Command Injection, CRLF Injection, Cross-Site Scripting 등 보안 위협의 큰 비중을 차지하는 공격으로, 신뢰되지 않은, 즉, 공격자가 컨트롤할 수 있는 데이터가 민감한 함수, 즉, 보안 침해를 일으킬 가능성이 있는 함수에 유입되면 발생할 수 있습니다. 인젝션 공격은 HTTP request와 같이 외부로부터 유입된 데이터를 테인트 소스로 지정하고, SQL 구문을 실행하는 함수나 OS 명령을 실행하는 함수처럼 인젝션 공격이 발생할 수 있는 지점들을 테인트 싱크로 지정하면 효과적으로 탐지할 수 있습니다.
아래는 SQL Injection에 취약한 코드를 정적 테인트 분석을 통해 탐지하는 예시로, 공격자로부터 전달된 HTTP request에서 추출한 tableName과 name의 값을 받아서 SQL 쿼리를 생성하고 있기 때문에, name의 값으로 name' OR 'a'='a 를 입력하면 조작된 쿼리문 전달이 가능한 형태의 프로그램입니다. getParameter 메소드를 테인트 소스로 지정하고 prepareStatement 메소드를 테인트 싱크로 지정하면, 굵은 글씨로 표시된 변수들이 테인트되면서 라인 4의 테인트 싱크에 테인트된 데이터, 즉, 신뢰할 수 없는 데이터가 유입됨을 알 수 있습니다.

01: String tableName = request.getParameter("tableName"); ← 테인트 소스
02: String name = request.getParameter("name"); ← 테인트 소스
03: String query = "select * from " + tableName + " where name = '" + name + "'";
04: stmt = con.prepareStatement(query); ← 테인트 싱크
05: rs = stmt.executeQuery();

그림 5. SQL Injection 취약점 예시 (원본 출처: 행정안전부 “홈페이지 SW(웹) 개발보안 가이드”)

둘째로, 테인트 분석은 데이터 유출 가능성을 탐지하는 데 유용하게 사용됩니다. [Enck 14] 패스워드 파일 등의 민감한 정보를 테인트 소스로 지정하고, send나 write처럼 데이터를 외부로 전송하는데 사용될 수 있는 함수들을 테인트 싱크로 지정하여 테인트 분석을 한 후, 테인트 싱크에 테인트된 정보가 유입될 가능성이 탐지될 경우, 민감한 정보를 유출할 수 있는 코드로 간주할 수 있습니다. 이 기술을 응용하여 휴대전화 등에 동적으로 적용할 경우, IMEI나 위치 정보 등 민감한 정보가 네트워크로 전송되는 이벤트를 실시간으로 탐지하는 목적으로 활용될 수도 있습니다.
셋째로, 프로그램의 의미상 연관된 코드만을 무리짓고자 할 때 사용할 수 있습니다. 연관된 코드를 그루핑하는 기술은 프로그램 특징화(program characterization), 즉, 악성코드의 행위 시그니처를 생성하거나, 코드 도용 판별을 위한 의미론적 특징점을 찾는 등의 분야에서 노이즈를 제거하는 용도로 사용될 수 있습니다. [Newsome 05, Jhi 11, Zhang 12]

맺음말

이번 글에서는 보안 연구에 자주 활용되는 프로그램 자동 분석 기술 중 가장 기본이라고 할 수 있는 프로그램 슬라이싱과 테인트 분석에 관해 살펴보았습니다. 다음에는 좀 더 복잡한 분석에 활용할 수 있는 기술들을 살펴보도록 하겠습니다.



References  :
[1] [Weiser 79] Weiser, Mark. "Program slices: formal, psychological, and practical investigations of an automatic program abstraction method." PhD thesis, University of Michigan, Ann Arbor, 1979.
[2] [Huang 04] Huang, Yao-Wen, et al. "Securing web application code by static analysis and runtime protection." Proceedings of the 13th international conference on World Wide Web. ACM, 2004.
[3] [Enck 14] Enck, William, et al. "TaintDroid: an information-flow tracking system for realtime privacy monitoring on smartphones." ACM Transactions on Computer Systems (TOCS) 32.2 (2014): 5.
[4] [Newsome 05] Newsome, James, and Dawn Song. "Dynamic taint analysis: Automatic detection, analysis, and signature generation of exploit attacks on commodity software." In In Proceedings of the 12th Network and Distributed Systems Security Symposium. 2005.
[5] [Jhi 11] Jhi, Yoon-Chan, et al. "Value-based program characterization and its application to software plagiarism detection." Proceedings of the 33rd International Conference on Software Engineering. ACM, 2011.
[6] [Zhang 12] Zhang, Fangfang, et al. "A first step towards algorithm plagiarism detection." Proceedings of the 2012 International Symposium on Software Testing and Analysis. ACM, 2012.



▶   해당 콘텐츠는 저작권법에 의하여 보호받는 저작물로 기고자에 저작권이 있습니다.
▶   해당 콘텐츠는 사전 동의없이 2차 가공 및 영리적인 이용을 금하고 있습니다.



공유하기
지윤찬
지윤찬 보안 전문가

SW Security Lab Leader, Samsung SDS
Samsung SDS Certified Professional

Pennsylvania State University에서 박사학위를 취득하였으며, 현재 삼성SDS의 SW보안Lab을 맡고 있습니다. SW 자동분석, 악성코드 방어, 품질보안 강화 등의 분야에 관심이 있습니다.