본문으로 건너뛰기

"보안" 태그로 연결된 21 개 게시물 개의 게시물이 있습니다.

사이버 보안, 스마트 계약 감사 및 모범 사례

모든 태그 보기

복사-붙여넣기 범죄: 간단한 습관이 암호화폐 지갑에서 수백만을 빼앗는 방법

· 약 4 분
Dora Noda
Software Engineer

암호화폐를 보낼 때 여러분은 어떤 절차를 밟나요? 대부분은 거래 내역에서 수신자의 주소를 복사하는 것이죠. 0x1A2b...8f9E 와 같은 40자 문자열을 외우는 사람은 없으니까요. 모두가 사용하는 편리한 바로 가기입니다.

하지만 그 편리함이 정교하게 꾸며진 함정일 수도 있습니다.

블록체인 주소 중독이라는 파괴적인 사기가 바로 이 습관을 노리고 있습니다. 카네기 멜론 대학의 최신 연구에 따르면, 이 위협은 엄청난 규모에 이른다고 합니다. 이더리움과 바이낸스 스마트 체인(BSC) 네트워크만으로도 2년 동안 사기꾼들은 2억 7천만 건 이상의 공격을 시도했으며, 1천 7백만 명의 피해자를 겨냥해 최소 8,380만 달러를 탈취했습니다.

이는 틈새 위협이 아니라 오늘날 가장 크고 성공적인 암호화 피싱 수법 중 하나입니다. 작동 원리와 보호 방법을 살펴보겠습니다.


사기의 작동 원리 🤔

주소 중독은 시각적 트릭을 이용합니다. 공격자의 전략은 단순하지만 뛰어납니다.

  1. 유사 주소 생성: 공격자는 사용자가 자주 송금하는 주소를 파악한 뒤, 강력한 컴퓨터를 이용해 시작과 끝 문자가 정확히 일치하는 새로운 암호화 주소를 만들어냅니다. 대부분의 지갑과 블록 탐색기는 주소를 축약해서 표시하기 때문에(0x1A2b...8f9E), 사기 주소는 눈에 보기에 진짜와 동일합니다.

  2. 거래 내역에 “독” 주입: 다음으로 공격자는 그 유사 주소를 여러분의 지갑 내역에 넣어야 합니다. 이를 위해 “독” 거래를 보냅니다. 방법은 다음과 같습니다.

    • 소액 전송: 공격자는 유사 주소에서 아주 작은 금액(예: $0.001)을 보냅니다. 그러면 해당 주소가 최근 거래 목록에 나타납니다.
    • 무가치 전송: 더 교묘하게는 많은 토큰 계약에 존재하는 기능을 악용해, 여러분이 그 주소로 보낸 것처럼 보이는 0달러 전송을 만들어냅니다. 이렇게 하면 가짜 주소가 더욱 신뢰성을 얻게 됩니다.
    • 가짜 토큰 전송: “USDTT”(USDT가 아니라)와 같은 가치 없는 토큰을 만들어, 이전에 실제로 보낸 금액과 비슷하게 보이도록 전송합니다.
  3. 실수 기다리기: 이제 함정이 완성되었습니다. 다음에 정당한 상대에게 송금하려고 할 때, 여러분은 거래 내역을 스캔하고, 올바른 주소라고 생각되는 것을 복사해 전송합니다. 실수를 깨달았을 때는 이미 자금이 사라진 뒤이며, 블록체인의 불가역성 때문에 은행에 전화해도 되돌릴 방법이 없습니다.


범죄 조직의 실태 🕵️‍♂️

이것은 고독한 해커가 만든 것이 아닙니다. 연구에 따르면, 이러한 공격은 규모가 크고 조직적인 범죄 집단에 의해 수행됩니다.

목표 대상

