mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6
688 字
3 分钟
长城杯2025初赛wp

EzFlag#

这题居然是密码?难道不是逆向么?

拖到ida里面看一下main函数吧:

int __fastcall main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rax
__int64 v4; // rax
char v6[32]; // [rsp+0h] [rbp-50h] BYREF
int v7; // [rsp+2Ch] [rbp-24h]
char v8; // [rsp+33h] [rbp-1Dh]
int i; // [rsp+34h] [rbp-1Ch]
unsigned __int64 v10; // [rsp+38h] [rbp-18h]
std::string::basic_string(v6, argv, envp);
std::operator<<<std::char_traits<char>>(&_bss_start, "Enter password: ");
std::getline<char,std::char_traits<char>,std::allocator<char>>(&std::cin, v6);
if ( (unsigned __int8)std::operator!=<char>(v6, "V3ryStr0ngp@ssw0rd") )
{
v3 = std::operator<<<std::char_traits<char>>(&_bss_start, "Wrong password!");
std::ostream::operator<<(v3, &std::endl<char,std::char_traits<char>>);
}
else
{
std::operator<<<std::char_traits<char>>(&_bss_start, "flag{");
std::ostream::flush((std::ostream *)&_bss_start);
v10 = 1LL;
for ( i = 0; i <= 31; ++i )
{
v8 = f(v10);
std::operator<<<std::char_traits<char>>(&_bss_start, (unsigned int)v8);
std::ostream::flush((std::ostream *)&_bss_start);
if ( i == 7 || i == 12 || i == 17 || i == 22 )
{
std::operator<<<std::char_traits<char>>(&_bss_start, "-");
std::ostream::flush((std::ostream *)&_bss_start);
}
v10 *= 8LL;
v10 += i + 64;
v7 = 1;
}
v4 = std::operator<<<std::char_traits<char>>(&_bss_start, "}");
std::ostream::operator<<(v4, &std::endl<char,std::char_traits<char>>);
}
std::string::~string(v6);
return 0;
}

发现每进行输出flag的字符时,都会进行睡眠。

于是我一开始想把调用nanosleep的call给nop掉,结果打了好几个补丁发现还是会睡眠。

既然弄不干净那么就干脆直接逆向加密算法吧。

看看一些加密的函数:

__int64 __fastcall f(unsigned __int64 a1)
{
__int64 v2; // [rsp+10h] [rbp-20h]
unsigned __int64 i; // [rsp+18h] [rbp-18h]
__int64 v4; // [rsp+20h] [rbp-10h]
__int64 v5; // [rsp+28h] [rbp-8h]
v5 = 0LL;
v4 = 1LL;
for ( i = 0LL; i < a1; ++i )
{
v2 = v4;
v4 = ((_BYTE)v5 + (_BYTE)v4) & 0xF;
v5 = v2;
}
return *(unsigned __int8 *)std::string::operator[](&K, v5);
}

再寻找秘钥:

int __static_initialization_and_destruction_0(void)
{
char v1; // [rsp+7h] [rbp-19h] BYREF
char *v2; // [rsp+8h] [rbp-18h]
v2 = &v1;
std::string::basic_string(&K, "012ab9c3478d56ef", &v1);
std::__new_allocator<char>::~__new_allocator(&v1);
return __cxa_atexit((void (__fastcall *)(void *))&std::string::~string, &K, &_dso_handle);
}

发现密钥是:012ab9c3478d56ef

解题脚本#

MASK64 = (1 << 64) - 1
def f_u64(a1_u64: int, k: str) -> str:
n = a1_u64 % 24
v5 = 0
v4 = 1
for _ in range(n):
v2 = v4
v4 = ((v5 & 0xFF) + (v4 & 0xFF)) & 0xF
v5 = v2
return k[v5]
def solve():
K = "012ab9c3478d56ef"
v11 = 1
out = []
for i in range(32):
out.append(f_u64(v11, K))
if i in (7, 12, 17, 22):
out.append("-")
v11 = (v11 * 8 + i + 64) & MASK64
flag = "flag{" + "".join(out) + "}"
print(flag)
if __name__ == "__main__":
solve()

babyGame#

拖到ida瞎看一眼发现太复杂了,但是能识别出来是godot引擎开发的游戏。

于是使用GDRE进行解包,在scripts发现flag.gdc:

extends CenterContainer
@onready var flagTextEdit: Node = $PanelContainer / VBoxContainer / FlagTextEdit
@onready var label2: Node = $PanelContainer / VBoxContainer / Label2
static var key = "FanAglFanAglOoO!"
var data = ""
func _on_ready() -> void :
Flag.hide()
func get_key() -> String:
return key
func submit() -> void :
data = flagTextEdit.text
var aes = AESContext.new()
aes.start(AESContext.MODE_ECB_ENCRYPT, key.to_utf8_buffer())
var encrypted = aes.update(data.to_utf8_buffer())
aes.finish()
if encrypted.hex_encode() == "d458af702a680ae4d089ce32fc39945d":
label2.show()
else:
label2.hide()
func back() -> void :
get_tree().change_scene_to_file("res://scenes/menu.tscn")

发现是AES的ECB模式加密:

  • 密钥是:FanAglFanAglOoO!
  • 密文是:d458af702a680ae4d089ce32fc39945d

使用赛博厨子解密发现不对,重新读题,感觉和金币的数量有关系。

接着继续看解包文件,发现game_manager.gdc:

extends Node
@onready var fan = $"../Fan"
var score = 0
func add_point():
score += 1
if score == 1:
Flag.key = Flag.key.replace("A", "B")
fan.visible = true

发现当分数达到1时,密钥会变成 FBnFglFBnFglOoO!

于是将 FBnFglFBnFglOoO! 作为密钥重新解密,成功得到flag。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

长城杯2025初赛wp
https://chaojixin.ren/posts/长城杯2025初赛wp/
作者
超級の新人
发布于
2025-12-28
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

封面
Sample Song
Sample Artist
封面
Sample Song
Sample Artist
0:00 / 0:00