블로그 이미지
자유로운설탕

calendar

1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

Notice

2017. 12. 2. 22:35 보안

  파이썬에 대한 글을 마치고, 이제 두 번째로 보안에 대해서 이야기를 한번 해보려고 한다. 개인적으로 생각했을때 아직 잘 모르는 영역들도 많고, 관심은 있지만 공부를 안해서 발전이 거의 없는 영역들도 많다고 생각한다. 

 

  이 글에서는 보안을 처음 공부하거나, 공부는 하고 있지만 너무 범위가 넓고 어렵게 느껴지거나, 개발이나 시스템, 테스팅 같은 연관이 있는 일을 하는 사람들에게 보안이 생각보다 그렇게 어려운 분야는 아니며, 개발이나 테스팅, 시스템, 네트워크 쪽의 지식처럼 해당 분야의 패턴을 익혀두면 여러 다른 분야에서도 유용하게 쓸 수 있다는 것을 얘기해 보려 한다. 나아가 얼마나 잘 될지는 모르겠지만 보안의 어떤 부분이 보안을 어렵게 생각하게 만들게 되는지도 개인적인 경험에 비추어 설명해보고 싶다. 이전 파이썬 글과 마찬가지로 하나의 접근 방식이라는 관점으로 비판적으로 받아들이기를 바라며 역시 재밌는 시간이 되길 바라면서 글을 시작하려 한다.

 

 

[목차]

1. 보안을 바라보는 방법

2. 보안에서의 코드 읽기

3. 인젝션(Injection) 살펴보기

4. 암복호화

5. 클라이언트 코드

6. 업로드, 다운로드

7. 스크립트 문제

8. API

9. 설정, 패치, 하드닝

10. 설계문제

11. 스캐너 vs 수동 테스트

12. 자동화 잡

13. 리버싱과 포렌식

14. 모니터링 문제

15. 악성코드

16. 보안과 데이터


 

