위험 경고: '가상화폐', '블록체인'이라는 이름으로 불법 자금 모집 위험에 주의하세요. — 은행보험감독관리위원회 등 5개 부처
검색
로그인
简中
繁中
English
日本語
한국어
ภาษาไทย
Tiếng Việt
BTC
ETH
HTX
SOL
BNB
시장 동향 보기
Paradigm CTF 2023解题报告
Salus Insights
特邀专栏作者
2024-02-16 10:53
이 기사는 약 10548자로, 전체를 읽는 데 약 16분이 소요됩니다
Salus安全团队在Paradigm 2023 CTF中共解决了13项挑战,在1011支队伍中以3645.60的分数获得第九名,并受邀成为Paradigm CTF 2024的客座作者。在这篇博文中,我们将介绍我们在比赛期间解决的所有挑战。

Paradigm CTF 블록체인 업계의 스마트 컨트랙트 해커를 대상으로 하는 가장 유명하고 최고의 온라인 대회로 web3의 최고 투자 회사인 Paradigm이 주최합니다. CTF 주제는 Sumczsun이 만든 여러 챌린지와 초대 게스트 작가로 구성됩니다. 각 챌린지의 목표는 기술적 문제를 해킹하거나 공격하여 문제를 해결하는 것입니다.

대회 기간 동안 참가자는 일련의 소프트웨어 퍼즐 과제를 완료하게 됩니다. 참가자가 올바르게 해결하거나 챌린지 기간이 끝나기 전에 가장 높은 점수를 획득한 각 챌린지에 대해 포인트가 부여됩니다. King of the Hill Challenge의 경우 점수는 Elo 점수 시스템을 기반으로 합니다. 챌린지를 올바르게 해결하여 각 참가자가 받게 되는 포인트 수는 챌린지 기간이 끝날 때까지 알 수 없습니다.

Salus 보안팀은 총 13개의 과제를 해결하여 3645.60점으로 1,011개 팀 중 9위를 차지했습니다.그리고 Paradigm CTF 2024에 게스트 작가로 초청받았습니다.이 블로그 게시물에서는 대회 기간 동안 우리가 해결한 모든 문제를 다룰 것입니다.

해결된 과제

  • Hello World

  • Black Sheep

  • 100% 

  • Dai++

  • DoDont

  • Grains of Sand

  • Suspicious Charity

  • Token Locker

  • Skill Based Game

  • Enterprise Blockchain

  • Dragon Tyrant

  • Hopping Into Place

  • Oven

1. Hello World

이 챌린지의 목표는 대상 주소에 이전보다 최소 13.37 더 많은 ETH 잔액이 있는지 확인하는 것입니다.

우리는 테스트 계약 SolveTest와 Solve 작업을 수행하기 위한 계약이라는 두 가지 계약을 만들었습니다. SolveTest 계약은 초기 환경을 설정하고 테스트 공격을 실행하여 문제가 해결되었는지 확인합니다.Solve 컨트랙트는 killMySelf() 함수의 selfdestruct 작업을 통해 대상 주소로 자금을 이체함으로써 대상 주소의 ETH 잔액을 늘리는 목적을 달성합니다.

2. Black Sheep

이 챌린지의 목표는 BANK 계약에서 모든 ETH를 인출하는 것입니다. WITHDRAW() 함수에 취약점이 존재합니다. CHECKSIG() 함수가 반환 값을 올바르게 처리하지 못하기 때문에 어떤 경우에는 스택에 값을 푸시하지 않고 직접 실행을 종료하여 반환 값이 CHECKVALUE(로 잘못 읽히게 됩니다. ).의 결과. 우리의 솔루션은 WITHDRAW() 함수의 취약점을 활용하고 CHECKVALUE()가 0을 반환하도록 보장하는 솔버 계약을 작성하여 WITHDRAW() 함수가 성공적으로 실행되고 BANK 계약에서 모든 ETH를 추출하는 것입니다.

취약점 분석

먼저 CHECKVALUE(), CHECKSIG() 함수를 순차적으로 실행한 후, 실행 결과에 따라 컨트랙트의 모든 ETH를 msg.sender로 보내는 WITHDRAW() 함수를 연구했습니다. 안에,CHECKSIG() 함수가 함수 반환 값을 올바르게 처리하지 않습니다.이 함수는 함수 실행을 종료하기 전에 결과를 반환 값으로 스택에 푸시해야 합니다. 그러나 어떤 경우에는 스택에 값을 푸시하지 않고 함수가 직접 실행을 종료하여 반환 값이 실수로 스택 상단의 첫 번째 요소로 읽히는 경우가 있는데, 이는 CHECKVALUE() 함수의 실행 결과입니다. CHECKSIG() 함수의 설계 결함으로 인해 서명 검증에 실패하더라도 CHECKVALUE() 함수가 0을 반환하도록 하면 WITHDRAW() 함수가 성공하도록 만들 수 있습니다.

CHECKSIG() 함수에서 입력 매개변수(바이트 32, 단위 8, 바이트 32, 바이트 32)를 사용하여 WITHDRAW() 함수를 호출하여 주소 0x 1을 호출합니다. 이 계약은 매개변수를 기반으로 공개 키 주소를 복구하는 기능을 가진 사전 컴파일된 계약입니다. 여기에는 두 가지 검사가 있습니다. 첫 번째는 서명이 유효한지 확인하는 것입니다. staticcall이 성공적으로 실행되면 서명이 유효하다는 의미이므로 입력 매개변수의 내용은 중요하지 않습니다. 공개 키의 정확성은 두 번째로 확인됩니다. 공개 키 주소가 올바르지 않으면 폴백하지 않고 바로 함수 끝으로 점프합니다. 이 함수에는 반환 값이 있으며, 일반적인 실행에 따르면 함수 실행을 종료하기 전에 결과를 반환 값으로 스택에 푸시해야 합니다.

그러나 실행이 직접 종료되면 스택에 값이 푸시되지 않습니다. 이로 인해 반환 값이 CHECKVALUE()의 결과인 스택 맨 위의 첫 번째 요소로 잘못 읽히게 됩니다.따라서 CHECKVALUE() 함수의 실행 결과가 0을 반환하는 한, WITHDRAW() 함수는 원활하게 실행되어 msg.sender로 10 ETH를 성공적으로 보낼 수 있습니다.

CHECKVALUE() 함수의 실행 결과가 0, 즉 스택의 최상위 요소가 0이 되기를 바랍니다. 호출 작업이 실패하도록 하려면 0x 10 > callvalue만 충족하면 됩니다.

해결책