공격자는 소액 계정을 낭비하지 않습니다. 그들은 다음과 같은 사용자를 체계적으로 노립니다.

  • 부유한 사용자: 스테이블코인 등 큰 잔액을 보유한 사람.
  • 활발한 사용자: 빈번하게 거래를 하는 사람.
  • 고액 거래자: 대규모 금액을 옮기는 사람.

하드웨어 무기 경쟁

유사 주소를 생성하는 것은 무차별 대입(brute‑force) 연산 작업입니다. 일치시킬 문자 수가 많을수록 난이도는 기하급수적으로 상승합니다. 대부분의 공격자는 일반 CPU로 어느 정도 설득력 있는 가짜 주소를 만들지만, 가장 정교한 범죄 조직은 한 차원 높은 하드웨어를 사용합니다.

이 최상위 그룹은 목표 주소의 20자까지 일치시키는 주소를 생성했습니다. 이는 일반 컴퓨터로는 거의 불가능한 수준이며, 연구진은 이들이 GPU 팜—고성능 게임이나 AI 연구에 쓰이는 대규모 그래픽 처리 장치—을 활용하고 있다고 결론지었습니다. 막대한 초기 투자에도 불구하고 피해자들로부터 빠르게 회수하기 때문에 비즈니스 모델이 성립합니다. 조직적인 범죄 집단이 운영하는 사업이 바로 여기 있습니다.


자산을 보호하는 방법 🛡️

위협은 정교하지만 방어는 간단합니다. 나쁜 습관을 끊고 더 경계하는 태도를 갖추면 됩니다.

  1. 모든 사용자에게 (가장 중요한 부분)

    • 전체 주소를 확인하세요. “확인” 버튼을 누르기 전, 주소 전체를 문자 하나하나씩 눈으로 확인하는 데 5초만 더 투자하세요. 앞뒤 몇 자리만 보는 실수를 피합니다.
    • 주소록을 활용하세요. 신뢰할 수 있는 주소를 지갑의 주소록이나 연락처에 저장하고, 송금 시 동적 거래 내역이 아니라 주소록에서 선택하도록 합니다.
    • 테스트 송금을 실행하세요. 큰 금액이나 중요한 결제일 경우, 먼저 소액을 보내 상대에게 도착했는지 확인한 뒤 전체 금액을 전송합니다.
  2. 지갑 개발자를 위한 제안

    • 사용자 인터페이스를 개선해 기본적으로 주소를 더 많이 표시하거나, 소액·무가치 전송만으로 상호작용한 주소에 대해 강력하고 명시적인 경고를 추가하도록 합니다.
  3. 장기적인 해결책

    • 이더리움 네임 서비스(ENS)와 같은 시스템을 활용하면 yourname.eth 같은 인간 친화적인 이름을 주소에 매핑할 수 있어, 이 문제를 근본적으로 차단할 수 있습니다. 널리 채택되는 것이 핵심입니다.

탈중앙화된 세계에서 여러분은 스스로 은행이자 보안 책임자입니다. 주소 중독은 편리함과 부주의를 노리는 조용하지만 강력한 위협입니다. 신중하게 두 번 확인함으로써 여러분의 소중한 자산이 사기꾼의 함정에 빠지는 일을 방지할 수 있습니다.

Ethereum의 익명성 신화: 연구원들이 검증자 15%를 어떻게 밝혀냈는가

· 약 5 분
Dora Noda
Software Engineer

Ethereum 과 같은 블록체인 기술의 핵심 약속 중 하나는 일정 수준의 익명성이다. 검증자라 불리는 참여자들은 암호화된 가명 뒤에 숨겨져 실제 신원을 보호하고, 따라서 보안도 확보된다고 여겨진다.

하지만 ETH Zurich 와 기타 기관의 연구원들이 발표한 최근 논문 “Deanonymizing Ethereum Validators: The P2P Network Has a Privacy Issue”는 이 가정에 중대한 결함이 있음을 밝혀냈다. 그들은 검증자의 공개 식별자를 해당 검증자가 실행 중인 머신의 IP 주소와 직접 연결하는 간단하고 저비용인 방법을 시연했다.

