介紹
區(qū)塊鏈智能合約相關(guān)題目,挺有意思,簡單分享。
題目
題目內(nèi)包含兩個鏈接:
https://github.com/paradigmxyz/paradigm-ctf-infrastructure
對應(yīng)后端服務(wù)搭建相關(guān),只看eth-challenge-base目錄即可。
random.zip,合約代碼內(nèi)容,也是題目關(guān)鍵,合約代碼貼在后面。
實(shí)現(xiàn)&分析
nc連接返回三個選項(xiàng)
1 - launch new instance
2 - kill instance
3 - get flag
1:表示啟動一個實(shí)例,就是具體實(shí)現(xiàn)見后端代碼,我理解就是部署了智能合約,會返回以下幾個參數(shù):
uuid:唯一標(biāo)示,實(shí)例校驗(yàn)使用。
rpc endpoint: 理解為智能合約節(jié)點(diǎn)地址,通過該地址可以訪問智能合約。
private key: 錢包地址私鑰
setup contract: 智能合約的地址。
2:刪掉當(dāng)前實(shí)例。
3:返回flag。
返回flag的前提
前面校驗(yàn)不細(xì)講,關(guān)鍵是這里。
查看具體代碼是:
def is_solved_checker(web3: Web3, addr: str) -> bool:
result = web3.eth.call(
{
"to": addr,
"data": web3.sha3(text="isSolved()")[:4],
}
)
return int(result.hex(), 16) == 1
調(diào)用合約Setup.isSolved返回true。
思路
兩個合約代碼如下:
contract Setup {
Random public random;
constructor() {
random = new Random();
}
function isSolved() public view returns (bool) {
return random.solved();
}
}
contract Random {
bool public solved = false;
function _getRandomNumber() internal pure returns (uint256) { // chosen by fair dice roll.
return 4; // guaranteed to be random.
}
function solve(uint256 guess) public {
require(guess == _getRandomNumber());
solved = true;
}
}
從代碼看,基本就是調(diào)用Random.solve(4),即解決問題。
因此實(shí)現(xiàn)先獲取返回的合約地址拿到當(dāng)前的Setup實(shí)例(個人理解,不一定對)
contract2 = web3.eth.contract(address=contract, abi=config["abi"])
接著獲取其中的random對象,也就是Random實(shí)例的合約地址,
randomAddress = contract2.functions.random().call()
然后調(diào)用random.solve(4)。
contract1 = web3.eth.contract(address=randomAddress, abi=config1["abi"])
result = contract1.functions.solve(4).transact()
這里調(diào)用不能像上面一樣調(diào)用call,是因?yàn)閹в袇?shù)需要調(diào)用transact,正常交易還需要往里面填入gas才能發(fā)起(個人理解)。文章來源:http://www.zghlxwxcb.cn/news/detail-734835.html
writeup
from socket import *
from web3 import Web3
from eth_utils import *
from eth_typing import *
uuid = "XXXX"
url = "http://34.66.135.107:8545/" + uuid
pkey = "xxxx"
contract = "xxxx"
ticket = "xxxx"
header = {'Content-type':'application/json'}
config = {
"abi":
[
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "isSolved",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "random",
"outputs": [
{
"internalType": "contract Random",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
]
}
config1 = {"abi":[
{
"inputs": [
{
"internalType": "uint256",
"name": "guess",
"type": "uint256"
}
],
"name": "solve",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "solved",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
}]
}
web3 = Web3(Web3.HTTPProvider(url))
contract2 = web3.eth.contract(address=contract, abi=config["abi"])
result = contract2.functions.isSolved().call()
print(result)
randomAddress = contract2.functions.random().call()
print(randomAddress)
contract1 = web3.eth.contract(address=randomAddress, abi=config1["abi"])
# result = contract1.functions.solve(4).call()
result = contract1.functions.solve(4).transact()
print(result)
result = contract1.functions.solved().call()
print(result)
總結(jié)
一直沒有時間學(xué)習(xí)智能合約這塊,通過比賽反而帶動學(xué)習(xí)興趣,也找到一些學(xué)習(xí)的方向。文章來源地址http://www.zghlxwxcb.cn/news/detail-734835.html
到了這里,關(guān)于【2022Paradigm.ctf】random writeup的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!