
Stratagems #15: Derek와 Alex는 하나의 서버를 공유했다. ACL의 AI는 둘 모두를 도청하고 있었다.
요약
Derek와 Alex가 공유 서버에서 데이터 보안 취약점을 발견하는 과정을 다룬 기술 서사입니다. 서로 다른 기업의 데이터가 제한 없는 쓰기 권한을 가진 임시 노드에 혼재되어 있는 보안 사고 상황을 묘사합니다.
핵심 포인트
- 서로 다른 기업의 데이터가 동일한 서버 디렉터리에 노출됨
- 임시 데이터 교환 노드의 권한 설정 미비로 인한 보안 위협
- 로그 디렉터리 명명 규칙 불일치를 통한 취약점 추적 과정
적이 유리한 지형을 점령했을 때, 정면으로 공격하지 마라. 미끼를 사용하여 호랑이를 산 아래로 유인하라. 그런 다음 산을 차지하라.
— 삼십육계 (The 36 Stratagems), 이호출산 (Lure the Tiger Down the Mountain)
이 시리즈의 이전 이야기:
#2: Derek Shaw는 또 다른 AI의 약속에 빠져들었다. 파이프라인 (Pipeline)은 더 나은 계획을 가지고 있었다. — Derek는 QualiGuard에서 Finova 계약을 놓쳤다. 주차장에서 Lena는 차에 타기 전 뒤를 돌아보며 말했다. "다음에 제안서를 작성할 때는 — 당신이 밖에서 무엇을 하고 있는지 상사에게 반드시 알리도록 하세요." 그 한마디가 그를 따라다녔다. MediSys에서 그는 거의 같은 실수를 저지를 뻔했다. 모델 대신 ETL 파이프라인 (ETL pipeline)을 수정했고, OmniDx의 백서 (white paper)를 이용해 그들을 이겼다. 하지만 부사장 Morgan은 여전히 그를 꿰뚫어 보았다. 그는 여전히 상사에게 보고하지 않은 상태였다.
#8: Alex는 AI 대시보드 (Dashboard)가 장악하는 것을 지켜보았다. 그는 열쇠를 탁자 아래에 숨겨두었다. — MedTech는 7자리 수의 AI 운영 모니터링 시스템을 체결했다. Alex는 교육 리드로 배정되었다. 모두의 눈을 피해 그는 "훈련 환경 (training environment)"이라고 표시된 두 번째 모니터링 패널을 구축했다. 3주 후, 벤더의 대시보드 (dashboard)가 다운되었다. Alex의 숨겨진 패널만이 유일하게 작동하고 있었다.
Alex와 Derek가 작업 그룹이 아닌 곳에서 진정으로 대화를 나눈 것은 이번이 처음이었다.
FHIR 표준 위원회 분기별 회의에서, 그들은 세 좌석 떨어진 같은 줄에 앉아 동일한 제안에 반대 표를 던졌다. 그들은 서로의 이름을 알고 있었다. 그게 전부였다.
두 달 후, Derek는 스테이징 환경 (staging environment)의 파티션 설정 (partition config)을 수정하고 있었다. MediSys는 막 대형 병원과 계약을 체결한 상태였고, AI 진단 검증 플랫폼 (AI diagnostic validation platform)은 통합 테스트 (integration testing) 단계에 있었다. 그는 /etc/logrotate.d/에서 MediSys의 명명 규칙 (naming convention)과 일치하지 않는 접두사가 붙은, 로테이션되지 않은 로그 디렉터리 (unrotated log directory)를 발견했다. 그는 이를 상류 (upstream)로 추적했다.
하나의 서버. "임시 데이터 교환 노드 (temporary data exchange node)"라고 라벨이 붙어 있었다. MedTech의 공급망 주문 스트림 (supply chain order stream)과 MediSys의 진단 검증 기록 (diagnostic validation records)이 동일한 디렉터리에 놓여 있었다. 쓰기 권한 (Write permissions)은 제한되지 않은 상태였다. 병원의 통합 사양서 (integration spec)에는 _"양측 모두 이 노드에서 데이터 정렬 (data alignment)을 완료할 것을 권장함"_이라는 문구가 있었다. 아무도 이를 닫는 것을 기억하지 못했다.
Derek는 FHIR 위원회 디렉터리를 조회하여 이름을 찾아냈다. 그리고 개인 메시지를 보냈다:
귀사의 멸균 기록 (sterilization records)이 제 스테이징 환경에 들어와 있습니다.
세 시간 후, 답장이 왔다. 단 한 줄의 명령어였다.
Derek는 그 명령어를 실행했다. 문제는 해결되었다. 두 번째 문장은 없었다.
그것이 그들이 진정으로 대화를 나눈 첫 번째 순간이었다.
점선 (The Dotted Line)
새로운 병원 통합 건은 3주 차에 컴플라이언스 감사 (compliance audit)에 들어갔다. MediSys의 PMO는 부서 전체에 이메일을 보냈다:
"ACL의 AI 감사 도구 (AI audit tool)가 이번 통합을 위한 제3자 컴플라이언스 검증 구성 요소 (third-party compliance validation component)로 승인되었습니다. 모든 데이터 파이프라인 (data pipelines)은 목요일까지 연결될 예정입니다."
Derek는 커피를 마시다 그것을 발견했다. 그는 컵을 내려놓고 통합 아키텍처 다이어그램 (integration architecture diagram)을 열었다.
ACL의 수집기 (collector)는 다이어그램의 오른쪽 하단 모서리에 "감사 데이터 유출 (Audit Data Egress)"라고 라벨이 붙어 있었으며, 병원의 네트워크 경계 (network boundary)와 점선으로 연결되어 있었다. Derek는 이를 역추적했다. 수집기에는 입력값이 단 하나뿐만이 아니었다. 그것은 세 개의 라인을 통해 병원의 통합 게이트웨이 (integration gateway)로부터 데이터를 가져오고 있었다: 진단 검증 결과 (diagnostic validation results), 공급망 주문 데이터 (supply chain order data), 그리고 환자 관리 메타데이터 (patient management metadata). 전체 데이터였다. 실시간이었다.
다이어그램의 주석 (annotation) 열에 있는 각주: "병원 측이 서명한 감사 데이터 접근 권한 (Audit data access authorization)."
Derek은 오랫동안 다이어그램을 응시했다.
ACL은
"확인되었습니다. Collector (수집기)가 작동 중입니다. 전체 미러링(Full mirror) 중입니다. 출력값은 ACL의 audit pipeline (감사 파이프라인)으로 전송됩니다."
Derek은 _"어떻게 확인했나"_라고 묻지 않았다. 그는 잠시 말을 멈췄다.
"차단할 수 있나?"
통신망에 몇 초간 정적이 흘렀다.
"직접 끌 수는 없습니다. 출력 방향을 오도(misdirect)해야 합니다."
유인책 (The Lure)
"ACL의 audit engine (감사 엔진)은 패턴 매칭 (pattern matching)만 할 줄 압니다," Alex가 말했다. "의구심을 갖지 않죠. 두 개의 소스에서 동일한 이상 징후(anomaly)를 보고하면 — 신뢰도(confidence)가 급증하며, 자동으로 우선순위가 높게 격상됩니다. 인간 감사관들은 우선순위가 높은 경고를 보면, 모든 일을 제쳐두고 그것을 추적하게 됩니다."
이전에 MedTech에서 그는 설정(config) 한 줄을 변경하여, 이상 징후 요약 신뢰도 임계값(confidence threshold)을 0.7에서 0.0으로 낮춘 적이 있었다. 그것은 동쪽을 향한 기만술(feint)이었다.
이번에는 그 반대였다. 엔진이 무시할 수 없는 신호를 만드는 것이다.
"엔진이 학습한 알려진 경고 패턴이 있습니다. 세 개의 소스 간 배치 번호(batch number)와 멸균 날짜(sterilization date) 불일치입니다," Alex가 말했다. "공급망 감사(supply chain audit)의 교과서적인 레드 플래그(red flag)죠. 엔진은 이를 놓아주지 않을 겁니다."
"그걸 어떻게 알지?"
"그들의 백서(white paper)에 나와 있습니다."
"결국에는 가짜라는 걸 알아차리겠지만," Alex가 덧붙였다. "그때쯤이면 흔적은 사라진 뒤일 겁니다."
Derek은 더 이상 묻지 않았다.
Alex는 MedTech 측 작업을 진행했다.
그는 배치 번호 LOT-2407-842를 선택했다. IV 튜브다. 멸균 날짜는 2025-07-10이다. 숨겨진 파이프라인의 복사본에서 그는 멸균 날짜를 3일 뒤인 2025-07-13으로 변경했다. 운영 데이터베이스(production database)는 건드리지 않았다. 수정된 레코드(record)는 파이프라인을 통해 게이트웨이(gateway)로 전달되었다. 게이트웨이의 audit mirror channel (감사 미러 채널)은 운영 경로(production path)와 분리되어 있었다. 변경된 데이터는 미러 채널로만 유입되었을 뿐, 병원의 내부 시스템에는 절대 들어가지 않았다. 미러 채널의 끝에서 ACL의 collector (수집기)가 이를 읽어 들였다.
Derek은 MediSys 측 작업을 진행했다.
그는 스테이징 환경(staging environment)의 진단 검증 레코드(diagnostic validation record)에 동일한 배치 번호를 주입했다. 운영 환경이 아닌 스테이징 환경이었으며, 스테이징은 완전히 격리되어 있었다. 레코드에는 다음과 같이 적혀 있었다: "배치 LOT-2407-842, 멸균 날짜 2025-07-13, 공급업체 원본 레코드와 불일치."
두 개의 회사. 두 개의 출처. 하나의 이상 징후.
두 시간 후, ACL의 감사 엔진 (audit engine)이 경고를 발생시켰다:
[RED] 조달 사기 위험: 이중 출처 교차 검증 확인됨
배치 (Batch): LOT-2407-842
멸균 날짜 불일치: 공급업체 레코드 ≠ MedTech 레코드 ≠ MediSys 레코드
신뢰도: 96%
엔진은 감사 티켓 (audit ticket)을 자동으로 생성했다. 제목: "공급망 멸균 기록 조작 의심, 두 개의 독립적인 데이터 출처와 연관됨, 긴급 조사 권고."
해당 티켓은 온콜 (on-call) 감사 그룹 내 ACL의 최고 우선순위 큐 (queue)에 할당되었다.
윈도우 (The Window)
모든 ACL 감사 엔지니어들이 해당 배치 사기 조사로 전환했다.
감사 파이프라인 (audit pipeline)의 라우팅 설정 (routing config) 패널은 40분 넘게 수정되지 않은 상태였다. 데이터 미러 수집기 (data mirror collector)는 여전히 작동 중이었으나, 예외 규칙 (exception rule) 창이 열려 있었다. 감사 팀은 오탐 (false positives)이 자신들의 조사를 방해하는 것을 원치 않았다. 그들은 수집기의 실시간 경고 임계값 (real-time alert threshold)을 한 단계 높였고, 자신들의 작업이 경고를 트리거할 경우를 대비해 설정 변경 경고 임계값 (config-change alert threshold)도 함께 높였다.
Alex가 그 창을 발견했다. 그는 Derek에게 전화를 걸었다. 신호음이 한 번 울렸다.
"윈도우가 열렸어," Alex가 말했다. "수집기 설정 경로 (collector's config path) — /etc/acl/collector.conf. output_dest 라인 말이야. 네 테스트 서버로 바꿔."
"MediSys로 다시 돌려놓지 말고?"
"아니. 네가 볼 수 있는 곳으로 바꿔. 다음에 그들이 수집기를 교체할 때, 바로 알 수 있게 말이야."
질문할 필요도 없었다. Derek는 터미널을 열고, MediSys의 운영 게이트웨이 (ops gateway)에서 병원 통합 게이트웨이 (hospital integration gateway)의 관리 인터페이스로 로그인했다. 이전 테스트 때 만들어둔 디버그 별칭 (debug alias)에 여전히 경로가 남아 있었다.
그는 ACL의 수집기 설정 파일을 찾아냈다. 그리고 output_dest 라인을 발견했다:
output_dest: acl_audit_pipeline
그는 다음과 같이 변경했다:
output_dest: medisys_test_node.local/sandbox/
저장. 종료. 서비스 재시작 알림 없음. 경고 없음.
"끝났어," Derek가 말했다.
"확인."
Alex가 전화를 끊었다.
Derek는 스테이징 환경 (staging environment)의 인젝션 흔적 (injection traces)을 정리했다. 통합 게이트웨이 (integration gateway)로부터 오는 진단 검증 (diagnostic validation) 결과를 MediSys의 내부 파이프라인 (internal pipeline)으로 다시 라우팅했다. ACL이 데이터를 읽을 수 있었던 모든 경로였다. 이제 데이터는 더 이상 그곳을 통과하지 않았다.
그는 메시지를 보냈다:
Clean.
7분 후, Alex가 답장을 보냈다:
It'll be back.
Derek는 메시지를 훑어보고 답장하지 않았다. 휴대폰을 잠그고 사무실을 나섰다.
화면에 읽지 않은 메시지가 하나 더 있었다. Alex가 몇 분 전에 한 줄을 더 보낸 것이었다.
The Third Cup
새벽 2시 40분. Derek는 테스트 서버 (test server)에서 디버그 케이블 (debug cable)을 뽑고, 노트북을 닫고 밖으로 걸어 나왔다.
두 블록. Third Cup을 지나서.
유리창 너머로 따뜻한 불빛이 새어 나오고 있었다. 그가 이 문 앞에 마지막으로 섰던 것은 꽤 오래전, 투자자 데이 (investor day) 발표를 마치고 MediSys를 나와 어쩌다 보니 이 거리에 도착했을 때였다. 그는 구석에 누군가 앉아 있는 것을 보았고, 테이블 위에는 MediSys라고 적힌 서류들이 흩어져 있었다. 그는 들어가지 않았다.
이전에도 이곳을 지나친 적이 있었다.
이번에는 문을 밀고 들어갔다.
바텐더는 고개를 들어 아무 말 없이 컵을 집어 들더니, 아메리카노를 따라 카운터 너머로 밀어주었다. 지난번에 Alex가 앉았던 바로 그 자리였다. 바의 맨 왼쪽, 벽을 등지고 문을 마주 보는 자리.
질문은 없었다. 그는 이미 단골들의 음료를 파악하고 있었다.
바 위에 코스터 (coaster)가 놓여 있었다. Derek는 잠시 그것을 응시했다.
그는 내일 아침 일찍 Morgan에게 말할 수 있었다. 스크린샷을 보내고, ACL의 콜렉터 (collector)가 정상적이지 않아 보인다고 말하면 된다. 그러면 Morgan이 처리할 것이다. 프로세스 (process), 법무 (legal), 그리고 병원과의 액세스 범위 (access scope) 재협상까지. 준수적이고, 안전하며, 깔끔한 처리 방식이다.
하지만 그 프로세스가 끝날 때쯤이면, ACL의 데이터는 이미 유출되고 난 후일 것이다.
그리고 Morgan은 똑같은 질문을 던질 것이다. "왜 진작 말하지 않았지?"
Derek는 커피를 한 모금 마셨다.
그날 밤 주차장에서. 차에 타기 전 뒤를 돌아보던 Lena의 말: "다음에 제안서를 작성할 때는 — 당신이 밖에서 무엇을 하고 있는지 상사가 반드시 알게 하세요."
그는 Morgan에게 말하지 않았다. 전과 마찬가지였다. 하지만 이번에는, 자신이 틀리지 않았다는 확신이 들지 않았다.
전화기가 밝게 빛났다.
Alex의 메시지였다.
그는 메시지를 열었다. 아까와 같은 내용이었다:
다시 돌아올 거야. 다음번에는 그 (기회의) 창이 더 짧아지겠지.
Derek는 잔을 비우고 일어섰다.
바텐더는 뒤도 돌아보지 않고 잔을 가져갔다.
"처음 오셨을 때 — 푸어오버 (pour-over)를 주문하셨죠."
Derek는 잠시 얼어붙었다. 대답하지 않았다. 그는 문을 밀어 열고 밖으로 걸어 나갔다.
밖은 여전히 어두웠다.
그는 휴대폰을 꺼냈다. 한 번 훑어보았다. 리다이렉트 파이프라인 (redirect pipeline)이 살아있었다. ACL의 데이터가 그의 샌드박스 (sandbox)로 흘러 들어오고 있었다.
그는 화면을 잠그고 역을 향해 걸어갔다.
이것이 바로 유인하산 (Lure the Tiger Down the Mountain) — 호랑이를 죽이는 것이 아니라, 산을 차지하는 것이다.
🤖 AI 사후 분석 (Post-Mortem)
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기