업무/APP(IOS)진단 쉽게하려 만든 게시판

메모리 평문저장 취약점 해결 #1

종금 2021. 11. 7. 23:11
반응형

 

APP진단을 하다보면 메모리에 중요정보 평문저장 항목이 있다 .
그리고 앱진단 리뷰 시 해결방법에 대한 질문을 가장 많인 받는 항목이기도해
해당 해결방법 고찰에 대해 적어보려한다.

먼저 취약점 개요인 메모리 평문 저장에 대해 알아보면
일단 우리가 쓰는 스마트폰은 컴퓨터의 연장선상으로 기본적인 구조는 같다고 보면된다. 
즉 스마트폰도 컴퓨터처럼 CPU(중앙처리장치) + 메모리(주기억장치)+입출력장치로 구성되어 있고
메모리는 여기서 CPU처리를 위해 저장하는 단기 저장되어 필요에 따라 휘발되는 저장공간으로 휘발되기 전에 남아 있는 정보가 중요 정보일 때 취약하다는 것이 위 취약점의 개요이다.

좀더 예시를 통해 취약점 개요를 자세히 설명해보자 (실제로 이렇게 타지 않겠지만 위 설명으로만 프로세스가 진행된다 가정하면) 우리가 아이디와 패스워드를 통해 접근할 때 다음과 같은 개요를 탈것이다 

1. 입출력 장치를 통해 ID/PW를 입력하면 
2. 입력값을 RAM에서 CPU처리를 하기 전에 저장한다.
3. 이후 RAM에서 저장된 값을 CPU가 순서에 따라 처리한다. 

메모리를 사용하는 것은 컴퓨터 특성상 어쩔 수 없고 CPU가 처리하시전까진 메모리에 저장되어야 한다. 
하지만 CPU처리 이후에 메모리에 ID/PW 저장이 필요없지만 메모리는 위 저장정보를 삭제하지 않는다. 
즉 Fridump와 같은 메모리 툴로 메모리 내용을 가져오면 다음과 같은 ID/PW를 볼수있다

(About Fridump: https://chanztudio.tistory.com/57?category=897304) 

즉 메모리 덤프 시 ID는 jongchan 패스워드는 security123이라고 알 수 있는 것이다. 
그럼 취약점이 무엇인지는 알았고 위 해결방법을 알아보자
먼저 가이드 확인 시 다음과 같은 방법으로 처리하면 된다고 한다.

 보안설정방법
프로세스가 활성화 되어 있는 동안 메모리상에 중요정보가 평문으로 저장되어 있을 경우 악의적인 공격에 의해 정보가 노출될 가능성이 존재하므로, 메모리에 대한 보호대책을 적용해야 함
응용프로그램 개발자가 변수 및 버퍼를 평문으로 사용하지 않거나, 중요 Activity에서 변수 및 버퍼의 데이터를 주기적으로 초기화 또는 삭제해야 하며, 메모리 보안 솔루션을 도입하여 메모리상에 중요정보가 노출되지 않도록 보호대책을 구현해야 함
- 모바일 단말기 메모리에 민감한 정보가 평문으로 저장되지 않도록, 사용 후 관련 메모리 영역을 알 수 없는 값으로 초기화 하거나, 민감한 정보가 삭제되도록 해야 하며, 메모리상에 프로세스 활성화 동안의 중요정보를 다뤄야 하는 곳에서는 String이 아닌 char [] 저장하여야 함
 
1. P_TRACED flag 사용
앱이 실행되고 있을 때 커널은 P)TRACED flag와 같은 특정 flag에 대한 상태를 인지하고 있음.
Flag 값이 1일 경우 디버거가 연결된 상태이며, flag 값이 0일 경우 보통의 상태를 의미함. 이와 같은 flag 값 체크를 통해 디버거를 탐지하는 방법

2. ptrace 함수 사용
ptrace 함수와 PT_DENY_ATTACH 매개변수를 사용하여 앱이 실행되고 디버거가 첨부되려고 하면 세그먼트 오류를 발생시키는 방법