우리는 은행 계약에서 돈을 인출하기 위해 Solver 계약을 작성했습니다. Bank 계약의 ETH는 WITHDRAW() 함수의 호출 작업을 통해 Solver 계약으로 전송됩니다. 구체적인 과정은 다음과 같습니다.

  1. Solver 컨트랙트의solv() 함수에서 Bank 컨트랙트의 WITHDRAW() 함수를 호출하여 출금 작업을 시작합니다.

  2. WITHDRAW() 함수에서는 CHECKVALUE() 함수가 먼저 실행됩니다.우리의 callvalue는 5 wei(0x10보다 작음)이므로 over 레이블로 점프합니다.

  3. over 태그에서는 callvalue * 2(즉, 10 wei)가 호출자(즉, Solver 계약)에게 전송됩니다. Solver 계약의 대체 기능에서수신한 Ether의 양이 10 wei이면 트랜잭션이 롤백되므로 over 태그의 호출 작업이 실패하고 CHECKVALUE() 함수가 0을 반환합니다.

  4. WITHDRAW() 함수는 계속해서 실행됩니다.Bank 계약의 전체 잔액을 호출자(즉, Solver 계약)에게 보냅니다. 이는 코드 자체 균형 호출자 가스 호출 라인을 통해 달성됩니다.그 중 selfbalance는 계약의 잔액, caller는 호출자의 주소, gas call은 호출을 시작하는 작업입니다.

  5. 이 호출 작업이 성공하면 은행 계약의 전체 잔액이 솔버 계약으로 전송됩니다. 이 작업이 실패하면 noauth 레이블로 직접 점프하고 되돌리기 작업을 수행하여 트랜잭션을 롤백합니다.

3. 100% 

이 챌린지의 목표는 SPLIT 및 _splitsById[ 0 ].wallet의 ETH 잔액이 0이 되어야 한다는 것입니다. abi.encodePacked 결과의 해시를 비교하여 매개변수의 유효성만 검증하는 distribution() 함수에 취약점이 존재하지만, 계정과 백분율이 동적으로 입력되므로 할당 프로세스 중에 조정될 수 있습니다. 우리의 해결책은 distribution() 함수의 인수 검증이 충분하지 않다는 점을 활용하여 계정 및 백분율 배열을 조작하여 예치한 것보다 더 많은 ETH를 추출하는 것입니다.

취약점 분석

Split 컨트랙트의 distribution() 기능을 사용하면 SplitWallet 생성 시 지정한 계정 및 비율에 따라 특정 자산을 분배할 수 있습니다. 할당 후, 사용자는 잔고에 저장된 가치에 따라 돈을 인출할 수 있습니다.그러나 distribution() 함수는 매개변수 유효성 검사가 충분하지 않습니다. 이 함수는 abi.encodePacked 결과의 해시를 비교하여 매개변수의 유효성을 검사하는 반면 계정과 백분율은 동적으로 입력됩니다. 따라서 할당 과정에서 계정과 비율을 약간 조정할 수 있습니다.

SplitWallet{id: 0} 생성 시 첫 번째 인덱스 계정이 실수로 공백으로 남겨졌습니다.

따라서 수정된 계정과 백분율을 사용하여 SplitWallet{id: 0}에서 모든 ETH를 추출할 수 있지만 해시를 변경하지 않고 유지하면서 누구에게도 배포할 수 없습니다(배열 요소는 32바이트로 채워집니다).

마찬가지로 abi.encodePacked로 인한 해시 충돌을 사용하여 예치된 것보다 더 많은 ETH를 인출하여 분할을 소모할 수 있습니다.

해결책

우리는 주로 SPLIT 및 _splitsById[ 0 ].wallet의 ETH 잔액을 비우는 해결 함수를 작성했습니다.전체 솔루션의 핵심은 계정 및 백분율 배열을 조작하고 배포 기능의 동작을 활용하여 해시 검증 메커니즘을 위반하지 않고 더 많은 ETH를 추출하는 것입니다.구체적인 아이디어는 다음과 같습니다.

  1. 계정 및 백분율 배열을 조정하여 ETH 할당을 제어할 수 있습니다. 여기서는 하나의 주소(주소)만 있는 계정 배열과 두 개의 요소가 있는 백분율 배열을 사용합니다.

  2. Split.distribute 기능을 사용하여 SplitWallet에서 우리 계정으로 ETH를 인출하세요. 이 단계는 ETH를 받을 수 있도록 분배 기능의 매개변수를 적절하게 조정하여 달성됩니다.

  3. 다음으로 분할 인스턴스를 만들고 주소를 수신자로 설정합니다.

  4. Split.deposit 기능을 통해 일정량의 ETH를 입금한 후, 다시 Split.distribute 기능을 사용하여 더 많은 ETH를 출금하세요.

  5. 마지막으로, Split.withdraw 함수를 호출하여 분할 계약에서 모든 ETH를 인출하여 챌린지를 완료하세요.

4. Dai++

이 챌린지의 목표는 Stablecoin의 총 공급량이 10^12* 10^18을 초과하도록 하는 것입니다. 취약점은 AccountManager 계약이 ClonesWithImmutableArgs를 사용하여 새 계정을 생성할 때 변경할 수 없는 매개변수의 길이 제한이 무시되어 매개변수 길이가 65535바이트를 초과할 때 손상된 계약이 배포된다는 것입니다. 우리의 해결책은 너무 긴 매개변수를 사용하여 계정을 생성하고, raiseDebt() 함수를 팬텀 함수로 전환하여 상태 확인을 우회하고 부채를 늘리지 않고도 대량의 스테이블코인을 발행할 수 있도록 하는 것이었습니다.

취약점 분석

SystemConfiguration 계약에 의해 승인된 계정만 스테이블코인을 발행할 수 있습니다. SystemConfiguration의 소유자만이 시스템 계약을 업데이트(즉, 계정 승인)할 수 있으며, AccountManager 계약은 승인된 유일한 계약입니다.

AccountManager 계약에서는 유효한 계정만 스테이블코인을 발행할 수 있습니다. 동시에 계정의 부채도 증가합니다.

증가Debt() 함수에서는 부채가 늘어난 후 계정이 건강하지 않으면 거래가 실패합니다. 그러나 플레이어는 10^12 스테이블코인을 발행하고 계정을 건강하게 유지하기에 충분한 ETH를 가지고 있지 않습니다.

