Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
octopus — Инструмент анализа безопасности для модуля WebAssembly (wasm) и смарт-контрактов блокчейна (BTC/ETH/NEO/EOS) | Kitploit
Инструменты/GitHubGitHub/fuzzinglabs/octopus
Статический анализДинамический анализ (песочница)Обратная инженерияФаззингАнализ Бинарных ФайловArchived
GitHubfuzzinglabs/octopus

octopus

Инструмент анализа безопасности для модуля WebAssembly (wasm) и смарт-контрактов блокчейна (BTC/ETH/NEO/EOS)

Репозиторий
494902 лет назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
Сайт

Octopus

made-with-python MIT license

Огромная благодарность QuoScient за спонсирование этого проекта.

Octopus — это фреймворк для анализа безопасности WebAssembly-модулей и смарт-контрактов блокчейна.

Цель Octopus — предоставить простой способ анализа закрытых WebAssembly-модулей и байт-кода смарт-контрактов для более глубокого понимания их внутреннего поведения.

Возможности

  • Обозреватель (Explorer): Реализация JSON-RPC-клиента Octopus для взаимодействия с блокчейн-платформами
  • Дисассемблер (Disassembler): Octopus может преобразовывать байт-код в ассемблерное представление
  • Анализ потока управления (Control Flow Analysis): Octopus может генерировать граф потока управления (CFG)
  • Анализ потока вызовов (Call Flow Analysis): Octopus может генерировать граф потока вызовов (на уровне функций)
  • Преобразование в промежуточное представление (IR conversion, SSA): Octopus может упрощать ассемблер в представление статического единичного присваивания (SSA)
  • Символическое выполнение (Symbolic Execution): Octopus использует символическое выполнение для поиска новых путей в программе

Платформы / Архитектуры

Octopus поддерживает следующие типы программ/смарт-контрактов:

  • WebAssembly-модули (WASM)
  • Скрипты Bitcoin (BTC script)
  • Смарт-контракты Ethereum (EVM bytecode & Ewasm)
  • Смарт-контракты EOS (WASM)
  • Смарт-контракты NEO (AVM bytecode)
  • PyPI package ✔️
  • Docker ✔️

✔️ ГОТОВО / ➕ В РАБОТЕ / ✖️ ЗАПЛАНИРОВАНО / ⭕ Н/П

Требования

Octopus поддерживается в Linux (желательно Ubuntu 16.04) и требует Python >=3.5 (желательно 3.6).

Зависимости:

  • Построение графов: graphviz
  • Обозреватель: requests
  • Символическое выполнение: z3-solver
  • Wasm: wasm

Быстрый старт

  • Установите системные зависимости```

Install system dependencies

sudo apt-get update && sudo apt-get install python-pip graphviz xdg-utils -y

root@kitploit:~
- Установка Octopus:```
# Download Octopus
git clone https://github.com/pventuzelo/octopus
cd octopus

# Install Octopus library/CLI and its dependencies
python3 setup.py install

или```

but prefer the first way to install if possible

pip3 install octopus

root@kitploit:~
- Запустить тесты```
# Run tests for all platforms (disassembly, CFG, ...)
./run_tests.sh
# Run tests that require internet access (explorer tests)
./run_explorer_tests.sh

# Run tests for only one platforms
# {btc, eth, eos, neo, wasm}_run_tests.sh
cd octopus/tests/
./wasm_run_tests.sh

Docker контейнер

Docker контейнер, предоставляющий набор инструментов, доступен на docker hub. В терминале выполните следующие команды:``` docker pull smartbugs/octopus docker run -it smartbugs/octopus cd octopus python3 octopus_eth_evm.py -s -f examples/ETH/evm_bytecode/61EDCDf5bb737ADffE5043706e7C5bb1f1a56eEA.bytecode

root@kitploit:~
## Инструменты командной строки

* WebAssembly: [octopus_wasm.py](https://github.com/fuzzinglabs/octopus/blob/HEAD/octopus_wasm.py)
* Ethereum (EVM): [octopus_eth_evm.py](https://github.com/fuzzinglabs/octopus/blob/HEAD/octopus_eth_evm.py)

## Подробные примеры использования API

<details><summary>WebAssembly</summary>
<p>

#### Дизассемблер

Дизассемблирование модуля Wasm:```python
from octopus.arch.wasm.disassembler import WasmDisassembler

FILE = "examples/wasm/samples/helloworld.wasm"

with open(FILE, 'rb') as f:
    module_bytecode = f.read()

