DETER: 트랜잭션 풀을 밀어내는 공격

Joonha Lee
Decipher Media |디사이퍼 미디어
14 min readDec 3, 2021

CCS 2021 에서 발표된 Kai Li et al. “DETER: Denial of Ethereum Txpool sERvices” ACM Conference on Computer and Communications Security, 2021. 연구를 소개합니다.

An attacker is pushing out the existing transactions and pulling in the new transactions.

[목 차]

  1. 소개
  2. DETER 공격
  3. 공격 분석
  4. 완화책
DETER: Denial of Ethereum Txpool sERvices Paper (https://dl.acm.org/doi/abs/10.1145/3460120.3485369)

Introduction

Txpool

이더리움 노드는 미승인 거래를 저장하는 버퍼를 가지고 있다. 이를 Txpool 혹은 mempool 이라고 부른다. 각 노드는 이 Txpool을 읽어 채굴이나 Transaction(이하 Tx) 전파 등 후속 작업에 이용한다.

Txpool 의 동작

Txpool 에 새로운 Tx 가 들어오면 다음 둘 중 하나의 동작을 수행한다.

밀어내기(Eviction): 기존의 Tx 을 밀어낸다. 이는 서로 다른 계정으로부터 발생한 Tx 의 우선순위가 기존 Tx 보다 높을 경우에 기존 Tx 의 우선순위를 뒤로 밀어내는 동작이다.

대체하기(Replacement): 기존 Tx 을 대체한다. 같은 계정으로부터 같은 논스(nonce)값을 갖는 Tx 이 들어오면 기존 Tx 가 버퍼에서 빠지고 새 Tx 가 자리하게 된다.

Transaction 종류

Txpool 에는 두 가지의 Tx 가 있다.

Pending Tx: 현재 Txpool 에 들어 있는 Tx 들과 이어지는 연속적인 논스값을 갖는 Tx.

Future Tx: 연속적이지 않은 논스값을 갖는 Tx.

예를 들어 논스값이 0, 1, 2, 3, 4, 5 인 Tx 들이 있다면, 논스값 1, 2, 3, 4, 5 인 Tx 들은 Pending Tx 이다. 한편 논스값이 0, 3, 4, 5, 6, 7 인 Tx 들이 있다면, 논스값 3, 4, 5, 6, 7 인 Tx 들은 Future Tx 에 해당한다. Future Tx 은 비트코인의 고아 거래(orphan transaction)와 같은 개념이다.

Transaction Admit Rule

Txpool 마다 Tx 을 받아들이는(Admit) 규칙이 있다. 일례로 Txpool 은 Pending Tx 뿐 아니라 Future Tx 도 받아들인다. 네트워크 상황에 따라 Tx 별로 도착이 다를 수 있는데, 그럼에도 채굴 수익을 최대화 해야 하기 때문에 Future Tx 도 받아들이는 것이다.

이더리움 클라이언트 Geth, Parity, Nethermind, Besu 는 서로 다른 Tx Admit 규칙을 사용한다. Tx 종류별로 Admit 제한을 두기도 하고, 계정별로 개수 제한을 두기도 한다.

Attacking a Txpool

그런데 예시로 든 Admit 규칙에는 버그가 있다. Future Tx 이 기존의 Pending Tx 보다 높은 가스비(Gas Price)를 제시하면, 우선순위가 더 높아질 수 있다. 본 연구는 바로 이 점을 이용하여 공격을 수행한다. 유효한 Tx 들의 우선순위를 낮추어 Txpool 밖으로 밀어내어 Txpool을 비워내는 것이다.

공격 대상은 마이닝 풀 등 주요한 채굴자나 RPC 서비스를 제공하는 노드 등 주요 노드들이다. 채굴 파워를 많이 가지는 노드의 Txpool 을 비우면 블록에 담기는 Tx 가 줄어들 것이다. RRC 서비스 노드의 Txpool 을 비우면 Gas station, DeFi 서비스, RPC 쿼리 등의 후속 서비스를 마비시킬 수 있다.

놀랍게도 이 공격에 드는 비용은 아주 낮다. 두 가지 공격이 있는데 하나는 비용이 전혀 들지 않고, 다른 하나는 베이스라인 공격에 비해 1000 배 정도 저렴하게 공격을 수행한다.

연구는 실제 네트워크에서 공격을 수행하기 위한 여러 엔지니어링 기법을 소개하며, 실제 공격을 수행하고 분석한다. 추가적으로 이 공격에 대한 완화책도 제시한다.

이 공격은 이더리움 클라이언트들에 보고되었으며, Geth 는 이 버그를 ‘high impact’ 로 평가하였다.

이제부터 Denial of Ethereum Txpool sERvices, DETER 공격을 알아보자.

DETER Attack

두 가지 공격 방법이 있다. 클라이언트별 Tx Admit 규칙 중 두 가지를 활용하여 DETER-X 와 DETER-Z 라는 이름의 두 가지 공격을 수행한다.

DETER-X

DETER-X 공격에서 활용하는 규칙은 다음과 같다.

높은 가스비를 제안하는 Future Tx 은 낮은 가스비를 제안하는 유효한 Pending Tx 보다 우선순위가 높다.

Geth 에서 Txpool 에 담길 수 있는 Tx 수는 5120 개다. 따라서 공격자는 5120 개의 유효하지 않은 Future Tx 에 아주 높은 가스비를 매겨 Txpool 에 넣는다. 5120 개의 Future Tx 은 5120 개의 기존 Tx 들 보다 우선순위가 높기에, 기존 Tx 들을 모두 밀어낸다.

그리고 Future Tx 들이 제시하는 높은 가스비는 실제 지불될 일이 없다. 유효하지 않은 거래이기 때문에 최종적으로 블록에는 포함되지 않을 것이기 때문이다.

5120 개를 밀어내는 데에는 성공했지만, 5120 개의 Future Tx 이 Txpool 에 저장되지는 않는다. Future Tx 에게는 1024 개의 공간이 할당되어 있기에 나머지 4096 개의 공간은 비어있게 된다. 공격 후에 다른 노드로부터 전파되어 들어오는 유효한 거래들이 다시금 자리할 수 있는 것이다.

따라서 공격의 효과를 극대화하려면 후속 서비스가 Txpool 을 읽기 직전에 이 공격을 수행해야 하고, 이를 유지하려면 그 읽기 주기에 맞추어 DETER-X 공격을 반복해야 한다.

이러한 Geth 와 달리 Nethermind 와 Besu 에서는 Future Tx 개수에 제한이 없어서 5120 개의 Future Tx 이 단번에 Txpool 을 점유할 수 있다. 주기적인 공격 업데이트가 필요하지 않은 것이다.

DETER-Z

DETER-X와 달리 Txpool 읽기 주기를 예측해야 하는 오버헤드가 없지만 비용이 발생하는 두 번째 공격 DETER-Z 를 소개한다. DETER-Z 가 활용하는 규칙은 다음과 같다.

높은 가스비를 제안하는 invalid Pending Tx 은 낮은 가스비를 제안하는 valid Pending Tx 보다 우선순위가 높다.

이때 invalid Pending Tx 이란, Pending Tx 중 계정의 잔액 부족으로 인해 시행되지 않고 있는 Tx 이다. 예를 들어 어떤 계정이 밸런스 B를 가지고 있을 때,
논스값이 0, 1, 2, 3, … 이며 각각 밸런스 B를 모두 사용하는 거래들이 있다고 하자. 이들을 각각 Tx0, Tx1, Tx2, Tx3…라고 한다면, Tx1, Tx2, Tx3, … 는 invalid Pending Tx 이고 Tx0 만이 valid Pending Tx 이다.

따라서 DETER-Z 공격에서는 invalid Pending Tx을 5120개 밀어넣어
기존의 valid Pending Tx 을 밀어낸다.

여기까지만 하면 Besu에서는 5120개의 invalid Pending Tx 이 Txpool 을 모두 점유하기 때문에 공격이 성공하는데, Geth 에서는 또 다르다.

Geth 는 invalid Pending Tx 이 valid Pending Tx 을 밀어내는 것은 허용하지만,
5120 개 전체가 아닌 4096 개의 공간만을 허용한다. 1024 개의 빈 공간이 생기는 것이다. 앞의 DETER-X 에서 Geth 의 Future Tx 에게 1024 개의 공간 점유가 허용된다고 말한 것을 기억하는가. 따라서 DETER-Z 는 1024 개의 Future Tx 을 추가로 집어 넣는다. 이들에게는 4096 개의 invalid Pending Tx 보다 낮고 추후 전파되어 오는 valid Pending Tx 보다 높은 가스비를 붙여 Txpool 에 자리하게 한다.

최종적으로 매 블록 Tx0 만이 블록에 포함된다. 따라서 Tx0 의 가스비만 지불하면 된다. 대부분의 valid Pending Tx 들에 가스비로 우위를 점하기 위해선 대략 1000 Gwei 의 가격을 매기면 된다고 한다. 따라서 매 블록 공격을 수행하기 위해선 1000 Gwei * 21000 Gas = 0.021 Ether 를 지불하면 되는 것이다.

Parity 와 Nethermind 에서는 계정 당 Tx 개수 제한이 있기 때문에 여러 가지의 invalid Pending Tx 들을 밀어 넣어 공격한다. 따라서 그 종류만큼 공격 비용은 증가한다.

Attack Analysis

연구에서는 우선 로컬 채굴 노드에서 실험을 수행하여 성공률을 분석했다. 뒤이어 실제 환경인 테스트넷과 메인넷에서도 실험하였다. 테스트넷에서는 실제 공격을 수행해보았고, 메인넷에서는 윤리적 문제와 변인 통제의 어려움 때문에 조금 다른 방법을 사용하여 실험했다. 두 경우 모두 1) 주요 노드를 발견하고 2) 그 노드를 공격하는 순서로 진행하였다.