AccountManager가 ClonesWithImmutableArgs를 사용하여 새 계정을 생성한다는 점은 주목할 가치가 있습니다. 계정과 상호 작용할 때 가스 비용을 절약하기 위해 호출 데이터에서 불변 매개변수를 읽습니다. 그러나 ClonesWithImmutableArgs에는 데이터 길이를 저장하는 데 2바이트가 사용되므로 @dev 데이터는 65535바이트를 초과할 수 없습니다라는 설명이 있습니다.

생성된 프록시 계약의 코드 영역에는 변경 불가능한 매개변수가 저장되므로 배포 중에 코드 크기는 데이터 길이를 기준으로 계산됩니다. 그러나 반환되어야 하는 코드 크기도 2바이트로 저장됩니다. 그러므로,runSize가 65535바이트를 초과하면 손상된 계약이 배포될 수 있습니다.이 호출을 무시하기 위해 raiseDebt() 함수를 팬텀 함수로 처리할 수 있습니다.

기존 매개변수 길이는 20 + 20 + 32 = 72바이트이며, 인코딩된 RecoveryAddresses의 길이는 32바이트의 배수가 됩니다.

해결책

우리는 Solve 계약을 작성하고 AccountManager 계약의 취약점을 이용하여 대량의 스테이블 코인을 발행했습니다.

  1. 먼저 AccountManager의 openAccount 함수를 호출하여 비정상적으로 긴 매개변수가 포함된 새 계정을 만듭니다. 이는 길이가 2044인 빈 주소 배열을 전달하여 수행됩니다. 이로 인해 예상되는 65535바이트 제한을 초과하는 매개변수 길이로 인해 내부에서 생성된 프록시 계약이 손상되었습니다.

  2. 매개변수 길이가 올바른지 확인하기 위해 계산 공식 72 + 2044 * 32 + 2 + 0x 43 - 11 = 65538이 사용됩니다. 여기서 72는 기존 매개변수 길이, 2044 * 32는 RecoveryAddresses의 인코딩된 길이, 2는 데이터 길이를 저장할 바이트 수, 0x 43은 생성 단계의 바이트코드 길이, 11은 런타임 계약 시 바이트코드 길이입니다. 생성됩니다. 계산 결과 65538이 최대 길이 65535를 초과하므로배포 시 깨진 계약이 생성됩니다.

  3. 새로 생성된 손상된 계정을 사용하여 mintStablecoins 기능을 통해 대량의 스테이블코인을 발행하세요. 계정계약 훼손으로 인해(계정 부채를 늘려야 하는) raiseDebt 기능은 실제로 올바르게 실행되지 않으므로 부채를 추가하지 않고도 스테이블코인을 발행할 수 있습니다.

5. DoDont

이번 챌린지의 목표는 DVM(Proxy Voting Mechanism) 프로젝트의 모든 WETH를 훔치는 것입니다. 이 취약점은 호출 제한이 없어 누구나 BASE_TOKEN 및 QUOTE_TOKEN 주소를 변경할 수 있는 DVM.sol의 초기화 함수에 있습니다. 우리의 솔루션은 플래시 대출 메커니즘의 잔액 확인을 우회하고 플래시 대출 프로세스 중에 이러한 주소를 우리가 제어하는 ​​토큰 계약으로 변경함으로써 이 취약점을 악용합니다.

취약점 분석

이 DVM 프로젝트를 빠르게 검토한 후 우리는DVM.sol의 init 함수에는 호출 제한이 없습니다.이것이 문제의 근본 원인입니다.

BASE_TOKEN 및 QUOTE_TOKEN을 변경하려면 언제든지 init() 함수를 호출할 수 있습니다., 이는 챌린지에서 플래시 대출의 기본 토큰 주소입니다. 플래시 대출의 이러한 취약점을 악용하는 것은 쉽습니다.플래시 대출 프로세스 중에 BASE_TOKEN 및 QUOTE_TOKEN을 그들이 관리하는 토큰 계약 주소로 변경합니다. 이를 통해 플래시 대출 메커니즘의 잔액 확인을 우회하여 플래시 대출 기간 동안 잔액을 제어할 수 있습니다.

해결책

우리는 챌린지 계약과 상호 작용하기 위해 Solve 계약을 만들었습니다. 공격을 수행하기 위한 Exploit 계약을 생성합니다. 계약은 먼저 flashLoan 함수를 사용하여 WETH 잔액을 얻은 다음 DVMFlashLoanCall 함수를 통해 init를 호출하여 BASE_TOKEN 및 QUOTE_TOKEN 주소를 제어되는 토큰 계약으로 변경합니다. 이러한 방식으로 우리는 플래시 대출 메커니즘의 잔액 확인을 우회하고 궁극적으로 DVM의 모든 WETH를 훔칠 수 있습니다.

6.Grains of Sand

이 챌린지의 목표는 토큰 스토어의 GoldReserve(XGR) 잔액을 최소 11111 × 10^8만큼 줄이는 것입니다. 허점은 GoldReserve 토큰을 전송할 때 수수료가 부과되지만 토큰 스토어에서는 전송 수수료가 있는 토큰을 지원하지 않는다는 것입니다. 우리의 솔루션은 GoldReserve 토큰을 반복적으로 입금하고 인출하여 토큰 저장소를 소진시키는 것입니다(두 작업 모두 전송 수수료가 있음).

취약점 분석

이 문제가 있는 프라이빗 체인은 이더리움 메인넷의 블록 18437825에서 분기되었습니다.

GoldReserve(XGR) 토큰은 전송 시 수수료가 부과되지만, 전송 수수료가 있는 토큰은 토큰 스토어에서 지원되지 않습니다. 그러므로 우리는 코인의 입출금을 반복하여 매장에서 코인을 빼낼 수 있습니다.

이제 먼저 GoldReserve 토큰을 가져와야 합니다! trade() 함수를 통해 $XGR의 서명을 교환할 수 있습니다.

거래 주문은 부분적으로 체결될 수 있습니다. 통과하다Dune, 만료되지 않은 GoldReserve 토큰 주문을 찾을 수 있습니다. 다행스럽게도 미판매 코인이 대량으로 2건의 주문이 있었습니다.

해결책

우리는 챌린지 계약과 상호 작용하기 위해 Solve 계약을 만들었습니다. 먼저, trade() 함수를 통해 거래하여 일부 GoldReserve 토큰을 얻으세요. 그런 다음 토큰 저장소의 입출금 메커니즘을 사용하여 반복적으로 작동하여 토큰 저장소의 토큰 잔액을 줄입니다. 이러한 방식으로 GoldReserve 토큰은 토큰 스토어에서 성공적으로 배출되어 도전 조건을 충족할 수 있습니다.

7.Suspicious Charity

