
개요
해당 포스트는 2023년 2월 27일 LZ finance에서 일어난 약 1,000,000 달러의 해킹 사건을 분석한 포스트입니다.
컨트랙트 취약점과 해킹 기법, 취약점 수정에 초점을 맞추어 포스트를 작성하였습니다.
취약한 컨트랙트
취약한 컨트랙트의 주소는 0x6D8981847Eb3cc2234179d0F0e72F6b6b2421a01입니다.
이 컨트랙트는 LZ finance에서 배포한 SwapXProxy의 implementation 컨트랙트입니다.
취약한 컨트랙트는 마치 Uniswap Router와 같은 역할을 수행하고 있으며,
LZ finance에서 해당 코드를 공개하지 않아, 바이트코드를 디컴파일해 분석할 수도 있으나,
이번 포스트에서는 Transaction 분석을 통해 해당 컨트랙트의 기능과 취약점을 분석하도록 하겠습니다.
Transaction 분석
같은 컨트랙트를 활용해 여러 공격이 들어왔으나, 대표적인 Transaction 하나를 분석하여 기능과 취약점을 파악해 보겠습니다.

취약한 컨트랙트(0x6d89...)의 4f1f05bc 함수를 호출하고 있습니다.
이 함수는 실질적으로 두 번의 call을 수행하게 됩니다.(LZtoken.transferfrom, BiswapPair.swap)
두 번의 함수 호출을 볼 때 이 함수는 UniswapRouter의 swap과 같은 역할을 한다는 것을 추측할 수 있습니다.
하지만 위 함수 호출에서 transferfrom의 sender가 msg.sender가 아닌 다른 주소가 들어간다는 것을 볼 수 있고, 여기서 취약점이 발생합니다.
(UniswapRouter의 경우 아래의 코드와 같이 sender에는 msg.sender가 들어갑니다.)
function safeTransferFrom(
address token,
address from,
address to,
uint256 value
) internal {
// bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
require(
success && (data.length == 0 || abi.decode(data, (bool))),
'TransferHelper::transferFrom: transferFrom failed'
);
}
function swapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external virtual override ensure(deadline) returns (uint[] memory amounts) {
amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path);
require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT');
TransferHelper.safeTransferFrom(
path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0]
);
_swap(amounts, path, to);
}
취약점 분석
위에서 확인한 컨트랙트의 취약점은 다른 사람의 swap을 대신할 수 있다는 것이었습니다.
해당 취약점은 uniswapV2의 구조에 대해 알고 있다면 얼마나 치명적인지 쉽게 이해할 수 있습니다.
(uniswapV2에 대해서 잘 모르시는 분들은 해당 포스트를 참고하시면 됩니다.)
공격 순서는 다음과 같습니다.
- 다른 사람들의 자산을 통해 UniswapPair에서의 특정 token의 가격을 뻥튀기 시킵니다.
- 공격자가 보유한 token을 해당 Pair를 통하여 swap합니다.
위와 같은 방식을 통해 자신의 자산을 불리고, 뻥튀기 하면서 발생하는 손해는 다른 사람에게 넘어가게 됩니다.
Transaction 분석에 사용된 Transaction은 사용자 한 명에 대해서 공격을 수행하였지만, 다른 Transaction의 경우 수많은 사용자들을 대상으로 공격을 수행하였습니다.
'Blockchain-Hacking > Hacking-analysis' 카테고리의 다른 글
| Dexible Hacking Analysis (0) | 2023.03.05 |
|---|---|
| Hakuna Matata($TATA) Hacking Analysis (0) | 2023.03.03 |
| Dynamic Finance($DYNA) Hacking Analysis (0) | 2023.02.25 |