2016년 10월 4일 화요일

아키텍처에서 취약성의 근본 원인 찾아내기

Dr. Carol Woody
CERT 부문 사이버 보안 엔지니어링 팀 관리자
복잡한 네트워크 시스템이나 시스템 오브 시스템의 보안 소프트웨어를 정의, 취득, 개발 및 관리하고 측정, 유지하는 작업 연구

Rick Kazman
하와이 대학 교수
소프트웨어 아키텍처, 소프트웨어 공학 경제학, 소프트웨어 시각화 연구



시스템에 구현된 아키텍처 설계 상의 약점은 다른 종류의 취약성에 비해 시간이 지나가면 갈수록 그 문제를 수정하기가 매우 어렵기 때문에 아키텍처 취약성에 좀 더 관심을 가져야 합니다. 아키텍처 설계 약점을 초기 단계에서 발견하여 수정할 수 있다면, 라이프사이클 기간 동안 더 편하게 시스템을 사용할 수 있습니다.

아키텍처에는 특정 패턴이 있는데 이 패턴은 필요한 요구사항에 따라 설계됩니다. 여러 종류의 아키텍처 패턴이 각각 보안에 어떤 영향을 주는지 이해하는 것이 매우 중요한데, 중요성을 아키텍처 커뮤니티나 설계 및 구현 커뮤니티에서 충분히 인식하지 못하고 있습니다. 단순한 패턴 상의 문제가 아니라 개발자들의 잘못된 인식 때문에 쓸모 있는 패턴이 문제를 일으키게 됩니다. 반드시 사용해야 하는 패턴을 사용하지 않는 개발자도 있고 사용하지 않았으면서 사용했다고 착각하는 개발자도 있습니다. 이런 이유로 아키텍처 패턴이 취약성의 주된 원인이 될 수 있습니다.

라이프사이클 초기의 취약점을 정확히 진단할 수 있는 도구가 없습니다. 초기 단계에는 각 시스템 조각이 어떻게 연결되고 설계되었는지 만 파악할 수 있을 뿐입니다. 설계 초기 단계에는 앞으로 문제가 될 소지가 있는 부분을 정확히 집어낼 수는 없지만, 관심을 두고 지켜봐야 하는 영역을 점차 좁혀 나가면서 문제를 찾아 내야만 노력과 시간을 줄일 수 있습니다.

시스템 진단 도구와 관련하여 Drexel 대학과 공동 연구를 진행하면서 좀 더 정확도가 높은 스트럭쳐를 얻어낼 수 있었습니다. 이 공동 작업으로 아키텍처 분석을 수행하면서 수많은 메소드를 개발했습니다. 잠재적인 리스크를 찾아내는 효과적인 방법을 개발하려 했지만, 발견한 리스크들의 범위가 너무나 넓었습니다. 좀 더 범위를 좁혀서 아키텍처 약점이나 오류를 찾아낼 수 있는 기능을 개발하고자 했습니다.

지난 5-6년 간 개발한 것은 기존 코드 베이스의 리버스 엔지니어링을 가능하게 하는 설계 재현(Design Representation)이었고 관련 도구도 개발했습니다. 아키텍처 정보, 설계 정보를 추출하고, 의미 있는 방식으로 정보를 조작한 다음 조작된 형태의 정보를 분석하여 아키텍처 오류를 찾아내는 것입니다. 과거에는 모든 리버스 엔지니어링이 전적으로 수작업을 통해 이루어졌기 때문에 매우 노동집약적이었지만, 지금은 이 모든 과정이 자동화 되어서 투입되는 비용과 시간을 크게 줄었습니다.

코드를 리버스 엔지니어링하기 위해 현재 Understand라는 상용 리버스 엔지니어링 툴을 주로 사용하고 있습니다. 엔터프라이즈 아키텍트 로부터 정보를 받아 들이면서 파일 간의 의존도를 발견할 수 있었고, A 파일, B 파일 그리고 두 파일 사이의 관계라는 3중 구조를 생각할 수 있게 되었습니다. 이 3중 구조를 바탕으로 거대한 매트릭스를 만들어 냈습니다. 바로 설계 스트럭처 매트릭스(DSM)입니다.

이 설계 스트럭처 매트릭스(DSM)는 분석과 조작이 가능합니다. 개발한 알고리즘을 통해 설계 규칙 계층 알고리즘이라 부르는 클러스터를 만듭니다. 설계 규칙은 시스템의 중요한 인터페이스나 중요한 클래스와 비슷합니다. 예를 들면, 시스템에서 Abstract Factory를 사용하는 경우, 그 abstraction에 의존하는 많은 다른 파일이 생성됩니다. Abstract Factory 인터페이스를 구현하고, 인터페이스에서 상속 받고, 인터페이스에 의존하고, 인터페이스를 사용하고 종합하는 클래스가 생깁니다. 이 abstract factory 재현은 설계 규칙이고 많은 파일이 그 설계 규칙에 의존하게 됩니다. 의존 관계에 따라 아키텍처를 클러스터로 묶어야 하는데, 최상위에는 시스템에서 가장 중요한 설계 규칙인 선두 클래스가 위치합니다.

시스템의 다른 많은 파일들이 의존하는 파일이나 클래스가 바로 선두 클래스인데요. 파일들을 묶어 계층으로 만들면, 최상위 파일에 의존하는 파일들이 하위 계층이 됩니다. 이런 식으로 계층 구조(Hierarchy)가 이루어집니다. 매우 간단한 예로 의존 관계 주기도 찾아낼 수 있습니다. A 파일이 B 파일을 호출하고, B 파일이 C 파일을 호출하고, C 파일이 A 파일을 호출하는 경우는 100% 잘못된 프로그래밍입니다. 그 이유는 세 파일 중 하나를 변경했을 때 일어날 수 있는 파급 효과를 예측할 수 없기 때문입니다. 하나의 파일을 수정했을 때 발생할 미묘한 변화를 알아내는 것도 쉽지 않습니다. 프로그래머는 수백만 줄의 코드를 확인해야 하기 때문에 이러한 미묘한 문제를 쉽게 찾아낼 수 없습니다.

요약 더보기       

댓글 없음 :

댓글 쓰기