1. 들어가면서

  보안 공부를 어떻게 해야하느냐를 알고 싶어서 검색엔진을 찾아보면 해야될 일이 엄청 많아 보인다. C++와 같은 프로그래밍 언어부터 시작해서, 웹 및 시스템 프로그래밍, 객체지향 개념, 운영체제, 웹서버, 네트워크 장치들, 프로토콜, 암호학, 리버싱, 포렌식, 악성코드 등에 대해 하나하나 이해해야 하고, 나아가 오픈소스, 모의해킹, 보안 관련 툴 들을 이해해야 한다고 한다. 

 

  사실 위의 요소 중 하나로만 범위를 제한하게 되더라도 엄청 많은 하위 카테고리로 확장되게 된다. 예를 들면 웹은 CGI(Common Gateway Interface) 같은 초창기 서비스 구조로부터 ASP, PHP 언어 같은 스크립트 베이스의 언어, JAVA, NET 같은 좀 더 포말한 프로그래밍 형태의 웹으로 확장되고, 여러 타입의 서비스와 API 등도 포함되게 된다.

 

  네트워크도 이름도 낯선 OSI 7 계층 구조부터, TCP/IP, 방화벽, IPS, 스위치, 라우터 등의 여러 이슈들로 나누어지고, 그런 부분도 또 관련 장비의 밴더나 각 진화된 세대에 따라서 서로 다른 영역으로 갈라질 수 있다. 나머지 필수 기술 항목들도 역시 마찬가지로 많은 갈림길이 있다. 웹 서버들도 아파치, IIS, 톰캣 등 조금씩 특성이 다른 여러가지의 웹 서버들이 있고, 각 서버는 각각의 버전마다 설정이나 지원 기능 등에 따라 특성이 또 조금은 다르다고 볼 수 있으며, 다른 웹 언어들과도 연결된다.

 

  게다가 현대의 빠른 기술의 변화에 맞춰서, 빅데이터나 머신러닝등의 새롭게 보안이 필요해지는 영역과 언어들이 계속 쏟아져나오고 있다. 또한 좀 더 넓게 현실적으로 보면 IT 기술의 범위를 벗어나서 물리적인 영역이나, 작업 및 관리 프로세스, 심리적인 부분도 관련 되게 된다.

 

 

  개인적인 관점에서 또 하나 보안을 어려운 분야로 생각하게 하는 부분은, 보안 측면을 바라보는 시각이 매력적인 모의해킹이라는 공격적 측면과, 자격증 획득이라는 측면에 많이 중심이 치우쳐 있기 때문인 것 같다.

 

  보안 지식 전체가 몸을 건강하게 해주는 운동들의 구성이라면, 모의해킹은 프로격투기 선수의 실전 스파링 훈련과 같다고 본다. 모의해킹은 시스템을 구성하는 모든 제반 기술들에 대한 균형있는 검증을 통해서, 안전한 디자인이 이루어졌나를 확인하는 활동이라고 생각한다. 그래서 모의해킹 기법 관련 책에서 얘기하는 많은 백과사전 방식의 기법을 익혀서 대상에 대해서 테스트를 하고, 취약점을 찾거나 찾지 못한 결과에 따라 대상이 불안하거나, 안전하다고 판단하는 것은, 사실 그렇게 많은 의미는 없어 보인다. 중요한 것은 그러한 기법들을 보안 세계 쪽에서 정리하고 권장하게 된 배경을 이해하고, 점검 하려는 대상에 대해 기술적으로 정확하게 이해하여 적절한 기법을 적용하여 검증하는 부분인 것 같다.

 

  자격증 또한 해당 분야를 마스터(사실 사람 자체가 불완전 하며, 모든 분야에서 한 개인은 역사를 스쳐가는 디딤돌 같은 역활인지라 어떤 분야를 마스터했다는 말은 신기루 같은 것 같기도 하지만...)한 전문가를 보면서 행동을 따라하는 것과 비슷하다고 본다. 자격증에 나오는 지식은 현실의 많은 보안 지식을 모아서, 전문가들이 정리하고 체계화된 지식에 불과하다고 본다. 해당 지식 체계가 보안의 전체적인 모습을 정리하고, 체계적으로 접근을 하게 해주는 것은 부정할 수 없는 사실이지만, 해당 지식안에는 현실을 객관화한 지식은 있지만, 현실 자체는 없는 경우가 많다.

 

   지식 자체는 손가락이고, 그 손가락이 가르키는 곳을 봐야지 의미가 있지 손가락 자체를 아무리 외어도 의미는 없다고 본다(자격증 책 본문의 시험용 암기 내용보다는, 각 챕터의 뒤에 있는 그 내용이 나오게 된 근거인 참고 서적이나 관련 링크들에 대한 포괄적인 이해가 사실 더 중요한것 같아 보이지만, 시험공부를 위해서 기본적으로 외우거나 이해해야 할 내용이 엄청 많기 때문에 그런 부분까지 차분히 읽을 분위기는 되지 않는다). 훌륭한 전문가의 행동을 따라하는 것보다, 그 행동을 일으키게 한 마음의 흐름을 이해해야지만, 실제 해당 전문가의 노하우의 그림자라도 익힐수 있게 되지 않을까 싶다.

 

 

 