요컨대, Ethereum 검증자는 많은 사람들이 생각하는 만큼 익명하지 않다. 이 발견은 Ethereum Foundation 으로부터 버그 현상금까지 수여받을 정도로 프라이버시 유출의 심각성을 인정받았다.

취약점 작동 원리: 가십(Gossip) 내 결함

취약점을 이해하려면 먼저 Ethereum 검증자들이 어떻게 통신하는지 기본적인 그림을 그려야 한다. 네트워크에는 백만 명이 넘는 검증자가 존재하며, 이들은 지속적으로 체인의 상태에 대해 “투표”한다. 이러한 투표를 attestation(인증)이라 하며, 피어‑투‑피어 (P2PP2P) 네트워크를 통해 모든 다른 노드에 전파된다.

검증자가 너무 많아 모든 투표를 모두에게 전파하면 네트워크가 즉시 과부하된다. 이를 해결하기 위해 Ethereum 설계자는 영리한 확장 방안을 도입했다: 네트워크를 64개의 별도 통신 채널, 즉 subnet(서브넷)으로 나눈 것이다.

  • 기본적으로 각 노드(검증자 소프트웨어가 실행되는 컴퓨터)는 이 64개 서브넷 중 두 개에만 구독한다. 노드의 주요 역할은 그 두 채널에서 보는 모든 메시지를 충실히 중계하는 것이다.
  • 검증자가 투표를 해야 할 때, 해당 attestation 은 무작위로 64개 서브넷 중 하나에 할당되어 전파된다.

바로 여기서 취약점이 발생한다. 예를 들어, 채널 12와 13만 관리하도록 설정된 노드가 있다고 하자. 이 노드는 하루 종일 그 두 채널의 메시지만을 전달한다. 그런데 어느 순간, 채널 45에 속한 메시지를 받게 된다.

이는 강력한 단서다. 왜 노드가 자신이 담당하지 않은 채널의 메시지를 처리하겠는가? 가장 논리적인 결론은 그 노드 자체가 해당 메시지를 생성했다는 것이다. 즉, 채널 45에 대한 attestation 을 만든 검증자가 바로 그 머신에서 실행되고 있다는 의미다.

연구진은 바로 이 원리를 이용했다. 자신들의 청취 노드를 구축하고, 피어들이 어느 서브넷에서 attestation 을 보내는지 모니터링했다. 피어가 공식적으로 구독하지 않은 서브넷에서 메시지를 보낼 경우, 그 피어가 해당 검증자를 호스팅하고 있다고 높은 확신을 가지고 추론할 수 있었다.

이 방법은 놀라울 정도로 효과적이었다. 세 날 동안 네 개의 노드만 사용해 팀은 161,000개 이상의 검증자 IP 주소를 찾아냈으며, 이는 전체 Ethereum 네트워크의 15% 이상에 해당한다.

왜 중요한가: 익명성 해제의 위험

검증자의 IP 주소가 노출되는 것은 사소한 문제가 아니다. 이는 개별 운영자를 겨냥한 공격은 물론, 전체 Ethereum 네트워크의 건전성을 위협하는 문을 연다.

1. 표적 공격 및 보상 탈취
Ethereum 은 다음 블록을 제안할 검증자를 몇 분 전에 공개한다. 공격자는 해당 검증자의 IP 주소를 알면 DDoS(서비스 거부) 공격을 감행해 트래픽을 폭주시켜 오프라인 상태로 만들 수 있다. 검증자가 4초 안에 블록을 제안하지 못하면 기회는 다음 검증자에게 넘어간다. 공격자가 바로 그 다음 검증자라면, 피해자 대신 블록 보상과 귀중한 트랜잭션 수수료(MEV)를 차지할 수 있다.

