全国大学生信息安全竞赛—区块链题目分析_MEMO:EOS

作者:Pinging

一、前言

前几天全国大学生信息安全竞赛初赛如期进行,在这次比赛中也看到了区块链题目的身影。所以我将题目拿来进行分析,并为后续的比赛赛题提供一些分析思路。

由于本次比赛我并没有参加,所以我并没有Flag等相关信息,但是我拿到了比赛中的相关文件以及合约地址并在此基础上进行的详细分析,希望能帮助到进行研究的同学。

二、题目分析

拿到题目后,我们只得到了两个内容,一个是合约的地址,一个是broken

eventSendFlag(uint256flagnum,stringb64email);functionpayforflag(stringb64email)public{require(balanceOf>=10000);emitSendFlag(1,b64email);}

首先我们看这个合约文件。合约开始定义了两个mapping变量——balanceOf与gift,之后为构造函数,以及发送flag的事件。当我们调用payforflag函数并传入使用base64加密的邮件地址之后,需要满足当前账户的余额比10000多。

由这第一手信息我们可以进行一些简单的猜想。这道题目需要领自己的余额大于10000,只有这样才能购买flag。这也是很常见的题目类型。而这个题目十分设计的还是十分巧妙的,我们接着向下看。

美国OCC有条件批准Anchorage成为首个全国性加密银行:金色财经报道,加密货币托管商Anchorage周三宣布,美国货币监理署(OCC)已有条件批准其获得国家信托执照,使其成为美国第一家全国性“数字资产银行”。据悉,Anchorage的信托公司部门于去年11月首次向OCC申请了执照,旨在与Kraken和Avanti一起成为加密银行。加密货币初创公司BitPay和Paxos也已经向OCC申请了联邦执照。[2021/1/14 16:06:52]

根据上面的合约代码,我们并不能得到更多的有用信息。然而此时我们就需要利用合约地址来进一步分析。

此处合约地址为:0x455541c3e9179a6cd8C418142855d894e11A288c。

我们访问公链信息看看是否能够访问到有价值的信息:

发现出题人并没有公开源代码,只有ABI码,此时我们只能根据此来进行合约逆向来寻找更有用的解题思路。

https://ethervm

varvar0=msg

var1=0x009c;func_01DC();stop();}elseif(var0==0x66d16cc3){//Dispatchtableentryforprofit()var1=msg

现场丨全国政协委员屠光绍:谁能抓住金融科技发展 谁就能后来居上:金色财经报道,9月26日,外滩大会第三日,全国政协委员、上海交通大学兼职教授、上海高级金融学院执行理事屠光绍现场指出,金融科技驱动地方金融发展新格局体现在:地方金融发展方式的变动,地方之间金融竞争的变局、地方金融生态环境的变化。各地积极发布金融科技的政策,召开金融科技相关的大会,千头万绪集中到一点,就是地方都在关注科技发展,地方的金融竞争也出现变局,谁能抓住金融科技的发展,谁就能后来居上。当然,现在中国金融经济的发展方兴未艾,各地还要看到自己的不足,补足短板。[2020/9/26]

var1=0x009c;profit();stop();}elseif(var0==0x6bc344bc){//Dispatchtableentryfor0x6bc344bc(unknown)var1=msg

vartemp0=memory;vartemp1=msg

elseif(var0==0x70a08231){//DispatchtableentryforbalanceOf(address)var1=msg

var1=0x013a;var2=msg

elseif(var0==0x7ce7c990){//Dispatchtableentryfortransfer2(address,uint256)var1=msg

全国人大代表易炼红:江西将加快区块链等新兴技术深度融合:全国人大代表、江西省省长易炼红表示,近年来江西深入推进产业融合,大力发展“智能+”,实施智能制造“万千百十”工程。下一步,江西将加大政策扶持力度,加快推进产业融合,进一步巩固和扩大智能制造成效。将深化强强联合。持续深化与阿里巴巴、华为等巨头企业务实合作,加快制造业和互联网、大数据、人工智能、区块链等新兴技术深度融合,实体经济与数字经济融合创新,以信息化培育新动能,以新动能推动新发展。(经济日报)[2020/5/27]

var1=0x009c;var2=msg

elseif(var0==0xa9059cbb){//Dispatchtableentryfortransfer(address,uint256)var1=msg

var1=0x009c;var2=msg

elseif(var0==0xcbfc4bce){//Dispatchtableentryfor0xcbfc4bce(unknown)var1=msg

var1=0x013a;var2=msg

else{revert(memory);}}//0x66d16cc3函数空投函数??functionfunc_01DC(){memory=msg

全国人大代表崔瑜:积极争取数字货币在长三角地区先行先试:全国人大代表、城银清算服务有限责任公司董事长崔瑜今年拟提交关于推进长三角支付清算一体化建设的建议。她建议,积极争取数字货币在长三角地区先行先试。在金融科技驱动支付清算产业变革发展的大背景下,建议将长三角支付清算一体化的历史机遇和区块链等创新技术结合起来,探索将华东三省一市银行汇票等传统区域支付工具数字化,并试点运用于供应链金融、平台经济等领域。(中国证券报)[2020/5/19]

memory=msg

//利润函数:functionprofit(){memory=msg

memory=msg

memory=msg

functionfunc_0278(vararg0){memory=msg

varvar0=0xb1bc9a9c599feac73a94c3ba415fa0b75cbe44496bfda818a9b4a689efb7adba;varvar1=0x01;vartemp0=arg0;varvar2=temp0;vartemp1=memory;varvar3=temp1;memory=var1;vartemp2=var30x20;varvar4=temp2;vartemp3=var40x20;memory=temp3-var3;memory=memory;varvar5=temp30x20;varvar7=memory;varvar6=var20x20;varvar8=var7;varvar9=var5;varvar10=var6;varvar11=0x00;if(var11>=var8){label_02FD:vartemp4=var7;var5=temp4var5;var6=temp4&0x1f;if(!var6){vartemp5=memory;log(memory,]);return;}else{vartemp6=var6;vartemp7=var5-temp6;memory=~(0x0100**(0x20-temp6)-0x01)&memory;vartemp8=memory;log(memory,]);return;}}else{label_02EE:vartemp9=var11;memory=memory;var11=temp90x20;if(var11>=var8){gotolabel_02FD;}else{gotolabel_02EE;}}}functionbalanceOf(vararg0)returns(vararg0){memory=0x00;memory=arg0;returnstorage)];}functiontransfer2(vararg0,vararg1){if(arg1<=0x02){revert(memory);}memory=msg

声音 | 杭州市委书记周江勇:杭州区块链头部企业数量居全国第三位:今天上午,第三届钱塘江论坛主论坛在杭州国际博览中心举行。中共浙江省委常委、杭州市委书记周江勇表示,2018年杭州全市实现生产总值1.35亿元,居全国大中城市的第十位,数字经济占生产总值的比值已超过四分之一,对经济增长的贡献率超过50%。人才的净流入率,互联网人才净流入率,海外人才净流入率连续多年居全国第一位。坚持科技赋能,数字驱动,杭州金融科技先发优势明显,高端人才资源集聚。区块链、大数据中心、智能投顾等领域重大创新成果不断涌现,区块链头部企业数量居全国第三位。[2019/11/2]

memory=msg

memory=msg

functiontransfer(vararg0,vararg1){if(arg1<=0x01){revert(memory);}memory=msg

memory=msg

memory=msg

functionfunc_0417(vararg0)returns(vararg0){memory=0x01;memory=arg0;returnstorage)];}}

