Reading text-only. View on full site →

앞 여섯 자와 뒤 여섯 자가 같았다

2026-10-16 · articles · ko

거래 내역에 내 주소와 앞뒤가 같은 가짜 주소를 심어 두고, 언젠가 그것을 복사해 가기를 기다리는 공격이 있다. 비트코인에서 실제로 0.1 BTC가 빠져나간 사례를 블록체인 기록으로 따라가고, 이더리움에서 이 공격이 훨씬 싼 이유, 같은 소액 입금이 프라이버시를 깨는 데 쓰이는 방식, 그리고 지갑에서 할 수 있는 대응을 정리한다.


2025년 1월 19일 02시 11분(UTC), 높이 879,853의 블록에 작은 거래 하나가 들어갔다. 입력 하나, 출력 하나. 443사토시를 가진 주소가 330사토시를 보냈고 나머지 113사토시는 수수료가 됐다. 받은 주소는 bc1qr9xkxanfstzqpfd5ce0t3evwc45pnmsr2wua0h였다. 보낸 주소는 bc1qr9wuw4zkjflet80lr9cr5ec8620c4fg52wua0h였다.

두 주소를 나란히 놓으면 앞의 bc1qr9와 뒤의 2wua0h가 같다. 가운데 서른 자는 다르다. 받은 쪽 주인의 지갑에는 이제 자기 주소와 앞뒤가 똑같아 보이는 주소에서 돈이 들어온 기록이 하나 생겼다.

53일 뒤인 3월 13일 09시 46분, 받은 쪽 주소에서 1 BTC짜리 코인이 쓰였다. 그 가운데 0.1 BTC가 앞뒤가 같은 그 주소로 갔다. 다음 날 0.1 BTC는 다시 다른 곳으로 옮겨졌다. 이것이 주소 오염(address poisoning)이다. 국내 보도에서는 주소 중독 공격이라고도 부른다.

가짜 기록을 심는 방법

공격은 세 단계다. 먼저 표적 주소와 앞뒤 몇 글자가 같은 주소를 만든다. 다음으로 그 주소에서 표적에게 아주 적은 금액을 보내, 표적의 거래 내역에 가짜 주소를 남긴다. 그리고 기다린다. 표적이 언젠가 주소를 새로 확인하지 않고 내역에서 복사해 쓰기를 기다리는 것이다.

비슷한 주소를 만드는 데에는 특별한 기술이 필요 없다. 키를 무작위로 만들고, 주소를 계산하고, 원하는 글자가 나올 때까지 반복한다. Bech32 주소는 한 글자가 32가지이므로 맞춰야 할 글자가 하나 늘 때마다 시도 횟수가 32배씩 는다. 위 사례에서 bc1q는 모든 SegWit v0 주소에 공통이니, 공격자가 실제로 맞춘 것은 앞의 r9 두 글자와 뒤의 여섯 글자, 모두 여덟 글자다. 32의 8제곱은 약 1조 1천억이다. 컴퓨터 한 대로 충분히 닿는 숫자다. 아홉 글자면 그 32배, 열 글자면 다시 32배가 된다. 앞뒤 네다섯 글자만 확인하는 습관은 공격자가 감당할 수 있는 비용 안에 정확히 들어 있다.

한 가지 더 있다. Bech32 주소의 마지막 여섯 글자는 체크섬이다. 주소에 오타가 났는지 검사하는 값이다. 사람들이 가장 많이 확인하는 자리가 바로 이 체크섬인데, 가짜 주소는 오타가 아니라 처음부터 올바르게 만든 주소이니 체크섬도 맞는다. 지갑은 아무 경고도 띄우지 않는다.

비트코인에서 이 공격이 드문 이유

Casa의 Jameson Lopp는 2025년 4월 비트코인 블록체인 전체를 훑어 이 공격의 흔적을 셌다. 입력과 출력이 하나씩이고, 입력 주소와 출력 주소의 앞 네 글자와 뒤 네 글자가 같은 거래를 찾는 방식이었다. 첫 흔적은 2023년 7월 7일 높이 797,570의 블록에 있었다. 그 뒤 2025년 1월까지 약 48,000건이 나왔다.

