목록분류 전체보기 (65)
Tyojong
query : {$query}"; $result = @mysqli_fetch_array(mysqli_query($db,$query)); if($result['id']) echo "Hello {$result[id]}"; if($result['id'] == 'admin') solve("dragon"); highlight_file(__FILE__); ?> 문제 목표$query = "select id from prob_dragon where id='guest'# and pw='{$_GET[pw]}'";where문 id값 뒤에는 주석처리가 된다.if($result['id'] == 'admin') solve("dragon");id가 admin이면 문제가 해결된다. 문제 해결#은 mysql에서 한 줄 주..
문제 설명코드 분석문제 컨트랙트 배포 시 설정된 패스워드와 일치하는 패스워드를 unlock함수 인자로 넣으면 금고의 잠금이 해제된다.익스플로잇password 변수가 private로 선언되어 있지만 private은 단순히 다른 컨트랙트에서 접근을 막을 뿐, 외부에서 직접 스토리지를 조회하는 것은 막지 못한다. cast storage 명령어를 사용해 storage 슬롯을 읽는다. (슬롯0: locked, 슬롯1: password) 알아낸 패스워드를 unlock함수의 인자로 넣고 실행시키면 문제를 해결할 수 있다.
문제 설명코드 분석이번 문제의 컨트랙트 코드를 보면 이더를 받기 위한 함수가 정의되지 않았다. 원래 컨트랙트에서는 이더를 받기 위해 receive() 함수, fallback() 함수, payable 함수를 사용해야한다.해당 함수들을 사용하지 않는 컨트랙트에 이더를 보내면 해당 트랜잭션은 revert된다.Selfdestructselfdestruct는 solidity에서 스마트 컨트랙트를 블록체인에서 제거하고, 남은 이더를 지정된 주소로 강제 전송하는 함수이다.이 함수를 사용하게 되면 컨트랙트의 어떤 코드도 실행하지 않고 강제로 이더를 전송하게 된다. receive나 fallback이 없어도, 이더 수신을 거부하는 로직이 있어도 강제로 받게 된다.익스플로잇공격 컨트랙트를 생성하여 selfdesturct를 이..
문제 설명코드 분석Delegate 컨트랙트는 배포 시 owner가 정해지지만 pwn() 함수를 이용해 owner를 호출한 사용자로 변경할 수 있다. Delegation 컨트랙트는 배포시 호출한 사용자가 owner로 지정된다.fallback() 함수는 컨트랙트에 존재하지 않는 함수를 호출할 경우 실행된다. fallback() 함수에서는 address(delegate)를 통해 위 Delegate 컨트랙트를 불러온다.Delegate컨트랙트의 함수를 delegatecall을 이용해 호출한다.call vs delegatecallCA1에서 CA2의 함수를 call로 호출하면 CA2의 storage를 이용하지만CA1에서 CA2의 함수를 delegatecall로 호출하면 CA1의 storage를 이용하게 된다. del..
query : {$query}"; $result = @mysqli_fetch_array(mysqli_query($db,$query)); if($result['id']) echo "Hello {$result[id]}"; $_GET[pw] = addslashes($_GET[pw]); $query = "select pw from prob_xavis where id='admin' and pw='{$_GET[pw]}'"; $result = @mysqli_fetch_array(mysqli_query($db,$query)); if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("xavis"); highlight_file(__FILE..
문제 설명코드 설명호출한 사용자의 잔액에서 _.value 만큼 _to에게 토큰을 전송한다.보내는 토큰은 잔액보다 많지 않아야 하고 _value값 만큼 사용자의 잔액에서 차감되며 _to의 잔액이 증가한다.익스플로잇solidity 0.6 버전에서는 언더플로우체크가 존재하지 않는다.balances[msg.sender] (사용자의 잔액) 보다 _value값이 크면 뺄셈 이후 음수가 되어야 하지만 uint의 경우 음수가 불가능하므로 언더플로우가 발생하게 된다. 사용자의 잔액이 20토큰으로 주어졌기 때문에 20보다 큰 값을 _value인자로 전달하면 된다. 문제 컨트랙트 transfer함수에 아무 주소와 21을 인자로 주면 문제가 해결된다.
문제 설명코드 분석이전 블록해시값과 FACTOR를 나눈 몫이 1이면 true값 아니면 false값을 반환하여_guess로 받은 bool값과 일치하면 consecutiveWins값이 1증가하고 틀리면 0으로 초기화된다. 이더리움에서 블록은 12초에 하나씩 생성되는데 하나의 블록에서 12초안에 10번의 트랜잭션을 보내면 모두 맞거나, 모두 틀리거나 50% 확률로 성공할 수 있는 가능성이 있다.때문에 문제에서는 이를 방지하기 위해 이전 트랜잭션에서 사용한 블록 해시와 현재 트랜잭션의 블록 해시를 비교해 일치하면 revert시켜 모두 다른 트랜잭션에서 시도하도록 만들었다.익스플로잇EOA(사용자)가 CA1(공격 컨트랙트)를 실행하고 CA1이 CA2(문제 컨트랙트)를 실행하면 이 과정은 하나의 트랜잭션으로 실행된다..
6) exit("No Hack ~_~"); $query = "select id from prob_nightmare where pw=('{$_GET[pw]}') and id!='admin'"; echo "query : {$query}"; $result = @mysqli_fetch_array(mysqli_query($db,$query)); if($result['id']) solve("nightmare"); highlight_file(__FILE__); ?> 문제 목표if($result['id']) solve("nightmare");id가 출력되면 문제가 해결된다. if(strlen($_GET[pw])>6) exit("No Hack ~_~"); pw의 입력 길이는 5자 이하로 제한되어있다. ..
문제 설명코드 분석처음 배포자가 owner로 설정되고 changeOwner에 주소를 넣고 호출 시 넣은 주소가 owner가 된다.단, changeOwner함수를 호출한 주소(msg.sender)가 트랜잭션을 시작한 주소(tx.origin)랑 동일하면 안된다. 즉, 공격자가 changeOwner함수를 직접 호출해 owner를 설정하면 적용되지 않는다.익스플로잇msg.sender의 경우 스마트 컨트랙트 또는 사용자(EOA)의 주소를 받아온다.하지만 tx.origin의 경우 사용자(EOA)의 주소만 가져온다. 공격 컨트랙트를 생성해 컨트랙트에서 changeOwner를 호출하면 msg.sender는 공격 컨트랙트의 주소가 되고 tx.origin의 경우 사용자의 주소가 되어 owner를 변경할 수 있게된다.공격 ..
보호되어 있는 글입니다.