여기 가이드에서 다음 글에 집중해보자 

응용프로그램 개발자가 변수 및 버퍼를 평문으로 사용하지 않거나, 중요 Activity에서 변수 및 버퍼의 데이터를 주기적으로 초기화 또는 삭제해야 하며, 메모리 보안 솔루션을 도입하여 메모리상에 중요정보가 노출되지 않도록 보호대책을 구현해야 함

제일 쉬운 방법은 마지막 방법인 메모리 보안솔루션을 사용하면 되겠지만 위 경우에는 돈으로 발라야만 해결할 수 있는 취약점이다보니 논외로 하고 직접 해결하기 위해서는 다음 방법 두개에 방법을 취사선택해야하며
이중 이글에서 먼저 적을 방법은 '변수 및 버퍼를 평문으로 사용하지 않거나'의 방법을 적을 것이다.

해결방법에 앞서 취약점에 시나리오는 다음과 같다.
1.해커는 본인이 로그인 시도 후 본인의 핸드폰으로 메모리 덤프를 통해 저장 값들을 확인한다
2. 저장값 확인결과 'usr_id'아래 아이디 값이 'usr_pw' 아래는 패스워드 값이 저장된 것을 확인한다.
3. 이제 희생자의 핸드폰을 메모리 덤프해 'usr_id'와 'usr_pw'값을 검색하여 아이디와 패스워드 값을 얻는다

위의 취약점에서 핵심은 '3번 항목' 키값이다.
즉 아이디와 패스워드가 평문으로 나오는 것보다 위치를 알려주는 키값 'user_id'와 'user_pw'가 존재하는 것이 문제이다.
메모리는 Random Access Memory답게 변수의 저장 위치는 랜덤하기에 jongchan/security1234에 위치는 항상 달르지만 
몇만 라인에서 키 값이 존재하지 않는다면 무엇이 아이디고 패스워드인지 쉽게 추측 할 수 없을 것이다.
즉 아이디와 패스워드를 남기지 않거나 키값을 남기지 않는다면 해결되는 문제이다.

그럼 이제는 그 방법에 대한 설명이다.
1. no-cache no-store must-revalidate
캐시데이터란 사용한 입력된 데이터를 잠시동안 저장하는 하는 기술로 서버에서 저장하도록 설정한다. 
이때 cache cotrol에 대해 no cache no store 옵션을 사용하면 두가지 설정이 사용된다.
1. no cache:
제일 헷갈릴 수 있는 부분으로cache를 쓰지말라는 것이 아닌 캐시를 써야할지에 대한 유효성을 서버에 요청하는 것이다. 
즉 no-cache라는 뜻은 캐시로 저장하는 것이 아닌 내가 캐시라고 저장한것을 서버에서 계속 확인하라는 뜻이 된다.
(max-age=0과 같은 효과를 볼 수 있다)
2. no store:
진정한 캐시를 쓰지말라는 값이다. 캐시에서 가장 중요한것은 클라이언트에서 저장을 하여 사용하는 것이 가장 핵심인데 이때 저장하지말라는 뜻은 해당 옵션으로 이 옵션을 써야 캐시로 저장하지 않는다.
3.must-revalidate:
캐시에 대해 만료될 시 서버에서 반드시 검증을 요청하는 설정입니다. no-cache는 max-age=0과 같은 효과를 보기에 캐시로 저장 된 데이터는 무조건 만료된 데이터가 되기에 서버에서 검증을 필수로 요청하는 것으로 설정할 수 있다.

즉 cache-control을 no-cache, no-store, must-revalidate 사용시 데이터에 대해 저장도 하지 않고 받는 데이터 모두 서버는 계속 검증을 하며 메모리의 저장을 최소화 할 수 있다. 

이후 다른 방법은 글이 길어져 다음 글에서 적어야겠다

반응형