Hackergame 2022 迫真跟风 Writeup

正如题所见,是为了跟风而写的迫真 Writeup。其实主要是因为我本周一直在摸鱼,所以没怎么做题,捂脸跑(

先上成绩:1000(Binary 550,Generl 400,Math 0,Web 50);排名 471 / 2747。没怎么参与嘛 所以不要打我 qwq

签到

URL Query result s/????/2022/ 即可。

猫咪问答喵

严防严控 Z 病毒扩散!

坏了喵,做整道题的时候脑子里都是永雏塔菲的声音喵

第五题:Google 这个 Key 即可。

第六题:先吐槽,为什么要去找一个 2003 年的文件((

思维方式:

  1. 先找到 网络通介绍 (2015 的),不对。

  2. 再搜 中国科学技术大学 网络通 20元 实行 (注意 实行 关键词),找到 关于实行新的网络费用分担办法的通知 (2010 的),不对。留意到页面最下面表格说 2003 的文件就实行 20 元了,于是还得找。

  3. "关于实行新的网络费用分担办法的通知" 2003 找到 关于实行新的网络费用分担办法的通知 (2003 的),这次对了。

再吐槽一下下,真是要找这个比我都老的红头文件啊啊(

家里的秘密

Flag1 是用 grep(1) 暴力搜到的:

% grep -rnw . -ie ".*flag{.*"
./.config/Code/User/History/2f23f721/DUGV.c:5:// flag{finding_everything_through_vscode_config_file_932rjdakd}

Flag2 不会做,不知道 rclone(1) 用的什么方式处理密码的(

传达不到的文件

是 A 宝推荐我做的,他说我肯定会做,但是我怎么那么没把握呢(

首先我进入这个虚拟机环境,看到一个 ---s--x--x 的二进制: /chall 以及一个 -r-------- 的文件: /flag2。我是 1000:1000 所以肯定读取不了。

于是我就 Google 了一下不能读的二进制是怎么跑的,StackOverflow 告诉我:读 ELF 发生在内核所以无视权限控制。嗯,学多。

之后就 ps -A 看了一下,发现 init 是个脚本:

% ps -A
  117 0         0:00 {rcS} /bin/sh /etc/init.d/rcS
  131 1000      0:00 /bin/sh
  132 1000      0:00 ps -A
% cat /etc/init.d/rcS
#! /bin/sh

mkdir -p /tmp
mount -t proc none /proc
mount -t sysfs none /sys
mount -t debugfs none /sys/kernel/debug
mount -t devtmpfs devtmpfs /dev
mount -t tmpfs none /tmp
mdev -s

echo 1 > /proc/sys/kernel/kptr_restrict
echo 1 > /proc/sys/kernel/dmesg_restrict
chmod 400 /proc/kallsyms

chown 0:0 /chall
chmod 04111 /chall

cat /dev/sda > /flag2
chown 1337:1337 /flag2
chmod 0400 /flag2

setsid /bin/cttyhack setuidgid 1000 /bin/sh

umount /proc
umount /tmp


poweroff -d 0  -f

很明显,我在的 sh 是用 setsid(1) 跑的,而 PID 1 是一个 root 跑的 sh(1)。似乎没什么漏洞,但我看到了 cttyhack(1)。很明显这是个不太寻常的二进制,于是我用 Base64 拖了下来打算研究一下。毕竟是 Binary 嘛,那很有可能得从这个文件下手(

拖呀 拖呀 拖 ….. 用 nc + base64 小水管传了好久好久,然后拿到一个 2.3MiB 的静态链接二进制。拖进 Ghidra 里,逆不动告辞(它甚至静态链接了 libc,我连 main 都找不到,呜呜(

那天是周四,见不会就从学校回家了。晚上做了会儿猫咪问答(没错,在这之前我就只签了个到,哈哈哈)。做完了才想起来跑 IDA 的 VM 开了。之后毫无悬念地把 cttyhack 拖进 IDA,毫无悬念地失败。

然后就又无聊地 nc 进虚拟机,然后 ….. 诶?!?!系统绝大多数文件(包括可执行文件)都是 777?

那岂不是好玩了呀(

想起之前 tgcn 广为流传的那篇《不要编辑运行中的 Bash 脚本》文章,我就想,或许能直接改 /etc/init.d/rcS 来让它在 sh(1) 退出后跑一个 root shell。结果失败了,我猜可能是那个 poweroff(1) 提前把机器关了?反正挺麻烦的。

然后我就看到了 poweroff(1)。它是一个到 busybox 的 symlink。如果能把它换成 sh(1) 不就拿到 root shell 了嘛。于是我就做了这样一个操作:

% rm /sbin/poweroff
% echo "#!/bin/sh" > /sbin/poweroff
% echo "sh" >> /sbin/poweroff
% chmod 777 /sbin/poweroff
% exit

然后 root shell 就出现在了我的面前((

于是我光速 cat flag2 并拿了分。

但是 flag1 怎么办呢 … 我思考了三分钟左右,我在想 /chall 是不是一个 Shell 脚本(后来想很明显不是,因为如果是的话,sh(1) 是需要在 Userspace 读取这个文件的,这很明显是不行的,因此它必定是一个二进制),于是就 cat(1) 了一下,然后 …

Flag 就出现在了二进制 strings 里面((

就这样做出来了,可谓是非预期解,买一赠一(

见 Flag 里说的 ptrace 什么,我是没思路(

就酱吧!以后有机会多多 ctf(