From 911a6a197a64ffa05a986ea618fd34fd4ce20a91 Mon Sep 17 00:00:00 2001 From: petergu Date: Wed, 4 Nov 2020 23:27:53 +0800 Subject: [PATCH] roommates_disk: update --- official/一闪而过的 Flag/README.md | 5 +- official/室友的加密硬盘/README.md | 141 +++++++++++++++++++++++++++++ official/来自一教的图片/README.md | 12 ++- 3 files changed, 153 insertions(+), 5 deletions(-) diff --git a/official/一闪而过的 Flag/README.md b/official/一闪而过的 Flag/README.md index c4c1d3a..8de7748 100644 --- a/official/一闪而过的 Flag/README.md +++ b/official/一闪而过的 Flag/README.md @@ -1,7 +1,6 @@ # 一闪而过的 Flag -这道题怎么做应该不用说了,在开始菜单中查找 cmd 或者 powershell 并打开,再将 Untitled01.exe 拖进去,回车,结束,用过命令行就能做出来。其他 OS 用户可用虚拟机和 wine 。 +这道题怎么做应该不用多说了,在开始菜单中查找 cmd 或者 powershell 并打开,再将 Untitled01.exe 拖进去,回车,结束。用过命令行就应该能做出来。其他 OS 用户可用虚拟机和 wine 。唯一的坑可能是录屏不能解,因为 Windows 10 默认 cmd 和 powershell 字体中 1 和大写 I 几乎完全相同无法区分。 -本题非常简单但确实来自于生活中真实事件:想想多年以前,刚刚学 C 语言或是使用 Mathematica 注册机的时候,你是否也被这个问题困扰过呢? +本题非常简单但确实来自于生活中我多次遇到的真实事件:想想多年以前,刚刚学 C 语言~~或是使用 Mathematica 注册机~~的时候,你是否也被这个问题困扰过呢? -唯一的坑可能是录屏不能解,因为 Windows 10 默认 cmd 和 powershell 字体中 1 和大写 I 几乎完全相同无法区分。 \ No newline at end of file diff --git a/official/室友的加密硬盘/README.md b/official/室友的加密硬盘/README.md index aedc445..078bff3 100644 --- a/official/室友的加密硬盘/README.md +++ b/official/室友的加密硬盘/README.md @@ -1 +1,142 @@ # 室友的加密硬盘 + +### 先说出题人的预期解 + +文件根据说明是磁盘镜像,用 fdisk 查看基本情况,就假设文件叫 target 了: + +``` +$ fdisk -l target.img +Disk target.img: 1.91 GiB, 2048000000 bytes, 4000000 sectors +Units: sectors of 1 * 512 = 512 bytes +Sector size (logical/physical): 512 bytes / 512 bytes +I/O size (minimum/optimal): 512 bytes / 512 bytes +Disklabel type: dos +Disk identifier: 0xa4ee910b + +Device Boot Start End Sectors Size Id Type +target.img1 * 2048 391167 389120 190M 83 Linux +target.img2 393214 16775167 16381954 7.8G 5 Extended +target.img5 393216 1890303 1497088 731M 82 Linux swap / Solaris +target.img6 1892352 3891199 1998848 976M 83 Linux +target.img7 3893248 16775167 12881920 6.1G 83 Linux +``` + +确实是磁盘, MBR 分区表,一个主分区,和一些 Linux 扩展分区 。明显文件只有 2GB ,最后一个分区只截取了一点点。 + +用 dd 提取出单独的分区来: + +``` +$ dd if=target.img of=boot.img bs=512 count=389120 skip=2048 +``` + +``` +$ dd if=target.img of=swap.img bs=512 count=1497088 skip=393216 +``` + +``` +$ dd if=target.img of=chome.img bs=512 count=1998848 skip=1892352 +``` + +用 file 查看一下并尝试 mount ,看出主分区是 ext4 格式的 boot 分区; 976M 分区 LUKS 加密,应该是题目中描述的家目录所在分区; swap 内有 SWSUSP1 镜像,表示有休眠存在;最后一个 6.1GB 分区只能是根分区了,因为虽然磁盘只得到了一小部分,分区表仍然是正常的。 + +那么之后自然的思路是看看 boot 内有没有东西,毕竟有些不太注意安全的人是会图方便把 LUKS 的key 放在 boot 中以便开机输入密码的。于是: + +``` +$ sudo mount boot.img /mnt +$ cat /mnt/keyfile +I'm not that stupid to put plaintext key in /boot! +``` + +信不信由你,我是信了。 + +那怎么办呢? AES 又不能破解,那就只有 swap 和根分区有戏了。 + +根分区只有一点点,但也可以通过 testdisk 之类看看内容,或者 strings 一下... 要是有更多的非预期解那也算是 OK 了。 + +那就看 swap 吧,既然休眠,那估计整个内存 dump 都在里头了,那就找一下 AES key 吧 -- 这一步萌新出题人不太清楚做题的人能不能想到,出题灵感来源于 cold boot attack ,本想弄一个真实冷启动 dump 出的内存镜像,但鉴于能力和成本不够,就索性用休眠导致的 memory dump 了。 + +搜索在内存镜像中找 AES key 的方法,我找到了以下几个: + +- [findaes](https://sourceforge.net/projects/findaes/) ,可用; + +- [r2](https://github.com/radareorg/radare2) ,可用,似乎更好; +- [aeskeyfind](https://github.com/makomk/aeskeyfind) ,需要指定参数阈值,但也可以得到结果。 + +以 r2 为例: + +``` +$ r2 swap_orig.img + -- I endians swap. +[0x00000000]> /ca +Searching 1 byte in [0x0-0x2db00000] +hits: 12 +0x006529d8 hit0_0 d913145b01b203ca068e48d2f40b048639d8c6f4cfe93b22c3795945ca9d9e2a +0x00652b08 hit0_1 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +0x0737c9d8 hit0_2 37d7deb43c0223b8656dd6a862562a1a8360926278dc65f445eda2146844589f +0x0737cb08 hit0_3 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +0x0a18ca1a hit0_4 e4d58f63d629f38803da3c712c5a0cc2be774b9d925d136024a181315d91ac99 +0x0a18cc0e hit0_5 136ce9ce0d3f130ebe629570a08bc2ea883e451533875140027d1b3fdb5d0091 +0x0a32db50 hit0_6 31c69dff83847a6c3c3c091e4ff6113ca5799e1b63656f0bd51bd6490c20769c +0x0b1c873a hit0_7 fa01a98089a38f606c148694e7a3509aaccfc165068ed67f5715384b93e56aa6 +0x0b1c890d hit0_8 e4581675c3f947f7b537a3dd6098e4a5898b0a18c2b3b0f675c61de4106fc6a1 +0x0bd08b20 hit0_9 4c82f3493f9a3381f51c394ab8532bd037db64b793057aade3d6bf67cbebf933 +0x0d013349 hit0_10 fa01a98089a38f606c148694e7a3509aaccfc165068ed67f5715384b93e56aa6 +0x0d01351c hit0_11 e4581675c3f947f7b537a3dd6098e4a5898b0a18c2b3b0f675c61de4106fc6a1 +[0x00000000]> q +``` + +嗯,确实有不少的 key 。题目描述密钥是 512 位(这也是 LUKS 分区加密的默认密钥),于是找两个地址相连的 key ,合并起来,尝试作为 LUKS 的 master key 打开分区。注意相连要正反顺序都试一下(应该反向连接)! + +这里直接以最终的成功结果为示例了,首先把 key 写入文件: + +``` +$ echo e4581675c3f947f7b537a3dd6098e4a5898b0a18c2b3b0f675c61de4106fc6a1fa01a98089a38f606c148694e7a3509aaccfc165068ed67f5715384b93e56aa6 | xxd -r -p > key.txt +``` + +然后尝试用这个 keyfile 给 LUKS 镜像添加一个密码: + +``` +$ cryptsetup luksAddKey chome.img --master-key-file key.txt +Enter new passphrase for key slot: ( 此处随便输一个密码,比如1 ) +Verify passphrase: +``` + +成功,然后打开分区: + +``` +$ sudo cryptsetup luksOpen chome.img chome +Enter passphrase for chome.img: ( 此处输入刚才写的密码 ) +``` + +挂载并得到 flag : + +``` +$ sudo mount /dev/mapper/chome /mnt +$ cat /mnt/petergu/flag.txt +``` + +这里不慎透露了出题人信息,抱歉考虑不周。 + +其实,出题和解题过程完全参考了这两篇文章: + +``` +https://blog.appsecco.com/breaking-full-disk-encryption-from-a-memory-dump-5a868c4fc81e?gi=f61ce0646b62 +``` +``` +https://access.redhat.com/solutions/1543373 +``` + +注意,第一篇文章中一个有问题的地方是 LUKS 分区的大小和物理分区大小不同,所以用里面类似于 `echo "0 crypt aes-xts-plain64 0 4096" | sudo dmsetup create luks-volume` 的方法是不行的,并且其实具体的加密方式题目中也没有提到。你可以自己创建一个 LUKS 分区实验一下,对于题目,二者差了 4096 字节。而红帽文章中直接用 master key 添加 key slot 的方法不需要知道这些信息。但本人也不是专业人士,具体细节还要以正规渠道得到的信息为准。 + +如果你能够搜到这两篇文章,尤其是第一篇(其实还是比较容易搜到的),那应该可以解出这个题了。 + +本来还想把家目录也只截一半,然后解密之后用 testdisk 把 flag.txt 恢复出来,但好像这样也没有变得更难,就算了。 + +### 一个非预期解 + +不知是因为 LUKS 分区打开的时候本该如此,还是出题人操作不慎在分区创建的时候密码复制到了剪贴板上,密码本身明文在 swap 中出现了,所以 strings 一下然后逐个字符串尝试就可以求解。但感觉其实这样做出来也算是正常解法了。密码是什么就留作练习吧。 + +### 其他可能方法 + +本题目的制作方法是在虚拟机装装上 xubuntu ,休眠之后 dump 出磁盘的一部分。就算不知道这个过程,一个自然的想法是尝试恢复启动,在 Linux 启动至 initrd 时进行分析(libreliu的思路)。 + diff --git a/official/来自一教的图片/README.md b/official/来自一教的图片/README.md index d376cb3..e7fb61a 100644 --- a/official/来自一教的图片/README.md +++ b/official/来自一教的图片/README.md @@ -1,6 +1,6 @@ # 来自一教的图片 -对图像二维傅里叶变换就结束了。灵感来自于三级大学物理实验“傅里叶光学”。 +对图像二维傅里叶变换就结束了。灵感来自于中国科学技术大学三级大学物理实验“傅里叶光学”。 用 Python 的解法: @@ -26,5 +26,13 @@ plt.imshow(logf, 'gray') 题目中傅里叶光学是提示,文件名意思是 4F 成像系统中间,就对应物的傅里叶变换平面,也算是提示了,但或许对非物理专业的同学还是有点脑洞吧。 -为什么题目中说是模拟呢,因为题目中的图片取的是物傅里叶变换的实部,而一般实验能直接观测光强和相位分布,看电场实部或者虚部还真没听说过。这么做的原因是衍射(就是 FFT ,可见参考[ Matlab 官方文档](https://www.mathworks.com/help/matlab/math/two-dimensional-fft.html))光强分布不同地方差几个量级,如果这样存到图片里就损失了大量的信息。就算取了实部其实强度信息也基本损失完了,所以图片上除了黑点就是白点,几乎没有中间颜色,但因为实部包含了相位信息,所以仍能成功重构图像,因为[图像的细节信息其实在相位而不是强度中](https://people.eecs.berkeley.edu/~sastry/ee20/vision2/node6.html)。 +相关模拟可以参考[ Matlab 官方文档](https://www.mathworks.com/help/matlab/math/two-dimensional-fft.html)。 + +为什么题目中说是模拟呢,因为题目中的图片取的是物傅里叶变换的实部,而一般实验能直接观测光强(用 CCD )和相位分布(用 [SH波前探测器](https://www.thorlabs.com/newgrouppage9.cfm?objectgroup_id=5287)),看电场实部或者虚部还真没听说过。 + +这么做的原因是衍射光强分布不同地方差几个量级,如果这样存到图片里就损失了大量的信息。就算像本题这样取了实部,其实强度信息也基本损失完了,所以图片上除了黑点就是白点,几乎没有中间颜色。但因为实部包含了相位信息,所以仍能成功重构图像,因为[图像的细节信息其实在相位而不是强度中](https://people.eecs.berkeley.edu/~sastry/ee20/vision2/node6.html)。 + +另外,真实情况的零频率分量是在成像中间的,模拟中其实需要进行 fftshift 操作,鉴于这里的图像根本区分不出中间还是边上,就也省去了。 + +本人数理基础也并不扎实,所以具体物理细节还以权威参考资料为准。