disasm = WasmDisassembler()
# return list of functions instructions (list)
print(disasm.disassemble_module(module_bytecode))
#[[<octopus.arch.wasm.instruction.WasmInstruction at 0x7f85e4904278>,<octopus.arch.wasm.instruction.WasmInstruction at 0x7f85e4904f60>,<octopus.arch.wasm.instruction.WasmInstruction at 0x7f85e4904ef0>]]

print()
# return text of functions code
print(disasm.disassemble_module(module_bytecode, r_format='text'))
# func 0
# i32.const 0
# call 0
# end

Дизассемблирование байт-кода wasm:```python from octopus.arch.wasm.disassembler import WasmDisassembler

bytecode in WebAssembly is the function code (i.e. function body)

bytecode = b'\x02\x7fA\x18\x10\x1cA\x00\x0f\x0b'

create a WasmDisassembler object

disasm = WasmDisassembler(bytecode)

disassemble bytecode into a list of WasmInstruction

attributes r_format='list' by default

print(disasm.disassemble())

#[<octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904eb8>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904278>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904390>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904ef0>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904f60>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4901048>] print() print(disasm.disassemble(r_format='reverse'))

#{0: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4901048>, 1: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904240>, 2: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904f60>, 3: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904ef0>, 4: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904278>, 5: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904390>} print() print(disasm.disassemble(r_format='text'))

block -1

i32.const 24

call 28

i32.const 0

return

end

root@kitploit:~
#### ModuleAnalyzer```python
from octopus.arch.wasm.analyzer import WasmModuleAnalyzer

FILE = "examples/wasm/samples/hello_wasm_studio.wasm"

with open(FILE, 'rb') as f:
    module_bytecode = f.read()

# return list of functions instructions (list)
# attributes analysis=True by default
analyzer = WasmModuleAnalyzer(module_bytecode)

# show analyzer attributes
print(analyzer.func_prototypes)
# [('putc_js', 'i32', ''),
#  ('__syscall0', 'i32', 'i32'),
#  ('__syscall3', 'i32 i32 i32 i32', 'i32'),
#  ('__syscall1', 'i32 i32', 'i32'),
#  ('__syscall5', 'i32 i32 i32 i32 i32 i32', 'i32'),
#  ('__syscall4', 'i32 i32 i32 i32 i32', 'i32'),
#  ('$func6', '', ''),
#  ('main', '', 'i32'),
#  ('writev_c', 'i32 i32 i32', 'i32'),
#  ('$func9', '', 'i32'),
#  ('$func10', 'i32', 'i32'),
#  ('$func11', 'i32', 'i32'),
#  ('$func12', 'i32', ''),
#  ('$func13', 'i32', 'i32'),
#  ('$func14', 'i32 i32 i32 i32', 'i32'),
#  ('$func15', 'i32 i32', 'i32'),
#  ('$func16', 'i32 i32', 'i32'),
#  ('$func17', 'i32', 'i32'),
#  ('$func18', 'i32', 'i32'),
#  ('$func19', 'i32', 'i32'),
#  ('$func20', 'i32 i32 i32', 'i32'),
#  ('$func21', 'i32 i32 i32', 'i32'),
#  ('$func22', 'i32 i64 i32', 'i64'),
#  ('$func23', 'i32 i32 i32', 'i32'),
#  ('$func24', 'i32', 'i32'),
#  ('$func25', 'i32 i32 i32 i32', '')]
print()
print(analyzer.contains_emscripten_syscalls())
#[('__syscall0', 'restart_syscall'),
# ('__syscall3', 'read'),
# ('__syscall1', 'exit'),
# ('__syscall5', 'open'),
# ('__syscall4', 'write')]

Анализ потока управления```python

from octopus.arch.wasm.cfg import WasmCFG

complete wasm module

file_name = "examples/wasm/samples/fib.wasm"

read file

with open(file_name, 'rb') as f: raw = f.read()

create the cfg

cfg = WasmCFG(raw)

visualize CFGGraph

generate graph.dot and graph.pdf file

cfg.visualize()

root@kitploit:~
<p align="center">
    <img src="https://assets.kitploit.com/production/public/readmes/6916/a317892fc1e0ce1939535b5f1e0fd00188634ec14f21e7f5eee950e4c2f92206.png" height="400px"/>
</p>


#### Аналитика инструкций функций```python
from octopus.arch.wasm.cfg import WasmCFG

# complete wasm module
file_name = "examples/wasm/samples/hello_wasm_studio.wasm"

# read file
with open(file_name, 'rb') as f:
    raw = f.read()

# create the cfg
cfg = WasmCFG(raw)

# visualization
cfg.visualize_instrs_per_funcs()