이 챌린지의 목표는 Python 스크립트에서 가격 캐시를 조작하여 토큰의 가격과 유동성 계산에 영향을 미치는 것입니다. 이번 문제의 취약점은 이름 기반 풀의 토큰 주소를 캐싱하는 Python 스크립트에서 발생하며, 이러한 이름이 문자열(uint 8)을 사용하여 구성되면 Python에서 0x80 이상의 값이 동일해지기 때문에 잘못된 캐싱이 발생합니다. 우리의 솔루션은 두 개의 거래 쌍을 생성하는 것입니다: 하나는 캐시에서 tokenPrice를 업데이트하는 데 사용되는 고가 및 저유동성 거래 쌍이고, 다른 하나는 캐시에서 업데이트되는 저가, 고유동성 거래 쌍입니다. 동일 이름 풀 tokenAmount. 이 방법을 통해 Python 스크립트의 잘못된 계산을 사용하여 토큰 가격과 유동성을 조작하는 데 성공했으며 궁극적으로 DVM에서 모든 WETH를 훔치는 목표를 달성했습니다.

취약점 분석

문제는 문자열(단위 8)을 사용하여 생성된 이름을 기반으로 풀의 토큰 주소를 캐싱하는 Python 스크립트에서 발생합니다. 우리는 알아차렸습니다.값이 0x80을 초과하면 Python 스크립트에서 동일해지기 때문에 잘못된 캐싱이 발생할 수 있습니다. Python 스크립트의 get_pair_prices 함수에서 이로 인해 가격 계산이 잘못되었습니다.

우리는 먼저 쓸모없는 78개의 거래 쌍을 생성한 다음 공격을 시작하기 위해 조작된 거래 쌍 2개를 생성했습니다.

높은 가격과 낮은 유동성을 특징으로 하는 첫 번째 거래 쌍은 캐시의 tokenPrice를 업데이트합니다. 그 후, 낮은 가격과 높은 유동성을 가진 두 번째 거래 쌍은 동일 이름 풀의 tokenAmount를 업데이트합니다. 데몬이 계속 실행되면서 누적되는 기부 가치는 다소 높은 수치에 도달합니다.

해결책

챌린지를 완료하려면 익스플로잇 계약을 생성하세요. 계약은 먼저 쓸모없는 토큰 거래 쌍을 생성한 다음 고가 저유동성 거래 쌍과 저가 고유동성 거래 쌍을 생성합니다. 이런 식으로 다음을 수행할 수 있습니다.Python 스크립트에서 가격 캐시를 조작하면 특정 조건에서 토큰 가격 및 유동성 계산에 오류가 발생합니다.챌린지 완료 후, 누적된 가치를 지정된 주소로 전송합니다.

8.Token Locker

이 챌린지의 목표는 UNCX_ProofOfReservesV2_UniV3 계약의 취약점을 악용하여 계약의 NFT를 훔치는 것입니다. 취약점은 lock() 함수를 사용하면 사용자가 계약의 유동성을 잠글 수 있지만 함수가 수신한 LockParams 구조의 nftPositionManager 매개변수가 악의적인 계약으로 대체될 수 있다는 것입니다. 이를 통해 맞춤형 NFT 위치 관리자를 통해 NFT의 위치와 유동성을 제어할 수 있습니다. 우리의 솔루션은 UNCX_ProofOfReservesV2_UniV3 계약에서 잠금 기능을 작동하고 CustomNftPositionManager 계약을 사용하여 NFT의 위치와 유동성을 조작하는 TokenLockerExploit 계약을 생성하는 것입니다. 이러한 방식으로 우리는 NFT 계약의 자산을 이전하고 통제할 수 있으며 궁극적으로 계약의 자금을 성공적으로 비울 수 있습니다.

취약점 분석

이 문제는 실제로 Ethereum 메인넷의 0x7f5C649856F900d15C83741f45AE46f5C6858234 계약의 포크인 UNCX_ProofOfReservesV2_UniV3 계약에서 발생합니다. 코드를 빠르게 검토한 후 사용자가 상호 작용할 수 있는 외부 기능, 특히 lock() 기능을 자세히 살펴봐야 합니다.

UNCX_ProofOfReservesV2_UniV3 계약에서 lock() 기능을 사용하면 사용자는 계약에서 유동성을 잠가서 유동성을 보호할 수 있습니다. 이 기능은 두 가지 옵션을 제공합니다. 사용자는 NFT를 전체 범위로 변환하고 관련 수수료를 청구한 후 요청자에게 반환하거나 기존 포지션을 활용할 수 있습니다.

이 함수는 LockParams 구조를 입력 매개변수, 특히 nftPositionManager로 수신합니다.

INonfungiblePositionManager nftPositionManager를 사용할 수 있다는 것은 계약을 체결할 수 있다는 의미이며 계약을 비워야 하는 외부 호출에서 UNCX_ProofOfReservesV2_UniV3을 반환합니다.

lock() 함수 실행 중에 _convertPositionToFullRange() 함수가 호출될 수 있습니다. 아래 강조된 부분은 약점입니다.

다음과 같은 매개변수를 전달하면 됩니다.

  1. mintParams.token 0 // nftPositionManager는 실제 Uniswap 위치 관리자의 주소를 반환합니다.

  2. address(_nftPositionManager) // nftPositionManager의 주소를 사용자 정의합니다.

  3. mintParams.amount 1 Desired // 배수하려는 NFT ID를 전달해야 합니다.

ERC 721과 ERC 20에는 동일한 transfer() 함수가 있으므로 _convertPositionToFullRange() 함수의 다음 표현식은 다음과 같습니다.자신의 NFT를 악성 nftPositionManager로 전송:

해결책

우리는 NFT를 훔치기 위해 TokenLockerExploit 계약을 만들었습니다. 본 컨트랙트는 UNCX_ProofOfReservesV2_UniV3 컨트랙트의 lock() 함수를 조작하고 CustomNftPositionManager 컨트랙트를 통해 NFT의 포지션과 유동성을 조작하여 컨트랙트 자금 비우기를 실현합니다.

9. Skill Based Game

이 챌린지의 목표는 연속 블랙잭 게임에서 승리하여 0xA65D59708838581520511d98fB8b5d1F76A96cad 이더리움 메인넷의 모든 자금을 소진하는 것입니다. 문제의 취약점은 BlackJack 게임 계약의 처리 기능(Deck.deal())이 블록 속성(예: block.number 및 block.timestamp)에 의존하여 무작위성을 시뮬레이션하여 결과를 예측할 수 있다는 것입니다. 우리의 솔루션은 공격자 계약을 생성하여 카드 거래 프로세스를 시뮬레이션하고 예측 결과에 따라 실제 베팅을 할지 여부를 결정하는 것입니다.