공격자가 쓴 돈도 세었다. 피해자에게 보낸 소액이 모두 0.0684 BTC, 수수료가 0.2231 BTC, 합쳐 약 0.29 BTC였다. 블록 공간으로는 블록 네 개 분량이다. 그리고 확인된 성공 사례는 한 건, 맨 앞에 쓴 0.1 BTC였다. 오염 거래를 받은 주소의 유형은 P2PKH, P2SH, P2WPKH였고, 탭루트(P2TR) 주소는 없었다. Lopp는 이 공격이 수수료가 낮을 때에만 경제성이 있다고 결론지었다.

맨 앞 사례의 공격 자금이 어디서 왔는지도 블록체인에 그대로 남아 있다. 2024년 11월 12일의 거래 하나가 출력 1,401개를 한 번에 만들었고, 그중 832개가 443사토시짜리였다. 가짜 주소에 들어간 443사토시가 그 가운데 하나다. 이 거래의 수수료율은 vB당 2.67사토시였고, 두 달 뒤의 오염 거래는 109vB에 113사토시, vB당 약 1사토시였다. 수수료가 vB당 수십 사토시로 오르면 오염 한 건에 드는 비용이 수천 사토시가 된다. 그 비용을 수만 번 내고 한 번 성공하는 장사는 맞지 않는다.

비트코인에서 이 공격이 비싼 근본적인 이유는 0원짜리 기록을 만들 수 없다는 데 있다. 내역에 무언가를 남기려면 실제 코인이 담긴 출력을 만들어야 하고, Bitcoin Core는 너무 작은 출력을 중계하지 않는다. 이 기준을 더스트(dust) 한도라고 한다. Core 소스의 정의는 단순하다. 그 출력을 쓰는 데 드는 수수료가 출력의 금액보다 크면 더스트다. 기본 더스트 수수료율 vB당 3사토시로 계산하면 P2PKH 출력은 546사토시, P2WPKH 출력은 294사토시가 한도로, 소스 주석에 그대로 적혀 있다. 같은 공식으로 P2TR을 계산하면 330사토시가 나온다. 위 사례의 공격자가 보낸 금액이 정확히 330사토시였다. 받는 쪽은 P2WPKH였으니 294사토시로도 중계됐을 텐데, 공격자는 그보다 조금 넉넉하게 보냈다.

이더리움에서는 왜 흔한가

계정 기반 블록체인에서는 사정이 다르다. 이더리움의 토큰 전송은 기록상 0개짜리일 수 있고, 아무나 만든 가짜 토큰을 보내 내역에 이름이 같은 토큰 기록을 남길 수도 있다. 공격자가 내는 것은 가스비뿐이다. Etherscan이 0원 토큰 전송을 기본으로 숨기고 가짜 토큰에 표시를 붙이는 것도 이 때문이다.

카네기멜런대 연구팀은 이더리움과 BNB 체인에서 2년 동안 일어난 주소 오염을 측정해 2025년 USENIX Security에 발표했다. 공격 시도가 2억 7천만 건, 표적이 된 주소가 1,700만 개였고, 실제로 돈을 보낸 피해가 6,633건, 확인된 손실이 8,380만 달러였다. 수수료가 더 싼 BNB 체인에서 오염 전송이 훨씬 잦았다. 비트코인의 48,000건과 이더리움의 2억 7천만 건, 이 차이가 곧 비용 구조의 차이다.

큰 피해는 대개 이쪽에서 나왔다. 2024년 5월 3일에는 한 사람이 WBTC 1,155개, 당시 약 7천만 달러를 가짜 주소로 보냈다. 이 사건은 공격자가 일주일쯤 뒤 이더로 바꾼 자금 대부분을 돌려주는 드문 결말로 끝났지만, 그런 결말은 예외다. 2025년 12월에는 약 5천만 달러어치 USDT를 잃은 사례가 보도됐다. 보도에 따르면 피해자는 먼저 소액으로 시험 송금을 했고, 그 직후 공격자가 가짜 주소에서 소액을 보내 내역을 오염시켰다. 시험 송금으로 주소를 확인한 다음 내역에서 그 주소를 복사해 본 송금을 한 것이다. 조심스러운 습관이 공격의 입구가 됐다.

먼지가 하는 다른 일

비트코인에서 원치 않는 소액 입금이 문제가 된 것은 주소 오염보다 훨씬 오래됐다. 이쪽은 돈을 훔치려는 것이 아니라 누가 누구인지 알아내려는 것이다. 흔히 더스트 공격(dusting attack)이라고 부른다.