Анализ потока вызовов```python

from octopus.arch.wasm.cfg import WasmCFG

fibonacci wasm module

file_name = "examples/wasm/samples/hello_wasm_studio.wasm"

read file

with open(file_name, 'rb') as f: raw = f.read()

create the cfg

cfg = WasmCFG(raw)

visualize Call Flow Graph

generate call_graph.dot and call_graph.pdf file

color similar to https://webassembly.studio/

imported func == turquoise / exported func == grey

edge label = number of different calls to the function

cfg.visualize_call_flow()

root@kitploit:~
<p align="center">
    <img src="https://assets.kitploit.com/production/public/readmes/6916/62fcb93f3dcec6856fdcb2618024b5e72da74112e8277d6113c9e2e008c5ecf6.png" height="400px"/>
</p>

Легенда:  

<p align="center">
    <img src="https://assets.kitploit.com/production/public/readmes/6916/332b97a2eb228b9a43dd7a13857b7e593353ebea1555d2d0efd38964ef902d20.png" height="400px"/>
</p>

#### Преобразование в IR (SSA)```python
from octopus.arch.wasm.emulator import WasmSSAEmulatorEngine

# complete wasm module
file_name = "examples/wasm/samples/fib.wasm"

# read file
with open(file_name, 'rb') as f:
    raw = f.read()


# run the emulator for SSA
emul = WasmSSAEmulatorEngine(raw)
emul.emulate_one_function('fib')
# or emul.emulate_functions(['fib'])
# or emul.emulate_functions() # emulate all the function

# visualization of the cfg with SSA
emul.cfg.visualize(ssa=True)

Ethereum (ETH) - EVM

Обозреватель```python

from octopus.platforms.ETH.explorer import EthereumInfuraExplorer from octopus.platforms.ETH.explorer import INFURA_ROPSTEN

KEY_API = "bHuaQhX91nkQBac8Wtgj"

connection to ROPSTEN network (testnet)

explorer = EthereumInfuraExplorer(KEY_API, network=INFURA_ROPSTEN)

connection to MAINNET network (mainnet)

explorer = EthereumInfuraExplorer(KEY_API)

Test ROPSTEN network current block number

block_number = explorer.eth_blockNumber() print(block_number)

3675552

Retrieve code of this smart contract

addr = "0x3c6B10a5239B1a8A27398583F49771485382818F" code = explorer.eth_getCode(addr) print(code)

0x6060604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c14606e575b600080fd5b3415605857600080fd5b606c60048080359060200190919050506094565b005b3415607857600080fd5b607e609e565b6040518082815260200191505060405180910390f35b8060008190555050565b600080549050905600a165627a7a72305820e1f98c821c12eea52047d7324b034ddccc41eaa7365d369b34580ab73c71a8940029

Ethereum (WASM)

Обозреватель```python

from octopus.platforms.ETH.explorer import EthereumInfuraExplorer from octopus.platforms.ETH.explorer import INFURA_KOVAN

connection to ROPSTEN network (testnet)

explorer = EthereumInfuraExplorer("bHuaQhX91nkQBac8Wtgj", network=INFURA_KOVAN)

connection to MAINNET network (mainnet)

explorer = EthereumInfuraExplorer("bHuaQhX91nkQBac8Wtgj")

test infura access

block_number = explorer.eth_blockNumber() print('blockNumber = %d' % block_number)

retrieve code of this smart contract

addr = "0x1120e596b173d953ba52ce262f73ce3734b0e40e" code = explorer.eth_getCode(addr) print() print(code)

blockNumber = 8803487

0x0061736d0100000001090260000060027f7f00021a0203656e7603726574000103656e76066d656d6f7279020102100303020000040501700101010501000601000708010463616c6c00010a120205001002000b0a00418008410b1000000b0b1201004180080b0b48656c6c6f20776f726c64000b076c696e6b696e6703010b0066046e616d65015f060003726574010570616e6963020463616c6c032f5f5a4e3134707761736d5f657468657265756d3365787433726574313768363034643830393864313638366338304504066465706c6f790511727573745f626567696e5f756e77696e64

NEO

Исследователь```python

from octopus.platforms.NEO.explorer import NeoExplorerRPC

get list nodes here: http://monitor.cityofzion.io/

explorer = NeoExplorerRPC(host='seed2.neo.org')

get current number of block on the blockchain

print(explorer.getblockcount())

2534868

get information on a contract

lock smart contract address: d3cce84d0800172d09c88ccad61130611bd047a4

contract = explorer.getcontractstate("d3cce84d0800172d09c88ccad61130611bd047a4") print(contract)

{'author': 'Erik Zhang',

'code_version': '2.0',

Скачать инструмент
BTCETH (EVM)ETH (WASM)EOSNEOWASM
Explorer✔️✔️✔️✔️✔️⭕
Disassembler✔️✔️✔️✔️✔️✔️
Control Flow Analysis✖️✔️✔️✔️✔️✔️
Call Flow Analysis✖️➕✔️✔️➕✔️
IR conversion (SSA)✖️✔️➕➕✖️✔️
Symbolic Execution✖️➕➕➕✖️➕
root@kitploit:~
#### Дизассемблер```python
from octopus.platforms.ETH.disassembler import EthereumDisassembler

