요즘 해킹 대회에서도 스마트컨트렉 보안관련 문제가 가끔 나온다.

스마트컨트렉은  온라인 계약이니 이더리움의 솔리디티관련 CTF 도장깨기를

시작해 볼까 한다.

 

생각보다 문제 많이 까다롭다.

천천히 올클을 목표로!!

 

레벨 0. Hello Ethernaut

https://ethernaut.zeppelin.solutions/level/0xdf51a9e8ce57e7787e4a27dd19880fd7106b9a5c

 

This level walks you through the very basics of how to play the game.

블록체인은 remote exploit 처럼 특정 contract에 계속 먼가를 던저야 되니

중간에 gdb처럼 디버깅되는 과정을 보기 힘들다.

그래서 다른 wargame과 다르게 조금 풀기가 까다로울수도 있다.

그리고 또 개념을 잘 잡아야 된다. Dapp을 만들던 메인넷을 하던 컨트렉을 짜던

개념이 아주 중요하다.

UTXO를 모르고 BTC지갑을 만들수 있을가?

이론적인 부분도 아주 중요한 부분이 된다.

1. Set up MetaMask
2. Open the browser's console
3. Use the console helpers
4. The ethernaut contract
5. Interact with the ABI
6. Get test ether
7. Getting a level instance
8. Inspecting the contract
9. Interact with the contract to complete the level 

설명은 차근 차근 읽어 보도록 한다.

0단계는 쉽다.

  

메타마스크 연동해서  롭스톤 테스트넷 연동하고 그런건 알아서 타 블로그를

참고 하길 바란다.

 

Get New instance를 하면 메타마스크에서 컨트렉을 하나 보낼수 있다.

크롬 개발자 도구 F12눌러서 Console에서 진행하면 된다.

 

블록체인은 동기 비동기라서 await와 sync를 잘 활용해야된다

자바스크립트 특징상 한꺼번에 처리 할려구 하니 모든 구문은

서버랑 통신하는 모든 구문은 거의 await를 쓴다고 보면된다.

 소스 코드는 원본 홈페이지를 참고하고 write up만 나열한다.

await contract.info()
"You will find what you need in info1()."


await contract.info1()
"Try info2(), but with "hello" as a parameter."


await contract.info2("hello")
"The property infoNum holds the number of the next info method to call."

await contract.infoNum()
t {s: 1, e: 1, c: Array(1)}c: [42]e: 1s: 1__proto__: Object


await contract.info42()
"theMethodName is the name of the next method."


await contract.theMethodName()
"The method name is method7123949."

await contract.method7123949()
"If you know the password, submit it to authenticate()."

await contract.password()

ethernaut0


await contract.authenticate('ethernaut0')
{tx: "0x9f6c29c29b5397f6df441d4eddb6ae82b89818e57f40635f37eec6ac9153205d", receipt: {…}, logs: Array(0)} 

 

 

Submit instance를 누러 메타마스크를 실행하면

Pendding이 완료되면

다음 단계로 넘어 간다.

 

 

 

'Ethernaut' 카테고리의 다른 글

ethernaut.zeppelin.solutions 1. Fallback  (0) 2018.12.28
블로그 이미지

iesay

,

테스트넷에 Token 생성  내일 뜯어보자

출처 : https://github.com/TronWatch/Desktop-Wallet/tree/master/app/components/Tokens

API : https://developers.tron.network/v3.0/reference#createtoken

 

 

메인넷은 마법사 보고 따라하면 생성 가능

https://www.youtube.com/watch?v=7cQrkHUijbo

블로그 이미지

iesay

,

참고 : https://tron.network/wallet?lng=kor

        https://github.com/TronWatch/TronLink/blob/master/packages/backgroundScript/services/WalletService/Account.js

 

to, from에서 조회한 내역을 MongoDB에 넣어보자

 

const TronWeb = require('../../dist/TronWeb.node.js');

const fullNode = 'https://api.shasta.trongrid.io';
const solidityNode = 'https://api.shasta.trongrid.io';
const eventServer = 'https://api.shasta.trongrid.io';
const privateKey = 'abc';

 

const app = async() => {
const tronWeb = new TronWeb(
    fullNode,
    solidityNode,
    eventServer,
    privateKey
);
tronWeb.setDefaultBlock('latest');

const nodes = await tronWeb.isConnected();
const connected = !Object.entries(nodes).map(([name, connected]) => {
    if (!connected)
        console.error(`Error: ${name} is not connected`);
        return connected;
    }).includes(false);


const transactions = [];


         let hasMoreTransactions = true;
         let offset = 0;


         while(hasMoreTransactions) {
             const newTransactions = (await tronWeb.trx.getTransactionsRelated("TS4AYYxrF38EA3fDw92mMWbWdFWRJ4VKih", 'all', 90, offset))
                 .map(transaction => {
                     transaction.offset = offset;
                     return transaction;
                 });


             if(!newTransactions.length)
                hasMoreTransactions = false;
             else offset += 90;


             transactions.push(...newTransactions);
         }
         console.log("transactions: ", transactions);

};
app();

 

 

 

 

데이터가 블록으로 넘어오는듯,, 블록을 한번 도 조회 해야 되는데

이더처럼 json형태로 to. from. 컨트렉종류, 금액 이렇게 넘어와야 되는데

트론은 token에 대한 개발이 아직 진행중인걸로 보임

 

테스트넷에 대한 지원도 좀 짜증날 정도로 지원을 안해주고 있음.

async updateTransactions() {
 if(this.updatingTransactions) return;
 this.updatingTransactions = true;
 const transactions = await this.getTransactions();
 const filteredTransactions = transactions .filter(( {
  txID
 }) => ( !Object.keys(this.transactions).includes(txID) && !this.ignoredTransactions.includes(txID) ));
 const mappedTransactions = TransactionMapper.mapAll(filteredTransactions) .filter(( {
  type
 }) => SUPPORTED_CONTRACTS.includes(type));
 const newTransactions = [];
 const manuallyCached = [];
 for (const transaction of mappedTransactions) {
  if(transaction.timestamp) {
   transaction.cached = true;
   newTransactions.push(transaction);
   continue;
  }const txData = await NodeService.tronWeb.trx .getTransactionInfo(transaction.txID);
  if(!txData.id) {
   logger.warn(`Transaction $ {
    transaction.txID
   }has not been cached,
   skipping`);
   continue;
  }// if(!txData.id) {
   // logger.warn(`Transaction ${
    transaction.txID
   }has not been cached`);
 // // StorageService.addPendingTransaction(address,
   transaction.txID);
 // transaction.cached = false; // // this.transactions[
    transaction.txID
   ]= transaction;
 // continue; //
  }// logger.info(`Transaction ${
   transaction.txID
  }has been cached`,
  transaction);
transaction.cached = true;
transaction.timestamp = txData.blockTimeStamp;
transaction.receipt = txData.receipt || false;
transaction.result = txData.contractResult || false;
newTransactions.push(transaction);
manuallyCached.push(transaction.txID);
 }const sortedTransactions = [
  ...Object.values(this.transactions),
  ...newTransactions
 ].sort((a,
 b) => b.timestamp - a.timestamp);
this.transactions = sortedTransactions .slice(0,
 100) .reduce((transactions,
 transaction) => {
  transactions[
   transaction.txID
  ]= transaction;
return transactions;
 },
 {});
manuallyCached.forEach(txID => {
  if(txID in this.transactions) return;
// Transaction is now too old for TronLink (100+) this.ignoredTransactions.push(txID);
 });
this.updatingTransactions = false;
this.save();
}

 

블로그 이미지

iesay

,