实现CTF智能合约题目的环境部署

本文章是参考一位大佬博客学来的。
智能合约题的环境主要包括两部分:一个是智能合约的部署,另一个就是监听合约事件进而发送flag的脚本。

智能合约部署

这里写的合约是指solidity合约,使用Remix IDE。
合约主要部署到以太坊测试链而非主链上(没钱??),几个主要的测试链:Ropsten,Rinkeby,Kovan。
这里需要一个浏览器钱包插件MetaMask(可以在FireFox和Chrom上下载),注册并申请账户后,选择测试网络(笔者选择的是Rospten):

新创建的账户是没有以太币的,需要到测试水管(在首页点击存入)申请:

有了以太币之后就可以利用Remix IDE将合约代码部署到测试网络。
这里先准备一个简单的发送flag的合约:

pragma solidity ^0.4.24; //选择solidity编译器版本

contract TestFlag {
    event victory(string b64email,string slogan); //定义事件

    function getFlag(string b64email) public {
        emit victory(b64email, "666!"); //触发此事件,发送flag到邮箱
    }
}

整个编译器界面是这样的:

右侧选择编译器版本,然后点击Start to compile进行编译,编译成功的话右侧就会显示一个写着合约名称的绿色框框。
点击右上角的Run,Envir选择Injected Web3,账户就会自动变为你MetaMask钱包里的账户,如果之前没有部署过这个合约就点击下方红框Deploy,此时会跳出支付gas的弹窗,点击确定即可,等待几秒合约就会部署完成,最下方就会显示已部署的合约(及其地址);如果之前部署过相同合约,那么可以将合约地址复制到At Address并点击蓝色按钮加载合约,效果相同。

红框getFlag就是合约里的函数,输入一个邮箱base64字符串(双引号括上)并点击红色按钮就可以调用此函数了,通过ropsten.etherscan.io可以查到此合约的交易和事件。

智能合约的部署就这样了,但是现在调用函数还不能收到邮件,现在还缺少自动发送邮件的脚本,往下看。
注意下面的脚本需要用到合约地址和事件日志中的topic0。

邮件发送脚本的编写

先注册Infura https://infura.io 获取远程节点rpc:

点击黑色按钮创建project,然后在KEYS栏中找到ENDPOINT,Ropsten网络的URL,就是后面脚本中加载的RPC了(注意,API key不要暴露,具体什么安全规则这里咱也不知道??)。

这里使用python3编写脚本,需要用到web3的包,提前下一个(不过安装这个包有一点坑,百度一下如何下载web3.py包)。
附上python脚本:

# -*- coding:UTF=8 -*-
from web3 import Web3,HTTPProvider
import os
import time
import binascii
import base64
import smtplib
from email.mime.text import MIMEText
from email.header import Header

contract_address = "0x128..." # 你的合约地址
contract_topic0 = "0x90c...1e8a11" # 事件日志中的topic0,针对同意合约的所有事件日志的topic0都是相同的
rpc = "https://ropsten.infura.io/v3/1b8...64b0" # 你注册的Infura中的ENDPOINT

flag = "flag{a_smart_contract_test}"
email = {
    "host":"smtp.163.com",
    "port":25,
    "user":"[email protected]", # 用来发送flag的邮箱
    "code":"******"  # 邮箱的客户端授权码
}
# initial
w3 = Web3(Web3.HTTPProvider(rpc))
sender = smtplib.SMTP(host=email["host"],port=email["port"])
sender.ehlo()
sender.starttls()
sender.login(email["user"],email["code"])

# email content
message = MIMEText("收下你的flag:"+flag, 'plain', 'utf-8')
message["From"] = email["user"]
message["Subject"] = Header("ctf flag","utf-8")

# 发送flag的函数
def sendflag(toEmail):
    message["To"] = toEmail
    sender.sendmail(email["user"],toEmail,message.as_string())
    # log
    os.system("echo "+time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) +": Get flag -- "+toEmail+" >> /tmp/variant_of_cat.log")
    print("send success")

# 监听合约事件的函数
def event():
    # 从网络中的事件日志中抓取符合这一合约的日志信息
    flag_logs = w3.eth.getLogs({
            "address":contract_address,
            "topic0":contract_topic0
        })
    if flag_logs is not []:
        for flag_log in flag_logs:
            data = flag_log["data"][2:]
            length = int(data[64*2:64*3].replace('00', ''),16)
            data = data[64*3:][:length*2]
            b64email = binascii.unhexlify(data).decode('utf-8')
            try:
                email = base64.b64decode(b64email).decode('utf-8')
                sendflag(email)
            except:
                errmsg = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())+":decode or send to b64 - {} fail".format(b64email)
                os.system("echo " + errmsg + ">> /tmp/variant_of_cat_error.log")
                print(errmsg)
# 循环运行
while(True):
    event()
time.sleep(30)

运行上述脚本就可以实现一旦调用合约的getFlag函数就能执行发送flag邮件的操作了。
不过这里还有一点小毛病,就是sleep(30)可能短于新区块的产生时间,导致会连续发送多个邮件过来(我猜测是这个原因,具体后面再推断)。

参考资料

智能合约攻击面及ctf出题指南

原文地址:https://www.cnblogs.com/KRDecad3/p/10798383.html

时间: 2024-08-26 23:20:35

实现CTF智能合约题目的环境部署的相关文章

郑重告之:智能合约开发实训营第4期学员招募正式启动!