# smart contract bytecode
bytecode_hex = "60606040526000357c0100000000000000000000000000000000000000000000000000000000900480635fd8c7101461004f578063c0e317fb1461005e578063f8b2cb4f1461006d5761004d565b005b61005c6004805050610099565b005b61006b600480505061013e565b005b610083600480803590602001909190505061017d565b6040518082815260200191505060405180910390f35b3373ffffffffffffffffffffffffffffffffffffffff16611111600060005060003373ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060005054604051809050600060405180830381858888f19350505050151561010657610002565b6000600060005060003373ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050819055505b565b34600060005060003373ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828282505401925050819055505b565b6000600060005060008373ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000505490506101b6565b91905056"

disasm = EthereumDisassembler()
disasm.disassemble(bytecode_hex)

# disassemble bytecode into a list of EthereumInstruction
# attributes r_format='list' by default
print(disasm.disassemble(bytecode_hex))

#[<octopus.platforms.ETH.instruction.EthereumInstruction object at 0x7f85d4add5c0>, <octopus.platforms.ETH.instruction.EthereumInstruction object at 0x7f85d4ad8588>, <octopus.platforms.ETH.instruction.EthereumInstruction object at 0x7f85d4ad8c50>]

print()
print(disasm.disassemble(bytecode_hex, r_format='reverse'))

# {0: <octopus.platforms.ETH.instruction.EthereumInstruction object at 0x7f85d4ad8160>, ..., 229: <octopus.platforms.ETH.instruction.EthereumInstruction object at 0x7f85d4ad8630>, 230: <octopus.platforms.ETH.instruction.EthereumInstruction object at 0x7f85d4ad87b8>}

print()
print(disasm.disassemble(bytecode_hex,r_format='text'))
# PUSH1 0x60
# PUSH1 0x40
# MSTORE
# PUSH1 0x0
# CALLDATALOAD
# PUSH29 0x100000000000000000000000000000000000000000000000000000000
# SWAP1
# DIV
# DUP1
# PUSH4 0x5fd8c710
# EQ
# PUSH2 0x4f
# JUMPI
# ...
# SWAP2
# SWAP1
# POP
# JUMP

Анализ потока управления```python

from octopus.analysis.graph import CFGGraph from octopus.platforms.ETH.cfg import EthereumCFG

ethernaut0 bytecode

file_name = "examples/ETH/evm_bytecode/Zeppelin_Hello_ethernaut0.bytecode"

read file

with open(file_name) as f: bytecode_hex = f.read()

create the CFG

cfg = EthereumCFG(bytecode_hex)

generic visualization api

generate graph.dot and graph.pdf file

graph = CFGGraph(cfg) graph.view()

or directly using the cfg binding

cfg.visualize()

and you can get a simplify cfg representation using

cfg.visualize(simplify=True) or graph.view(simplify=True)

root@kitploit:~
<p align="center">
    <img src="https://assets.kitploit.com/production/public/readmes/6916/f1ab0983ab68ff22aa4d97893fa25466cf220562fecdffebd6de1333877a8b57.png"/>
</p>

#### Преобразование IR (SSA)```python
# The conversion to SSA is already done by the SSAEmulator
# when the CFG is reconstruct
# by default you have just to visualize it
from octopus.platforms.ETH.cfg import EthereumCFG

# ethernaut0 bytecode
file_name = "examples/ETH/evm_bytecode/Zeppelin_Hello_ethernaut0.bytecode"

# read file
with open(file_name) as f:
    bytecode_hex = f.read()

# create the CFG
cfg = EthereumCFG(bytecode_hex)

# SSA visualization
cfg.visualize(ssa=True)

root@kitploit:~
#### Дисассемблер