취약점 분석

이 챌린지를 완료하려면 어떤 게임을 플레이할지에 대해 정보에 입각한 결정을 내릴 수 있도록 뽑힐 카드를 미리 알아야 합니다. 이제 계약이 카드 거래에 어떻게 적용되는지 자세히 살펴보겠습니다. 플레이어는 deal() 함수를 호출해야 하며 마지막에 checkGameResult()가 트리거되어야 합니다.

거래 프로세스는 Deck.deal() 함수 내에서 처리됩니다.무작위성을 생성하는 이 방법은 블록 속성과 특정 변수에 의존합니다.,아래 코드 조각에서 알 수 있듯이.이 구현에서는 결과를 예측할 수 있는 취약점이 발생합니다.

카드를 딜링하는 과정에는 블록해시, 플레이어 주소, 딜링된 카드 수, block.timestamp의 해시 계산이 포함됩니다. 이는 단순히 필요한 블록을 기다리고 새로운 데이터를 기반으로 게임 결과를 다시 계산하여 무작위성을 모방하는 잘 알려진 방법이며, 게임 결과가 우리의 요구 사항과 일치하면 플레이해야 합니다.

해결책

공격을 수행하기 위해 Deck 라이브러리를 사용하여 Attacker 계약을 만들었습니다. 계약은 먼저 카드 거래 과정을 시뮬레이션한 후 예측 결과를 바탕으로 실제 배팅 여부를 결정합니다.

이 시점에서 우리는 BLACKJACK 계약의 자금이 소진될 때까지 5 Ether를 값으로 사용하여 이 계약의 play() 함수를 반복적으로 실행하면 됩니다. 이를 달성하기 위한 스크립트는 다음과 같습니다.

10. Enterprise Blockchain

이 챌린지의 목표는 L1 체인의 l1 브리지에서 최소 10개의 FlagToken을 추출하는 것입니다. 문제의 취약점은 특정 ADMIN 사전 컴파일된 계약 호출을 처리할 때 L2 노드가 충돌하여 L2 노드가 다시 시작되고 이전 상태에서 로드될 수 있다는 것입니다. 우리의 솔루션은 이 취약점을 악용하고 먼저 L2에서 L1로 원격 메시지를 보내 FlagToken을 L1로 전송한 다음 L2 노드가 충돌하고 다시 시작되도록 트리거하는 것입니다. 이로써 L2 노드의 상태가 이전 이전 상태로 복원되더라도 L1으로 자금이 성공적으로 이체되어 L2의 자금이 줄어들지 않아 챌린지의 목적을 달성하게 됩니다.

취약점 분석

여기에는 두 개의 체인이 있습니다.

(1) 챌린지 계약은 L1에 배포됩니다.처음에는 l1 Bridge에 100개의 FlagToken(소수점 18자리)이 있습니다.

사용자는 브리지를 사용하여 체인 간에 자금을 이체할 수 있습니다. 릴레이는 두 체인 모두에서 SendRemoteMessage 이벤트를 수신하고 메시지를 대상 체인으로 전달합니다.

SendRemoteMessage 이벤트를 발행하기 위해 sendRemoteMessage() 함수를 호출할 수 있으며, 다른 체인에서 수행할 트랜잭션을 사용자 정의할 수 있습니다.

L2 RPC도 제공되고 플레이어가 일부 에테르를 소유하고 있으므로 L2에서 L1로 원격 메시지를 보내고 l1 브리지에서 사용자에게 토큰을 전송할 수 있습니다.

하지만,the sendRemoteMessage() 이 기능은 공개적으로 사용하기 위한 것이 아니며, ethOut() / ERC 20 Out()을 통해 체인 간에 자금을 전송하는 데만 사용됩니다.

(2) SimpleMultiSigGov 계약이 L2 체인에 배포됩니다., 주소 0x31337에 위치. 사전 컴파일된 계약 ADMIN과 상호 작용하는 데 사용할 수 있습니다.

ADMIN의 미리 컴파일된 계약에는 정의되지 않은 동작이 발생할 수 있는 작업인 fn_dump_state() 함수가 있습니다. 첫째, x.len()은 0x 10보다 커야 합니다. 그렇지 않으면 i == x.len()일 때 범위를 벗어난 인덱스로 인해 프로그램이 패닉 상태가 됩니다. States는 x 86-64에서 16바이트인 슬라이스 [u 8 ]에 대한 원시 포인터입니다. States.offset의 계산 단위는 슬라이스입니다. i의 최대값은 0x 10이므로 할당해야 하는 최소 메모리는 0x 100이 아닌 0x 110(16 * (0x 10 + 1))입니다. 그러므로,x.len()이 0x 10보다 크면 프로그램은 할당되지 않은 메모리 states.offset(0x 10)에 씁니다.

fn_dump_state()를 호출할 때,x.len() > 0x 10이면 L2 노드가 충돌하게 됩니다.모루 서비스가 곧 제공될 예정입니다.재시작이전에 덤프된 상태에서로딩 상태

상태 덤프 간격은 5초이지만 리피터가 SendRemoteMessage 이벤트를 포착하는 한 메시지를 전달합니다.새로운 크로스체인 전송 트랜잭션이 블록에 포함되어 있지만 최신 상태가 덤프되지 않았을 때 L2 노드가 충돌하는 경우 메시지는 L1으로 전달되며 L2의 상태는 이전 상태로만 복원될 수 있습니다. 전송이 발생했습니다. 이 경우 사용자는 L2에서 자금을 지출하지 않고도 L1으로 자금을 이체할 수 있습니다.

0x 31337의 SimpleMultiSigGov만 ADMIN과 상호 작용할 수 있지만 트랜잭션을 실행하기 위한 유효한 서명을 얻을 수 없습니다. 또한 상태 적용 범위 세트를 사용하여 0x 31337의 코드를 임시로 덮어쓰고 호출을 시뮬레이션할 수 있습니다.

ADMIN의 admin_func_run() 함수는 진입점입니다. fn_dump_state() 함수를 호출하려면 처음 2바이트가 0x0204여야 합니다.

해결책

pwn 및 기타 도구를 사용하여 일련의 작업을 수행하여 L2 노드의 충돌을 트리거한 다음 L2 노드가 다시 시작되고 이전 상태에서 로드될 때 크로스 체인 전송을 수행할 수 있습니다. 이렇게 하면 실제로 L2에 자금을 지출하지 않고도 자금을 L1으로 이동할 수 있습니다.이 과정에는 L2 노드 상태의 정밀한 타이밍 제어와 동작이 필요합니다.

