2020 BJDCTF WriteUp
主办方:由江苏科技大学、北京工业大学、西南民族大学、杭州师范大学、江苏大学、湖南工业大学、新疆大学七校联合举办。北京工业大学的官方信息也确认参与了本次赛事的组织
Misc
just a rar(RAR 爆破 + Hex 隐写)

rar的名字是四位数,那么密码应该也是四位数

WinHex 打开拿到 flag

你猜我是个啥(Hex 隐写)

WinHex 打开拿到 flag

藏藏藏(文件附加隐写)

010 看到文件中有 PK 头,推测还附加有压缩文件

使用 BinWalk 提取出来后有个名为 “福利.doc” 的文件,打开发现有个二维码

认真你就输了(文件附加隐写)

解压缩文件,给了一个 XLS 文件,打开该文件,发现是 PK 头

改为 .zip 后缀解压缩拿到 flag


签个到(文件后缀名欺骗)

下载压缩包解压报错,WinHex 打开发现是 PNG 文件头

改后缀为 PNG 是一张二维码,扫码得到 flag

一叶障目(PNG 宽高篡改)

改一下宽高就行

鸡你太美(文件头篡改)

WinHex 打开发现缺少了文件头

补充上去后换个方向就能看到 flag
1 | flag{zhi-yin-you-are-beautiful} |

Crypto
sign in(签到)

直接 Hex 转 ASCII 码即可

rsa_output(共模攻击)

1 | # 导入所需的函数:长整数转字节串、求最大公约数 |
Polybius(Polybius 方阵密码)

题目提示解码得到
1 | The length of this plaintext: 14 |
密文长度是 28,根据提示说明密文应该是两个字符表示一个明文字母
密文只由 5 个元音组成,5 个符号,两两组合,可以表示
1 | 5 * 5 = 25 |
这正好对应经典的 Polybius 方阵密码
Polybius 方阵常用 5x5 表编码 25 个字母,一般把 i/j 合并
1 | a b c d e |
我们可以直接爆破 5 个元音的排列
1 | import base64 |
编码与调制(曼彻斯特编码)

曼彻斯特编码的特点是每个原始 bit 会被编码成 2 个 bit,常见规则之一是
1 | 0 -> 01 |
或者相反
1 | 0 -> 10 |
先把十六进制密文转成二进制,再按照曼彻斯特规则还原得到
1 | BJD{DifManchestercode} |
rsa(共素数攻击)

题目源码
1 | from Crypto.Util.number import getPrime,bytes_to_long |
输出里一共有四个重要值
1 | 第一组: |
两组 RSA 生成过程
1 | p = getPrime(1024) |
两个模数共用了同一个素数 q
1 | n_1 = p_1 * q |
那么直接计算 gcd(n_1, n_2) 就能得到 q
1 | #!/usr/bin/env python3 |
base??(Base64 换表)

解题思路:
建立题目字符表
custom建立标准 Base64 字符表
standard对密文中每个字符
ch:找到
ch在custom表中的索引i替换成
standard[i]
得到正常 Base64 字符串
base64 解码
1 | import base64 |
EasyRSA(素数对称式泄露)

题目给出条件
1 | z = Fraction(1, Derivative(arctan(p), p)) - Fraction(1, Derivative(arth(q), q)) |
Derivative(arctan(p), p):求反正切函数对p的导数我们知道
d(arctan(p))/dp = 1 / (1 + p²)Fraction(1, ...):用 1 除以这个导数所以第一项变成:
1 / (1/(1+p²)) = 1 + p²第二项:
Derivative(arth(q), q),其中arth是反双曲正切函数它的导数是
d(arth(q))/dq = 1 / (1 - q²)再用 1 除以它,得到:
1 / (1/(1-q²)) = 1 - q²最后相减:
z = (1 + p²) - (1 - q²) = p² + q²
所以这行代码实际计算的是 z = p² + q²,又因为 n = pq
利用完全平方公式
1 | (p + q) ^ 2 = p ^ 2 + 2pq + q ^ 2 |
因此


令:
1 | s = p + q = sqrt(z + 2n) |
假设 p > q,则

1 | from math import isqrt |
Reverse
JustRe(签到)

反编译就能拿到 flag

EasyRe(隐藏函数)

IDA 反编译可以发现 main 函数并没有运行其他函数

在 PLT 表中发现一个 ques 函数

这段代码的本质是一个 ASCII 字符画打印程序
1 | int ques() |
用 Python 脚本还原
1 | # 硬编码的位图数据,每个值对应点阵的一行(50 位宽,5×10 像素) |
拿到 flag:BJD{HACKIT4FUN}

Web
Cookie is so subtle!(Twig 模板注入)

hint.php 的源码里有个提示如下,说明本题的关键在 Cookie
1 | <!-- Why not take a closer look at cookies? --> |
在 flag.php 中输入内容会回显出来,抓包发现传参位置在 Cookie 中,测试存在模板注入漏洞

经过测试这题是 Twig 的模板注入

Payload:{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("cat /flag")}}
_self:当前模板对象env:Twig 的环境管理器,负责管理过滤器registerUndefinedFilterCallback:告诉 Twig:”如果找不到某个过滤器,就调用我给你的函数”,这里给的函数是 PHP 的execgetFilter:尝试获取一个名字叫"cat /flag"的过滤器显然这个过滤器根本不存在,于是 Twig 就按照第一步设置的后备计划,调用
exec("cat /flag")
easy_search(信息泄露 + SSI RCE)

目录扫描出 index.php.swp,这是 Vim 编辑器留下的交换文件,属于源码泄露
源码内容如下
1 |
|
密码校验是 $admin == substr(md5($_POST['password']),0,6)
也就是需要找一个字符串,其加密后的前 6 个字符是 6d0bc1,可用的值如下
1 | 2020666 -> 6d0bc1153791aa2b4e18b4f344f26ab4 |
爆破脚本
1 | import hashlib |
源码会把 username 写入 <h1>Hello,'.$_POST['username'].'</h1> 并保存成 public/<随机hash>.shtml
.shtml 文件在开启 SSI 的 Web 服务器上会被服务端解析。Apache 官方文档说明,SSI 可以给 HTML 文档加入动态内容,通常通过 .shtml 后缀触发解析;其中 exec 指令可以运行 shell 命令并把输出包含到页面里
1 | <!--#exec cmd="ls" --> |
抓取登录包注入 Payload 发送后回显了一个路径

访问过去则是命令的回显

最后发现 flag 在当前 public 目录的上一级,文件名是 ../flag_990c66bf85a09c664f0b6741840499b2