Baseline Attack

비교를 위한 베이스라인 공격은 다음과 같다. 공격자는 기존 Tx 보다 높은 가스비를 제시하는 유효한 Pending Tx 들을 밀어넣어 블록에 먼저 포함시킨다. 예를 들어 공격 Tx 당 1000 Gwei 의 가스비를 매겼다고 가정하면, 12500000 Gas 의 비용으로 한 블록 전체를 점유할 수 있다.

Success Rate (Local Experiment)

전체 valid Pending Tx 중 밀려난 Tx 개수를 성공률로 정의한다. DETER-X 의 경우, 주기적으로 공격을 시행해야 하기 때문에 그 주기를 어떻게 설정하느냐에 따라 성공률이 달라진다.

DETER-X 의 공격 주기가 0.25 msg/sec 일 때에는 성공률이 65.2% 이고 2 msg/sec 일 때에는 84.9% 의 성공률을 보였다. 두 경우 모두 공격에 드는 비용은 0 였다.

반면 DETER-Z 는 블록 채굴 주기에 맞추어 수행하면 되므로 공격 시점이 명확하다. 따라서 99% 의 높은 성공률을 보였지만 0.021 Ether 의 비용이 발생했다. 12.5 Ether 가 드는 베이스라인 공격과 비교하면 약 1000 배 정도의 비용이 절감되었음을 알 수 있다.

