源码:
pragma solidity ^0.4.24;
contract hf {
address secret;
uint count;
address owner;
mapping(address => uint) public balanceOf;
mapping(address => uint) public gift;
struct node {
address nodeadress;
uint nodenumber;
}
node public node0;
event SendFlag(string b64email);
constructor()public{
owner = msg.sender;
}
function payforflag(string b64email) public {
require(balanceOf[msg.sender] >= 100000);
balanceOf[msg.sender]=0;
owner.transfer(address(this).balance);
emit SendFlag(b64email);
}
//to fuck
modifier onlySecret() {
require(msg.sender == secret);
_;
}
function profit() public{
require(gift[msg.sender]==0);
gift[msg.sender]=1;
balanceOf[msg.sender]+=1;
}
function hfvote() public payable{
uint geteth=msg.value/1000000000000000000;
balanceOf[msg.sender]+=geteth;
}
function ubw() public payable{
if (msg.value < 2 ether)
{
node storage n = node0;
n.nodeadress=msg.sender;
n.nodenumber=1;
}
else
{
n.nodeadress=msg.sender;
n.nodenumber=2;
}
}
function fate(address to,uint value) public onlySecret {
require(balanceOf[msg.sender]-value>=0);
balanceOf[msg.sender]-=value;
balanceOf[to]+=value;
}
}
payforFlag那里要求require(balanceOf[msg.sender] >= 100000);
,因此还是要想办法提高balance。经过查看,发现fate函数存在整形下溢出:
require(balanceOf[msg.sender]-value>=0);
balanceOf[msg.sender]-=value;
balanceOf[to]+=value;
原因就是balanceOf[msg.sender]
和value
都是uint类型,因此它们相减的结果也一定是uint类型,一定是>=0的,因此这个require一定满足,然后就是balanceOf[msg.sender]-=value;
,存在下溢出,因此非常好利用。
但是问题就是,它是被onlySecret修饰的:
modifier onlySecret() {
require(msg.sender == secret);
_;
}
没法绕过,就很迷。后来学了一下别的师傅的WP,原来这题还有另外一个考点,就是Uninitialized Storage Pointer。
注意到ubw函数,虽然我一开始也注意到了,就是else里的n是没有初始化的。
function ubw() public payable{
if (msg.value < 2 ether)
{
node storage n = node0;
n.nodeadress=msg.sender;
n.nodenumber=1;
}
else
{
n.nodeadress=msg.sender;
n.nodenumber=2;
}
}
n会被当成一个指针,而且默认指向slot[0]
和slot[1]
,因此修改n.nodeaddress和n.nodenumber
,就是修改这两个:
address secret;
uint count;
因此secret可以覆盖成msg.sender
,至此这题就全部绕过了。
其实对于Uninitialized Storage Pointer还是有些懵,还是自己solidity没有学的扎实,接下来应该还会再写一篇关于Uninitialized Storage Pointer的理解,但是可能还是不够那么的理解,也算是正常叭。当时自己学PHP的反序列化的时候也是感觉很懵,后来接触的越来越多,学的东西越来越多,对于原理和基础理解的越来越深,也就渐渐的很明白了,所以慢慢来,循序渐进,先去查一下solidity手册来解一下疑惑。
上篇文章给大家介绍了 Java正则表达式匹配,替换,查找,切割的方法 ,接下来,...
4月11日20:30~22:00通过腾讯会议进行了第二次在线学习讨论我把学习笔记整理一下...
错误描述: 在开发.net项目中,通过microsoft.ACE.oledb读取excel文件信息时,报...
DELETEFROMTablesWHEREIDNOTIN(SELECTMin(ID)FROMTablesGROUPBYName) Min的话保...
复制代码 代码如下: % URL="http://news.163.com/special/00011K6L/rss_newstop....
本文实例讲述了Laravel框架源码解析之反射的使用。分享给大家供大家参考,具体如...
Elasticsearch 是通过 Lucene 的倒排索引技术实现比关系型数据库更快的过滤。特...
工具:Eclipse,Oracle,smartupload.jar;语言:jsp,Java;数据存储:Oracle。...
正则忽略大小写 – RegexOptions.IgnoreCase 例如: 复制代码 代码如下: Str = R...
项目中用到的一些特殊字符和图标 html代码 XML/HTML Code 复制内容到剪贴板 div ...