之后我们针对此逆向后的代码进行分析。

我们经过分析发现了如下的public函数:

很明显这是代币合约,并且可以进行转账。而此代码中拥有两个转账函数。并且可以查看余额。

我们具体根据代码对函数详细分析:

首先我们分析编号为0x652e9d91的func_01DC()函数。

首先合约将内存切换到0x01位置,此处为:mapping(address=>uint)publicgift;

memory=msg

不知用户是否发现,我们就看到了漏洞点了,这是一个典型的溢出漏洞。

根据作者给出的代码,我们发现其具体余额是使用uint定义的,由于uint的位数是有限的,并且其不支持负数。所以当其负数溢出时就会变成一个很大的正数。

而根据我们的transfer2函数内容,我们知道:require(balance(msg.sender)-arg1>=0);。此句进行判断的时候是将用户余额减去一个arg1来判断是否大于0的。而如果arg1设置一个比较大的数,那么balance(msg.sender)-arg1就会溢出为一个非常大的数,此时就成功绕过了检测并且转账大量的代币。

所以我们可以利用此处的整数溢出来进行题目求解,然而在分析的过程中我又发现了另一个解法。

如果做题人没有发现此处的漏洞点,我们可以利用常规做法来进行求解。

根据给出的flag函数我们知道,我们只需要余额>10000即可,那么我们可以发现,我们的profit函数可以给我们不断的新增钱。

根据我们的分析,我们需要令合约余额==1并且gitf==1,此时即可调用profit()来将余额,调用后余额为2,gift为1。这时候将余额转给第二个账户,余额就又变成1了,就又可以调用profit()函数。这样不断给第二个用户转账,转账10000次即可。

三、漏洞利用技巧

此处我们介绍漏洞利用的技巧。

首先我们需要拥有两个钱包地址。

此时我们令Addr1调用func_01DC()函数领取1个代币以及1个gift。

之后我们调用profit领取一个代币。此时余额为2,gift为1。

由于transfer2需要余额大于2才能调用,所以我们首先令Addr2同样执行上面的两步。此时两个钱包均有余额为2。

这时候Adde1调用transfer给Addr2转账两个代币,此时Addr余额为0,Addr2为4。

之后Addr2就可以调用transfer2给Adde1转账一个非常大的金额。达到溢出效果。此时Addr1与Addr2均拥有了大量的代币。任意地址均可以调用flag函数。

具体的交易日志如下:

此时flag就被调用发送到用户账户上了。

四、总结

本次题目非常巧妙,如果后面的同学想直接查看交易日志是非常难通过一个账户来进行跟踪的。并且本题目没有公布合约,所以考验逆向能力。但是只要逆出来后就是一道比较简单的题目,没有完全逆出来的同学也可以使用常规做法进行不断转账来使余额满足要求。希望本文对大家之后的研究有所帮助。欢迎讨论。

郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。

金宝趣谈

[0:31ms0-3:115ms