11. Dragon Tyrant 

이 챌린지는 드래곤과의 게임입니다. 드래곤을 물리쳐 승리하고 챌린지를 완료하세요. 이 과제에는 두 가지 주요 취약점이 있습니다.

(1) 예측 가능한 난수:게임의 난수 생성 과정을 예측할 수 있으며, 이 난수가 공격/방어 결정을 결정하여 게임의 결과에 영향을 미칩니다. 게임의 난수 생성기는 특정 블록체인 트랜잭션(resolveRandomness)을 모니터링하여 미리 얻을 수 있는 예측 가능한 시드에 의존합니다. 우리의 솔루션은 먼저 트랜잭션 풀 리스너를 통해 충분한 시드 정보를 모니터링하고 수집한 후 이 정보를 사용하여 다음 시드를 예측하는 것입니다.

(2) 논리적 허점:플레이어가 전설적인 검과 방패를 장비해야만 공격력과 방어력을 극대화할 수 있습니다. 게임 계약을 통해 플레이어는 장비 구매를 위해 자신의 상점 계약 주소를 전달할 수 있으며, 이 맞춤 상점이 합법적인지 확인하는 메커니즘은 주소가 아닌 상점 계약의 코드해시 비교를 기반으로 합니다. 이는 플레이어가 공식 스토어와 동일한 코드해시를 사용하여 계약을 생성할 수 있지만 생성자가 다른 경우 일반적인 구매 프로세스 및 가격 제한을 우회할 수 있음을 의미합니다. 우리의 솔루션은 높은 구매 비용을 우회하고 전설적인 검과 방패를 구매하기 위한 맞춤형 상점 계약을 생성함으로써 이 취약점을 이용합니다.

게임 배경

이번 챌린지 배경은 미니게임입니다. 게임에서초강력/체격(높은 공격력/방어력)에 체력 60을 지닌 드래곤이 있습니다.그리고 당신은,주인공은 무작위로 약한 속성과 체력 1을 생성했으며,이 용을 물리쳐야 합니다. 당신과 드래곤 모두 ERC 721 토큰입니다. 드래곤이 전투 중일 때실패하고 이후에 파괴됨시간(솔루션 확인), 도전은 성공과 같습니다.

싸워야 해, 싸워야 해최대 256개의 미니 라운드가 있습니다.. 매 턴마다 당신과 드래곤은 다음을 할 수 있습니다.공격 또는 방어를 선택하세요피해 계산다음과 같이 요약됩니다.

각 작은 라운드가 끝나면 양 당사자의 체력이 해당 손상만큼 감소합니다. 파티의 체력이 0이 되면 파티는 파괴되고 게임은 종료됩니다. 양 당사자의 체력이 0이 되면,공격측(플레이어)은 파괴됩니다.

드래곤과 플레이어의 공격/방어 속성은 다음과 같습니다.각 속성과 장비를 기준으로 계산됩니다.. 각 진영은 무기 1개와 방패 1개를 장비할 수 있습니다.상점에는 매우 강력한 검을 포함하여 일부 장비를 판매하고 있습니다.. 드래곤은 아무것도 장착하지 않으며 플레이어는 처음에1000 ETH

게임 내에서 난수 생성기가 사용되는 두 곳이 있습니다. 하나를 위해플레이어 속성 결정, 다른 하나는드래곤의 공격/방어 결정을 결정합니다.ECC 기반 난수 생성기 사용,씨앗오프체인에서 제공

공격/방어 결정

드래곤을 물리치려면 유일한 체력을 유지하면서 드래곤의 체력을 0으로 줄여야 합니다. 공격/방어 매트릭스를 살펴보면 이는 공격/공격 시나리오가 발생하도록 허용할 수 없음을 의미합니다. 공격/공격 턴 동안 두 플레이어의 체력이 모두 0으로 감소하여 플레이어가 실패하게 됩니다. 왜냐하면 양측의 공격 속성이 상대방의 체력보다 훨씬 높기 때문입니다. 방어-방어 라운드는 NOP와 유사하므로 공격/방어 라운드와 방어/공격 라운드에만 의존할 수 있습니다.

양 당사자의 공격/방어 결정은 다음과 같으므로사전 제출예, 공격/공격 라운드를 방지하려면 드래곤의 선택을 미리 알아야 합니다. 이를 위해서는 예측이 필요합니다.난수 생성, 그런 다음 예측해야 합니다.무작위 시드. 다행히도파이썬 라이브러리Python의 무작위 모듈 출력은 생성기에서 약 20k 비트의 출력을 관찰하면 예측할 수 있습니다.

그렇다면 우리가 접근할 수 없는 Python 무작위 모듈의 20k 비트 출력을 이 라이브러리에 어떻게 제공할 수 있을까요? 우리가 할 수 있다는 것이 밝혀졌습니다원하는 수의 플레이어 캐스팅, 각 주조 거래는오프체인 시드 제공자가 무작위 시드를 제출하도록 트리거보류 중인 트랜잭션 풀에서 이러한 트랜잭션을 모니터링하여 시드를 캡처할 수 있습니다. 실제로 우리는 78개의 주조된 씨앗을 채취한 후 무작위 씨앗을 예측할 수 있다는 것을 발견했습니다.:

ECC 난수 생성기는 결정론적이므로 드래곤의 공격/방어 결정을 예측할 수 있습니다. 우리는 항상 용과 반대되는 행동을 합니다. 용이 공격하면 우리는 방어합니다. 용이 방어하면 우리는 공격한다.

공격/방어 속성

장비가 없으면 우리의 겸손한 속성으로 인해 전투에서 실패하게 됩니다. 드래곤은 유형(uint 40).max의 공격 속성과 유형(uint 40).max - 1의 방어 속성을 갖습니다. 아무런 장비도 없이 우리가 공격하고 용이 방어하면 우리는 용에게 피해를 주지 않습니다. 용이 공격하고 우리가 방어하면 우리는 즉시 실패합니다.

자연스럽게 우리의 관심이 집중되었습니다.전설의 검. 이 검을 사용하면 공격 속성이 type(uint 40).max에 도달하여 우리가 공격하고 드래곤이 방어할 때 드래곤에게 1 HP 피해를 입힐 수 있습니다. 이 과정을 60번 반복하면 용은 죽습니다. 희망이 있습니다.

