博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实现CTF智能合约题目的环境部署
阅读量:5095 次
发布时间:2019-06-13

本文共 3373 字,大约阅读时间需要 11 分钟。

本文章是参考一位大佬博客学来的。

智能合约题的环境主要包括两部分:一个是智能合约的部署,另一个就是监听合约事件进而发送flag的脚本。

智能合约部署

这里写的合约是指solidity合约,使用Remix IDE。

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

1669883-20190430222609574-1889211379.png

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

1669883-20190430222632417-138528891.png

有了以太币之后就可以利用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到邮箱    }}

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

1669883-20190430222659655-1193583875.png

右侧选择编译器版本,然后点击Start to compile进行编译,编译成功的话右侧就会显示一个写着合约名称的绿色框框。

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

1669883-20190430222758668-1680675236.png

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

1669883-20190430222816149-1375316095.png

1669883-20190430222823150-159775255.png

智能合约的部署就这样了,但是现在调用函数还不能收到邮件,现在还缺少自动发送邮件的脚本,往下看。

注意下面的脚本需要用到合约地址和事件日志中的topic0。

邮件发送脚本的编写

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

1669883-20190430222844689-855375318.png

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

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

附上python脚本:

# -*- coding:UTF=8 -*-from web3 import Web3,HTTPProviderimport osimport timeimport binasciiimport base64import smtplibfrom email.mime.text import MIMETextfrom email.header import Headercontract_address = "0x128..." # 你的合约地址contract_topic0 = "0x90c...1e8a11" # 事件日志中的topic0,针对同意合约的所有事件日志的topic0都是相同的rpc = "https://ropsten.infura.io/v3/1b8...64b0" # 你注册的Infura中的ENDPOINTflag = "flag{a_smart_contract_test}"email = {    "host":"smtp.163.com",    "port":25,    "user":"sender@163.com", # 用来发送flag的邮箱    "code":"******"  # 邮箱的客户端授权码}# initialw3 = Web3(Web3.HTTPProvider(rpc))sender = smtplib.SMTP(host=email["host"],port=email["port"])sender.ehlo()sender.starttls()sender.login(email["user"],email["code"])# email contentmessage = 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)可能短于新区块的产生时间,导致会连续发送多个邮件过来(我猜测是这个原因,具体后面再推断)。

1669883-20190430222908454-1091640081.png

参考资料

转载于:https://www.cnblogs.com/KRDecad3/p/10798383.html

你可能感兴趣的文章
sublimie 知乎
查看>>
一些方便系统诊断的bash函数
查看>>
Floyd算法 - 最短路径
查看>>
【转载】基于vw等viewport视区相对单位的响应式排版和布局
查看>>
<转>关于MFC的多线程类 CSemaphore,CMutex,CCriticalSection,CEvent
查看>>
《你们都是魔鬼吗》实验十二 团队作业八:Alpha冲刺
查看>>
jquery中ajax返回值无法传递到上层函数
查看>>
[Leetcode]942. DI String Match
查看>>
css3之transform-origin
查看>>
1003 Emergency
查看>>
bm25
查看>>
[转]JavaScript快速检测浏览器对CSS3特性的支持
查看>>
Master选举原理
查看>>
[ JAVA编程 ] double类型计算精度丢失问题及解决方法
查看>>
小别离
查看>>
微信小程序-发起 HTTPS 请求
查看>>
WPF动画设置1(转)
查看>>
backgound-attachment属性学习
查看>>
个人作业——关于K米的产品案例分析
查看>>
基于node/mongo的App Docker化测试环境搭建
查看>>