Testnet

테스트넷에서는 주요 노드가 알려져 있지 않기에 공격을 위해선 주요 노드를 우선 찾아야 한다.

주요 RPC 노드는 고유한 codename 을 가지고 있다. RPC 쿼리의 응답을 보면 codename 을 알 수 있다. 이 codename 을 가지는 노드를 알아내기 위해 네트워크에 임의의 ‘수퍼 노드’를 참여시키고 이웃 수를 최대로 하여 RPC 노드와 연결되도록 한다. 연결 시 peer-discovery message 에 찾고자 하는 codename 이 포함되었는지를 모니터 하고, 찾았다면 그것이 주요 노드에 해당한다.

주요 채굴 노드를 찾고자 하는 경우, 채굴 점유율을 알아내는 방법을 사용한다. 위와 같이 수퍼 노드를 참여시키고 수퍼 노드에 들어오는 block-arrival message 를 분석한다. 그 메시지는 timestamp 를 담고 있다. 가장 이른 timestamp 를 나타내는 메시지의 발송자를 home 노드로 지정한다. 이 home 노드를 블록의 채굴자로 볼 수 있는데, 블록별로 Home 노드로 지정된 횟수를 카운트하면 채굴 점유율을 계산할 수 있다. 채굴 점유율 순서에 따라 주요 노드로 지정한다.

