知識點
- 整形下溢位
- Uninitialized Storage Pointer
WP
原始碼:
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手冊來解一下疑惑,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/275528.html
標籤:區塊鏈
上一篇:如何花1塊錢建立一個能正常訪問的網站--搭建服務器(ubuntu18)(騰訊云服務器)
下一篇:BUG:K8S生成ETCD證書時報錯 “code“:5200,“message“:“could not read configuration file“
