2026 18th CODEGATE CTF 문제 풀이

0. 개요

  • 문제 이름 : conero
  • 문제 유형 : Crypto / Blockchain / Ring Signature Exploit
  • 환경 :
    • 프리컴파일 주소: 0x000…10c0
    • 주요 기능:
      • deposit
      • private transfer
      • withdraw
  • 목표 :
    • pool balance == 0 이면서 0x1337 주소 잔고를 bootstrap 이상으로 만들기

1. 전체 구조 분석

1-1. 시스템 구조

Coneroㄴㄴ Monero 스타일의 privacy transaction 시스템이다.

지원 기능으로는

  • 0x01 : deposit
  • 0x03 : private transfer
  • 0x04: withdraw

1-2. 트랜잭션 흐름

deposit -> note 생성 -> private transfer -> 새로운 note 생성 -> withdraw -> ETH 출금


1-3. 검증 구조

withdraw / transfer 에서 다음 검증이 수행된다.

verifyRingSignature(…)

challenge 계산식:

1
2
3
4
5
H("conero:ring-transfer-challenge"
|| contextHash
|| keyImage
|| L
|| R)
  • keyImage가 포함되어야 검증 통과

2. 문제 핵심

2-1. 목표 조건

pool balance == 0
AND
balance(0x1337) > bootstrap


2-2. 아이디어

같은 note를 여러 번 소비한다.


3. 취약점 분석

3-1. 취약점 1 - key image 검증 누락

verifyRingSignature → Point.SetBytes만 수행

문제:

  • prime-order 검사 없음
  • canonical 체크 없음

결과:

  • I = x * Hp(P)
  • I’ = I + T (torsion)

서로 다른 key image로 동일 note 재사용 가능


3-2. 취약점 2 - note 필드 오류

private transfer 출력 구조:
(pubkey, txpub, amount)
하지만 실제 spend key는: pubkey가 아니라 txpub


실험 결과

  • pubkey → withdraw 실패
  • txpub → withdraw 성공

즉, on-chain note는 txpub 기준


3-3. 취약점 결론

두 취약점 결합:

  • note 재사용 가능
  • attacker가 spend key 제어 가능

무한 인출 가능 구조이다.


4. 공격 시나리오

4-1. 초기 상태

  • bootstrap pool: 7 ETH
  • 플레이어: 1.1 ETH

4-2. 공격 전략

핵심은 1 ETH note 하나로 여러 번 withdraw 하는것.

4-3. 공격 단계

1) deposit

  • 1 ETH → 정상 note 생성

2) private transfer

  • 출력 note 생성 → txpub에 내가 아는 키 삽입, controllable note 생성

3) withdraw 반복

  • for torsion index in 0..7:
    withdraw(note, key_image_variant)

서로 다른 key image로 동일 note 재사용


4-4. 결과 상태

총 8 ETH -> 0x1337 이동
pool balance -> 0


5. 익스플로잇 흐름

전체 흐름은

  • deposit 1 ETH
  • → private transfer (repeatable note 생성)
  • → withdraw × 8 (torsion key image)
  • → pool empty
  • → flag 조건 만족

6. Payload 구조

6-1. deposit

0x01   pubkey   txpub

6-2. private transfer

1
2
3
4
5
6
7
0x03
[input]
[ring]
[key_image]
[challenge]
[responses]
[output(pubkey, txpub, amount)]

6-3. withdraw

1
2
3
4
5
0x04
[input]
[key_image]
[recipient]
[amount]

7. 전체 공격 흐름 정리

전체 과정:

  1. 정상 note 생성
  2. private transfer로 controllable note 생성
  3. txpub 기반 spend key 확보
  4. torsion key image 생성
  5. 동일 note 반복 소비
  6. pool balance 0 만들기
  7. 0x1337 잔고 증가
  8. flag 조건 만족

8. 포인트

이 문제의 포인트는 다음과 같다.

  • key image subgroup 검증 누락
  • note 필드 잘못된 매핑 (txpub 사용)
  • torsion point를 이용한 key image 변형
  • 동일 note의 multi-spend 가능

9. 정리

key image 검증 누락과 note 필드 오류를 이용해 동일 note를 torsion 기반으로
여러 번 소비하여 풀을 비우고 조건을 만족시키는 문제

10. 최종 플래그

1
codegate2026{acdb27306fba0f4512ad33352c4f9e340498eb98d23e773f49ba3cfc069d7256}