Дизассемблирование модуля Wasm:```python
from octopus.platforms.ETH.disassembler import EthereumDisassembler

FILE = "examples/ETH/wasm/helloworld_kovan.bytecode"

with open(FILE, 'r') as f:
    module_bytecode = f.read()

disasm = EthereumDisassembler(arch='wasm')
# return list of functions instructions (list)
print(disasm.disassemble_module(module_bytecode))
#[[<octopus.arch.wasm.instruction.WasmInstruction object at 0x7efc0ceaa898>], [<octopus.arch.wasm.instruction.WasmInstruction object at 0x7efc0ceaa7b8>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7efc0ceaa780>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7efc0ceaa748>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7efc0ceaa6d8>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7efc0ceaa710>]]

print()
# return text of functions code
print(disasm.disassemble_module(module_bytecode, r_format='text'))
# func 0
# end
# 
# func 1
# call 1
# i32.const 1036
# i32.const 232
# call 0
# end

Дизассемблирование wasm-байткода:```python from octopus.platforms.ETH.disassembler import EthereumDisassembler

bytecode in WebAssembly is the function code (i.e. function body)

bytecode = b'\x02\x7fA\x18\x10\x1cA\x00\x0f\x0b'

create a WasmDisassembler object

disasm = EthereumDisassembler(bytecode, arch='wasm')

disassemble bytecode into a list of WasmInstruction

attributes r_format='list' by default

print(disasm.disassemble())

#[<octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904eb8>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904278>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904390>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904ef0>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904f60>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4901048>] print() print(disasm.disassemble(r_format='reverse'))

#{0: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4901048>, 1: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904240>, 2: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904f60>, 3: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904ef0>, 4: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904278>, 5: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904390>} print() print(disasm.disassemble(r_format='text'))

block -1

i32.const 24

call 28

i32.const 0

return

end

root@kitploit:~
#### ModuleAnalyzer```python
from octopus.arch.wasm.analyzer import WasmModuleAnalyzer

FILE = "examples/ETH/wasm/helloworld_kovan.bytecode"

with open(FILE, 'r') as f:
    module_bytecode = f.read()

# return list of functions instructions (list)
# attributes analysis=True by default
analyzer = WasmModuleAnalyzer(module_bytecode)

# show analyzer attributes
print(analyzer.func_prototypes)
# [('ret', 'i32 i32', '', 'import'), ('$func1', '', '', 'local'), ('call', '', '', 'export')]
print()
print(analyzer.exports)
# [{'field_str': 'call', 'kind': 0, 'index': 2}]
print()
print(analyzer.imports_func)
# [('env', 'ret', 1)]
print()
print(analyzer.datas)
# [{'data': b'Hello world', 'index': 0, 'offset': None, 'size': 11},
# {'data': b'\x00asm\x01\x00\x00\x00\x01\t\x02`\x00\x00`\x02\x7f\x7f\x00\x02\x1a\x02\x03env\x03ret\x00\x01\x03env\x06memory\x02\x01\x02\x10\x03\x03\x02\x00\x00\x04\x05\x01p\x01\x01\x01\x05\x01\x00\x06\x01\x00\x07\x08\x01\x04call\x00\x01\n\x12\x02\x05\x00\x10\x02\x00\x0b\n\x00A\x80\x08A\x0b\x10\x00\x00\x0b\x0b\x12\x01\x00A\x80\x08\x0b\x0bHello world\x00\x0b\x07linking\x03\x01\x0b\x00f\x04name\x01_\x06\x00\x03ret\x01\x05panic\x02\x04call\x03/_ZN14pwasm_ethereum3ext3ret17h604d8098d1686c80E\x04\x06deploy\x05\x11rust_begin_unwind',
# 'index': 0,
# 'offset': None,
# 'size': 232}]

Анализ потока управления```python

from octopus.platforms.ETH.cfg import EthereumCFG

HelloWorld on Kovan Parity Network

file_name = "examples/ETH/wasm/helloworld_kovan.bytecode"

read file

with open(file_name) as f: bytecode_hex = f.read()

create the CFG

cfg = EthereumCFG(bytecode_hex, arch='wasm') cfg.visualize()

root@kitploit:~
<p align="center">
    <img src="https://assets.kitploit.com/production/public/readmes/6916/7a8e6cc4ce71f467e09100a231e1916c4101a56094a5883bd42534c419ba0dc2.png" height="400px"/>
</p>

#### Аналитика инструкций функций```python
from octopus.platforms.ETH.cfg import EthereumCFG

# HelloWorld on Kovan Parity Network
file_name = "examples/ETH/wasm/helloworld_kovan.bytecode"

# read file
with open(file_name) as f:
    bytecode_hex = f.read()

# create the CFG
cfg = EthereumCFG(bytecode_hex, arch='wasm')

# visualization
cfg.visualize_instrs_per_funcs()