2. 네트워크 가용성 및 안전성 위협
자원이 풍부한 공격자는 이러한 “스니핑” 공격을 반복해 전체 블록체인의 처리 속도를 늦추거나 정지시킬 수 있다(가용성 공격). 더 심각한 경우, 이 정보를 이용해 네트워크 분할 공격을 수행해 체인의 이력에 대한 합의를 깨뜨릴 수 있다(안전성 공격).

3. 중앙화된 현실 드러남
연구는 네트워크 탈중앙화에 대한 불편한 진실도 밝혀냈다:

  • 극단적 집중: 팀은 하나의 IP 주소가 19,000개 이상의 검증자를 운영하고 있음을 발견했다. 단일 머신의 장애가 네트워크에 과도한 영향을 미칠 수 있다.
  • 클라우드 의존: 찾아낸 검증자의 90% 이상이 AWS, Hetzner 등 클라우드 제공업체에서 운영되고 있었다. 이는 개인 홈 스테이커가 아닌 클라우드에 의존하고 있음을 의미한다.
  • 숨겨진 의존성: 많은 대형 스테이킹 풀은 운영자가 독립적이라고 주장하지만, 연구 결과 서로 경쟁하는 풀의 검증자들이 같은 물리 머신에서 실행되고 있는 사례가 발견돼 시스템적 위험이 은폐돼 있음을 보여준다.

완화 방안: 검증자는 어떻게 스스로를 보호할 수 있는가?

다행히 이 익명성 해제 기법에 맞설 방법이 존재한다. 연구진은 다음과 같은 완화 방안을 제시했다:

  • 노이즈 증가: 검증자는 두 개 이상의 서브넷—심지어는 전체 64개—에 구독하도록 선택할 수 있다. 이렇게 하면 관찰자가 중계 메시지와 자체 생성 메시지를 구분하기 훨씬 어려워진다.
  • 다중 노드 운영: 운영자는 서로 다른 IP를 가진 여러 머신에 검증자 역할을 분산시킬 수 있다. 예를 들어, 하나의 노드는 attestation 전송에만 사용하고, 별도의 프라이빗 노드는 고가치 블록 제안에만 활용한다.
  • 프라이빗 피어링: 검증자는 신뢰할 수 있는 소수의 노드와 전용 연결을 구축해 메시지를 중계함으로써 진짜 출처를 작은 신뢰 그룹 안에 숨길 수 있다.
  • 익명 브로드캐스트 프로토콜: Dandelion 과 같이 메시지의 출처를 무작위 “줄기(stem)”를 통해 전달한 뒤 널리 퍼뜨리는 방식을 구현하면 출처 추적을 더욱 어렵게 만든다.

결론

이 연구는 분산 시스템에서 성능과 프라이버시 사이의 근본적인 트레이드오프를 강력히 보여준다. 확장성을 위해 Ethereum 의 P2PP2P 네트워크가 채택한 설계는 가장 핵심적인 참여자들의 익명성을 희생시켰다.

취약점을 공개함으로써 연구진은 Ethereum 커뮤니티에 문제 인식과 해결 방안을 제공했다. 이 작업은 보다 견고하고 안전하며 진정으로 탈중앙화된 네트워크를 구축하기 위한 중요한 첫걸음이다.

Docker Compose + Ubuntu 로 안전한 배포

· 약 5 분

실리콘밸리 스타트업에서는 Docker Compose가 컨테이너화된 애플리케이션을 빠르게 배포하고 관리하기 위한 선호 도구 중 하나입니다. 하지만 편리함에는 보안 위험이 따르기 마련이죠. 사이트 신뢰성 엔지니어(SRE)로서 보안 취약점이 가져올 수 있는 재앙적인 결과를 잘 알고 있습니다. 이 글에서는 Docker Compose와 Ubuntu 시스템을 실제 업무에 결합해 적용하면서 정리한 최고의 보안 관행을 공유합니다. Docker Compose의 편리함을 누리면서도 시스템 보안을 확실히 지키는 방법을 알려드리겠습니다.

Docker Compose + Ubuntu 로 안전한 배포