2. 보안이 어렵게 느껴지는 이유

  우리가 어떤 것을 배우려면, 우리가 어떤 것을 배우고 싶어 하는지를 우선 명확히 알아야 하는 아이러니가 있다(파이썬 글 21교시의 5 orders of ignorance 를 참고). 보안이란 분야가 어떤 것 인지에 대해서 많은 사람들이 서로 다른 정의를 가지고 접근하겠지만, 개인적인 관점에서 가장 주요한 부분은 데이터의 흐름을 따라가는 것이라고 본다. 데이터의 관점에서 한정해 보면 개발은 데이터가 설계된 길로 가게하는 것이고, 테스팅은 데이터가 주어진 길로 제대로 가는지를 증명하는 일이며, 보안은 데이터가 주어진 길에서 납치나 회유되지 않는지 살펴보는 일이라고 볼수 있다고 생각한다. 

 

  또한 보안은 일반적인 프로그래밍이나 테스팅 보다는 우리의 일상생활이나 시스템 바깥의 물리적, 프로세스적 환경의 관리까지 생각하기 때문에 조금 더 범위가 넓게 된다. 여담이지만 점점 개인정보보호 분야의 영역과 보안의 영역이 많이 겹치게 되고 있는데, 개인정보는 (개인의) 중요한 데이터를 보호하는 분야이고, 보안은 중요한 데이터를 보호 하는 분야이기 때문에, 어쩔 수 없이 기술적인 영역에 대해서 관심사는 살짝 다르지만 상당 부분 겹치게 되어있다고 본다.

 

 

  그럼 데이터의 흐름을 따라가려면 어떻게 해야 할까? 데이터가 보여지거나, 지나가거나, 처리되거나, 저장되는 모든 영역을 잘 이해해야 한다. 컴퓨터 안의 CPU, 레지스터부터, 메모리, 디스크 내의 바이너리 형태의 데이터, 운영체제, 프로세스, 프레임워크, 응용 프로그램, 웹서버, 네트워크(프로토콜), 서버, 관리프로그램, 사용자 프로그램, 사용자, 외부 장치, 업무 프로세스 또는 은행의 비밀번호를 기억하고 있는 고객들에 이르기 까지 데이터가 현실의 물리적 형태, 0과 1의 형태의 바이너리 형태로 존재하거나, 레지스트 값, 변수, 메모리 값, 프로그램 내의 변수, 설정 값, 입력 값, 전송 값 등 모든 머무는 영역에 대해서 올바르게 이해해야 한다. 결론적으로 얘기하면 앞의 많은 기술의 요소 부분을 이해해야만 보안을 잘 할 수 있는 것이 아니고, 꺼꾸로 보안을 잘하기 위해서, 그러기 위해서 데이터를 이해하기 위해서, 데이터의 흐름을 이해하고 적절히 보호하기 위하여 해당 기술들을 익혀야 한다고 본다. 

 

  이러한 끝이 잘 보이지 않는 넓은 범위의 기술 범위들은, 앞의 파이썬 글에서 얘기했던 프로그래밍의 배경지식과 비슷하다고 본다. 보안은 보안의 원리 자체가 어려운게 아니라(뭐 쉽다는 의미는 아니고, 배경지식을 잘 안다면 생각보다는... 이라는 말이지만... 반대로 얘기하면 배경지식을 모르면 실제보다 과도하게 어려워 보인다) 이러한 배경지식의 균형있는 습득이 어려우며, 프로그래밍에서의 게임 프로그래밍의 위치와 비슷하게, IT계의 종합 예술 영역 같은 성격을 띄고 있다고 생각한다. 그래서 보안은 데이터를 제대로 보고 흐름을 따라가기 위해서 많은 배경 지식이 필요하게 된다. 프로그래밍도 그러한 배경 지식 중 하나이고, 앞서 얘기한 많은 분야들도 그래서 필요하게 된다. 그리고 모든 분야가 마찬가지겠지만 모르는 분야나, 새로운 기술을 계속 따라가야 하는 어려움도 있게 된다.

 

 

  예를 들어 보안을 모의해킹 같은 공격의 관점으로 봐서, 아주 뛰어난 도둑이 있다고 가정을 해보자. 해당 도둑은 사회공학적 기법을 이용해 사람들을 속여 정보를 얻거나, 원하는 행동을 하게 하는 것도 능숙하고, 담을 타거나 빠르게 이동하기 위한 신체능력도 뛰어나며, 일반 자물쇠나, 생체인식등과 같은 현존하는 모든 자물쇠의 이해에 능통한 상태로 그러한 기법들을 이용하여 원하는 목표를 놓친적이 없다고 하자.

 

  그런데 어느날 열쇠의 주인이 아니면 절대 풀수 없다는 양자역학을 이용한 자물쇠(무슨 자물쇠인지는 모르지만 그런 어려운게 생겼다고 해보자)가 발명되면서 주요 보물들이 해당 자물쇠에 의해서 보호되게 되었다. 이제 도둑이 계속 목표를 달성하려면 어떻게 해야될까? 해당 양자역학적 자물쇠를 이해하여 속일 수 있는 방법을 찾는 수 밖에 없다(미션 임파서블 영화를 생각하면 된다. 물론 영화에서처럼 어떤 자물쇠로 잠겼는 지에 상관없이 사람이나 환경을 이용하여 사회공학적 기법으로 푸는 방법도 있긴 하겠지만 말이다. 기술은 기술을 운영하는 사람의 스마트함에 비례해 효과가 있으니 말이다).

 

  또는 반대로 여러분이 자물쇠가 얼마나 안전한지 체크를 해주는 보안 전문가고, 해당 양자역학적 자물쇠를 사용하는 사람으로부터 해당 자물쇠가 얼마나 안전한지 검증을 해달라고 요청을 받았다고 해보자. 새로운 자물쇠의 안전을 검증하려면 해당 자물쇠의 원리를 우선 이해해야만 한다. 물론 해당 자물쇠를 이해 못한다고 기존의 뛰어난 도둑(악의적인 해커)이 뛰어나지 않은 것은 아니고, 뛰어난 보안 전문가가 전문가가 아니게 되는 것은 아니다. 하지만 해당 분야에서 전문가 명성을 계속 유지하기 위해서는 새로운 기술을 이해하여, 자신이 기존 체계로 부터 이해하고 있는 패턴을 적용하여 공략점을 찾거나, 외부의 공격에 안전한 설계인가를 증명하지 않으면 안된다.

 

 

  다른 예로 당신이 모든 사기 유형을 마스터한 유명한 사기꾼이고, 새로운 매력적인 파생 상품이 나와서 해당 부분을 이용해서 사기를 치고 싶을 때도, 마찬가지로 대상에 대한 이해가 필요하게 될것 이다(사기는 상대방에 대한 이해와 공감을 바탕으로 한, 9개의 진실과 1개의 거짓으로 이루어진 행위라고 생각한다).

 

  현실의 보안 영역으로 내려오면, 윈도우 보안의 전문가인 당신이 리눅스, IOS, 안드로이드의 보안에 대해 체크하고, 적절한 가이드를 하려면 해당 OS 환경을 잘 이해하는 수밖에 없다. 마찬가지로 새로운 데이터베이스, 프레임워크나, 빅데이터 기술에 대한 보안을 체크하려면 해당 분야를 잘 이해할 수 밖에 없다(물론 관련 영역에 대한 스캐너 같은 여러 솔루션을 사용해서 해결하는 방법도 있겠지만, 원리와 무슨 일을 왜 수행 하는지 정확히 모르는 블랙박스 형태의 툴에 의존하는 것은 보안 일을 하는 사람으로서는 너무 순진한 행동이라고 본다). 물론 기존의 다른 유사한 분야에 대한 풍부한 이해는 새로운 분야에 대해서도 많은 부분 패턴으로 적용될 가능성이 높지만, 그것은 새로운 분야를 제대로 이해한 후에야 완전하게 발휘될 수 있는 능력일 것이다(물론 대상의 빠른 이해에도 일정부분은 도움은 된다고 본다). 새로운 분야에서 데이터가 어떻게 흘러가는지를 확실히 이해할 수 없다면, 기존에 익힌 보안에 대한 패턴들을 어디에 적용할지 몰라서 손가락만 빨고 있게 될 수도 있다(아마 아는척 사기를 치지 않는 이상은 말이다)

 

