Blockchain security
Article directory
Jump Oriented Programming Practice 1
Purpose
Learn to use the web3 module of python3
Learn to analyze Jump Oriented Programming (JOP) issues in Ethereum smart contracts
Deeply understand EVM bytecode
Find contract vulnerabilities, analyze them and exploit them
lab environment
Ubuntu18.04 operating machine
Experimental tools
python3
Experimental principle
The idea of JOP is similar to ROP: small code snippets (gadgets) are connected in series to achieve a certain purpose.
The following three bytecodes are involved in JOP: 0x56 JUMP 0x57 JUMPI 0x5B JUMPDEST. The destinations of unconditional jump JUMP and conditional jump JUMPI in the EVM must be JUMPDEST. This POINT and ROP can optionally have different return addresses.
Usually contracts that require the use of JOP are mixed with inline assembly backdoors when writing. This experiment uses JOP to control the program control flow to achieve a specific purpose.
Experiment content
There is a simple JOP problem built into the contract. To find the contract vulnerability and exploit it, just trigger the SendFlag (address addr) event of the contract
Use the web3 module of python3 to remotely exploit the vulnerability and Get flag
The experimental address is nc ip 10015
Jump Oriented Programming Practice 1 Experimental Steps
Get the contract address and contract source code
Connect nc ip 10015 to the question, enter 1, and get the game account and token for deploying the contract
Open http://ip, enter the game account assigned above, and click Request to obtain eth
nc ip 10015 connect to the question, enter 2 to get the address of the deployment contract and new token
nc ip 10015 connect to the question, enter 4 to get the contract source code, or find the contract source code in the question attachment
Analyze contract source code vulnerabilities
pragma solidity ^0.4.23;
contract ETH15 {
address private owner;
bytes4 internal constant SET = bytes4(keccak256('fifth(uint256)'));
event SendFlag(address addr);
struct Func {
function() internal f;
}
constructor() public payable {
owner = msg.sender;
}
modifier onlyOwner {
require(msg.sender == owner);
_;
}
// 0x4b64e492
function execute(address _target) public payable{
require(_target.delegatecall(abi.encodeWithSelector(this.execute.selector)) == false, 'unsafe execution');
bytes4 sel;
uint val;
(sel, val) = getRet();
require(sel == SET);
Func memory func;
func.f = gift;
assembly {
mstore(