이 검을 어떻게 살 수 있습니까? 비용은 100만 ETH인데 우리에게는 1000 ETH밖에 없습니다. 우리가이 검을 장비하세요, 게임을 통해 우리는 매장 계약을 직접 전달할 수 있습니다.매장 계약은 공장 계약 소유자가 사전에 승인한 것입니다., 게임은 즐겁게 계속됩니다. 자세히 살펴보니 이 확인은 매장 계약 주소를 확인하는 것이 아니라,매장 계약의 코드해시 비교완료합니다. 이는 동일한 코드해시를 사용하여 상점 계약을 전달하는 한 계속할 수 있음을 의미합니다. extcodehash에는 생성자가 포함되어 있지 않기 때문에동일한 코드이지만 생성자가 다른 자체 아이템 상점을 만들고 이를 사용하여 플레이어에게 검을 장착할 수 있습니다.

이 방법은 효과적입니다. 다음 생성자와 함께 가짜 상점을 사용하면 전설적인 검과 새로운 전설적인 방패를 얻을 수 있습니다.

이 두 가지 전설적인 장비를 사용하여 type(uint 40).max의 공격 속성과 type(uint 40).max의 방어 속성을 구현하겠습니다. 드래곤이 공격할 때 우리는 HP를 잃지 않으며, 공격할 때 드래곤에게 1HP의 데미지를 줍니다.

해결책

솔루션의 단계별 프로세스는 다음과 같습니다.

  1. 플레이어 토큰을 우리 지갑에 넣어보세요.

  2. 가짜 상점을 배치하고 이를 사용하여 플레이어에게 전설적인 장비 두 개를 장착하세요.

  3. 챌린지의 요구에 따라 공격자 계약을 배포합니다. 이 계약은 플레이어 토큰을 인수하고, 전투를 시작하고, 플레이어에게 공격/방어 결정을 제공합니다.

  4. 플레이어 토큰을 공격자 계약으로 전송합니다.

  5. ResolveRandomness 트랜잭션을 모니터링하려면 보류 중인 트랜잭션 풀 리스너를 시작하세요. 씨앗을 캡쳐해 충분한 정보를 수집한 후 다음 씨앗을 예측합니다.

  6. 78개의 추가 플레이어 토큰을 주조하세요.

  7. 이 시점에서 풀 수신기는 다음 시드를 예측하기에 충분한 정보를 수집해야 합니다.

  8. 예측된 시드는 난수 생성기에 입력되어 드래곤의 공격/방어 결정을 결정합니다.

  9. 플레이어의 결정을 도출하기 위해 드래곤의 결정 문자열을 비트 단위로 뒤집습니다. 질문을 받으면 공격자 계약이 플레이어의 결정을 제공합니다.

  10. 공격자 계약이 공격을 시작하여 드래곤이 실패하게 됩니다.

12. Hopping Into Place

이 챌린지의 목표는 크로스체인 브리지 계약에서 모든 자금을 인출하는 것입니다. _additionalDebit() 함수에 취약점이 존재하며, 이 함수가 채권자의 부채를 계산할 때, ChallengePeriod가 0으로 설정되면 부채가 추가되지 않습니다. 우리의 솔루션은 numTimeSlots도 0이 되도록 ChallengePeriod를 0으로 설정하여 이 취약점을 악용하여 부채 증가를 방지하는 것입니다. 다음으로, 이 경우 getDebitAndAdditionalDebit() 함수가 원래 기능을 잃어 부채가 증가하지 않기 때문에 bondTransferRoot() 함수를 사용하여 원하는 양의 토큰을 인출합니다. 이런 식으로 우리는 크로스체인 브릿지에서 자금을 성공적으로 소진했습니다.

취약점 분석

이 챌린지에서 우리의 정체성은 거버너(Governor)이므로 크로스체인 브리지의 일부 구성을 변경할 수 있습니다.

문제의 근본 원인은 _additionalDebit() 함수에 있습니다.if 문에 부채가 추가됩니다. 이는 numTimeSlots가 0이면 명령문이 실행되지 않음을 의미합니다.보증인의 책임은 증가하지 않습니다. 분명히 이러한 설계는 무리한 것이며 어떠한 경우에도 부채 증가를 간과해서는 안 됩니다.

이를 활용하여 ChallengePeriod를 0으로 설정하여 numTimeSlots가 0이 되는 조건을 달성할 수 있습니다.

이러한 방식으로 getDebitAndAdditionalDebit 함수는 추가 기능을 잃습니다.우리가 무엇을 하든 부채는 늘어나지 않을 것입니다.

이는 함수가 실행된 후 신용이 증가된 부채보다 커야 함을 요구하는 requirePositiveBalance 수정자에도 영향을 미칩니다. 그러나 함수가 추가 기능을 잃기 때문에 부채는 그대로 유지됩니다. 이것은 의미한다이 수정자로 수정된 기능을 사용하여 크로스체인 브리지를 배수할 수 있습니다.

마지막으로 bondTransferRoot의 로직을 살펴보겠습니다. 이 함수는 호출자의 부채에 totalAmount를 설정하고 추출을 위해 transferRoots에 totalAmount를 추가합니다. 따라서 우리는 이 기능을 사용하여 원하는 만큼의 토큰을 인출할 수 있습니다.

해결책

우리는 크로스체인 브릿지에서 자금을 인출하기 위한 챌린지 기간을 0으로 설정하여 추가 부채 추가를 방지하기 위해 몇 가지 주요 계약을 작성했습니다. 각 계약은 특정 기능을 구현합니다.

  1. Exploit Contract : 공격의 주요 계약으로 전체 공격 프로세스의 실행을 담당합니다. 먼저 챌린지 계약 Challenge와 연계한 후 일련의 작업을 통해 크로스체인 브릿지 IBridge를 조작하고 최종적으로 자금 인출 목적을 달성합니다.

  2. MockMessageWapper 계약: 이 계약은 크로스체인 메시지 전달 프로세스를 시뮬레이션합니다. 실제 애플리케이션에서는 효과적인 작업을 수행하지 않지만 자리 표시자 역할을 하여 익스플로잇 계약이 크로스 체인 상호 작용 프로세스를 시뮬레이션할 수 있도록 합니다.

  3. 계약 해결: 이 계약은 CTFSolver에서 상속되며 CTF(Capture The Flag) 챌린지에서 챌린지 계약 챌린지와 상호 작용하는 데 사용됩니다. Exploit 컨트랙트의 Exploit 메서드를 호출하여 공격을 수행하고, 공격 성공 후 문제가 해결되었는지 확인하는 역할을 주로 담당합니다.

  4. IBridge 인터페이스: 크로스체인 브릿지 계약 방법을 정의하는 인터페이스입니다. 여기에는 보증인 추가, 챌린지 기한 설정, 이체 루트 바인딩, 자금 인출 등 익스플로잇 계약에 사용되는 크로스체인 브릿지 운영 방법이 포함됩니다.

  5. IChallenge 인터페이스: 이 인터페이스는 챌린지 계약 챌린지의 메서드를 정의하여 익스플로잇 계약이 챌린지의 크로스체인 브리지 주소에 액세스할 수 있도록 합니다.