[거짓말 잘하는 비결 - 동아사이언스]

http://m.dongascience.donga.com/news.php?idx=6462

 

 

  또한 보안은 언제나 사실에 기반한 마술과 비슷하다. 취약점은 이해하기 어렵거나 신비로울 수는 있지만, 항상 사실(코드나 설계)에 기반하여 일어나는 것임은 분명하다(그래야 방어의 설계도 가능한 것일테고...). 보안 취약점은 기술의 빈 틈을 파고 들어가는것이며, 기술 자체의 안전한 구성원으로 위장하여 들어가, 데이터베이스 등 외부 요소나 기술 자체에 영향을 미치는 것을 의미한다.

 

  웹 보안에서 가장 흔하게 나오는 SQL Injection 같은 부분은, 만약 여러가지 데이터베이스의 명령어나 관리 기술에 두루 능통하다면, 정말 빠르게 공격과 방어에 대한 원리를 이해할 수 있다(A piece of cake라고 하고 싶다) . 그런데 만약 데이터베이스를 모르는 상태에서 SQL Injection 을 이해하려 한다면, 보안 자체의 측면보다는 데이터베이스와 SQL 문장의 이해의 늪에 빠져서 시간도 많이 걸리고 불완전하게 단편적으로 이해하고 넘어갈 가능성이 높다.

 

  비슷하게 자바스크립트를 기반으로 한 XSS 나 CSRF 같은 취약점 패턴 등도 자바스크립트를 얼마나 잘 이해하고 있느냐에 이해의 난이도와 깊이가 달려있고, 커맨드 인젝션이나, XML 인젝션 등도 얼마나 시스템 명령어나, 프로그램의 내부 구조 및 관련 함수들, XML 구조를 잘 이해하느냐에 중요 포인트가 있다(물론 특정 취약점은 프로그램의 다른 요소와 믹스되어서 효과가 증폭되거나 경감되는 부분도 있긴 때문에 한 기술의 타입으로 단순화 하기는 힘들지만 말이다). 해당 부분에 대한 이해가 충분하다면 보안 이라는 패턴을 적용해 어떻게 해당 기술이 악용이 되고, 방지할 수 있는지를 쉽게 이해할 수 있게 된다. 나아가 그 방어 방식의 한계 및 제약과, 한계에 따른 리스크를 다른 수단으로 보완하여 경감해야 된다는 사실도 인지할 수 있게 된다. 해킹이란게 시스템을 속이는 것이라 얘기되지만, 그 앞에는 사실 시스템을 (잘 이해하고) 속이는 것 이라는 중요한 말이 숨어 있다고 생각한다.

 

  그럼 이 글에서는 맘대로긴 하지만 (기술적인) 보안 공부를 다음과 같이 정의해 보도록 하겠다. "데이터의 흐름을 이해하기 위해서, 데이터가 흘러가는 공간을 구성하고 있는 기술에 대해서 이해하는 과정". 앞으로의 시간들은 쓰는 사람의 지식의 한계 때문에, 그러한 부분의 아주 깊은 곳까지는 안내하진 못하겠지만, 데이터의 흐름을 이해하기 위해 이용되는 여러가지 방법들을 살펴보는 방식으로 진행될 것 같다. 하지만 뭐 항상 그렇지만 진행되다보면 원래 의도와 다르게 흘러가기는 한다...

 

 

 