I. Ubuntu 시스템 보안 강화

컨테이너를 배포하기 전에 Ubuntu 호스트 자체의 보안을 확보하는 것이 가장 중요합니다. 주요 단계는 다음과 같습니다.

1. Ubuntu와 Docker를 정기적으로 업데이트

시스템과 Docker 모두 최신 상태를 유지해 알려진 취약점을 즉시 패치합니다.

sudo apt update && sudo apt upgrade -y
sudo apt install docker-ce docker-compose-plugin

2. Docker 관리 권한 제한

Docker 관리 권한을 엄격히 제어해 권한 상승 공격을 방지합니다.

sudo usermod -aG docker deployuser
# 일반 사용자가 쉽게 Docker 관리 권한을 얻지 못하도록 함

3. Ubuntu 방화벽(UFW) 설정

네트워크 접근을 합리적으로 제한해 무단 접근을 차단합니다.

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

4. Docker와 UFW 연동 올바르게 구성

Docker는 기본적으로 UFW를 우회해 iptables를 설정하므로 수동 제어가 필요합니다.

Docker 설정 파일을 수정합니다:

sudo nano /etc/docker/daemon.json

다음 내용을 추가합니다:

{
"iptables": false,
"ip-forward": true,
"userland-proxy": false
}

Docker 서비스를 재시작합니다:

sudo systemctl restart docker

Docker Compose에서 주소를 명시적으로 바인딩합니다:

services:
webapp:
ports:
- "127.0.0.1:8080:8080"

II. Docker Compose 보안 모범 사례

아래 설정은 Docker Compose v2.4 이상을 기준으로 합니다. Swarm 모드와 비 Swarm 모드의 차이점에 유의하세요.

1. 컨테이너 권한 제한

컨테이너가 기본적으로 root 권한으로 실행되면 위험이 크므로 비 root 사용자로 전환합니다.

services:
app:
image: your-app:v1.2.3
user: "1000:1000" # 비 root 사용자
read_only: true # 읽기 전용 파일시스템
volumes:
- /tmp/app:/tmp # 쓰기 권한이 필요한 경우에만 특정 디렉터리 마운트
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE

설명

  • 읽기 전용 파일시스템은 컨테이너 내부에서의 변조를 방지합니다.
  • 마운트하는 볼륨은 반드시 필요한 디렉터리만 제한합니다.

2. 네트워크 격리 및 포트 관리

내부 네트워크와 외부 네트워크를 명확히 구분해 민감한 서비스가 외부에 노출되지 않도록 합니다.

networks:
frontend:
internal: false
backend:
internal: true

services:
nginx:
networks: [frontend, backend]
database:
networks:
- backend
  • frontend 네트워크: 외부에 공개 가능.
  • backend 네트워크: 내부 통신 전용으로 엄격히 제한.

3. 비밀 관리 보안

민감한 데이터는 Compose 파일에 직접 넣지 않습니다.

단일 머신 모드:

services:
webapp:
environment:
- DB_PASSWORD_FILE=/run/secrets/db_password
volumes:
- ./secrets/db_password.txt:/run/secrets/db_password:ro

Swarm 모드:

services:
webapp:
secrets:
- db_password
environment:
DB_PASSWORD_FILE: /run/secrets/db_password

secrets:
db_password:
external: true # Swarm 내장 비밀 관리 사용

주의

  • Docker Swarm의 기본 비밀 관리 기능은 Vault, AWS Secrets Manager와 같은 외부 도구를 직접 사용할 수 없습니다.
  • 외부 비밀 저장소가 필요하다면 자체적으로 읽어오는 로직을 구현해야 합니다.

4. 리소스 제한 (Docker Compose 버전에 맞게 적용)

컨테이너 하나가 호스트 리소스를 고갈시키는 일을 방지합니다.

단일 머신 모드 (v2.4 권장):

version: '2.4'

services:
api:
image: your-image:1.4.0
mem_limit: 512m
cpus: 0.5