13. Oven

이 챌린지의 목표는 숨겨진 FLAG 값을 복구하는 것입니다. 챌린지의 핵심은 fiat_shamir() 함수입니다. 이 함수는 사용자 정의 해시 함수 custom_hash()를 사용하여 난수를 생성한 다음 이 숫자를 사용하여 계산에 참여합니다. 주요 취약점은 fiat_shamir() 함수, 특히 알려진 r, c, p 값과 알려지지 않은 FLAG 값을 포함하는 r=(v - c * FLAG) mod(p-1) 표현식에 있습니다. 해결책은 문제를 격자 문제로 변환한 다음 격자 기반 감소 알고리즘(LLL 알고리즘)을 사용하여 FLAG 값을 찾는 것입니다.

취약점 분석

코드 함수: 사용자는 FLAG의 무작위 서명을 얻을 수 있으며, 무작위 서명을 생성하는 로직은 fiat_shamir() 함수에 있습니다. 사용자 정의 해시 함수 custom_hash는 4개의 서로 다른 해싱 알고리즘을 호출하는 해시 값을 생성하는 데 사용되므로 현재로서는 무작위성을 해독할 수 없습니다.

또한 fiat_shamir 변환은 암호화에서 매우 중요한 도구로, 그 핵심은 해시 알고리즘을 사용하여 난수를 생성하고 암호화 프로토콜에 무작위성을 추가하는 것입니다. FS 변환의 일반적인 적용은 영지식 증명 시스템에 비상호작용을 도입한 다음 snark 및 stark와 같은 프로토콜을 구축하는 것입니다.

소스코드에서는 t, r, p, g, y 등의 정보를 얻을 수 있지만 실제로 c는 custom_hash() 함수를 사용하여 계산할 수 있습니다. 따라서 취약점은 r=(v - c * FLAG) mod (p-1)에 중점을 두고 FLAG를 서명하는 기능 부분인 fiat_shamir() 함수에 집중되어 있습니다. 이 방정식의 경우 현재 얻을 수 있는 정보는 r, c, p가 모두 알려진 값이고 FLAG 비트 수가 결정되었다는 것입니다.<384 。 이는 1996년 Dan Boneh가 제안한 HNP 문제(가변 모듈러스 포함)와 관련될 수 있으며 표준 격자 알고리즘을 사용하여 공격할 수 있습니다.격자 기반 공격에 대한 자세한 암호 분석은 다음을 참조하세요.관련 논문

문제는 코드의 r=(v - c * FLAG) mod (p-1)입니다. r, c, p는 모두 알려진 값이므로 다음과 같습니다.

  1. 먼저 위 방정식을 수학적으로 변환합니다. r-v+c*FLAG= 0 mod (p-1). 여기서 v와 FLAG만 알 수 없습니다.

  2. 둘째, 격자를 구성합니다.여기서 K는 FLAG의 상한이고 모든 공백은 0입니다.

  3. Babai의 CVP 솔루션 알고리즘에 따르면 jM=jk를 참으로 만드는 솔루션 벡터 j=[l1, l2, l3, FLAG, 1]이 있어야 합니다.

  4. jk는 격자의 짧은 벡터이므로 LLL 알고리즘을 사용하여 다항식 시간에 이 짧은 벡터를 찾을 수 있습니다. 짧은 벡터의 각 요소는 64비트로 표현될 수 있으므로 상한 K= 2^64가 결정됩니다.

팁: 다음은 데이터 볼륨 문제에 대한 참고 사항입니다. FLAG를 복구하는 데 필요한 데이터 세트 수를 어떻게 알 수 있나요? 이를 위해서는 가장 짧은 벡터 길이를 추정하기 위해 가우스 휴리스틱을 사용해야 하며, 필요한 목표 벡터 놈은 이 길이보다 작습니다. 그러나 이것이 CTF 대회의 맥락이기 때문에 일반적으로 처음에는 3~4개 또는 5개의 데이터 세트를 사용할 수 있습니다. 그렇지 않은 경우 위의 방법을 사용하여 정확한 계산을 수행할 수 있습니다. 여기,백업을 위해 5개의 데이터 세트를 수집했지만 FLAG를 해결하는 데 실제로 사용된 데이터 세트는 3개뿐입니다.

해결책

우리 코드는 sage-python 환경에서 실행되어야 합니다. 주요 아이디어는 다음과 같습니다.

  1. 격자 구성: 먼저 알려진 p, c, r 값과 알려지지 않은 FLAG 값을 포함하는 특정 격자를 구성합니다. 이 그리드는 위의 방정식에서 변환됩니다.

  2. LLL 알고리즘 사용: LLL 알고리즘을 적용하여 격자에서 짧은 벡터를 찾습니다. LLL 알고리즘은 원래 문제의 해와 수학적으로 관련된 격자의 기저 벡터를 다항식 시간에 찾을 수 있는 효율적인 알고리즘입니다.

  3. FLAG 복구: 짧은 벡터가 발견되면 여기에서 FLAG 값을 추출할 수 있습니다. 짧은 벡터의 요소는 64비트로 표현될 수 있으므로 FLAG 크기에 상한이 적용됩니다.

대회부터 실습까지

Salute 팀은 현재 Paradigm CTF 2023 대회에서 귀중한 경험을 얻었습니다.Salus Security가 제공하는 향상된 스마트 계약 감사 서비스의 중요한 부분. 최고의 스마트 계약 감사 서비스가 필요하다면 언제든지문의하기. 우리는 귀하의 요구에 대해 포괄적이고 효율적인 지원을 제공하기 위해 최선을 다하고 있습니다.

안전
스마트 계약
Paradigm
Odaily 공식 커뮤니티에 가입하세요
AI 요약
맨 위로
Salus安全团队在Paradigm 2023 CTF中共解决了13项挑战,在1011支队伍中以3645.60的分数获得第九名,并受邀成为Paradigm CTF 2024的客座作者。在这篇博文中,我们将介绍我们在比赛期间解决的所有挑战。
작성자 라이브러리
Odaily 플래닛 데일리 앱 다운로드
일부 사람들이 먼저 Web3.0을 이해하게 하자
IOS
Android