3. 보안의 공격과 방어 측면의 차이

  프로그래머들에게 조금 미안하긴 하지만 개인적으로 IT 쪽의 많은 분야에서 그다지 바람직하지는 못하다고 생각되는 흐름 중 하나는, 프로그래밍 경험이 있느냐에 대한 부가가치를 너무 크게 잡는 다는 부분이라고 본다. 물론 QA나 보안이나, 시스템, 빅데이터 등의 여러 분야에 대해서 프로그래밍 능력이 상당한 도움이 되는 것은 맞다.

 

  하지만 프로그래밍 실력을 미리 갖추고 일을 시작 하는게 중요한 거라기 보다는, 해당 업무의 특정 레벨에 올라가게 될때 자연스럽게 업무의 효율성과 확장성을 위해서 자연스럽게 필요성이 생기게 되는 것이라고 본다. 무언가 귀찮거나 반복되서 의미 없는 일을 줄이기 위해 위해서는 어쩔 수 없이 자동화의 힘을 빌려야 하고, 그러다 보면 조금씩 자연스럽게 프로그램이란 세계에 발을 들이게 된다. 물론 그 전에도 API 사용이나, 명령어 스크립트 작성 등 기본적인 프로그래밍 지식이 있으면 좀더 적응이 용이한 부분들도 분명히 있다. 

 

  개인적으로는 프로그래밍 능력이 있느냐가 원천적으로 있느냐가 중요하다기 보다는, 업무상 자연스럽게 필요하게 되서 프로그래밍 능력을 습득하게 된다는 것이 좀더 맞을 것 같다. 물론 해당 부분에 대한 부분은 금방 휘리릭 습득되는 부분은 아니기 때문에 직업의 초기부터 조금씩 꾸준히 노력하는 것이 맞아보인다. 추가로 분야에 따라 프로그래밍 이란 것도 각 분야에 적절한 스타일로 다르게 접근 되기 때문에 쓰이는 포커스가 다른 경우도 많다. 제일 중요한 것은 해당 분야의 도메인 지식을 기반으로 적절하게 프로그래밍 언어의 능력을 쓰는 것인것 같다.  파이썬 글 17교시의 머신러닝 부분에서 프로그래밍이 어떤 식으로 쓰이고 있는지와 비슷하게 보면 된다고 할까? 표현하긴 좀 어렵지만 프로그래밍은 프로그래머 들에게만 생기는 직업적 기술이라기 보다는 약간 공공재 적인 기술적 영역이라고 보고 싶다. 그래서 두려워 하지 말고 일단 뛰어들어 보는 것을 추천한다. 시간을 들여 익숙해 지면 야매 정도는 되니까...

 

 

 보안 쪽도 비슷한 흐름이 있다고 보는데, 웹어플리케이션 보안 부분을(특히 모의해킹이라고 칭해지는 부분) 특수한 인력이 특수한 절차를 밟아서 획득할 수 있는 완전한 검증 방식으로 생각한다는 부분이다. 모의해킹은 표면적인 효과 이외에 생각할 점이 많은 분야라고 본다. 

 

  우선 수행하는 사람의 능력에 많이 좌우된다. 보안 분야도 개발이나 테스팅과 비슷하게 사람들마다 접근하는 전략과 효율성의 차이가 많이 나고, 기술 및 도메인에 대한 이해도도 틀리며, 그 차이가 외부에서 볼때 확실히 구분되기 힘들다. 인력이나 도메인에 많은 영향을 받아 어떤 기술셋을 가진 사람이 어떤 분야를 점검하느냐도 중요하고, 어떤 언어나, 개발프로세스를 거쳐 만든 도메인을 만나느냐에 대한 운도 작용하는 것 같다. 또 점검 후 점검한 영역에서 실제 사고가 나거나, 비슷하거나 더 상위 수준(또는 비슷하지만 시간에 쫒기지 않은 한가한)의 인력이 충분한 시간을 가지고 크로스 체크 하기 전에는 효과를 증명하기 힘든 경우도 종종 있는 듯 싶다. 또 이해한 만큼만 점검이 가능하기 때문에, 시행자의 대상의 이해 정도에 의해서도 많이 차이가 나고, 일반적으로 리소스나 범위 등의 여러가지 사유로 소스 기반이 아닌 블랙박스나 그레이박스 기반, 그리고 제한된 시간 프레임 내에서 진행되기 때문에, 구성되어 있는 자원이나 소스에 대한 완전한 커버리지를 가지긴 힘든 경우도 많은것 같다.

 

  그리고 대부분의 경우 증명보다는 시나리오 기반으로 진행되기 때문에, 해당 시나리오를 벗어난 전체적인 보안성 측면에 대해서는 보장(Assureance)하지는 못한다고 보는게 맞을 것 같다. 또한 불행하게도 점검한 소스나 환경은 계속 변할 수도 있기 때문에, 해당 점검 시점 후 시간이 지나게 되면 다시 코드의 안전함을 보장하지 못한다는 모순에 빠지게 된다(개발자중 한명이 모의해킹이 완료된 후의 코드 베이스에 취약한 코드를 하나 넣었다면 어떻게 될까?).

 

  마지막으로 시스템이 너무 기초적인 보안 설계가 안 되어 있다면 중요한 취약점들을 다수 발견할 수는 있겠지만, 해당 취약점에 대부분의 시간을 쏟고, 진행이 막히게 되어, 더 미묘한 내부를 들여다 보지 못할 수도 있다. 뭐 중요한 기본 취약점들을 찾았다는 의미는 있긴 하지만, 해당 취약점들에 갈 길이 막혀 깊이 있는 취약점은 찾지 못할 수 있다. 기본적인 기능의 동작도 제대로 안되서 중요도가 높은 버그를 잔뜩 올렸지만, 해당 가능에 대해 깊이 있는 테스트를 하지 못하는 QA 테스트와 비슷한 상황이라고 보면 된다. 해당 경우는 모의해킹이 중요한게 아니라 시스템이나 프로세스를 기초부터 개선 하는게 더 중요할지도 모르는 상황이라고 본다. 분명히 모의해킹은 보안쪽의 중요한 요소이기도 하고, 수술에 꼭 필요한 잘 드는 메스이기는 하지만 은총알은 아니여서, 환자의 상태나 다른 검사 장비들과, 의사에 판단에 의해 잘 조합하여 사용해야 효과가 큰 것 같다.

 

  그래서 모의해킹은 어떻게 보면 공부를 열심히 하고 보게되는 고3의 수능 같은 평가 활동 같다고 보고 있다. 테스팅을 아무리 하더라도 최초부터 없는 품질을 얻을 수는 없는 것과 마찬가지로(중요한 버그들을 발견하고 고치는 행위자체가 반드시 품질을 보장하진 못한다 파이썬 머신러닝 파트에서 얘기했던 garbage in garbage out 과 마찬가지로...), 모의해킹으로 애초부터 들어 있지 않은 보안성을 잡을 수는 없다. 그런 믿음은 이미 다 지어진 집에서 발견된 균열들을 급하게 메우면서 집이 안전하길 바라는 것과 비슷하다. 사실은 설계 부터의 과정에서 뭔가 어긋나서 생긴 문제인데도 말이다. 

 

  보안성은 시험 전에 한참 꾸준히 해왔던 공부 같이, 여러 요구사항의 수집에서 시작하여, 안전한 설계, 개발의 과정 중에 이루어지는 여러 관점의 보안적 리뷰와 체크에서 생기는 것이라고 보는게 좀더 근본적일 것 같다. 모의해킹은 어플리케이션 보안에 대한 오랜 동안의 업계 사람들의 시각과 기술적 노하우, 취약점에 대한 개인의 감, 실제 경험들이 총 집성된 평가 체계라고 생각하지만, 역으로 그런 기본 역량을 충분히 갖춘 사람들이 평가를 해야지 충분한 의미가 있다는 단점도 분명히 있다는 것을 잊으면 안된다(물론 절차적인 면죄부라는 느낌이 좀 있긴 하다...) 

 

 

  그럼 해킹, 모의해킹과 같은 공격과 시큐어 코딩과 같은 방어의 차이는 무엇일까? 우선 둘의 공통점은 공격하고자 하는 대상과 방어하고자 하는 대상이 먼저 얘기한 데이터라는 것이다. 두 가지의 차이점은 , IT를 무협과 비교하는 걸 별로 선호하는 편은 아니지만, 무협만화에 나오는 빠른 검과 느린 도의 대결과 비슷하다고 본다(멋진 캐릭이 나오는 게임 또는 만화의 삽화를 넣고 싶긴 하지만, 저작권 문제로.. 무협 만화 좋아하는 사람은 열혈강호의 담화린(빠른칼)과 도제(느리지만 무거운 도)가 싸우는 장면을 상상해 보면 어떨까 싶다^^). 공격은 시스템의 헛점을 노리고 다양한 영향을 미치려고 계속 변화하면서 수행되는 반면, 방어는 사실 기본기에 충실해서 느리지만 핵심을 지키면서(靜中動) 공격으로 들어온 외부 코드들을 무용지물로 만들게 된다고 본다.

 

 

  그럼 느리지만 무거운 도에 해당하는 방어를 코드로 예를 들면 어떻게 될까? 개인적인 생각에는 아래와 같이 (외부에 입력된 변수로 부터 영향을 받을 가능성이 있는) 내부에서 사용할 변수의 타입과 범위를 체크하는 코드가 아닐까 싶다. 아래와 같이 정확한 정수 타입과 필요한 수의 범위를 제한하게 되면, (아래와 같은 숫자 변수에 대한 코드에 경우에는) 어떠한 인젝션 시도에도 안전한 코드가 될 것 같다.