Swarm 모드 (v3 이상):

services:
api:
deploy:
resources:
limits:
cpus: "0.5"
memory: 512M
reservations:
cpus: "0.25"
memory: 256M

Note: 비 Swarm 환경에서는 deploy 섹션의 리소스 제한이 적용되지 않으니 Compose 파일 버전에 유의하세요.

5. 컨테이너 헬스 체크

헬스 체크를 설정해 문제를 사전에 감지하고 서비스 다운타임을 최소화합니다.

services:
webapp:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20s

6. latest 태그 사용 금지

프로덕션 환경에서는 latest 태그가 가져오는 불확실성을 피하고, 명시적인 이미지 버전을 지정합니다.

services:
api:
image: your-image:1.4.0

7. 로그 관리 적절히 수행

컨테이너 로그가 디스크를 가득 채우는 일을 방지합니다.

services:
web:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "5"

8. Ubuntu AppArmor 설정 확인

Ubuntu는 기본적으로 AppArmor를 활성화합니다. Docker 프로파일 상태를 확인하는 것이 좋습니다.

sudo systemctl enable --now apparmor
sudo aa-status

Ubuntu에서 Docker는 기본적으로 AppArmor를 활성화하므로 별도 설정이 필요하지 않습니다. Ubuntu에 SELinux를 동시에 활성화하면 충돌이 발생하므로 권장되지 않습니다.

9. 지속적인 업데이트와 보안 스캔

  • 이미지 취약점 스캔: CI/CD 파이프라인에 Trivy, Clair, Snyk 등 도구를 연동합니다.
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image your-image:v1.2.3
  • 자동 보안 업데이트 프로세스: 알려진 취약점을 해결하기 위해 최소 주 1회 이상 이미지를 재빌드합니다.

III. 사례 연구: Docker Compose 설정 실수에서 얻은 교훈

2019년 7월, Capital One은 1억 명이 넘는 고객의 개인 정보를 유출하는 대규모 데이터 유출 사고를 겪었습니다12. 주요 원인은 AWS 설정 오류였지만, 컨테이너 보안 문제도 크게 작용했습니다.

  1. 컨테이너 권한 문제: 공격자는 과도한 권한을 가진 컨테이너 내 WAF 취약점을 이용했습니다.
  2. 네트워크 격리 미비: 침해된 컨테이너가 다른 AWS 리소스에 접근할 수 있었으며, 이는 네트워크 격리가 충분히 이루어지지 않았기 때문입니다.
  3. 민감 데이터 노출: 설정 오류로 인해 대량의 고객 민감 데이터에 접근·탈취가 가능했습니다.
  4. 보안 설정 실수 누적: 컨테이너와 클라우드 서비스 설정 오류가 복합적으로 작용해 사고가 확대되었습니다.

이 사건으로 Capital One은 수억 달러 규모의 벌금과 장기적인 신뢰 위기를 겪었습니다. 권한 관리, 네트워크 격리, 민감 데이터 보호 등 보안 설정의 중요성을 다시금 일깨워 주는 사례라 할 수 있습니다.

IV. 결론 및 권고사항

Docker Compose와 Ubuntu 조합은 컨테이너 애플리케이션을 빠르게 배포하는 편리한 방법이지만, 보안은 전체 프로세스에 걸쳐 내재되어야 합니다.

  • 컨테이너 권한과 네트워크 격리를 철저히 관리합니다.
  • 민감 데이터가 유출되지 않도록 비밀 관리를 강화합니다.
  • 정기적인 보안 스캔과 업데이트를 수행합니다.
  • 기업 규모가 커짐에 따라 Kubernetes와 같은 고급 오케스트레이션 시스템으로 전환을 고려합니다.

보안은 끝이 없는 연속적인 실천입니다. 이 글이 Docker Compose + Ubuntu 환경을 보다 안전하게 운영하는 데 도움이 되길 바랍니다.