비트코인 지갑에는 잔고가 아니라 UTXO, 곧 쓰이지 않은 코인 조각들이 있다. 송금할 때 지갑은 이 조각 몇 개를 골라 한 거래의 입력으로 묶는다. 블록체인 분석은 바로 이 지점을 이용한다. 한 거래의 입력들은 대개 같은 사람의 것이라고 가정하는 것이다(공통 입력 소유 휴리스틱). 받는 사람이 자기 코인을 보태는 페이조인 같은 예외를 빼면 이 가정은 대개 맞는다. 누군가 내 주소에 소액을 보내 두면, 내 지갑이 언젠가 그 소액을 다른 코인과 함께 쓰는 순간 서로 다른 주소들이 한 사람의 것으로 묶인다.

Bitcoin Core는 2019년 11월 0.19 판에서 이 문제를 겨냥한 지갑 옵션 avoid_reuse를 넣었다. 릴리스 노트는 그 이유를 이렇게 적었다.

this can eliminate a serious privacy issue where a malicious user can track spends by sending small payments to a previously-paid address that would then be included with unrelated inputs in future payments.

악의적인 사용자가 이미 돈을 받은 적 있는 주소에 소액을 보내 두면, 그 소액이 나중에 관계없는 입력들과 함께 쓰이면서 지출을 추적당하는 문제를 없앨 수 있다는 뜻이다. 이 옵션을 켜면 지갑은 이미 한 번 쓰인 주소에 들어온 코인을 코인 선택에서 기본으로 뺀다.

주소 오염에 쓰인 소액도 같은 성질을 갖는다. 330사토시짜리 P2WPKH 코인을 쓰려면 입력 하나에 68vB 남짓이 든다. 수수료율이 vB당 5사토시만 돼도 쓰는 비용이 340사토시로, 코인 값보다 크다. 받아 봐야 쓸 수 없는 돈이고, 무심코 쓰면 내 코인들의 연결만 드러낸다.

지갑에서 할 수 있는 것

첫째, 주소는 거래 내역에서 복사하지 않는다. 받는 사람에게 매번 새로 받거나, 처음 확인한 주소에 라벨을 붙여 주소록에서 꺼내 쓴다. 내 지갑끼리 옮길 때도 마찬가지다. 받을 지갑에서 새 주소를 만들어 쓰면 오염된 내역이 끼어들 자리가 없다. 주소를 한 번만 쓰는 원칙을 지키면 공격자가 겨냥할 "늘 쓰는 주소"부터 사라진다.

둘째, 확인은 앞뒤 몇 글자가 아니라 전체로 한다. 위에서 셈한 대로, 앞뒤 몇 글자를 맞추는 비용은 공격자에게 감당할 만하다. 하드웨어 지갑을 쓴다면 기기 화면에 표시된 주소 전체를 받는 쪽 주소와 대조한다. 컴퓨터 화면은 클립보드를 바꿔치기하는 악성코드에 속을 수 있지만, 기기 화면은 기기가 직접 서명할 거래를 보여 준다.

셋째, 받은 적 없는 소액은 동결한다. 코인 컨트롤을 지원하는 지갑은 특정 코인을 쓰지 않도록 묶어 둘 수 있다. Sparrow는 UTXO 목록에서 Freeze UTXO로, Electrum은 Coins 탭에서 동결로 묶는다. Bitcoin Core는 lockunspent 명령으로 잠그는데, 기본값은 재시작하면 풀리므로 persistent를 켜야 남는다. 지갑을 새로 만든다면 avoid_reuse를 켜 두는 것도 방법이다.

마지막으로, 시험 송금을 했다면 본 송금의 주소는 내역에서 가져오지 않는다. 처음 주소를 받은 곳에서 다시 가져온다. 시험 송금과 본 송금 사이가 공격자가 노리는 틈이다.

정리

주소 오염은 암호를 깨지 않는다. 키를 훔치지도 않는다. 사람이 긴 문자열을 다루는 방식, 곧 앞뒤만 보고 나머지는 믿는 습관을 이용한다. 비트코인에서는 기록 하나를 남기는 데에도 실제 코인과 수수료가 들기 때문에 이 공격이 드물고 비싸지만, 0.1 BTC 사례가 보여 주듯 없지는 않다. 내역은 내가 한 일의 기록이 아니라 누구나 끼워 넣을 수 있는 기록이다. 보낼 주소는 내역이 아니라 받는 사람에게서 가져와야 한다.

Read on the full site: https://learn.txid.uk/ko/articles/address-poisoning/