Анализ потока вызовов```python

from octopus.platforms.ETH.cfg import EthereumCFG

HelloWorld on Kovan Parity Network

file_name = "examples/ETH/wasm/helloworld_kovan.bytecode"

read file

with open(file_name) as f: bytecode_hex = f.read()

create the CFG

cfg = EthereumCFG(bytecode_hex, arch='wasm')

visualization

cfg.visualize_call_flow()

root@kitploit:~
<p align="center">
    <img src="https://assets.kitploit.com/production/public/readmes/6916/a3b69354067c4b7c707fc60c7c844688a30bbb6dd4de54528545554148e83d0e.png" height="400px"/>
</p>

Легенда:  

<p align="center">
    <img src="https://assets.kitploit.com/production/public/readmes/6916/332b97a2eb228b9a43dd7a13857b7e593353ebea1555d2d0efd38964ef902d20.png" height="400px"/>
</p>


#### Преобразование IR (SSA)```python
# TODO

'description': 'Lock 2.0',

'email': '[email protected]',

'hash': '0xd3cce84d0800172d09c88ccad61130611bd047a4',

'name': 'Lock',

'parameters': ['Integer', 'PublicKey', 'Signature'],

'properties': {'dynamic_invoke': False, 'storage': False},

'returntype': 'Boolean',

'script': '56c56b6c766b00527ac46c766b51527ac46c766b52527ac4616168184e656f2e426c6f636b636861696e2e4765744865696768746168184e656f2e426c6f636b636861696e2e4765744865616465726c766b53527ac46c766b00c36c766b53c36168174e656f2e4865616465722e47657454696d657374616d70a06c766b54527ac46c766b54c3640e00006c766b55527ac4621a006c766b51c36c766b52c3617cac6c766b55527ac46203006c766b55c3616c7566',

'version': 0}

smart contract code in contract['script']

print(contract['script'])

root@kitploit:~
#### Дизассемблер```python
from octopus.platforms.NEO.disassembler import NeoDisassembler

# lock contract
file_name = "examples/NEO/samples/Lock.bytecode"

# read file
with open(file_name) as f:
    bytecode = f.read()

disasm = NeoDisassembler()

print(disasm.disassemble(bytecode, r_format='text'))
# PUSH6
# NEWARRAY
# TOALTSTACK
# FROMALTSTACK
# DUP
# TOALTSTACK
# PUSH0
# PUSH2
# ROLL
# SETITEM
# FROMALTSTACK
# ....
# PICKITEM
# NOP
# FROMALTSTACK
# DROP
# RET

Анализ потока управления```python

from octopus.analysis.graph import CFGGraph from octopus.platforms.NEO.cfg import NeoCFG

lock contract

file_name = "examples/NEO/samples/Lock.bytecode"

read file

with open(file_name) as f: raw = f.read()

create neo cfg - automatic static analysis

cfg = NeoCFG(raw)

graph visualization

graph = CFGGraph(cfg, filename="Lock_cfg") graph.view_functions()

root@kitploit:~
<p align="center">
    <img src="https://assets.kitploit.com/production/public/readmes/6916/049c210aab8b977951cb7236f6f5d3361f0dd4be330df21392543b1e6538f5de.png"/>
</p>


</p>
</details>

<details><summary>EOS</summary>
<p>

#### Обозреватель```python
from octopus.platforms.EOS.explorer import EosExplorer

host = "api.cypherglass.com"

# by defaul the port is 8888
explo = EosExplorer(host=host)

# get info about the node
explo.get_info()

'''
{'block_cpu_limit': 180289,
 'block_net_limit': 1045680,
 'chain_id': 'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906',
 'head_block_id': '018d6e2bcf6295126cd74cf694b5cca3529eefc42b334b394ef87c3a43876739',
 'head_block_num': 26045995,
 'head_block_producer': 'eosswedenorg',
 'head_block_time': '2018-11-09T14:11:29.500',
 'last_irreversible_block_id': '018d6cdcff78bbd9f25c605b02fb67c47a337ece78ddcf73089cee4bf6a410ee',
 'last_irreversible_block_num': 26045660,
 'server_version': 'c71d2245',
 'server_version_string': 'mainnet-1.3.0',
 'virtual_block_cpu_limit': 38092879,
 'virtual_block_net_limit': 1048576000}
'''
explo.get_block(1337)

