2 个版本
0.1.1 | 2022 年 4 月 10 日 |
---|---|
0.1.0 | 2022 年 4 月 10 日 |
#87 in #smart
每月 70 下载
用于 sol-ctf-framework
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
,它为 ConfirmedTransaction
和 EncodedConfirmedTransaction
都实现了此特性。这个特性提供了 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_airdrop
和 airdrop
函数。
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