#smart-contracts #smart #contracts #solana #contract

poc-framework-osec

一个以简单直观的方式创建 Solana 智能合约 PoC 的框架:https://github.com/neodyme-labs/solana-poc-framework 的分支

2 个版本

0.1.1 2022 年 4 月 10 日
0.1.0 2022 年 4 月 10 日

#87 in #smart

Download history 3/week @ 2024-03-26 30/week @ 2024-04-02

每月 70 下载
用于 sol-ctf-framework

MIT/Apache

445KB
1K SLoC

包含 (ELF 库,165KB) src/programs/spl_token-3.1.0.so,(ELF 库,130KB) spl_associated-token-account-1.0.1.so,(ELF 库,75KB) src/programs/spl_memo-3.0.0.so,(ELF 库,18KB) src/programs/spl_memo-1.0.0.so

Solana PoC 框架

该项目是 poc-framework 的分支。

免责声明:强烈反对使用此框架进行非法活动。Solana 上的大多数项目都提供了丰厚的漏洞赏金。而且你也不想你的膝盖骨被折断。

使用方法

要开始,只需将以下行添加到 dependencies 部分中 Cargo.toml

[dependencies]
poc-framework-osec = "0.1.1"

此包已重新导出您可能需要的所有 Solana 依赖项。

此框架的用途

此框架是为安全研究人员制作的,以简化 Solana 智能合约或甚至 Solana 核心中的漏洞 PoC 的快速和方便的开发。通用的 Environment 接口允许在本地开发漏洞,然后在 Testnet 或 Devnet 上进行测试。

功能概述

实用工具

此框架提供了许多实用函数,这些函数在我们的 Neodyme 审计的智能合约中开发的 PoC 中被证明非常有用。

在 PoC 中,你首先想要做的是设置日志。如果你使用的是本地环境,这将非常有用,因为这是确定交易无法执行的原因(例如,如果签名者缺失)的唯一方法。

setup_logging(LogLevel::DEBUG);

之后,你需要定义你将使用哪些密钥。密钥在打印交易时应该很容易识别。这由 keypair(n: u8) 函数来满足。框架包含 256 个预先生成的密钥,以 Kxxx 开头,其中 xxx 是参数 n 的 3 位数字表示。请注意,base58 字符集中不包含 0,这就是为什么我们使用 o 的原因

let authority = keypair(0);   // KoooVyhdpoRPA6gpn7xr3cmjqAvtpHcjcBX6JBKu1nf
let target    = keypair(1);   // Koo1BQTQYawwKVBg71J2sru7W51EJgfbyyHsTFCssRW
let mint      = keypair(2);   // Koo2SZ393psmp7ags3hMz59ciV3XWLj1GkPousNgTH1
let victim    = keypair(137); // K137jwH7CncXBTadHbLDsHNWUhuLDN4ddegJL2hmn6u

还有一个 random_keypair 函数,如果你不关心识别密钥对。

对于调试目的来说,能够以整洁的方式打印交易结果同样非常有价值。为此,该框架提供了特性 PrintableTransaction,它为 ConfirmedTransactionEncodedConfirmedTransaction 都实现了此特性。这个特性提供了 print 函数,可以方便地链接到任何 env.execute_transaction 调用的末尾

env.execute_as_transaction(&[...], &[...]).print();

环境

该框架的核心是 Environment 特性。它封装了在某些链状态上执行交易的能力,以及拥有一个支付所有费用和租金支出的 payer 的实用功能。

目前有两种不同的实现:执行所有交易的集群上的 RemoteEnvironment,以及在本地上任意链状态上执行所有交易的 LocalEnvironment

Environment 特性还提供了许多发送交易的有用快捷方式,如与 spl-token 账户交互,甚至创建具有任意内容(但显然具有固定所有者)的账户。

远程环境

要构建远程环境,你需要一个 RpcClient。这些可以通过 devnet_client()/testnet_client()/localhost_client() 方式方便地构建。我们不鼓励在主网上使用此框架。还实现了空投,具有 new_with_airdropairdrop 函数。

let payer = read_keypair_file("big-fat-wallet.json").unwrap();
let client = devnet_client();
let mut env = RemoteEnvironment::new(client, payer);

本地环境

构建本地环境通常需要一些努力,因为首先必须克隆相关的链状态。该框架提供了多种不同的方法来实现这一点。从从文件部署合约到插入任意账户,再到从集群克隆账户和整个可升级程序

let mut env = LocalEnvironment::builder()
    .add_account_with_lamports(authority, system_program::ID, sol_to_lamports(10.0))
    .add_token_mint(mint, Some(authority), 0, 1, None)
    .add_associated_token_account(authority, mint, 1337)
    .clone_upgradable_program_from_cluster(client, my_program::ID)
    .build();

但是请注意,使用此构建器可能会构建出链上不合法的状态(例如,属于包含程序自身永远不会写入的状态的程序的所有者账户),导致只能在本地复现的漏洞。尽可能多地使用环境上的交易来防止这些陷阱。

依赖项

~88MB
~1.5M SLoC