'''
{'action_mroot': 'bcb9763baa3bbf98ed36379b4be0ecb2d9cd21c75df01729c63b2b021001c10c',
 'block_extensions': [],
 'block_num': 1337,
 'confirmed': 0,
 'header_extensions': [],
 'id': '00000539d17a03af7126e073be4c4d99a72b7f58793cf2c87b9bfd41b6c711fb',
 'new_producers': None,
 'previous': '00000538b374c1cbfaeed7253ad3075ddc72a28f0a0515301fc1bbed675f2316',
 'producer': 'eosio',
 'producer_signature': 'SIG_K1_K5jWf36t6j454Hb2fGuV37YTwMTvuQ51ZPBtpru8Ud2axtMTEauWyvtpJuTpnvqzReUndDgEDXvoeEP4jdj2bpnYKBt6g2',
 'ref_block_prefix': 1944069745,
 'schedule_version': 0,
 'timestamp': '2018-06-09T12:09:21.500',
 'transaction_mroot': '0000000000000000000000000000000000000000000000000000000000000000',
 'transactions': []}
'''

Дизассемблер```python

from octopus.platforms.EOS.disassembler import EosDisassembler

complete wasm module

file_name = "examples/EOS/samples/eos_ping.wasm"

read file

with open(file_name, 'rb') as f: raw = f.read()

just disassembly

disasm = EosDisassembler()

because we provide full module bytecode

we need to use disassemble_module()

otherwise just disassemble() is enough

text = disasm.disassemble_module(raw, r_format="text") print(text)

func 0

get_local 0

get_local 1

i32.const 32

call 12

i32.eqz

end

func 1

get_local 0

i64.load 3, 0

get_local 0

i64.load 3, 8

call 6

end

func 2

...

end

...

root@kitploit:~
#### ModuleAnalyzer```python

from octopus.platforms.EOS.analyzer import EosAnalyzer

# complete wasm module
file_name = "examples/EOS/samples/eos_ping.wasm"

with open(file_name, 'rb') as f:
    module_bytecode = f.read()

# return list of functions instructions (list)
# attributes analysis=True by default
analyzer = EosAnalyzer(module_bytecode)

# show analyzer attributes
print(analyzer.func_prototypes)
#[('action_data_size', '', 'i32', 'import'), ('eosio_assert', 'i32 i32', '', 'import'), ('eosio_exit', 'i32', '', 'import'), ('memcpy', 'i32 i32 i32', 'i32', 'import'), ('prints', 'i32', '', 'import'), ('read_action_data', 'i32 i32', 'i32', 'import'), ('require_auth2', 'i64 i64', '', 'import'), ('_ZeqRK11checksum256S1_', 'i32 i32', 'i32', 'export'), ('_ZN5eosio12require_authERKNS_16permission_levelE', 'i32', '', 'export'), ('apply', 'i64 i64 i64', '', 'export'), ('$func10', 'i32 i64', '', 'local'), ('$func11', 'i32 i32', 'i32', 'local'), ('memcmp', 'i32 i32 i32', 'i32', 'export'), ('malloc', 'i32', 'i32', 'export'), ('$func14', 'i32 i32', 'i32', 'local'), ('$func15', 'i32', 'i32', 'local'), ('free', 'i32', '', 'export'), ('$func17', '', '', 'local')]
print()
print(analyzer.exports)
# [{'field_str': 'memory', 'kind': 2, 'index': 0}, {'field_str': '_ZeqRK11checksum256S1_', 'kind': 0, 'index': 7}, {'field_str': '_ZN5eosio12require_authERKNS_16permission_levelE', 'kind': 0, 'index': 8}, {'field_str': 'apply', 'kind': 0, 'index': 9}, {'field_str': 'memcmp', 'kind': 0, 'index': 12}, {'field_str': 'malloc', 'kind': 0, 'index': 13}, {'field_str': 'free', 'kind': 0, 'index': 16}]
print()
print(analyzer.imports_func)
# [('env', 'action_data_size', 3), ('env', 'eosio_assert', 5), ('env', 'eosio_exit', 2), ('env', 'memcpy', 6), ('env', 'prints', 2), ('env', 'read_action_data', 4), ('env', 'require_auth2', 1)]

Анализ потока управления```python

from octopus.platforms.EOS.cfg import EosCFG from octopus.analysis.graph import CFGGraph

complete wasm module

file_name = "examples/EOS/samples/eos_ping.wasm"

read file

with open(file_name, 'rb') as f: raw = f.read()

create the cfg

cfg = EosCFG(raw)

visualize

graph = CFGGraph(cfg) graph.view_functions()

root@kitploit:~
<p align="center">
    <img src="https://assets.kitploit.com/production/public/readmes/6916/18a84dcc6e2fd330c93192f2c9850ddacec3981e2d3f1f0c6eae676791ad0bec.png"/>
</p>

#### Анализ потока вызовов```python
from octopus.platforms.EOS.cfg import EosCFG

# complete wasm module
file_name = "examples/EOS/samples/eos_ping.wasm"