주요 노드를 찾았다면, 로컬 노드와 같이 공격을 바로 수행하면 된다.

연구가 Ropsten Testnet 에서 수행한 실제 공격은 이더스캔에서 그 결과를 확인할 수 있었다. 보통 블록마다 4–50 개의 Tx 가 포함되는데, 공격이 시행되니 블록 당 Tx 개수가 0–1 개로 줄어든 것을 확인할 수 있었다.

결론적으로 테스트넷에서는 31 ~ 77 배의 거래 개수를 줄였고, 18 ~ 55 배의 가스비를 줄였다.

Mainnet

메인넷에서도 테스트넷과 마찬가지로 주요 노드를 발견하여 공격하는 순서로 실험한다. 그런데 메인넷에서의 주요 노드는 인터넷 상에 이미 공개가 되어 있으므로 따로 발견하는 절차를 거치지 않고 연결할 수 있다.

간단한 노드 발견과 달리 공격 검증은 비교적 복잡하다. 테스트넷이나 로컬 환경과 달리 윤리적인 문제가 있어 공격을 그대로 수행해볼 수 없다. 따라서 연구에서는 공격 타겟이 될 Tx 을 임의로 넣어두고, 그것이 밀려났는지를 확인하는 방식으로 공격을 검증한다. 이때 잠시 동안 Txpool 의 크기를 늘려 밀려나게 되는 다른 기존 Tx 들을 저장해두고 실험 후에 복구하여 윤리적 문제를 최소화 하였다. 또한 가스비를 낮게 설정하여 밀려나는 Tx 의 수를 줄였다.

[DETER-X 를 검증하기 위한 실험 Tm1]

  1. 가스비 p 를 제시하는 임의의 트랜잭션 tx1 을 넣는다.
  2. p 보다 조금 높은 가스비를 제시하는 Future Tx 들을 넣어 tx1 을 밀어낸다.
  3. tx1 과 동일한 계정에서 동일한 논스값과 더 낮은 가스비를 제시하는 임의의 트랜잭션 tx2 를 넣는다.
  4. tx2 가 전파되는지 관찰한다.

tx2 가 관찰되었다는 말은 곧 tx1 이 밀려나 tx2 가 새로운 Tx 으로 인식되었다는 것이고 DETER-X 공격이 성공했음을 뜻한다. 반면 tx2 가 관찰되지 않았다는 말은 곧 tx1 과 tx2 의 우선순위 경쟁에서 tx1 가 우세하여 밀려나지 않고 Txpool 에 계속 위치했음을 뜻하고, 이는 DETER-X 공격의 실패를 뜻한다.

[DETER-Z 를 검증하기 위한 실험 Tm2]

  1. 가스비 p 를 제시하는 tx1 을 x2 개 넣는다. 이때 x2 개 tx1 은 논스값이 연속적인 Pending Tx 들이다.
  2. tx1 을 밀어내기 위해서 p+1 의 가스비를 제시하는 invalid Pending Tx 을 보낸다.
  3. Tm1 과 마찬가지로 tx1 의 대체 여부를 확인하기 위한 x2개의 tx2를 보낸다.
  4. tx2 의 전파 여부를 관찰한다.

