이번 시간에는 코드 읽기라는 주제로, 어플리케이션 보안에 있어 코드를 읽는 부분이 어떤 의미를 가지고 있는지에 대해서 이야기 해보고, 현실적으로 코드 읽기를 적용하려 할때 어떤 문제가 있는지에 대해서도 잠시 얘기해 보려 한다. 개인적으로는 일반적인 테스트든, 보안에 관한 테스트든 가능하면 블랙이나, 그레이 박스 관점에서 진행하는 것에 추가해 소스를 이용하는 것을 선호하는 편이다. 그렇게 함으로써 미지의 범위에 대한 불안감도 많이 덜어주고, 적절히 사용하면 효율성 면에서도, 원래대로 라면 당연히 해야 되는 단순 작업을(인형눈 끼우기 같은...) 많이 줄여주기 때문이다.
[목차]
[목차]
1. 보안을 바라보는 방법
2. 보안에서의 코드 읽기
3. 인젝션(Injection) 살펴보기 #1, #2
4. 암복호화
5. 클라이언트 코드
6. 업로드, 다운로드
7. 스크립트 문제
8. API
9. 설정, 패치, 하드닝
10. 설계문제
11. 스캐너 vs 수동 테스트
12. 자동화 잡
13. 리버싱과 포렌식
14. 모니터링 문제
15. 악성코드
16. 보안과 데이터
1. 들어가면서
만약에 아래와 같은 단순한 터치스크린 화면 기반의 프로그램에 대한 보안 테스트를 한다고 가정해 보자. 로직은 단순해서 금액을 넣을 경우 돈이 인출되는 프로그램이다(단순화를 위해 인증이나, 비밀번호 등의 체크는 앞에서 이미 진행했다고 가정).
그럼 일반적인 테스트나 보안 테스트 요소를 적당히 리스트업 해 보면, 아래와 같은 여러가지 케이스 들이 생길 수 있다.
1) {-1}, {0, 1, 2}, {999, 1000, 1001} - 마이너스 값, 경계 값
2) {10000}, {32768} - 아주 큰 값
3) SQL 등 Injection 에 관련된 문자나 특수 문자
4) show me the money 같은 치트키 입력
5) 그 밖의 예상 못한 결과들(버튼을 빠르게 두 번 누르거나, 화면의 구석에 "Hi" 라고 그리면, 비밀 메뉴가 열린다 든지)
위의 케이스 중에서 1~3번 정도는 어떻게든 커버할 수 있겠지만, 4~5의 영역은 블랙박스(외부의 UI만 보고 하는)나 그레이 박스(외부의 UI 와 일부 내부 테이터를 보면서 하는) 테스트 기법을 가지고는 사실 커버하기가 힘들다. 4번 같은 경우는 잘 악용되는 문구의 사전식 대입 정도가 최선일 것이다(보안에서 스캐너가 어드민 페이지 경로를 찾을때 하듯이 말이다). 결국 보안 테스트에 대한 케이스는 요즘 같은 복잡한 어플과 인터페이스 및 서비스 들이 엮어 있는 상태에서는 사실 거의 무한대라고 봐도 될 것이다.
그런데 만약 우리가 해당 화면에 대한 소스를 볼 수 있어서, 입력 박스가 "intMyMoney"라는 이름을 가지고 있고, 인출 버튼이 "btnWithdraw" 라는 이름을 가진것을 알수 있고,
버튼을 눌렀을 때의 실행되는 코드가 아래와 같이 이루어 졌다는 것을 볼 수 있다면 어떻게 될까?(참고로 아래의 코드는 예를 들기 위한 가상의 코드이다)
1
2
3
4
5
6
7
8 |
On_btnWithdraw{
If(isNumeric(intMyMoney) & intMyMoney >= 1 & intMyMoney <= 1000)
{ 인출 하는 함수 }
Else
{ error 를 처리하는 함수 }
} |
cs |
충분히 코드의 관리나 빌드 및 배포가 안전한 프로세스 상에서 이루어지고 있다는게 보장되고 있는 상태라면, 우리가 앞에 리스트업 했던 여러 상상의 테스트 케이스 들은 현실적인 케이스로 좁혀질 수 있게된다. 예를 들어 아래와 같은 코드라면 isNumeric 함수가 잘 동작되는지 보기위해 문자, 특수문자 정도를 넣어서 예외처리가 잘되는지 보고, 1과 1000 사이의 경계값 정도를 체크해 보면 테스트가 마무리 될 것 같다.
다만 한가지 눈에 코드가 보인다고 해서, 해당 코드의 동작을 증명하는 실제 테스트 조차 안 하는건 아주 위험한 행위이다. 사람이란 언제나 편견에 의한 착각과 실수를 하기 때문에 눈으로 보기에 확실해 보이는 것도, 실제로는 아닌 경우가 많기 때문이다(개인적으로 자신있게 그러다가 몇번 돌을 맞은 후 얻게 된 교훈으로, 개발자와 같이 동시에 보더라도 서로 의견을 나누다가 편견이 생기기도 한다. 만약 두사람이 라면 서로 상대방의 가정을 모르는 상태에서 보는게 더 날것 같다-비슷한 경험으로 백화점 알바할때 재고 숫자를 세기 위해서 두 명의 알바가 따로 따로 세서 서로 숫자가 맞으면 넘어갔던 적이 있다).
게다가 만약 위의 코드에 개발자가 테스트를 위해서(또는 나중에 이익을 얻기 위해서) 아래와 같은 코드를 심어 놓았다면 어떻게 될까? 물론 저런 사고를 막기위해서, 개발자 간 피어 리뷰 또는 커밋이나 빌드 전 커미터라고 불리우는 시니어들의 최종 코드 리뷰를 하기도 하고, 개발 환경에서만 유효한 안전한 디버킹 코드를 넣는 방식을 가이드 하기도 한다지만 해당 부분은 한쪽으로 밀어놓고 무시해 보자.
1
2
3
4
5
6
7
8
9
10
11 |
On_btnWithdraw{
If(intMyMoney == "Show Me the Money")
{ 무한대 인출 가능 함수 }
If(isNumeric(intMyMoney) & intMyMoney >= 1 & intMyMoney <= 1000)
{ 인출 해줘 함수 }
Else
{ error 처리 함수 }
} |
cs |
아마 블랙박스 스타일의 검증으로는 위의 부분을 절대 잡을 수 없을 것 이다. 실제 저런 일은 드물거나, 어딘가 안 들키고 조심스럽게 숨겨져 있겟지만, 비슷한 느낌의 사건이 맥 OS 쪽에서 발생했었다(아마 해당 경우는 최초 root 계정이 비활성화 된 상태에서, 패스워드를 지정하면서 명시적으로 활성화 할수 있는데, 어떤 이유인진 모르지만 패스워드가 없는 상태에서 디폴트로 활성화 된것으로 추정되긴 한다).
여튼 위와 같은 방식의 코드는 아니겠지만, 백도어 기능이 생겨버렸던 것도 맞고, 리그레이션 케이스(새로운 빌드가 나왔을 때 기존의 주요 취약점이나 버그등을 확인하는 것)로도 잡기는 힘들었을 것이다(왜냐하면 나름 저런 희귀 케이스들은 보통 사건이 일어난 후 리그레이션 테스트에 추가되기 때문이다). 저런 사실을 해커가 아는 상태에서 모르는 척 사용한다면 얼마나 큰일이 될까 생각해보면, 화이트 박스 개념의 취약점 체크가 블랙 박스 만큼 중요한 의미를 가진다는 것을 조금은 어필이 되지 않을까 싶다.
[애플, 하이 시에라 ‘루트’ 취약점 수정한 보안 업데이트 배포 - IT World]
http://www.itworld.co.kr/news/107371
2. 다른 예 - 복잡성의 단순화
또는 만약 특정 사이트에 있는 모든 이미지 업로드 기능을 체크 하거나, 이미지 업로드 기능이 많은 관리자 페이지에 대해서 업로드 취약점이 있는지 체크를 한다고 할 경우, 만약 소스의 내용을 전혀 파악할 수 없는 상태라고 해보자. 이 경우 모든 페이지를 일일히 살펴보면서 체크하거나, 시간이나 리소스가 충분하지 않다면 업로드 로직 호출 패턴이나, 감에 의해서 같아 보이는 종류로 묶어서 유형별로 한개씩만 테스트 하고 무사하길 빌 수 밖에 없다(물론 운이 좋은 경우는 공통 업로드 URL 이 존재해서, 해당 URL만 호출 할 경우도 있을 수는 있을 것 같지만...).
이렇게 내부적으로 공통적인 로직이 들어있는지 알 수 없는 경우 막막하게 느껴지지만, 반대로 소스를 볼수 있을 경우에는 문제가 달라지게 된다. 소스내에서 공통된 업로드 처리 함수가 있는지 체크하고, 해당 함수내에서 외부에서 들어온 업로드 관련 인자들을 어떻게 처리하는지, 어느 폴더에, 어떤 이름으로 저장하는지를 체크 후, 실제 존재하는 업로드 관련 페이지들이 해당 안전한 공통 로직을 이용하는지만 여러 방법으로 찾아 증명만 하면 된다(해당 부분은 나중에 파일 업/다운로드에 대한 시간에 자세히 살펴 보려고 한다).
최악의 경우 개발자 들이 각각 공통 함수를 무시하고, 자신만의 로직으로 업로드 코드를 개발하였다고 하더라도 어떤 부분이 공통이 아니여서 좀더 세심하게 들여다 볼 필요가 있는지를 정확하게 알 수 있게 된다. 물론 이런 작업을 페이지 소스를 살펴보면서도 할 수 있지만, 들이는 에너지와 정확도 면에서 소스를 보는 쪽이 휠씬 유리하다.
3. 일반 언어와의 비교
그럼 프로그래밍 언어에만 한정 짓지 말고 일반 언어와 한번 비교해 보려고 한다. 언어에도 읽기, 쓰기, 듣기, 말하기가 있듯, 코드에 대해서도 비슷한 부분이 있다.
3.1 읽기
읽기 측면에서 코드를 통해서 여러 점검이 필요한 중요 로직들을 얻어낼 수 있다. 특히 전형적인 취약점이 아닌 설계에 대한 보안 문제는 전체적인 로직을 잘 살펴보아야만 발견할 수 있을 가능성이 높다. 물론 관련 기획 문서를 보거나, 실제 해당 페이지나 기능들을 실행해 보는 것도 효과가 있지만, 소스 읽기는 밖에선 잘 안 보이는 숨겨진 부분들을 다른 관점에서 살펴보게 해준다.
다만 여기서 한가지 짚고 넘어가고 싶은 것은 해당 효과를 꼭 소스 읽기를 통해서만 얻을 수 있는 것은 아니라는 점이다. 기존에 알고 있는 여러 지식으로 부터의 유추나, 관련 개발자와의 대화 및 문의에 의해서도 많은 것을 얻어낼 수 있다. 다만 이 경우도 소스를 어느정도 이해하고 있는 것은 정확한 질문을 던져서 원하는 해답을 얻어낼 수 있을 가능성을 높여주게 된다. 보안과는 조금 먼 관점의 해당 개발자 스타일의 설명을 잘 이해해, 점검에 도움이 되는 형태로 스스로 재가공 할 수도 있다. 경험상 맘에 맞거나, 일하는 스타일이 맞는 개발자 동료가 있는 것은, 구글 검색엔진이 도와주는 것과 비슷하게 든든한 효과를 주게 되므로, 상황이 어쩔 수 없다면 모르겠지만 꼭 혼자서 모든 걸 부딛치려고 하는 것은 좋은 것은 아니다.
또한 로직을 이해하기 위해 코드를 읽는 것은 개발을 하기위해 코드를 읽는 것과는 조금 다른 측면이 있다. 만들기 위한 코드 읽기는 프로그램의 세부 로직과 문법의 디테일한 구조를 동시에 살펴봐야 하지만, 보안을 위한 코드 읽기는 데이터의 흐름에 따른 요점만을 읽는다고 보면 된다. 예를 들면 입력 인자들이 어떤 외부에서 들어오고, 해당 인자들이 내부 로직에 어떻게 전달되고, 어떤 처리를 거쳐서, 어떻게 안전하게 사라지게 되는가의 라이프 사이클을 살펴보는 작업이다. 또한 현실과 차단되어 코드 만을 보는 것 보다, 블랙박스 같이 바깥 쪽의 흐름도 참고하면서 비교해 보는게 좀더 난듯 하다.
3.2 코드 쓰기
현대의 코드 쓰기 작업은 많은 부분이 수정(modify)의 측면에서 사용되는 경우가 많은 듯 하다. 예를 들어 API 를 호출해 결과를 화면에 뿌려줄 경우도 처음 부터 맨땅에서 시작하는게 아니라, API 를 만든 사람이 제공하는 샘플을 기반으로 구현하게 된다. 또 구글링을 통해서 많은 코드를 얻고 있고, 해당 언어에 대한 샘플이 없더라도, 다른 언어로 이루어진 샘플을 보면서도 아이디어를 얻게 된다.
그래서 패턴이 되는 조각 코드들을 적절히 만들거나 참조해 쓸 수 있게 되면(예를 들어 HTTP 요청과 받기, HTTP 소스 분석, 주기적인 처리), 어느 언어를 사용하든 구글을 이용하여 적당히 원하는 동작을 하는 코드를 참조해 만들어낼 수 있다(어떤 사람들은 이런 웹에 돌아다니는 코드는 돌아가긴 하지만 유지보수가 성능이 보장 못 한다고 저평가 하는 측면도 있지만 해당 부분은 관점에 따라 맞는 것도 틀린 것도 같다. 그렇게 따지면 우리가 쓰는 오픈소스도 웹에서 돌아다니는 코드니까 말이다). 이러한 작업이 가능하기 위해서는 정규 표현식, 여러 데이터베이스, 스크립트언어, 빌드 방식 언어, 빅데이터 오픈소스 등등 여러 언어와 배경 지식들을 평소에 습득하되, 특정한 기술에 의존적인 부분 보다는 기반적인 부분에 초점을 익히는 것이 좀더 바람직 하지 않을까 싶다.
또 이러한 "서당개 3년" 스타일의 쓰기는 보안 테스팅을 할때도, 실제 환경상으로 불가능하거나, 실 사이트에 영향을 미쳐 수행하기 힘든 부분을, 코드를 적절히 변경하여 테스트 환경에서 체크함으로서, 최소한의 안전을 보장하게 만들 수도 있다(예를 들어 위의 예를 든 업로드 코드를 실제 운영 환경에서 돌려볼 순 없지만, 방어를 하는 필터 함수만을 잘라내어 체크한다든지 하는 상황이 있을 수 있다).
그래서 코드를 백지부터 만드는 능력이 떨어져도(요즘 이런 사람이 얼마나 될까는 싶다), 우선은 기존 프로그램들을 조금씩 수정해 보는 모드로 공부하는 것을 추천한다. 언어로 따지면 쓰기 전에 우선 많이 읽어서 여러 패턴을 익힌후, 해당 패턴을 이용해서 더듬더듬 쓴다고 봐도 될것 같다. 프로그램의 좋은 점은 언어의 말과는 달리 잘못 쓰게 되면 아예 안돌아가거나 버그가 바로 나오기 때문에 짧은 한마디를 할때부터 자동 교정의 훈련이 되는 점이다. 다만 충분한 경험이 쌓이기 전에는 이해가 안 되는 에러가 나서 답답함이 많긴 하지만 말이다(그 경우 구글을 도움을 받으면 된다).
3.3 듣기 & 말하기
취약점이 발견됬을때 해당 취약점을 올바르게 고치려면 해당 언어와 돌아가는 환경을 올바르게 이해할 수 있으면 좋다. 해당 지식을 기반으로 개발자와 의논하게 되면, 앞에서 얘기한 바와 같이 개발자의 언어로 설명하는 주제들에 대해서도 비교적 쉽게 이해도 할수 있고(또 이러면서 많이 배우게 된다), 적절한 논의 및 보정, 협의를 할수 있게 된다.
또한 이쪽에서 원하는 부분에 대한 빠른 피드백을 얻을 수도 있고, 단순히 어떠한 작업을 해달라고 요구사항 만을 기계적으로 전달하는 것보다는(보통 취약점은 찾을 수 있지만, 대상 코드를 어떻게 수정해야되는지에 대해 정확하게 모르는 경우 이런 태도를 취한다. 극단적으로 보면 "네가 알아서 고쳐" 이런 모드다) 사이드 이펙트가 없는 정확한 코드의 수정이 이루어질 수 있다. 개발 쪽에서는 의외로 보안 쪽에서 당연하다고 생각하는 언어의 보안적 관점에 대해서 모르는 경우가 많기 때문에, 원하는 방식과 결과만을 이야기 하는것만으로 충분하지 못할 때가 많다.(원리와 결과에 이르는 과정을 이해시켜 주는 것이 종종 필요하다).
다만 이 부분은 이상적인 얘기고, 개발자에 따라서는 자신의 코드 영역에 들어오는 것을 싫어하는 사람들도 꽤 많다. 그런 경우 본인의 코드 영역을 간섭 받고 있다고 받아들이게 되어 역효과를 가져올수도 있다. 반대로 적극적으로 코드의 흐름에 대해서 얘기하면서 의논하는걸 좋아하는 개발자도 많이 있다. 상황 상황에 따라 틀리지만, 적절히 상대의 성향에 맞추어서 잘 협상하는 것이 좋다고 생각한다(개인적으로 이런 문제로 부딛쳐 사이가 안 좋아진 경우가 있는데 지금은 좀 후회가 된다. 지나고 나면 좀 부질 없는 일들 같기도 하다)
4. 보안에서의 코드 읽기의 문제점
아마 어떤 분들은 위의 글들을 읽으면서 현실과 동떨어진 얘기라고 생각 할수도 있을 것 같은데, 그런 부분들에 대해서 언급해 보려고 한다.
4.1 현실적으로 어려운 점
확실히 코드를 읽으면서 보안 설계가 잘 되어 있는지 체크하는 방법은 단점 또한 많다. 첫 번째로 한정된 시간이다. 주어진 시간이 몇 일 밖에 안되는 상황에는 남이 만든 소스를 들여다 보면서 로직을 파악하는 것보다는, 주어진 시간을 효율적으로 쓸수 있는 다른 방법들을 찾아보는 것이 낫다. 시간과 리소스를 고려하여 블랙박스 접근법 만을 쓸지, 화이트 박스 접근법을 같이 쓸지, 아니면 일부만을 보조해서 쓸지를 선택해야 한다.
두 번째는 "1 vs N" 의 문제로써, 인원 비율 상 수 많은 개발자들이 만든 소스를 보통 한 사람이 살펴봐야하기 때문에 적절히 범위를 제한하거나, 요점만을 읽는 속도를 높이는 방법을 계속 고민하고 연습해야 한다.
세 번째는 초기 진입 장벽으로 이것은 영어를 처음 배울때와 비슷하다. 처음에 소스를 읽게되면 하나하나 문법적인 부분도 따져가면서 읽어야 해서 모르는 것도 많고, 느리고, 난해한 해석 과정을 거쳐야 한다. 이 부분은 프로그래밍을 만드는 것을 배우는 것과 비슷하다고 보고, 피할 수 없는 측면이 조금은 있다. 분명한 것은 영어책과 마찬가지로 많이 읽으면 읽을 수록 빨라진다.
네 번째는 회사에서 보안이나, 지적재산권 보호 등의 여러가지 이유로 특정 개발자 이외에는 소스를 보여주지 않는 경우도 있을 수 있다. 이 경우는 세월을 이용한 증명과 설득 밖에 없어 보이는데, 해당 회사에서 꾸준히 근무하여 신뢰를 쌓고, 검증을 위해 코드를 보는 방법이 효율적이고, 안전한 코드를 만드는데 도움이 된다는 부분을 설득해서 권한을 획득하는 방법밖에 없을 것 같다. 어떤 회사는 내부자에게 모두 공개하는 회사도 있으니 복불복일 듯은 싶다. 근데 막상 공개해 줘도 실력이 안되 못 볼 수도 있으니 자기 실력은 잘 객관적으로 파악하고 있어야 하는 듯도 싶다.
마지막으로 세상엔 많은 언어들이 있고, 자신의 일하는 환경에도 많은 언어들이 혼재되어 있을 수 있다는 부분이다. ASP, PHP, C#, 자바, SQL, 자바스크립트, jQuery, Node.js, 스칼라 등등의 수 많은 언어들과 언어의 배경지식들을 적절히 따라잡아야 한다. 또 앞으로 나오는 새로운 기술들도 새 프로젝트에서 기존의 패턴들을 사용하기 위해서 어느 정도의 깊이로는 따라가야 한다고 본다. 또 은근 코드를 볼때, 코드가 저장된 저장소 특성에 따라서, 해당 저장소에 적합한 검색 방식을 습득하거나 궁리해야 하기 때문에 문제가 된다. 낯설지 않은 저장소에 담겨진 소스를 봐야하는 경우는 이전 버전의 비교라든지 하는 작업 부분에서 병목을 가져올수 있게 된다.
4.1 현실적으로 다행인 점
위와 같이 난해한 코드 읽기의 세계에서도 다행인 점들이 있다.
첫째로 패턴화가 가능하다는 것이다. 한 프로젝트 안에는 많은 유사한 구조와 로직들이 있고, 그 구조와 로직은 다른 프로젝트에서도 존재할 가능성이 아주 높다(코드나 구조의 복사는 바이러스와 같고 생각보다 정답은 비슷한 경우가 많다). 또 많은 소스들이 구글 검색이나, 해당 언어 및 라이브러리의 가이드, 다른 시니어, 이전 개발자의 코드 등을 기반으로 만들어졌기 때문에, 이런저런 사유로 유사한 로직과 구조들도 많은 편이다. 또한 웹같은 경우는 동작이나, 디자인 상의 유사적인 부분이 많다(이런 것을 편하게 만들기 위해서 파이썬의 장고나, 자바의 스프링, .NET의 MVC 패턴 같은 프레임워크 들이 있는 것일테고..).
둘째로 영어, 중국어 등의 언어와 마찬가지로 소스를 많이 보게되면 그만큼 읽는 속도가 빨라지게 된다. 요점만 골라읽는 요령도 조금이나마 늘게 되고 말이다. 또 스스로 로직을 정리하기 때문에 계속적으로 업그레이드가 되는 프로그램 이라면, 향후 추가적인 점검을 진행 할 때 해당 지식들이 좋은 백그라운드를 형성하게 된다(그래서 도메인 전문가가 생기는 걸꺼다..). 그리고 아마도 직접 만드는 만큼은 아니지만, 간접적으로 프로그래밍에 대한 경험적 노하우가 쌓이게 되어 나중에 자동화 등의 분야에서 코드를 만들어 볼때도 도움이 된다.
마지막으로 앞에도 잠시 얘기 했지만 잡(Job), API 같은 UI 적인 형태가 없는 프로그램을 분석하고 테스트 할 때, 프로그램의 형태 및 어떻게 돌아가는지를 이해하기 쉬워 해당 검증 작업을 용이하게 해줄 수 있다.
5. 실행 전략
조금 앞의 내용과는 겹치는 듯 하지만, 정리하는 의미에서 어떻게 그럼 코드 읽기를 이용할까를 생각해 보자.
첫 번째로, 항상 "시간 vs 선택한 방법의 효율"을 생각해야 한다. 자신이 선호하는 한 두가지 기술에만 집착하면서 진행하다 보면, 오히려 자가당착에 빠지게 된다. 정말로 안으로부터 보는 게 가치가 있는가를 검토해서 확신이 있을 경우만 코드 읽기 방법을 이용해야 한다. 프로그램의 도메인에 따라서 밖에서 보는 것이 더 단순하고 명확할 때도 많다.
두 번째로, 코드를 읽으면서 습득한 지식은 가능하면 문서화를 해두는 것이 좋다. 시간은 기억을 희미하게 만들어서, 다 이해했던 코드도 몇달만 지나면 가물가물 해서 다시보면 이게 뭔가 싶어진다. 이건 매일 코드를 보는 개발자들도 마찬가지라고 한다.
세 번째로, 자신이 선호하는 언어는 있어도 괜찮지만, 보통 주력 언어의 업무를 가능한 고집할 수 있는 개발쪽 과는 달리(물론 새로운 기술의 압박은 계속 되겠지만), QA나 보안 같은 경우는 언제 어떤 언어와 환경을 체크해 해달라고 던져올지 알수가 없는 부분이 있다. 그래서 가능한 언어 자체보다는 언어가 의존하는 여러 배경 지식을 익히고, 언제라도 새로운 언어나 환경에 적응해야 된다는 마음가짐을 가지고 있어야 한다고 생각한다. 다만 다행히 패턴이란게 있고, 새 언어는 기존 언어를 벤치마킹 하는 경향이 있기 때문에, 스크립트 언어를 하나 열심히 경험에 두면 다른 스크립트 언어에 대해 적응이 많이 수월하고, NET, 자바 같은 객체지향의 언어도 마찬가지라고 본다.
네 번째로, 읽는 속도도 분명이 중요한 요소중 하나라는 것이다. 코드를 읽고, 기능을 분류하고, 케이스를 제외하거나, 뽑아내는 것도 보안 테스팅의 한 요소이긴 하지만, 그 부분에 너무 시간을 쏟다보면, 실제 해당 분석에서 세운 가설들을 직접 해보면서 증명할 시간이 모자랄 수도 있게 된다. 그리고 보통 개발 뒤에 일어나는 검수 업무에 대해서는 생각보다 충분한 시간이 주어지진 않는 경우가 많아서 마린의 스팀팩과 같이 집중해서 속도를 낼 수 있는 훈련을 꾸준히 하는것도 중요한 것 같다(뭐 이렇게 보면 스포츠 경기의 준비 단계와 비슷한 것도 같다). 더 좋은 방법은 분석에 대한 시간을 미리 벌기 위해 개발 단계에서부터 참여가 가능하다면 좋을 것 같다.
다섯번째로, 역시 앞에서 한 얘기지만 혼자서 모든걸 할수 있다고 생각하는 것 보다, 믿을 수 있는 동료들과의 좋은 네트워크를 가지는 것이 좋다. 일하는 스타일이 맞는 친한 개발자들을 만들고(물론 일을 위해서 억지로 관계를 만들라는건 아니다), 개발자들이 프로그래밍 언어에 접근하는 방식을 계속 관찰하다보면, 단순히 책이나 혼자서 공부하는 과정에서는 발견하지 못하는 사실들을 배울 수 있게 되는 것 같다.
마지막으로 쓰기의 경우는 스스로도 잘 못하는 부분이긴 하지만, 좋은 라이브러리들의 사용에 집중을 하고, 오픈소스들을 이해하고, 실용성에 중심을 두고 접근을 하는게 어떨까 싶다. 앞의 파이썬 글도 사실 그런 바램에서 진행된 활동이라고 보면 된다.
6. 이런 저런 꼬투라기
꼬리가 길지만 마지막으로 몇가지 생각나는 부분을 적어보면
첫 번째로 화이트 박스 기법을 적용하는데 있어서 가장 중요한 부분 중 하나가 소스 컨트롤이 얼마나 잘 구축되 있으냐 인것 같다. 소스가 자기 멋대로 변경되어 버린다면, 기껏 분석 및 테스트 했던 내용들이 도로묵이 될 수 있으니 말이다. 또는 소스 비교나 변경이력 추적도 분석에 도움이 되는데, 해당 부분이 체계적이고 원활하게 되는 환경이 지원된다면 좀더 유리할 것 같다. 다만 개발쪽에서 편한 툴은 검증 하는 쪽에서는 좀 정보가 부족해 불편한 경우가 많긴 한다.
두 번째로 방법론이 검증하고자 하는 대상을 앞서서는 안 된다. 방법론은 효과적인 점검을 위한 수단이 뿐이지 가장 중요한 것은 대상에 대한 분석적 파악이 우선이다. 이후 어떠한 방법론을 쓸까 하는 것은 분석의 결과지 행동의 목적이 되어서는 안된다.
세 번째로 방어측면 에서 OWASP 같은 데서 제공하는 여러 방어 함수의 효율성과 성능에 대해 꾸준히 관심을 가지는것도 좋은것 같고, 파이썬 등으로 조그마한 툴을 만들어 업무에 사용해 보는 것도 괜찮은 것 같다. 보안 쪽은 의외로 패턴화된 문제들이 많아서 자동화의 ROI 가 좋고 생색내기도 편한 것 같다. 또한 오픈 소스의 사용은 내부 로직을 제대로 이해한 채 사용해야, 필요한 커스터마이징도 할수 있고(외국은 보통 이렇게 쓰는 듯하다), 해당 프로그램의 적절성과 한계를 인식할 수 있다고 생각한다.
[마무리 하면서]
스스로 코드 읽기에 대해서 충분히 잘 한다고는 할수 없다 생각되지만, 보안이나 QA에 새로 들어오는 사람들이 직업의 초창기 때부터 의식적으로 노력했으면 하는 부분이라서, 이렇게 얘기를 하게 되었다(개인적으로 더 열심히 할걸 하는 아쉬운 부분이기 때문이기도 하다). 아무쪼록 공감하는 분이 있음 좋겠다.
'보안' 카테고리의 다른 글
구글로 공부하는 보안 - 6교시 (업로드, 다운로드) (0) | 2019.02.24 |
---|---|
구글로 공부하는 보안 - 5교시 (클라이언트 코드) (0) | 2018.11.11 |
구글로 공부하는 보안 - 4교시 (암호화) (0) | 2018.07.15 |
구글로 공부하는 보안 - 3교시 (인젝션 Injection) (0) | 2018.06.06 |
구글로 공부하는 보안 - 1교시 (보안을 바라보는 방법) (6) | 2017.12.02 |