# read file
with open(file_name, 'rb') as f:
    raw = f.read()

# create the cfg
cfg = EosCFG(raw)

# visualize
cfg.visualize_call_flow()

Анализ инструкций функций```python

from octopus.platforms.EOS.cfg import EosCFG

complete wasm module

file_name = "examples/EOS/samples/eos_ping.wasm"

read file

with open(file_name, 'rb') as f: raw = f.read()

create the cfg

cfg = EosCFG(raw)

visualize

cfg.visualize_instrs_per_funcs()

root@kitploit:~
<p align="center">
    <img src="https://assets.kitploit.com/production/public/readmes/6916/c5b52a71702f65f6edc5be98fa1683679313c3be85aaf86202d68c5bad9205f9.png"/>
</p>

</p>
</details>

<details><summary>Биткоин</summary>
<p>

#### Обозреватель```python
from octopus.platforms.BTC.explorer import BitcoinExplorerRPC

RPC_USER = 'test'
RPC_PASSWORD = 'test'
RPC_HOST = 'localhost'

host = '%s:%s@%s' % (RPC_USER, RPC_PASSWORD, RPC_HOST)

explorer = BitcoinExplorerRPC(host)

explorer.getbestblockhash()
# '00000000000000000012085cfe8c79bcdacf81fbd82f6ab52c3cb3a454d4987c'

explorer.getblockcount()
#550859

Дисассемблер```python

from octopus.platforms.BTC.disassembler import BitcoinDisassembler

Witness Script

file_name = "examples/BTC/witness_script.hex"

read file

with open(file_name) as f: bytecode = f.read()

disasm = BitcoinDisassembler()

print(disasm.disassemble(bytecode, r_format='text'))

0

OP_ROT

OP_ROT

2

0203f4d01d0b35588638631ebb7d46d8387fd1aeb3dbecfdd3faf7c056b023c833

03aa6677e3ce1bd634f4f2e1cd60a60af002e1b30484d4d1611b183b16d391ee96

03bf164811abb8c91ed39e58d4e307f86cb4e487c83f727a2c482bc71a0f96f1db

3

OP_CHECKMULTISIG

root@kitploit:~
</p>
</details>


Примеры находятся в папке [examples](https://github.com/fuzzinglabs/octopus/blob/HEAD/examples).

## Публикации и видео

* BLACKALPS 2018 [Реверс-инжиниринг и исследование уязвимостей смарт-контрактов Ethereum](https://www.blackalps.ch/ba-18/talks.php#111)
* Devcon iv. [Реверс-инжиниринг смарт-контрактов Ethereum для выяснения того, что скрывается за EVM-байткодом](https://guidebook.com/guide/117233/event/21956134/)
* hack.lu 2018 [Реверс-инжиниринг и исследование уязвимостей смарт-контрактов Ethereum](https://2018.hack.lu/talks/#Reversing+and+Vulnerability+research+of+Ethereum+Smart+Contracts)
* ToorCon XX - 2018 [Реверс-инжиниринг смарт-контрактов Ethereum (Введение)](https://frab.toorcon.net/en/toorcon20/public/events/97)
* ToorCon XX - 2018 [Диссекция модуля WebAssembly](https://frab.toorcon.net/en/toorcon20/public/events/92)
* REcon Montreal 2018: [Обратный инжиниринг смарт-контрактов блокчейна](https://recon.cx/2018/montreal/schedule/system/event_attachments/attachments/000/000/053/original/RECON-MTL-2018-Reversing_blockchains_smart_contracts.pdf)

## Авторы

**Patrick Ventuzelo** - *Создатель* - [@Pat_Ventuzelo](https://twitter.com/pat_ventuzelo)

Также смотрите список [участников](https://github.com/quoscient/octopus/contributors), которые внесли вклад в этот проект.

## Лицензия

Этот проект распространяется под лицензией MIT - подробности в файле [LICENSE](https://github.com/fuzzinglabs/octopus/blob/HEAD/LICENSE).

## Благодарности

Спонсор:
* [QuoScient](https://www.quoscient.io/)

Вдохновлено:
* [Manticore](https://github.com/trailofbits/manticore)
* [Mythril](https://github.com/ConsenSys/mythril)
* [Rattle](https://github.com/trailofbits/rattle)
* [ethersplay](https://github.com/trailofbits/ethersplay)
* ...

# Обучение и контакты

Patrick Ventuzelo - [@pat_ventuzelo](https://twitter.com/pat_ventuzelo)
* Независимый исследователь безопасности / тренер.
* Бесплатные онлайн-курсы: [здесь](https://academy.fuzzinglabs.com/)