Move共学-TASK7完成 MoveCTF Check in挑战
需求
- 完成 CLI 调用学习
- 理解合约交互传值
- 完成 Move CTF Check In
- 必须用Sui CLI 调用完成
一、 MoveCTF介绍
CTF(Capture The Flag)中文一般叫夺旗赛,主要涉及以下活动: <!--StartFragment-->
1.1、网络安全技能实践
1.1.1. 漏洞挖掘与利用
- Web 安全漏洞挖掘:参赛选手需要对网站应用程序进行安全检测,寻找诸如 SQL 注入漏洞。例如,在一个存在 SQL 注入漏洞的登录页面中,选手通过构造恶意的 SQL 语句,尝试绕过登录验证。如果成功,就可能获取到网站后台的权限或者用户数据等敏感信息,这就像是在虚拟的网络战场上找到了对手的一个弱点并成功突破。
- 二进制漏洞挖掘:对于二进制文件(如可执行程序),要寻找缓冲区溢出、格式化字符串漏洞等。以缓冲区溢出为例,当程序没有对输入数据的长度进行合理限制时,攻击者可以输入超出缓冲区容量的数据,从而覆盖程序的其他关键数据区域,如函数返回地址,使程序执行流程被攻击者控制。
- 系统漏洞挖掘:包括操作系统(如 Linux、Windows)漏洞。例如,某些旧版本操作系统存在未修复的本地权限提升漏洞,选手需要通过分析系统调用、内核模块等,找到可以利用的漏洞路径,从而获取更高的系统权限。
1.1.2. 密码学破解与应用
- 密码分析:CTF 中会出现各种加密方式,如古典密码(凯撒密码、维吉尼亚密码等)和现代密码(RSA、AES 等)。参赛选手需要了解加密算法的原理,通过分析密文的特征、频率等信息来破解密码。例如,对于简单的凯撒密码,由于它是一种单字母替换密码,通过统计密文中字母出现的频率,与正常文本中字母频率(如在英文中字母 e 出现的频率最高)进行对比,就可以尝试破解出密钥。
- 密码算法实现与应用:除了破解密码,选手还需要能够正确地实现密码算法。在安全通信场景的题目中,要求选手利用密码学知识建立安全的通信信道,例如使用 SSL/TLS 协议相关知识来保障网络通信的保密性和完整性。
1.1.3. 逆向工程
- 软件逆向分析:对给定的二进制文件或恶意软件进行逆向,理解其功能和算法。例如,通过反汇编工具(如 IDA Pro)将二进制文件转换为汇编语言代码,然后分析程序的控制流和数据结构,找出程序隐藏的功能,如软件注册验证机制、隐藏的配置信息等。
- 恶意软件分析:当面对一个恶意软件样本时,选手需要分析其传播方式、感染目标、恶意行为(如窃取数据、发起 DDoS 攻击等)。通过逆向工程技术,还原恶意软件的代码逻辑,找到其控制服务器的地址、加密密钥等关键信息,从而为防范和清除恶意软件提供依据。
<!--EndFragment-->
<!--StartFragment-->
1.2、安全知识竞赛与解题
1.2.1. 安全知识问答
- CTF 比赛中会有一些关于网络安全法律法规、安全标准(如 ISO 27001)、安全漏洞分类(如 OWASP Top 10)等知识的题目。选手需要具备扎实的安全知识基础,能够准确回答这些问题。例如,题目可能会问 “根据 OWASP Top 10,2023 年最常见的 Web 安全漏洞是哪一个?” 选手需要熟悉 OWASP 的最新报告内容来作答。
1.2.2. 安全工具使用与开发
- 工具使用:熟练掌握各种网络安全工具是 CTF 的重要内容。如网络扫描工具(Nmap)用于发现网络中的主机和开放端口;漏洞扫描工具(如 Nessus)用于检测目标系统的安全漏洞;密码破解工具(如 John the Ripper)用于破解简单密码等。选手需要知道如何正确配置和使用这些工具来获取有用的信息。
- 工具开发:在一些高级别的 CTF 比赛中,还会要求选手开发安全工具或脚本来解决特定的问题。例如,开发一个自动化的 Web 漏洞扫描脚本,能够快速检测网站是否存在常见的漏洞。
1.2.3. 安全攻防场景模拟
- 攻击场景:模拟真实的网络攻击场景,如模拟黑客攻击企业网络,包括突破防火墙、入侵内部网络、获取敏感数据等一系列过程。选手需要运用多种攻击技术和策略,如利用防火墙规则漏洞、通过社会工程学获取内部网络信息等,完成攻击任务。
- 防御场景:也会有防御模拟场景,要求选手构建安全的网络架构,部署安全防护设备(如入侵检测系统、防病毒软件等),并制定安全策略来抵御攻击。例如,在面对 DDoS 攻击模拟场景时,选手需要正确配置流量清洗设备,调整防火墙规则,以保障网络服务的正常运行。
<!--EndFragment-->
二、任务指南
<!--StartFragment-->
- 目标网络: 测试网(testnet)
- 合约部署地址:
0x914099b4d1b4f5513acc8aaa4fdc1f67578522b81d818f61bae527d590c6d87d
- FlagStr Object:
0xc8dcd54baa7724177593a9f70598a09ae6a4286f996542e058f248209db08147
- random:
0x8
- github id: 填写自己的github id <!--EndFragment-->
2.1 check_in源码分析
module check_in::check_in {
use std::ascii::{String, string};
use std::bcs;
use std::hash::sha3_256;
use std::vector;
use sui::event;
use sui::object;
use sui::random;
use sui::random::Random;
use sui::transfer::share_object;
use sui::tx_context::{Self, TxContext};
const ESTRING: u64 = 0;
public struct Flag has copy, drop {
sender: address,
flag: bool,
ture_num: u64,
github_id: String
}
public struct FlagString has key {
id: UID,
str: String,
ture_num: u64
}
fun init(ctx: &mut TxContext) {
let flag_str = FlagString {
id: object::new(ctx),
str: string(b"LetsMoveCTF"),
ture_num: 0
};
share_object(flag_str);
}
entry fun get_flag(
flag: vector<u8>,
github_id: String,
flag_str: &mut FlagString,
rand: &Random,
ctx: &mut TxContext
) {
// 定义一个可变的字节向量
let mut bcs_flag = bcs::to_bytes(&flag_str.str);
// 将GitHub ID对应的字节追加到bcs_flag字节向量后面
vector::append<u8>(&mut bcs_flag, *github_id.as_bytes());
// 验证传入的标志(flag)与 bcs_flag是否一致
assert!(flag == sha3_256(bcs_flag), ESTRING);
// 调用getRandomString函数,获取一个随机字符串
// 更新FlagString结构体中的str字段,替换原来的字符串内容
flag_str.str = getRandomString(rand, ctx);
// 将FlagString结构体中的ture_num字段值加1
flag_str.ture_num = flag_str.ture_num + 1;
// 触发一个事件(event)
// 更新后的ture_num值以及传入的GitHub ID等信息
event::emit(Flag {
sender: tx_context::sender(ctx),
flag: true,
ture_num: flag_str.ture_num,
github_id
});
}
fun getRandomString(rand: &Random, ctx: &mut TxContext): String {
let mut gen = random::new_generator(rand, ctx);
let mut str_len = random::generate_u8_in_range(&mut gen, 4, 30);
let mut rand: vector<u8> = b"";
while (str_len != 0) {
let rand_num = random::generate_u8_in_range(&mut gen, 34, 126);
vector::push_back(&mut rand, rand_num);
str_len = str_len - 1;
};
string(rand)
}
}
get_flag函数主要逻辑是,利用 assert!
宏进行验证,将传入的 flag
(以字节向量形式表示的外部传入的标志数据)与对构造好的 bcs_flag
数据进行 sha3_256
哈希计算后的结果做比较。如果两者不相等,则会触发错误(错误码由常量 ESTRING
表示),意味着标志验证失败;若相等,则说明传入的标志符合预期,验证通过,继续后续逻辑。
2.2 利用CLI获取flag_str.str
获取flag_str.str可以直接用Sui cli命令直接获取,下面截图仅供参考,我当时任务返回的str是“\T2R” sui client object 0xc8dcd54baa7724177593a9f70598a09ae6a4286f996542e058f248209db08147
注意:这里需要注意sui里面一些特殊转义符,可能导致Hash计算的结果不正确。
2.3 计算flag标志字符串
将flag_str和GitHubID进行哈希计算后的字符串
#[test_only]
module check_in::check_in_tests {
use std::debug;
use std::vector;
use std::bcs;
use std::hash::sha3_256;
use std::ascii::{String, string};
// uncomment this line to import the module
// use check_in::check_in;
const ENotImplemented: u64 = 0;
const ESTRING: u64 = 0;
#[test]
fun test_check_in() {
// pass
let flag_str= string(b"\\T2R");
let github_id = string(b"LeonDev1024");
let mut bcs_flag = bcs::to_bytes(&flag_str);
vector::append<u8>(&mut bcs_flag, *github_id.as_bytes());
debug::print(&sha3_256(bcs_flag));
//assert!(flag == sha3_256(bcs_flag), ESTRING);
}
}
运行单元测试sui move test --skip-fetch-latest-git-deps
2.4 验证标志正确性
用CLI调用get_flag方法进行验证
三、总结
这是一个简单的 CTF(Capture The Flag) 挑战,玩家需要通过验证给定的标志(flag)来获取一个新的标志,并触发事件。 通过CTF 题目我们了解了如何通过验证和生成哈希,成功获取新的标志,并通过智能合约与区块链互动。
对于单测和CLI常用命令可以参考: <!--StartFragment-->
Sui Move 调试Debugging和test_scenario单测工具使用 Sui move单测从入门到精通 Sui CLI常用指令介绍 Sui Client CLI 命令行详解
<!--EndFragment-->
四、官方资源
- Sui 官方文档:Sui 的官方网站提供了全面且权威的文档,涵盖了 Sui 区块链的基本概念、架构、Move 语言的语法、特性,以及在 Sui 上开发智能合约的详细指南等内容,这是深入理解 Sui Move 的基础资料,网址为<https://docs.sui.io/> 。
- MoveCTF 2024 官方网站:由 MoveBit 主办、Sui 独家赞助的 MoveCTF 2024 竞赛网站,提供了竞赛的具体信息、规则、题目示例等,可通过<https://movectf2024.movebit.xyz/>访问
<!--StartFragment-->
关注《HOH水分子》公众号,我们将持续分享和制作变成语言教程,让大家对编程产生化学反应。
<!--EndFragment-->
版权声明
本文仅代表作者观点,不代表区块链技术网立场。
本文系作者授权本站发表,未经许可,不得转载。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。