1
2
3
4
5
6
ext_var = "union all ... --"
 
if type(ext_var) is int and ext_var > 0 and ext_var <= 10:
    print ("use variable");
else:
    print ("not safe");
cs

 

   해당 방어 코드를 모르는 공격자는 공격을 위해서 많은 화려한 기법을 사용할테고, 그 중에 똑똑한 공격자는 금새 잘 막혀 있다는 걸 알아채고, 시간낭비 없이 다른 취약한 변수나 코드들을 찾아 다니게 될 것이다. 좀 더 나아가면 해당 부분은 관련 방어를 지원하는 프레임워크를 쓰거나, 해당 프로그래밍 언어에서 지원하는 범용적인 보안 함수를 사용하는게 더 맞겠지만, 여기서는 방어하는 무거운 도(刀)에 대한 극단적인 이미지를 나타내기 위해서 아래와 같은 코드로 제시해 보았다. 문자열 변수 등과 같이 좀더 상세하게 따져가며 저울질할 부분들은 나중에 해당 주제에 대해서 다루면서 얘기하면 될 것 같다.

 

  파이썬 코드의 실행을 모를 경우 파이썬 2교시 글을 참고하면 된다

c:\Python\code>python variable_check.py
not safe

 

 

  한가지 더 인터넷에서 많이 언급되는 얘기를 생각해 보면, 공격의 대표적인 방식인 모의해킹의 기법을 이해해야만, 코드의 방어를 어떻게 해야 할지 제대로 알수 있다는 부분이 있다. 해당 부분은 맞는 얘기기는 하지만, 다른 한편으로 조금 더 생각해 볼  부분이 있다고 본다.

 

  방어 측면에서의 모의해킹의 이해란, 모의해킹에서 사용하는 기법이나 다양한 툴의 원리와 사용의 이해의 측면 보다는, 해당 공격으로 일어나는 데이터들의 변화에 초점을 맞추는 것이 맞을 듯 싶다(이 부분은 보안 테스팅을 위해 코드를 읽을 때도 비슷하게 적용된다. 물론 취약점의 원리를 이해하면 자동으로 툴이 무엇을 하려 하는지를 어느정도 이해하게 되겠지만 말이다..). 어차피 방어 측면에서는 공격과 같이 현란한 데이터의 변경으로 맞설 수는 없기 때문에(물론 뭐 요즘의 OS 등에서 실행파일이 로드되는 메모리 번지를 계속 변경 시킨다든지, 솔루션 등에서 머신러닝 등을 이용해서 비 정상적인 통계 패턴을 계속 추적한다든지 하는 등은 공격과 비슷한 다이나믹한 방어로 볼수 있긴 하겠지만), 일반적으로는 공격의 원리에 대치되는 배치로 대응하는 수밖에 없다. 공방 게임에서 공격 유닛에 대한 방어는, 해당 유닛에 상응하는 방어 건물의 배치로 이루어지는 것과 비슷하지 않을까 싶다. 그 방어 건물이 우리가 자주보게 되는 "시큐어 코딩 가이드" 같은 거고 말이다.

 

 물론 모의해킹의 아주 미묘한 부분까지 이해하여, 관련 전문가 수준으로 알게되면 분명 더 좋은 방어를 하게 될듯 싶다(물론 공격 뿐만 아닌 방어 관점의 이슈들도 충분히 잘 안다는 가정하에 얘기이다). 

 

  보안에 대한 분야는 사실 너무 넓은 분야이고, 모든 존재하는게 사실 보안과 연관이 있고, 그 안에 서식하고 있는 많은 요소들도, 계속 살아있는 생태계 처럼 변하고 있기 때문이다. 지금 해당 영역에서 완벽하더라도 앞으로 계속 따라기기 위해서 해야 될 공부가 너무 많다. 실제로 외부에서 보기엔 완벽해 보이는 사람들도, 좀 더 자세히 들여다 보면 생각보다는 완벽하지 못한 경우가 많고, 그것은 비단 보안 뿐만 아니라 모든 지식의 영역이 마찬가지인듯 싶다.

 

 

  