tx2 가 x2 개 관찰되었다면 ‘완전 성공’으로, 그 중 몇 개만 관찰되었다면 ‘부분 성공’으로 구분한다.

메인넷에서의 공격 시뮬레이션을 위해 위의 Tm1 과 Tm2 를 수행하였다. 그리고 그 결과는 위 표와 같이 ‘완전 성공’하였다.

Attack Mitigation

연구에서는 제시한 공격에 대한 완화책으로 휴리스틱(heuristic)한 방법으로 기존의 Tx Admit 규칙을 수정하기를 제안한다.

그 규칙은 아주 간단하다.
첫째, Future Tx 이 기존의 valid Pending Tx 을 밀어내는 경우 받아들이지 않는다. 둘째, invalid Pending Tx 이 기존의 valid Pending Tx 을 밀어내는 경우 받아들이지 않는다. 셋째, 새로 들어오는 Tx 이 다른 Pending Tx 을 밀어내면서 다른 Future Tx 을 풀에 남겨둔다면 받아들이지 않는다.

결과는 위 표와 같은데, 완화책 M1은 기존 Geth 와 달리 DETER-X 와 DETER-Z 공격을 모두 막아낼 수 있었다. 또한 기존 공격에서 빈 블록 채굴로 인해 줄어들었던 채굴자 수익이 어느 정도 늘어나는 효과도 있음을 알 수 있다.

맺는 말

DETER 는 아무도 생각치 못한 포인트를 짚어 재밌게 풀어낸 좋은 연구였다.

그러나 휴리스틱한 완화책은 보완될 필요가 있어보인다. 예컨대 Future Tx 을 받아들임으로 인해 얻을 수 있는 수익보다 그것을 거부함으로써 얻는 이득이 분명 크지 않을 것 같기 때문이다.

확장하면 이렇게 쉬운 완화책으로 해결될 문제였을까 하는 생각도 든다. Txpool 의 Admit 규칙은 분명 이 둘 뿐 아니라 여러 가지가 얽혀있는 형태일 것이다. 즉 전체 규칙의 구조를 살펴야 개별 규칙을 개선할 수 있을 것이라는 나의 개인적인 생각이다.

버그 리포트를 받은 Geth 의 향후 업데이트에 관심이 간다. (이미 반영되었을 수도.)

참고 문헌

https://ropsten.etherscan.io/block/9450105

글쓴이: 이준하

  • CURG(Crypto United Research Group)는 2018년 5월 대학(원), 기업, 스타트업 등 다양한 분야의 열정적인 블록체인-er들이 모인 연합 연구 그룹입니다. CURG는 2018년 5월 출범된 이후, ‘Trendy, Thoughtful, and Transdisciplinary’ 한 자세로 한 주도 빠짐없이 블록체인 연구를 지속해오고 있습니다.
  • 디사이퍼(DECIPHER)는 “건강한 블록체인 생태계 조성에 기여한다” 라는 미션 아래 블록체인에 대해 연구하고 이를 실용적으로 응용하는 서울대 블록체인 연구 학회입니다. 2018년 3월에 처음 조직 되어 현재까지 블록체인 기술을 다방면에서 연구하고 산업계에 응용하고 있는 100명 이상의 회원들을 배출해왔습니다. 다양한 팀별 연구활동과 프로젝트, 컨퍼런스 개최, 서울대학교 블록체인 강의 개설, 유수 기업들과의 산학협력과 파트너십 체결을 해오며 국내 최고의 블록체인 학회로 자리 잡았습니다.
  • 커그와 디사이퍼는 향후 적극적인 협력을 통해 블록체인 필드에서의 강력한 시너지를 구축하고자 합니다.

--

--