BaseCTF [Week3]
Misc
[Week3] 白丝上的flag
BaseCTF{there_is_the_flag@}
用Stegsolve打开在Red plane 0 能看到flag
[Week3] 纯鹿人
BaseCTF{d176adc7-5919-4a0c-9556-0301fc4d9c35}
图片后面有隐藏字符,全选改下字体和颜色就能显示,是一串base64编码
解码获得:password:ikunikun
这是一串密码肯定有用的到的地方
用010打开文档中的图片,发现藏有压缩包,提取出来,
压缩包需要密码,前面拿到的密码就派上用场了,打开txt获得flag
[Week3] broken.mp4
BaseCTF{x1a_Ci_1_DIn9_y0Ng_MKV}
签到题,跟着第一个视频指引关注公众号找到文章下载程序修复视频
[Week3] 我要吃火腿!
BaseCTF{SSTV_Happpy!}
打开文件看到一大堆嗷呜,猜测是兽音加密,解密获得一段加密脚本,将图片的字节进行异或操作,将图片再进行一次操作就能还原
def xor_with_ham(input_file, output_file):
ham_bytes = [0x48, 0x61, 0x6D]
with open(input_file, 'rb') as f:
data = bytearray(f.read())
for i in range(len(data)):
data[i] ^= ham_bytes[i % 3]
with open(output_file, 'wb') as f:
f.write(data)
xor_with_ham('Hamorl.jpg', 'Ham.jpg')
将还原后的图片用010打开,发现图片藏有东西,在kali中分离
分离获得了一个音频,听声音怀疑是SSTV,用虚拟声卡排除干扰,运行软件获得flag
Crypto
[Week3] exgcd
BaseCTF{feb7e1ae-a8f7-4fc4-8d6d-945a45cc3f6d}
from Crypto.Util.number import *
import libnum
import gmpy2
flag=b'BaseCTF{}'
m=bytes_to_long(flag)
p=getPrime(1024)
q=getPrime(1024)
n=p*q
e1=3747
e2=2991
c1=pow(m,e1,n)
c2=pow(m,e2,n)
print("n =",n)
print("e1 =",e1)
print("e2 =",e2)
print("c1 =",c1)
print("c2 =",c2)
分析源码看到两个e以及两个c,尝试用共模攻击的脚本解题,发现解不出,原因是用正常脚本计算出来的m为km
发现gcd(e1,e2)=3,e1,e2不互质,所以,需要对e进行爆破的同时,需要对m^k进行判别
exp
from Crypto.Util.number import *
import libnum
import gmpy2
n =
e1 = 3747
e2 = 2991
c1 =
c2 =
e1e2=e1*e2
def rsa_gong_N_def(e1, e2, c1, c2, n): # 共模攻击函数
e1, e2, c1, c2, n = int(e1), int(e2), int(c1), int(c2), int(n)
s = gmpy2.gcdext(e1, e2)
s1 = s[1]
s2 = s[2]
if s1 < 0:
s1 = - s1
c1 = gmpy2.invert(c1, n)
elif s2 < 0:
s2 = - s2
c2 = gmpy2.invert(c2, n)
m = (pow(c1, s1, n) * pow(c2, s2, n)) % n
return int(m)
def de(c, e, n): # 因为此时的m不是真正的m,而是m^k,所以对m^k进行爆破
k = 0
while k < 1000: # 指定k小于1000
mk = c + n * k
flag, true1 = gmpy2.iroot(mk, e) # 返回的第一个数值为开方数,第二个数值为布尔型
if True == true1:
return flag
k += 1
for e1 in range(2, e1e2):
if e1e2 % e1 == 0: # 爆破可整除的e
e2 = e1e2 // e1
c = rsa_gong_N_def(e1, e2, c1, c2, n)
e = gmpy2.gcd(e1, e2)
m1 = de(c, e, n)
if m1:
flag = libnum.n2s(int(m1))
if b"CTF" in flag:
print(flag)
参考来源:http://t.csdnimg.cn/Q4JZ6
[Week3] ez_log
BaseCTF{BF3DCONZ-67FE-ENZU-385S-CSNI13B2}
from Crypto.Util.number import bytes_to_long as b2l, long_to_bytes as l2b, getPrime
from Crypto.Cipher import AES
from random import randint
flag = b"flag{test_flag}"
pad = lambda x: x+b'\x00'*(16-len(x)%16)
def encrypt(KEY):
cipher= AES.new(KEY,AES.MODE_ECB)
encrypted =cipher.encrypt(flag)
return encrypted
def decrypt(KEY):
cipher= AES.new(KEY,AES.MODE_ECB)
decrypted =cipher.decrypt(enc)
return decrypted
flag = pad(flag)
x = randint(10 ** 7, 10 ** 8)
y = randint(10 ** 7, 10 ** 8)
n = getPrime(28)
z = pow(y, x, n)
enc = encrypt(pad(l2b(x)))
print(f'enc = {b2l(enc)}')
print(f'y = {y}')
print(f'n = {n}')
print(f'z = {z}')
分析源码:
pad = lambda x: x+b'\x00'*(16-len(x)%16)
对字符串进行分析,是否满足16的倍数,未满足的进行补齐
encrypt是加密函数,KEY是随机生成的x
x的随机范围不大,可以进行爆破
exp
from Crypto.Util.number import bytes_to_long as b2l, long_to_bytes as l2b, getPrime
from Crypto.Cipher import AES
from random import randint
enc =
enc = l2b(enc)
y = 82941012
n = 228338567
z = 51306718
pad = lambda x: x+b'\x00'*(16-len(x)%16)
def decrypt(KEY):
cipher= AES.new(KEY,AES.MODE_ECB)
decrypted =cipher.decrypt(enc)
return decrypted
for x in range(10**7, 10**8):
flag1=decrypt(pad(l2b(x)))
if b"CTF{" in flag1:
print(flag1)
print(x)
break
官方WP
from sage.all import *
from Crypto.Cipher import AES
from Crypto.Util.number import bytes_to_long as b2l, long_to_bytes as l2b
pad = lambda x: x+b'\x00'*(16-len(x)%16)
def decrypt(KEY):
cipher= AES.new(KEY,AES.MODE_ECB)
decrypted =cipher.decrypt(enc)
return decrypted
enc = 33416570913716503492297352041317858420349510954381249751537743898024527101872454706181188441210166165803904185550746
y = 82941012
n = 228338567
z = 51306718
# 离散对数
enc = l2b(enc)
G = GF(n)
z = G(z)
y = G(y)
x = discrete_log(z, y)
print(decrypt(pad(l2b(x))))
# BaseCTF{BF3DCONZ-67FE-ENZU-385S-CSNI13B2}
[Week3] 没有n啊
BaseCTF{2eefa8ef-ba57-4bed-9230-d280ac2273d8}
from Crypto.Util.number import *
import gmpy2
import random
flag=b'BaseCTF{}'
m=bytes_to_long(flag)
p=getPrime(512)
q=getPrime(512)
n=p*q
e=65537
phi=(p-1)*(q-1)
d=gmpy2.invert(e,phi)
c=pow(m,e,n)
x=pow(n,e,c)
print("c =",c)
print("e =",e)
print("d =",d)
print("x =",x)
$$ n=c+a\\ x=n^e\quad mod(c)\\ 二项式定理:x=a^e\quad mod(c)\\ e*d_c=1\quad mod(\phi(c))\\ x^{d_c}=a^{e*d_c}=a\quad mod(c) $$
可用yafu或者factordb分解c
exp
from Crypto.Util.number import *
import gmpy2
import random
c =
e =
d =
x =
p=
q=
r3=
r4=
r5=
r6=
r7=
r8=
r9=
phi=(p-1)*(q-1)*(r3-1)*(r4-1)*(r5-1)*(r6-1)*(r7-1)*(r8-1)*(r9-1)
d1=gmpy2.invert(e,phi)
a = pow(x,d1,c)
m = pow(c,d,c+a)
print(long_to_bytes(m))
Reverse
[Week3] 世界上最简单的题目
BaseCTF{easyvmvmvm}
a1 =[1 ,1 ,1 ,3 ,1 ,1 ,1 ,3 ,1 ,1 ,1 ,3 ,1 ,1 ,3 ,1 ,1 ,3 ,1 ,1 ,3 ,1 ,3 ,1 ,3 ,1 ,3 ]
f1 =[101 ,102 ,117 ,120 ,119 ,108 ,102 ,124 ,100 ,109 ]
def o1 ():
return input ("please input your flag: ")
def p1 (O0O0OOOOO00OOOOO0 ):
return list (O0O0OOOOO00OOOOO0 )
def main ():
num =o1 ()
num1 =1
num2 =0
if len (num )!=len (f1 ):
print ("Input length does not match.")
exit ()
list1 =p1 (num )
print (list1)
for i in range (len (a1 )):
if a1 [i]==1 :
list1 [num2]=chr (ord (list1 [num2 ])^num1 )
num1 +=1
elif a1 [i]==3 :
num2 +=1
for x in range (len (f1 )):
if f1 [x ]!=ord (list1 [x ]):
print ("nooooo")
exit ()
print ("yes, your flag is")
print ("BaseCTF{"+''.join (num )+"}")
if __name__ =="__main__":
main ()
分析源码,就是遍历a1,根据a1的值进行异或操作。
exp
#将f1转成字符串
i="efuxwlf|dm"
a1 =[1 ,1 ,1 ,3 ,1 ,1 ,1 ,3 ,1 ,1 ,1 ,3 ,1 ,1 ,3 ,1 ,1 ,3 ,1 ,1 ,3 ,1 ,3 ,1 ,3 ,1 ,3 ]
num1=1
list1=list(i)
num2=0
for i in range(len(a1)): # line:50
if a1[i] == 1: # line:51
list1[num2] = chr(ord(list1[num2]) ^ num1) # line:57
num1 += 1 # line:58
elif a1[i] == 3: # line:59
num2 += 1 # line:60
for x in list1:
print(x,end="")
[Week3] 出题人已疯
BaseCTF{y0u_KnOw_UTF16_6uT_U_r_n0t_Cr@zym@n}
用查壳工具可用看到是.NET程序,用ILSpy打开查看源代码
将用户输入的字符串分成字符数组进行遍历,将对应的ASCII码值平方,然后进行异或操作
char[] array = Tb_Input.Text.ToCharArray();
char[] array2 = string.Join("", sentences).ToCharArray();
for (int i = 0; i < array.Length; i++)
{
array[i] *= array[i];
array[i] = (char)(array[i] ^ i ^ array2[i % array2.Length]);
}
判断加密后的字符串是否和source相等,不相等就输出\ud83d\ude2d我有异或症!
if (new string(array) != new string(source.Select((uint c) => (char)c).ToArray()))
{
MessageBox.Show("\ud83d\ude2d我有异或症!");
}
else
{
MessageBox.Show("\ud83d\ude0b异或症好了!");
}
要获得flag,我们只要将source进行异或操作,再进行开平方
exp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HelloWorldApplication
{
class HelloWorld
{
static void Main(string[] args)
{
string[] sentences = new string[5] { '太长了自己复制(○` 3′○)' };
uint[] source = new uint[44]
{
24164u, 27173u, 32145u, 17867u, 40533u, 21647u, 17418u, 30032u, 27950u, 62998u,
60750u, 64870u, 52680u, 61797u, 49234u, 59762u, 16704u, 19200u, 32132u, 24038u,
21764u, 30130u, 28113u, 23070u, 27413u, 27917u, 28938u, 50207u, 64834u, 60132u,
64832u, 63334u, 55103u, 22176u, 21991u, 20073u, 22281u, 19476u, 28302u, 24336u,
24720u, 19544u, 23018u, 43976u
};
char[] array = new string(source.Select((uint c) => (char)c).ToArray()).ToCharArray();
char[] array2 = string.Join("", sentences).ToCharArray();
for (int i = 0; i < array.Length; i++)
{
array[i] = (char)(array[i] ^ i ^ array2[i % array2.Length]);
array[i] = (char)Math.Sqrt(array[i]);
}
Console.WriteLine(new string(array));
}
}
}
运行结果:
PPC
[Week3] BaseCTF 崩啦 - 导言
BaseCTF{29a86c3b-8477-4deb-b089-989d0321a007}
打开readme.txt文件就能看到
悲报~ BaseCTF 崩溃啦!
7w 条提交记录, 服务器顶不住计算排行榜的压力, 崩溃啦!
Kengwang 拼尽全力抢救下来了数据和日志, 他悬赏了几个 Flag, 找到人能够对这些数据进行处理.
你说的对,但是《BaseCTF》是由高校联合举办的一场 CTF 新生赛。比赛开展在一个被称作「Base::CTF」的平台,在这里,被选中的人将被授予「Flag」,导引 Hacker 之力。你将扮演一位名为「GZCTF」的神秘角色,在繁多的提交中找到姓名各异、能力独特的队伍,和他们一起检查 Flag,找回丢失的排行榜——同时,逐步发掘「BaseCTF」的真相。
附件包含几个文件
- teams.json 存储了参赛队伍的信息,
Name
为队伍名称,Members
存储了队伍选手信息 - challenges.json 存储了题目信息,
Points
为题目分数,EndAt
为截止提交时间 - flags.json 存储了 Flag 信息,
TeamId
为队伍 ID,ChallengeId
为题目 ID,Flag
为他们正确的 Flag 内容
submissions.log
为提交的日志记录, 预期的格式为:
"[时间 INF] FlagChecker: 队伍 [队伍名] 提交题目 [题目] 的答案 [Flag] <用户名> @ IP"
你需要解析以上信息, 完成之后题目的要求
BaseCTF{29a86c3b-8477-4deb-b089-989d0321a007}
[Week3] BaseCTF 崩啦 II - 过期了?
BaseCTF{f577e4522ccba9ed07727212657f139e}
队伍ID:5f2ceeda-80a5-9664-7b51-e3be1e1f8147
利用脚本将超时提交的记录提取出来
[2024/8/31 20:28:55 +08:00 INF] 提交题目 [[Week1] 你也喜欢圣物吗]
[2024/8/31 16:09:34 +08:00 INF] 提交题目 [[Week1] UPX mini]
[2024/8/31 18:07:48 +08:00 INF] 提交题目 [[Week2] Ezpy]
[2024/8/31 23:33:54 +08:00 INF] 提交题目 [[Week2] Aura 酱的旅行日记 VI <图寻擂台>]
[2024/8/31 17:38:58 +08:00 INF] 提交题目 [[Week3] wiener?]
[2024/8/31 18:30:22 +08:00 INF] 提交题目 [[Week2] 一起吃豆豆]
exp
import re
import time
log=open("submissions.log","r",encoding='utf-8').read().splitlines()
time1=time.mktime(time.strptime("2024-08-31 15:00:00", "%Y-%m-%d %H:%M:%S"))
for i in log:
if "Damien Schroeder" in i:
time_str = re.findall(r'(?<=\[).+?(?= \+08:00 INF])', i)[0]
dt = time.strptime(time_str, "%Y/%m/%d %H:%M:%S")
time2=time.mktime(dt)
if time2>=time1:
print(i)
按照时间顺序排列
[2024/8/31 16:09:34 +08:00 INF] 提交题目 [[Week1] UPX mini]
[2024/8/31 17:38:58 +08:00 INF] 提交题目 [[Week3] wiener?]
[2024/8/31 18:07:48 +08:00 INF] 提交题目 [[Week2] Ezpy]
[2024/8/31 18:30:22 +08:00 INF] 提交题目 [[Week2] 一起吃豆豆]
[2024/8/31 20:28:55 +08:00 INF] 提交题目 [[Week1] 你也喜欢圣物吗]
[2024/8/31 23:33:54 +08:00 INF] 提交题目 [[Week2] Aura 酱的旅行日记 VI <图寻擂台>]
将对应ID用西文逗号隔开,取其md5值就是flag