各位同学,抱歉久等了- 这是终于到来的<以太坊智能合约全栈开发>实战特训营第四期的正式招募通知. <以太坊智能合约全栈开发>实战特训营是由硅谷密探和 celer network 共同打造的全球第一档·智能合约全栈开发实战课程,也是目前唯一一个实现来自中.美.澳.英.日.韩等多国学员在线互动学习的区块链技术实战特训课程. 为了保证教学质量,如今已调整为每期仅招募100人,参与有门槛,需经过层层审核,录取通过率一度不到10%,并非所有人都适合参与. 拉至文末可直接进行报名. 请点击此处

用Solidity在Truffle上构建一个HelloWorld智能合约

原文地址:石匠的blog Truffle的环境安装在前文已经整理,这次用Solidity在Truffle写一个HelloWorld以太坊智能合约,并在testrpc上进行测试.当前的软件版本信息如下: Truffle v4.1.11 (core: 4.1.11) Solidity v0.4.24 (solc-js) 项目创建 打开Mac的terminal终端,创建一个新目录,并truffle项目初始化. > mkdir HelloWorld > cd HelloWorld > truff

以太坊智能合约入门项目-众筹项目

一.智能合约 智能合约(英语:Smart Contract)是一种旨在以信息化方式传播.验证或执行合同的计算机协议.智能合约允许在没有第三方的情况下进行可信交易.这些交易可追踪且不可逆转.智能合约概念于1994年由Nick Szabo首次提出. 以上解释来自于维基百科 由于缺少可信的执行环境,智能合约并没有被应用到实际产业中,自比特币诞生后,人们认识到比特币的底层技术区块链天生可以为智能合约提供可信的执行环境,以太坊首先看到了区块链和智能合约的契合,发布了白皮书<以太坊:下一代智能合约和去中心化

第一行代码:以太坊(2)-使用Solidity语言开发和测试智能合约

智能合约是以太坊的核心之一,用户可以利用智能合约实现更灵活的代币以及其他DApp.不过在深入讲解如何开发智能合约之前,需要先介绍一下以太坊中用于开发智能合约的Solidity语言,以及相关的开发和测试环境. 智能合约就是运行在以太坊上的程序.客户端可以通过Web3.js API调用智能合约,而智能合约本身又可以直接访问以太坊网络,也就是说,智能合约前面连接着客户端,后面连接着以太坊网络,起到了承前启后的作用,而且通过智能合约,可以让整个以太坊网络更灵活,可控性更强.其实智能合约的作用相当于微软O

第一行代码:以太坊(3)-使用更多的工具编写和测试智能合约

<第一行代码:以太坊>开始连载了 在上文中已经使用了Remix环境运行和测试了本书编写的第一个智能合约程序,不过编写和测试智能合约的测试方式很多,例如,在testrpc环境测试:在Intellij IDEA集成开发环境中用Solidity语言编写智能合约:在纯Web环境中测试智能合约:使用AJAX方式测试智能合约等.本文将详细介绍这些用于编写和测试智能合约的方法. 1.安装本地remix环境(Windows.Mac OS X和Linux) 在本节使用Remix环境运行和测试了Calc智能合约,

【刘文彬】【精解】开发一个智能合约

原文链接:醒者呆的博客园,https://www.cnblogs.com/Evsward/p/contract.html 智能合约 这两天被老大搞去搬砖,学习计划有变但无大碍,这篇文章将仔细分析智能合约相关内容. 关键字:智能合约,remix,Solidity,truffle,geth,leveldb,datadir,ganache,web3j 合约 合约也称合同.协议,是甲乙双方参与的,制定一系列条目规范双方权利与义务的文件.智能合约是电子化的,自动执行的,去中心化的,具有不可抵赖性,本质上它

solidity编写智能合约(入门)

一个简单的智能合约 先从一个非常基础的例子开始,不用担心你现在还一点都不了解,我们将逐步了解到更多的细节. 存储 contract SimpleStorage { uint storedData; function set(uint x) { storedData = x; } function get() constant returns (uint retVal) { return storedData; } } 在Solidity中,一个合约由一组代码(合约的函数)和数据(合约的状态)组成

135.001 智能合约设计-——单员工薪酬系统

@(135- Block Chain| 区块链) Introduction 参考阅读:老董-以太坊智能合约全栈开发 课程导读 1. 最终产品Demo 员工系统--人员管理+工资发放 大公司如何发工资?雇主跑路,讨薪难. 雇佣员工时,先把半年工资打到员工??? 去中心化信任 雇主,雇员 传统的员工系统 人力资源公司的成本太高 小公司--信任问题,拖欠工资,讨薪难? 目标 高效低成本 防止黑心老板违约拖欠工资? 2.项目特点 1)前端交互很简单,后端运行在智能合约???? 2)智能合约--不存在所谓

win7下以太坊基于truffle+ganache开发环境搭建以及智能合约的部署调用

上一篇介绍的是以太坊下基于geth+remix-ide智能合约环境的搭建和部署运行,本篇介绍的是基于truffle+ganache. ganache相当于是geth的图形化操作界面,相对于纯指令操作的geth较为简单易上手,并且运行交易和生成区块的过程一目了然. [前期准备] 1.Node.js安装(这一点在上一篇文章中提到过,所以此处不做展示) 2.指令输入: npm install -g solc(安装智能合约) npm install -g ganache-cli (安装ganache开发