4. 마무리 하면서

  앞으로 글을 진행 하면서 앞에서 한 얘기들을 좀더 자세히 설명하기 위해서, 몇 가지 방향을 잡고 진행하려 한다. 우선 공격보다는 방어에 필요한 부분을 위주로 설명할 예정이며, 공격을 얘기할 경우는 방어 측면에서 이해가 필요한 공격의 측면을 중심으로 얘기하려고 한다. ASP, Python, PHP 와 같은 스크립트 언어와, 자세히는 모르지만 .NET 이나, JAVA 같은 주제를 잘 이해시켜 줄 수 있는 언어를 가지고, 가능한 실제 움직이는 코드를 구현하고자 한다. 그리고 피들러와 같은 관찰 및 조작 할수 있는 툴을 통해 데이터가 흘러가고, 변조 되는 부분을 시연하고, 방어를 위한 코드를 제시하며, 해당 방어의 원리와 제한 들에 대해서 얘기하려 한다. 

 

  비교적 잘 설명이 가능할 거리고 생각하는 웹 기술을 중심으로 이야기를 시작하며(사실 웹이나 다른 분야나 넓게 보면 기본적인 보안 패턴은 비슷하다고 생각하지만 아직은 크게 자신은 없다^^), 후반에 일반 어플리케이션에 대한 등에 대한 얘기도 얇은 지식이나마 정리해 볼까 한다. 이 글의 목표는 읽은 사람들이 각 보안 영역에 대해서 어떻게 접근해야 겠다는 스스로의 생각을 가지게 되고, 여러 보안 가이드를 볼 때, 해당 가이드를 작성한 사람이, 어떤 관점에서 그러한 방어 전략을 제시했는지에 대한 이해의 기반을 가지게 하는 것이다. 

 

  물론 앞의 파이썬 글과 마찬가지로 각 주제들에 대해 깊은 부분 까지 설명하기에는 스스로 아는 것이 적다고 생각하고, 시간의 제한도 받기 때문에 "보안에 대한 이런 저런 주제를 가볍게 다루는 기술적 산문집" 이라고 기대하고 읽어주면 좋을 듯하다. 내용 중 잘못됬거나 의견이 다른 부분은 댓글을 달아 알려주심 감사할듯 싶다.

 

그럼 재미있는 보안공부가 되길 바라며...

posted by 자유로운설탕