Hackergame 2024¶
约 397 个字 60 行代码 预计阅读时间 2 分钟
Abstract
中国科学技术大学第十一届信息安全大赛。
- 比赛链接:Hackergame 2024
- 比赛时间:2024 年 11 月 2 日 12:00 - 2024 年 11 月 9 日 12:00
- 成绩:总分数 5000,总排名 56 / 2460,浙江大学组内排名 6 / 44
本题解记录一些和大家不一样的解及个人比较喜欢的题目。
喜爱的题目¶
PowerfulShell¶
Bash 变量展开。
~ 展开为 /players,$[] 为 0,$- 为 hB,通过字符串切片可拼接出 sh。
__=~ # /players
___=$[] # 0
____=$- # hB
${__:7:1} # s
${____:___:1} # h
${__:7:1}${____:___:1} # sh
强大的正则表达式¶
构造 DFA 后状态消除算法转换为正则表达式。
优雅的不等式¶
构造积分
\[
\int_0^1 \frac{x^{2n} ( 1 - x^2 )^n (a + b x^2)}{1 + x^2} \mathrm{d}x,
\]
该积分的结果为 \(p\pi - q\) 形式,计算积分后解方程可得 \(a, b\)。需满足 \(a > 0\) 且 \(a + b > 0\),\(n\) 需足够大。观察到测试点对应的 \(n\) 单调不减,据此优化枚举。
不一样的解¶
猫咪问答 Q4 & Q6¶
枚举爆破。
旅行照片 Q5¶
其实截取图中建筑物进行 Google 识图可直接匹配到原建筑,为京张高铁北京北动车所。
不太分布式的软总线¶
D-Bus 通信题。
大家都是 C 写的,然而我一直配不好这里编译所需的 C 环境;这里使用了 Rust 实现。
Example
use std::ffi::CString;
use zbus::{Connection, Result, dbus_proxy};
use nix::unistd::{pipe, write};
use zbus::zvariant::Fd;
#[dbus_proxy(
interface = "cn.edu.ustc.lug.hack.FlagService",
default_path = "/cn/edu/ustc/lug/hack/FlagService"
)]
trait FlagService {
fn GetFlag1(&self, input: &str) -> Result<String>;
fn GetFlag2(&self, input: Fd) -> Result<String>;
fn GetFlag3(&self) -> Result<String>;
}
fn set_process_name(name: &str) {
let c_name = CString::new(name).unwrap();
unsafe {
libc::prctl(libc::PR_SET_NAME, c_name.as_ptr() as usize, 0, 0, 0);
}
}
#[tokio::main]
async fn main() -> Result<()> {
let connection = Connection::system().await?;
let proxy = FlagServiceProxy::new(&connection).await?;
// Flag 1
let flag1 = proxy.GetFlag1("Please give me flag1").await?;
println!("{flag1}");
// Flag 2
let (read_fd, write_fd) = pipe().expect("Failed to create pipe");
write(write_fd, b"Please give me flag2\n").expect("Failed to write to pipe");
nix::unistd::close(write_fd).expect("Failed to close write end of pipe");
let fd = Fd::from(read_fd);
let flag2 = proxy.GetFlag2(fd).await?;
println!("{flag2}");
// Flag 3
set_process_name("getflag3");
let flag3 = proxy.GetFlag3().await?;
println!("{flag3}");
Ok(())
}
禁止内卷¶
目录穿透任意文件写,由于开了 debug 所以 RCE 了。
比较非预期的地方是,不查看 answers.json,直接读取 /flag 文件。
prerun.py 中有 open("/flag") 逻辑,修改 app.py 在 flash 消息中输出 flag 内容即可。