{"id":2714,"date":"2024-08-23T21:25:00","date_gmt":"2024-08-23T13:25:00","guid":{"rendered":"https:\/\/systw.net\/note\/?p=2714"},"modified":"2025-08-23T22:46:06","modified_gmt":"2025-08-23T14:46:06","slug":"ctf-coinflip","status":"publish","type":"post","link":"https:\/\/systw.net\/note\/archives\/2714","title":{"rendered":"CTF CoinFlip"},"content":{"rendered":"\n<p>\u9019\u9053Blockchain CTF\u984c\u76ee\u6d89\u53ca\u4e00\u500b\u4ee5\u592a\u574a\u667a\u80fd\u5408\u7d04\u7684\u96a8\u6a5f\u6578\u6f0f\u6d1e\u5229\u7528\uff0c\u984c\u76ee\u8981\u6c42\u7528\u6236\u731c\u6e2c\u4e00\u500b\u57fa\u65bc\u5340\u584a\u54c8\u5e0c\u7684\u64f2\u786c\u5e63\u7d50\u679c\uff08true \u6216 false\uff09\u3002\u901a\u904e\u7de8\u5beb\u653b\u64ca\u5408\u7d04\uff0c\u7528\u6236\u53ef\u4ee5\u5728\u6bcf\u500b\u65b0\u5340\u584a\u751f\u6210\u5f8c\u8a08\u7b97\u6b63\u78ba\u7684\u731c\u6e2c\uff0c\u5f9e\u800c\u9054\u6210 CTF \u6311\u6230\u7684\u76ee\u6a19\u3002<\/p>\n\n\n\n<p>\u984c\u76ee\u4f4d\u7f6e\uff1a<a href=\"https:\/\/ethernaut.openzeppelin.com\/level\/3\" target=\"_blank\" rel=\"noopener\">https:\/\/ethernaut.openzeppelin.com\/level\/3<\/a><\/p>\n\n\n\n<p>\u9019\u7a2e\u6f0f\u6d1e\u5728\u4ee5\u592a\u574a\u667a\u80fd\u5408\u7d04\u4e2d\u5f88\u5e38\u898b\uff0c\u5408\u7d04\u7684\u6f0f\u6d1e\u5728\u65bc\u5176\u4f7f\u7528\u4e86\u53ef\u9810\u6e2c\u7684\u5340\u584a\u54c8\u5e0c\u4f5c\u70ba\u96a8\u6a5f\u6578\u4f86\u6e90\uff0c\u9019\u4f7f\u5f97\u653b\u64ca\u8005\u53ef\u4ee5\u901a\u904e\u67e5\u8a62\u5340\u584a\u54c8\u5e0c\u8f15\u9b06\u9810\u6e2c\u786c\u5e63\u7d50\u679c\u4e26\u9023\u7e8c\u731c\u5c0d\u3002<\/p>\n\n\n\n<p><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dots\"\/>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u984c\u76ee\u8aaa\u660e<\/h2>\n\n\n\n<p>\u9019\u662f\u64f2\u9285\u677f\u7684\u904a\u6232\uff0c\u5982\u679c\u8981\u904e\u95dc\u5fc5\u9808\u9023\u7e8c\u731c\u5c0d10\u6b21<\/p>\n\n\n\n<p><strong>\u4e3b\u8981\u529f\u80fd<\/strong>: \u7528\u6236\u901a\u904e\u8abf\u7528 <code>flip<\/code> \u51fd\u6578\u731c\u6e2c\u786c\u5e63\u7d50\u679c\uff08true \u6216 false\uff09\u3002\u5982\u679c\u731c\u5c0d\uff0c<code>consecutiveWins<\/code> \u589e\u52a0 1\uff1b\u5982\u679c\u731c\u932f\uff0c<code>consecutiveWins<\/code> \u91cd\u7f6e\u70ba 0\u3002<\/p>\n\n\n\n<p><strong>\u73a9\u6cd5<\/strong>\uff1a\u5728chrome\u7684console \u57f7\u884c <code>contract.flip(true)<\/code>\u6216<code>contract.flip(false)<\/code> \u4f86\u731c\u667a\u80fd\u5408\u7d04\u6703\u62ff\u5230true\u6216false\u3002\u4e5f\u53ef\u57f7\u884c <code>contract.address<\/code>\u67e5\u667a\u80fd\u5408\u7d04\u4f4d\u7f6e\uff0c\u5728\u93c8\u4e0a\u67e5consecutiveWins \u76ee\u524d\u9023\u52dd\u5e7e\u6b21\u3002<\/p>\n\n\n\n<p><strong>\u5408\u7d04\u5167\u5bb9\u5982\u4e0b\uff1a<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ncontract CoinFlip {\n    uint256 public consecutiveWins;\n    uint256 lastHash;\n    uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n\n    constructor() {\n        consecutiveWins = 0;\n    }\n\n    function flip(bool _guess) public returns (bool) {\n        uint256 blockValue = uint256(blockhash(block.number - 1));\n\n        if (lastHash == blockValue) {\n            revert();\n        }\n\n        lastHash = blockValue;\n        uint256 coinFlip = blockValue \/ FACTOR;\n        bool side = coinFlip == 1 ? true : false;\n\n        if (side == _guess) {\n            consecutiveWins++;\n            return true;\n        } else {\n            consecutiveWins = 0;\n            return false;\n        }\n    }\n}<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dots\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u4ee3\u78bc\u89e3\u8aaa<\/strong><\/h2>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>\u5408\u7d04\u7d50\u69cb\u8207\u529f\u80fd<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u72c0\u614b\u8b8a\u91cf<\/strong>:\n<ul class=\"wp-block-list\">\n<li><code>consecutiveWins<\/code>: \u8a18\u9304\u7528\u6236\u9023\u7e8c\u731c\u5c0d\u7684\u6b21\u6578\u3002<\/li>\n\n\n\n<li><code>lastHash<\/code>: \u8a18\u9304\u4e0a\u4e00\u6b21\u4f7f\u7528\u7684\u5340\u584a\u54c8\u5e0c\u503c\uff0c\u7528\u65bc\u9632\u6b62\u91cd\u8907\u4f7f\u7528\u76f8\u540c\u7684\u5340\u584a\u54c8\u5e0c\u3002<\/li>\n\n\n\n<li><code>FACTOR<\/code>: \u4e00\u500b\u5e38\u91cf\uff0c\u7528\u65bc\u5c07\u5340\u584a\u54c8\u5e0c\u503c\u8f49\u63db\u70ba 0 \u6216 1\uff08\u6a21\u64ec\u786c\u5e63\u7684\u6b63\u53cd\u9762\uff09\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u69cb\u9020\u51fd\u6578<\/strong>: \u521d\u59cb\u5316 <code>consecutiveWins<\/code> \u70ba 0\u3002<\/li>\n\n\n\n<li><strong>\u4e3b\u8981\u51fd\u6578<\/strong>: <code>flip(bool _guess)<\/code>\uff0c\u6839\u64da\u5340\u584a\u54c8\u5e0c\u751f\u6210\u96a8\u6a5f\u6578\uff0c\u4e26\u8207\u7528\u6236\u7684\u731c\u6e2c <code>_guess<\/code> \u9032\u884c\u6bd4\u8f03\u3002<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>contract CoinFlip {\n    uint256 public consecutiveWins;\n    uint256 lastHash;\n    uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n\n    constructor() {\n        consecutiveWins = 0;\n    }\n\n    function flip(bool _guess) public returns (bool) {\n    ...omit...<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>flip \u51fd\u6578\u7684\u5de5\u4f5c\u539f\u7406<\/strong><\/h4>\n\n\n\n<p><strong>\u7372\u53d6\u5340\u584a\u54c8\u5e0c<\/strong>:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u4f7f\u7528 <code>blockhash(block.number - 1)<\/code> \u7372\u53d6\u524d\u4e00\u500b\u5340\u584a\u7684\u54c8\u5e0c\u503c\uff0c\u4e26\u5c07\u5176\u8f49\u63db\u70ba <code>uint256<\/code> \u985e\u578b\uff0c\u5b58\u5165 <code>blockValue<\/code>\u3002<\/li>\n\n\n\n<li><code>block.number - 1<\/code> \u8868\u793a\u524d\u4e00\u500b\u5340\u584a\u7684\u7de8\u865f\uff0c\u56e0\u70ba\u7576\u524d\u5340\u584a\u7684\u54c8\u5e0c\u5728\u4ea4\u6613\u57f7\u884c\u6642\u5c1a\u672a\u751f\u6210\u3002<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>    function flip(bool _guess) public returns (bool) {\n        uint256 blockValue = uint256(blockhash(block.number - 1));<\/code><\/pre>\n\n\n\n<p><strong>\u9632\u6b62\u91cd\u8907\u4f7f\u7528\u5340\u584a\u54c8\u5e0c<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u6aa2\u67e5 <code>lastHash<\/code> \u662f\u5426\u7b49\u65bc\u7576\u524d\u7684 <code>blockValue<\/code>\u3002\u5982\u679c\u76f8\u7b49\uff0c\u5247\u8abf\u7528 <code>revert()<\/code> \u7d42\u6b62\u4ea4\u6613\uff0c\u9632\u6b62\u540c\u4e00\u5340\u584a\u54c8\u5e0c\u88ab\u91cd\u8907\u4f7f\u7528\u3002\u63db\u53e5\u8a71\u8aaa\u5c31\u662f\u5fc5\u9808\u7b49\u5230\u4e0b\u4e00\u500b\u65b0\u7684\u5340\u584a\u7522\u751f\u624d\u80fd\u73a9\u9019\u904a\u6232<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>        if (lastHash == blockValue) {\n            revert();\n        }\n        lastHash = blockValue;<\/code><\/pre>\n\n\n\n<p><strong>\u751f\u6210\u96a8\u6a5f\u6578<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5c07 <code>blockValue<\/code> \u9664\u4ee5 <code>FACTOR<\/code>\uff08\u4e00\u500b\u5927\u5e38\u6578\uff09\uff0c\u5f97\u5230 <code>coinFlip<\/code>\uff0c\u5176\u503c\u70ba 0 \u6216 1\u3002\u9019\u662f\u7528\u4f86\u6a21\u64ec\u96a8\u6a5f\u6027\u7684\u4e00\u7a2e\u7c21\u55ae\u65b9\u6cd5\uff0c\u5c07\u5340\u584a\u54c8\u5e0c\u7684\u9ad8\u4f4d\u90e8\u5206\u7c21\u5316\u70ba\u4e8c\u5143\u7d50\u679c\uff080 \u6216 1\uff09\u3002<\/li>\n\n\n\n<li>\u5982\u679c <code>coinFlip == 1<\/code>\uff0c\u5247 <code>side = true<\/code>\uff1b\u5426\u5247 <code>side = false<\/code>\u3002\u9019\u6a21\u64ec\u4e86\u786c\u5e63\u7684\u6b63\u53cd\u9762\u3002<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>        uint256 coinFlip = blockValue \/ FACTOR;\n        bool side = coinFlip == 1 ? true : false;<\/code><\/pre>\n\n\n\n<p><strong>\u6bd4\u8f03\u7528\u6236\u731c\u6e2c<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5982\u679c <code>side<\/code> \u7b49\u65bc\u7528\u6236\u7684\u8f38\u5165 <code>_guess<\/code>\uff0c\u5247\uff1a\n<ul class=\"wp-block-list\">\n<li><code>consecutiveWins<\/code> \u589e\u52a0 1\u3002<\/li>\n\n\n\n<li>\u8fd4\u56de <code>true<\/code> \u8868\u793a\u731c\u5c0d\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>\u5426\u5247\uff1a\n<ul class=\"wp-block-list\">\n<li><code>consecutiveWins<\/code> \u91cd\u7f6e\u70ba 0\u3002<\/li>\n\n\n\n<li>\u8fd4\u56de <code>false<\/code> \u8868\u793a\u731c\u932f\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>        if (side == _guess) {\n            consecutiveWins++;\n            return true;\n        } else {\n            consecutiveWins = 0;\n            return false;\n        }<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dots\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>\u6f0f\u6d1e\u5206\u6790<\/strong><\/h3>\n\n\n\n<p>\u9019\u6bb5\u5408\u7d04\u7684\u8a2d\u8a08\u770b\u8d77\u4f86\u8a66\u5716\u901a\u904e\u5340\u584a\u54c8\u5e0c\u4f86\u751f\u6210\u96a8\u6a5f\u6578\uff0c\u4f46\u5340\u584a\u54c8\u5e0c\u4e26\u4e0d\u662f\u4e00\u500b\u771f\u6b63\u5b89\u5168\u7684\u96a8\u6a5f\u6578\u4f86\u6e90\uff0c\u9019\u5c0e\u81f4\u4e86\u4ee5\u4e0b\u6f0f\u6d1e\uff1a<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>1. \u5340\u584a\u54c8\u5e0c\u7684\u53ef\u9810\u6e2c\u6027<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u554f\u984c<\/strong>: \u5340\u584a\u54c8\u5e0c\uff08<code>blockhash(block.number - 1)<\/code>\uff09\u662f\u516c\u958b\u6578\u64da\uff0c\u4efb\u4f55\u4eba\u90fd\u53ef\u4ee5\u901a\u904e\u4ee5\u592a\u574a\u5340\u584a\u93c8\u67e5\u8a62\u5230\u524d\u4e00\u500b\u5340\u584a\u7684\u54c8\u5e0c\u503c\u3002<\/li>\n\n\n\n<li><strong>\u5f71\u97ff<\/strong>: \u653b\u64ca\u8005\u53ef\u4ee5\u5728\u8abf\u7528 <code>flip<\/code> \u51fd\u6578\u4e4b\u524d\uff0c\u901a\u904e\u67e5\u8a62\u524d\u4e00\u500b\u5340\u584a\u7684\u54c8\u5e0c\u503c\uff0c\u8a08\u7b97\u51fa <code>blockValue \/ FACTOR<\/code> \u7684\u7d50\u679c\uff0c\u5f9e\u800c\u9810\u6e2c\u786c\u5e63\u7684\u6b63\u53cd\u9762\uff08<code>side<\/code>\uff09\u3002<\/li>\n\n\n\n<li><strong>\u5229\u7528\u65b9\u5f0f<\/strong>:\n<ul class=\"wp-block-list\">\n<li>\u653b\u64ca\u8005\u53ef\u4ee5\u7de8\u5beb\u4e00\u500b\u653b\u64ca\u5408\u7d04\uff0c\u5728\u540c\u4e00\u4ea4\u6613\u4e2d\uff1a\n<ol class=\"wp-block-list\">\n<li>\u7372\u53d6\u524d\u4e00\u500b\u5340\u584a\u7684\u54c8\u5e0c\u503c\u3002<\/li>\n\n\n\n<li>\u8a08\u7b97 <code>blockValue \/ FACTOR<\/code> \u5f97\u5230 <code>coinFlip<\/code>\uff0c\u9032\u800c\u78ba\u5b9a <code>side<\/code>\uff08true \u6216 false\uff09\u3002<\/li>\n\n\n\n<li>\u4f7f\u7528\u8a08\u7b97\u51fa\u7684 <code>side<\/code> \u4f5c\u70ba <code>_guess<\/code> \u53c3\u6578\u8abf\u7528 <code>flip<\/code> \u51fd\u6578\uff0c\u4fdd\u8b49\u6bcf\u6b21\u90fd\u80fd\u731c\u5c0d\u3002<\/li>\n<\/ol>\n<\/li>\n\n\n\n<li>\u901a\u904e\u9023\u7e8c\u8abf\u7528\uff0c\u653b\u64ca\u8005\u53ef\u4ee5\u7121\u9650\u589e\u52a0 <code>consecutiveWins<\/code>\uff0c\u5b8c\u6210 CTF \u6311\u6230\uff08\u901a\u5e38 CTF \u8981\u6c42\u9054\u5230\u4e00\u5b9a\u7684 <code>consecutiveWins<\/code>\uff0c\u4f8b\u5982 10 \u6b21\uff09\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>2. \u7f3a\u4e4f\u8a2a\u554f\u63a7\u5236<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u554f\u984c<\/strong>: <code>flip<\/code> \u51fd\u6578\u662f\u516c\u958b\u7684\uff08<code>public<\/code>\uff09\uff0c\u4efb\u4f55\u4eba\u90fd\u53ef\u4ee5\u8abf\u7528\uff0c\u4e14\u6c92\u6709\u9650\u5236\u8abf\u7528\u983b\u7387\u6216\u7528\u6236\u8eab\u4efd\u3002<\/li>\n\n\n\n<li><strong>\u5f71\u97ff<\/strong>: \u653b\u64ca\u8005\u53ef\u4ee5\u53cd\u8986\u8abf\u7528 <code>flip<\/code> \u51fd\u6578\uff0c\u7121\u9700\u4efb\u4f55\u6210\u672c\uff08\u9664\u4e86 gas \u8cbb\u7528\uff09\uff0c\u76f4\u5230\u9054\u6210 CTF \u76ee\u6a19\u3002<\/li>\n\n\n\n<li><strong>\u5229\u7528\u65b9\u5f0f<\/strong>: \u9019\u4f7f\u5f97\u653b\u64ca\u8005\u53ef\u4ee5\u901a\u904e\u81ea\u52d5\u5316\u8173\u672c\u6216\u5408\u7d04\u53cd\u8986\u8abf\u7528 <code>flip<\/code>\uff0c\u7d50\u5408\u6f0f\u6d1e 1 \u7684\u53ef\u9810\u6e2c\u6027\uff0c\u8f15\u9b06\u9054\u6210\u9023\u7e8c\u731c\u5c0d\u3002<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dots\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u89e3\u7b54\u6b65\u9a5f<\/h2>\n\n\n\n<p>\u6e96\u5099\u4e00\u500b\u653b\u64ca\u5408\u7d04\uff0c\u6703\u901a\u904e\u8907\u88fd <code>CoinFlip<\/code> \u5408\u7d04\u7684\u96a8\u6a5f\u6578\u751f\u6210\u908f\u8f2f\uff08\u57fa\u65bc\u5340\u584a\u54c8\u5e0c\u548c <code>FACTOR<\/code>\uff09\uff0c\u5229\u7528\u5340\u584a\u54c8\u5e0c\u7684\u516c\u958b\u6027\u548c\u53ef\u9810\u6e2c\u6027\uff0c\u78ba\u4fdd\u6bcf\u6b21\u8abf\u7528 <code>flip<\/code> \u6642\u90fd\u80fd\u731c\u5c0d\u786c\u5e63\u7d50\u679c\u3002\u53ea\u9700\u5728\u65b0\u5340\u584a\u751f\u6210\u5f8c\u8abf\u7528 <code>attack<\/code> \u51fd\u6578\uff0c\u91cd\u8907\u82e5\u5e72\u6b21\u5373\u53ef\u5b8c\u6210 CTF \u6311\u6230\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>\u653b\u64ca\u5408\u7d04\u793a\u4f8b<\/strong><\/h3>\n\n\n\n<p>\u4ee5\u4e0b\u662f\u4e00\u500b\u53ef\u80fd\u7684\u653b\u64ca\u5408\u7d04\uff0c\u7528\u65bc\u5229\u7528\u5340\u584a\u54c8\u5e0c\u7684\u53ef\u9810\u6e2c\u6027\u4f86\u9023\u7e8c\u731c\u5c0d\u786c\u5e63\u7d50\u679c\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface ICoinFlip {\n    function flip(bool _guess) external returns (bool);\n}\n\ncontract CoinFlipAttacker {\n    ICoinFlip public target;\n    uint256 private FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n\n    constructor(address _targetAddress) {\n        target = ICoinFlip(_targetAddress);\n    }\n\n    function attack() external {\n        uint256 blockValue = uint256(blockhash(block.number - 1));\n        uint256 coinFlip = blockValue \/ FACTOR;\n        bool side = coinFlip == 1 ? true : false;\n        target.flip(side);\n    }\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>\u653b\u64ca\u5408\u7d04\u5206\u6790<\/strong><\/h4>\n\n\n\n<p><strong>\u63a5\u53e3\u5b9a\u7fa9<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>   interface ICoinFlip {\n       function flip(bool _guess) external returns (bool);\n   }<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u4f5c\u7528<\/strong>: \u5b9a\u7fa9\u4e86 <code>CoinFlip<\/code> \u5408\u7d04\u7684 <code>flip<\/code> \u51fd\u6578\u63a5\u53e3\uff0c\u5141\u8a31\u653b\u64ca\u5408\u7d04\u8207\u76ee\u6a19\u5408\u7d04\u4ea4\u4e92\u3002<\/li>\n\n\n\n<li><strong>\u7d30\u7bc0<\/strong>: \u63a5\u53e3\u6307\u5b9a\u4e86 <code>flip<\/code> \u51fd\u6578\u63a5\u53d7\u4e00\u500b\u5e03\u6797\u503c\u53c3\u6578 <code>_guess<\/code>\uff08\u8868\u793a\u731c\u6e2c\u786c\u5e63\u7684\u6b63\u53cd\u9762\uff09\uff0c\u4e26\u8fd4\u56de\u4e00\u500b\u5e03\u6797\u503c\uff08\u8868\u793a\u731c\u6e2c\u662f\u5426\u6b63\u78ba\uff09\u3002<\/li>\n<\/ul>\n\n\n\n<p><strong>\u72c0\u614b\u8b8a\u91cf<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>contract CoinFlipAttacker {\n   ICoinFlip public target;\n   uint256 private FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>target<\/code>: \u5b58\u5132\u76ee\u6a19 <code>CoinFlip<\/code> \u5408\u7d04\u7684\u5730\u5740\uff0c\u985e\u578b\u70ba <code>ICoinFlip<\/code>\uff0c\u7528\u65bc\u8abf\u7528\u76ee\u6a19CTF\u5408\u7d04\u7684 <code>flip<\/code> \u51fd\u6578\u3002<\/li>\n\n\n\n<li><code>FACTOR<\/code>: \u8207 <code>CoinFlip<\/code> \u5408\u7d04\u4e2d\u76f8\u540c\u7684\u5e38\u91cf\uff0c\u7528\u65bc\u5c07\u5340\u584a\u54c8\u5e0c\u8f49\u63db\u70ba 0 \u6216 1\uff08\u6a21\u64ec\u786c\u5e63\u7d50\u679c\uff09\u3002\u9019\u500b\u503c\u7d04\u70ba ( 2^{255} )\uff0c\u78ba\u4fdd\u9664\u6cd5\u7d50\u679c\u53ea\u6709 0 \u6216 1\u3002<\/li>\n<\/ul>\n\n\n\n<p><strong>\u69cb\u9020\u51fd\u6578<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>   constructor(address _targetAddress) {\n       target = ICoinFlip(_targetAddress);\n   }<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u4f5c\u7528<\/strong>: \u5728\u90e8\u7f72\u653b\u64ca\u5408\u7d04\u6642\uff0c\u63a5\u6536CTF\u76ee\u6a19 <code>CoinFlip<\/code> \u5408\u7d04\u7684\u5730\u5740\uff0c\u4e26\u5c07\u5176\u5b58\u5132\u5728 <code>target<\/code> \u8b8a\u91cf\u4e2d\u3002<\/li>\n\n\n\n<li><strong>\u7d30\u7bc0<\/strong>: \u901a\u904e\u5c07\u5730\u5740\u8f49\u63db\u70ba <code>ICoinFlip<\/code> \u985e\u578b\uff0c\u653b\u64ca\u5408\u7d04\u53ef\u4ee5\u8abf\u7528\u76ee\u6a19\u5408\u7d04\u7684 <code>flip<\/code> \u51fd\u6578\u3002<\/li>\n<\/ul>\n\n\n\n<p><strong>\u653b\u64ca\u51fd\u6578<\/strong>:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>   function attack() external {\n       uint256 blockValue = uint256(blockhash(block.number - 1));\n       uint256 coinFlip = blockValue \/ FACTOR;\n       bool side = coinFlip == 1 ? true : false;\n       target.flip(side);\n   }<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u4f5c\u7528<\/strong>: \u8a08\u7b97\u786c\u5e63\u7684\u6b63\u78ba\u7d50\u679c\uff08true \u6216 false\uff09\uff0c\u4e26\u8abf\u7528\u76ee\u6a19CTF\u5408\u7d04\u7684 <code>flip<\/code> \u51fd\u6578\u9032\u884c\u731c\u6e2c\u3002<\/li>\n\n\n\n<li><strong>\u57f7\u884c\u6b65\u9a5f<\/strong>:\n<ol class=\"wp-block-list\">\n<li><strong>\u7372\u53d6\u5340\u584a\u54c8\u5e0c<\/strong>:\n<ul class=\"wp-block-list\">\n<li>\u4f7f\u7528 <code>blockhash(block.number - 1)<\/code> \u7372\u53d6\u524d\u4e00\u500b\u5340\u584a\u7684\u54c8\u5e0c\u503c\uff0c\u4e26\u8f49\u63db\u70ba <code>uint256<\/code> \u985e\u578b\uff0c\u5b58\u5165 <code>blockValue<\/code>\u3002<\/li>\n\n\n\n<li>\u9019\u8207 <code>CoinFlip<\/code> \u5408\u7d04\u4e2d\u751f\u6210\u96a8\u6a5f\u6578\u7684\u65b9\u5f0f\u4e00\u81f4\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u8a08\u7b97\u786c\u5e63\u7d50\u679c<\/strong>:\n<ul class=\"wp-block-list\">\n<li>\u5c07 <code>blockValue<\/code> \u9664\u4ee5 <code>FACTOR<\/code>\uff0c\u5f97\u5230 <code>coinFlip<\/code>\uff0c\u5176\u503c\u70ba 0 \u6216 1\u3002<\/li>\n\n\n\n<li>\u4f7f\u7528\u4e09\u5143\u904b\u7b97\u7b26 <code>coinFlip == 1 ? true : false<\/code> \u5c07 <code>coinFlip<\/code> \u8f49\u63db\u70ba\u5e03\u6797\u503c <code>side<\/code>\uff08true \u8868\u793a\u786c\u5e63\u6b63\u9762\uff0cfalse \u8868\u793a\u53cd\u9762\uff09\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u8abf\u7528\u76ee\u6a19\u5408\u7d04<\/strong>:\n<ul class=\"wp-block-list\">\n<li>\u4f7f\u7528\u8a08\u7b97\u51fa\u7684 <code>side<\/code> \u4f5c\u70ba\u53c3\u6578\uff0c\u8abf\u7528 <code>target.flip(side)<\/code>\uff0c\u5411 <code>CoinFlip<\/code> \u5408\u7d04\u63d0\u4ea4\u731c\u6e2c\u3002<\/li>\n\n\n\n<li>\u7531\u65bc <code>side<\/code> \u662f\u6839\u64da\u76f8\u540c\u7684\u908f\u8f2f\uff08\u5340\u584a\u54c8\u5e0c\u548c <code>FACTOR<\/code>\uff09\u8a08\u7b97\u7684\uff0c\u731c\u6e2c\u5fc5\u7136\u6b63\u78ba\uff0c<code>CoinFlip<\/code> \u7684 <code>consecutiveWins<\/code> \u6703\u589e\u52a0 1\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dots\"\/>\n\n\n\n<p><\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>\u653b\u64ca\u6d41\u7a0b<\/strong><\/h4>\n\n\n\n<p><strong>\u90e8\u7f72\u653b\u64ca\u5408\u7d04<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u90e8\u7f72 <code>CoinFlipAttacker<\/code>\uff0c\u4e26\u5728\u69cb\u9020\u51fd\u6578\u4e2d\u50b3\u5165CTF\u984c\u76ee <code>CoinFlip<\/code> \u5408\u7d04\u7684\u5730\u5740\u3002<\/li>\n<\/ul>\n\n\n\n<p><strong>\u7b49\u5f85\u65b0\u5340\u584a<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u7531\u65bc <code>CoinFlip<\/code> \u5408\u7d04\u4e2d\u7684 <code>lastHash<\/code> \u6aa2\u67e5\uff08<code>if (lastHash == blockValue) { revert(); }<\/code>\uff09\uff0c\u653b\u64ca\u8005\u5fc5\u9808\u5728\u65b0\u5340\u584a\u751f\u6210\u5f8c\u8abf\u7528 <code>attack<\/code> \u51fd\u6578\uff0c\u4ee5\u78ba\u4fdd <code>blockhash(block.number - 1)<\/code> \u8207\u4e0a\u4e00\u6b21\u8abf\u7528\u7684\u54c8\u5e0c\u503c\u4e0d\u540c\u3002<\/li>\n\n\n\n<li>\u5728\u4ee5\u592a\u574a\u4e3b\u7db2\u4e0a\uff0c\u5340\u584a\u751f\u6210\u6642\u9593\u7d04\u70ba 12-15 \u79d2\uff0c\u56e0\u6b64\u9700\u8981\u7b49\u5f85\u65b0\u5340\u584a\u3002<\/li>\n<\/ul>\n\n\n\n<p><strong>\u57f7\u884c\u653b\u64ca<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5728\u65b0\u5340\u584a\u751f\u6210\u5f8c\uff0c\u8abf\u7528 <code>attack<\/code> \u51fd\u6578\u3002<\/li>\n\n\n\n<li>\u653b\u64ca\u5408\u7d04\u8a08\u7b97\u8207 <code>CoinFlip<\/code> \u76f8\u540c\u7684\u96a8\u6a5f\u6578\u7d50\u679c\uff08<code>side<\/code>\uff09\uff0c\u4e26\u8abf\u7528 <code>target.flip(side)<\/code>\u3002<\/li>\n\n\n\n<li>\u7531\u65bc\u731c\u6e2c\u5fc5\u7136\u6b63\u78ba\uff0c<code>CoinFlip<\/code> \u7684 <code>consecutiveWins<\/code> \u589e\u52a0 1\u3002<\/li>\n<\/ul>\n\n\n\n<p><strong>\u91cd\u8907\u57f7\u884c<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u91cd\u8907\u4ee5\u4e0a\u6b65\u9a5f\uff0c\u6bcf\u6b21\u5728\u65b0\u5340\u584a\u751f\u6210\u5f8c\u8abf\u7528 <code>attack<\/code>\uff0c\u76f4\u5230 <code>consecutiveWins<\/code> \u9054\u5230 CTF \u6311\u6230\u7684\u8981\u6c42\uff08\u4f8b\u5982 10 \u6b21\u9023\u7e8c\u731c\u5c0d\uff09\u3002<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u9019\u9053Blockchain CTF\u984c\u76ee\u6d89\u53ca\u4e00\u500b\u4ee5\u592a\u574a\u667a\u80fd\u5408\u7d04\u7684\u96a8\u6a5f\u6578\u6f0f\u6d1e\u5229\u7528\uff0c\u984c\u76ee\u8981\u6c42\u7528\u6236\u731c\u6e2c\u4e00\u500b\u57fa\u65bc\u5340\u584a\u54c8\u5e0c\u7684\u64f2\u786c\u5e63\u7d50\u679c\uff08true \u6216 false\uff09\u3002\u901a\u904e\u7de8\u5beb\u653b\u64ca\u5408\u7d04\uff0c\u7528\u6236\u53ef\u4ee5\u5728\u6bcf\u500b\u65b0\u5340\u584a\u751f\u6210\u5f8c\u8a08\u7b97\u6b63\u78ba\u7684\u731c\u6e2c\uff0c\u5f9e\u800c\u9054\u6210 CTF \u6311\u6230\u7684\u76ee\u6a19\u3002<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"","fifu_image_alt":"","_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"enabled":false},"version":2}},"categories":[371],"tags":[],"class_list":["post-2714","post","type-post","status-publish","format-standard","hentry","category-web3-security"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/systw.net\/note\/wp-json\/wp\/v2\/posts\/2714","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/systw.net\/note\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/systw.net\/note\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/systw.net\/note\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/systw.net\/note\/wp-json\/wp\/v2\/comments?post=2714"}],"version-history":[{"count":5,"href":"https:\/\/systw.net\/note\/wp-json\/wp\/v2\/posts\/2714\/revisions"}],"predecessor-version":[{"id":2721,"href":"https:\/\/systw.net\/note\/wp-json\/wp\/v2\/posts\/2714\/revisions\/2721"}],"wp:attachment":[{"href":"https:\/\/systw.net\/note\/wp-json\/wp\/v2\/media?parent=2714"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/systw.net\/note\/wp-json\/wp\/v2\/categories?post=2714"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/systw.net\/note\/wp-json\/wp\/v2\/tags?post=2714"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}