目录
FunZip
Magic_Keyboard
Number_is_the_key
RSA_KU
成语学习
钢铁侠在解密
工业互联网模拟仿真数据分析
精装四合一
时间刺客
有人让我给你带个话
FunZip
题目给了一个txt,内容如下
一眼丁真,base隐写,使用工具即可得到flag
Flag:ISCC{ttR3PVFgurn6}
Magic_Keyboard
题⽬给了⼀段⾳频,是敲键盘的声⾳,需要知道敲的是什么键。
类似题:2021年pbctf有个题⽬叫 Ghost Writer ,跟这个题⽬类似,⽹上可以找到这个题⽬的wp
https://github.com/apoirrier/CTFs-writeups/blob/master/PBCTF2021/Misc/GhostWriter.md使⽤了GitHub上的⼀个项⽬acoustic_keylogger 。
它可以统计出哪⼏次按键是按的同⼀个键。使⽤该脚本跑出来以 abcdadadef 开头的⼀串字符,这刚好对应 ISCC{ 的⼗六进制“495343437b”,最后两个字符⼀定对应的是 } 的⼗六进制“7d”,其他的字符就需要反复的推敲。{}内部全都是⼩写字⺟和_ ,所以最终还是很容易推出⼀张映射表的。注意{}内是正常的英文句子。
{"a":4,"b":9,"c":5,"d":3,"e":7,"f":"b","m":"d","g":6,"h":8,"i":"f","j":1,"k":2,"l":"c","n":"e"}
EXP:
from sklearn.preprocessing import MinMaxScaler
from librosa.feature import mfcc
import numpy as np
from scipy.io import wavfile as wav
def wav_read(filepath):
sample_rate, data = wav.read(filepath)
if type(data[0]) == np.ndarray:
return data[:, 0]
else:
return data
def detect_keystrokes(sound_data, sample_rate=44100):
threshold = 5000
keystroke_duration = 0.3
len_sample = int(sample_rate * keystroke_duration)
keystrokes = []
i = 0
while i < len(sound_data):
if abs(sound_data[i]) > threshold:
a, b = i, i + len_sample
if b > len(sound_data):
b = len(sound_data)
while abs(sound_data[b]) > threshold and b > a:
b -= 1
keystroke = sound_data[a:b]
trailing_zeros = np.array([0 for _ in range(len_sample - (b - a))])
keystroke = np.concatenate((keystroke, trailing_zeros))
keystrokes.append(keystroke)
i = b - 1
i += 1
return np.array(keystrokes)
def extract_features(keystroke, sr=44100, n_mfcc=16, n_fft=441, hop_len=110):
spec = mfcc(y=keystroke.astype(float), sr=sr, n_mfcc=n_mfcc, n_fft=n_fft, hop_length=hop_len)
return spec.flatten()
data = wav_read("attachment-45.wav")
keystrokes = detect_keystrokes(data)
X = [extract_features(x) for x in keystrokes]
X_norm = MinMaxScaler().fit_transform(X)
letters = {}
phrase = []
current_letter = ord('a')
for x in X_norm:
if x[0] not in letters:
letters[x[0]] = current_letter
current_letter += 1
phrase.append(letters[x[0]])
mappings = {}
flag=("".join(mappings.get(char, char) for char in "".join([chr(x) for x in phrase])))
print(flag)
flag1=""
dict1={"a":4,"b":9,"c":5,"d":3,"e":7,"f":"b","m":"d","g":6,"h":8,"i":"f","j":1,"k":2,"l":"c","n":"e"}
for i in range(0,len(flag)):
if flag[i] in dict1:
flag1+=str(dict1[flag[i]])
else:
flag1+="_"
print(flag1)
运行后得到一串16进制字符
495343437b68655f7761735f61626c655f68756d616e7d
解密后得到flag:ISCC{he_was_able_human}
Number_is_the_key
仔细观察后发现excel部分单元格被进行了加粗处理
将被加粗部分涂黑即可得到一个二维码
手机扫码后即可得到flag
ISCC{rKmjyi1HRnqd}
RSA_KU
Info:
n = 129699330328568350681562198986490514508637584957167129897472522138320202321246467459276731970410463464391857177528123417751603910462751346700627325019668100946205876629688057506460903842119543114630198205843883677412125928979399310306206497958051030594098963939139480261500434508726394139839879752553022623977
e = 65537
c = 128078960193140808683559118633217600879940998817909568182141311537800867512690722368075522141556996276359237558158477733024825996070234180820860244607694198815376269550287105459194572190573383166386710828931679858562777866446477175529580658436251900048546779677845065373412279418363747278489630829416405841200
#(p-2)*(q-1) = 129699330328568350681562198986490514508637584957167129897472522138320202321246467459276731970410463464391857177528123417751603910462751346700627325019668067056973833292274532016607871906443481233958300928276492550916101187841666991944275728863657788124666879987399045804435273107746626297122522298113586003834
#(p-1)*(q-2) = 129699330328568350681562198986490514508637584957167129897472522138320202321246467459276731970410463464391857177528123417751603910462751346700627325019668066482326285878341068180156082719320570801770055174426452966817548862938770659420487687194933539128855877517847711670959794869291907075654200433400668220458
exp:(轩禹秒了)
成语学习
首先打开流量包,过滤http协议,发现上传了一张图片
将图片导出后修改宽高后得到key
key:57pmYyWt
然后用key作为密码去解压压缩包,解压出来的内容为something_copy103。后面加上.zip后缀,解压后发现O7avZhikgKgbF这个文件夹下面有flag文件,内容如下:
《你信我啊》
李维斯特指着墙上的“功成不居”边享用onion边和你说,你千万不要拿我的食物去加密啊。
然后用在线网址解密https://www.mklab.cn/utils/hmac ,其中“功成不居”是密文,密钥是onion,加密后得到flag为:457e684312266a62178513d47bbf992c
即:ISCC{457e684312266a62178513d47bbf992c}
钢铁侠在解密
题目给了一个图片:ironman.bmp和一个txt,txt内容如下:
首先将图片放到静谧之眼里面进行解密,得到一个新的txt文件,内容为:
网上找个板子(half-gcd),sage脚本跑完就能得到flag
ISCC{huan_ran_bing_shi_263}
Exp:
#sage
def HGCD(a, b):
if 2 * b.degree() <= a.degree() or a.degree() == 1:
return 1, 0, 0, 1
m = a.degree() // 2
a_top, a_bot = a.quo_rem(x ^ m)
b_top, b_bot = b.quo_rem(x ^ m)
R00, R01, R10, R11 = HGCD(a_top, b_top)
c = R00 * a + R01 * b
d = R10 * a + R11 * b
q, e = c.quo_rem(d)
d_top, d_bot = d.quo_rem(x ^ (m // 2))
e_top, e_bot = e.quo_rem(x ^ (m // 2))
S00, S01, S10, S11 = HGCD(d_top, e_top)
RET00 = S01 * R00 + (S00 - q * S01) * R10
RET01 = S01 * R01 + (S00 - q * S01) * R11
RET10 = S11 * R00 + (S10 - q * S11) * R10
RET11 = S11 * R01 + (S10 - q * S11) * R11
return RET00, RET01, RET10, RET11
def GCD(a, b):
print(a.degree(), b.degree())
q, r = a.quo_rem(b)
if r == 0:
return b
R00, R01, R10, R11 = HGCD(a, b)
c = R00 * a + R01 * b
d = R10 * a + R11 * b
if d == 0:
return c.monic()
q, r = c.quo_rem(d)
if r == 0:
return d
return GCD(d, r)
c1= 5351361435857354387644649659807113414229291648124734626745135198025698262851565531227275726598186093299640514377395244915284596752406671236222666830757455350781507657409525375993004003904268779400607143555598077316829176928860616940977501500053500617712428449519097936694069642312135953745146704457248433761849390123995761802692554762839532264856082713758585479437250011966512162009110500292456855899122603992497598349164825604642850794780409498411709154088138092404544306536513045319831486328867256219055016086185606392692562529644736782852853956670786208072423129373574126238164820946034733762267231637399020600473
c2= 10618458145966120480315499552726242705225099910596551233343623626371417178328307296439989167890692797080430010155270465833905384994306100207159200601762805644260559444600024171026528618755868358184107754737373113297678489872712796953136189024814002801858819870365117638297431031058987275725855946001791651845025125841201792166220197308971541916765179282551103642377403714477934592317869385394429509566520297527105060654104864950248563369117916530386995259741271368991151591237723139637011859850624171256798839551855594064157429161608898619665868867796298148016209125715637635692507717452493865536296764182085644494967
N= 14333611673783142269533986072221892120042043537656734360856590164188122242725003914350459078347531255332508629469837960098772139271345723909824739672964835254762978904635416440402619070985645389389404927628520300563003721921925991789638218429597072053352316704656855913499811263742752562137683270151792361591681078161140269916896950693743947015425843446590958629225545563635366985228666863861856912727775048741305004192164068930881720463095045582233773945480224557678337152700769274051268380831948998464841302024749660091030851843867128275500525355379659601067910067304244120384025022313676471378733553918638120029697
e = 52595
pad1 = 1769169763
pad2 = 1735356260
PR.<x>=PolynomialRing(Zmod(N))
g1 = (x*2^32+pad1)^e - c1
g2 = (x*2^32+pad2)^e - c2
X=584734024210292804199275855856518183354184330877
print(g1(X),g2(X))
res = GCD(g1,g2)
m = -res.monic().coefficients()[0]
print(m)
print(bytes.fromhex(hex(m)[2:]).decode().replace("flag{",'ISCC{'))
工业互联网模拟仿真数据分析
步骤如下
第一问
在某些网络会话中,数据包可能保持固定大小,请给出含有此确定性特征的会话IP地址和数据包字节大小值。
只有192.168.1.2à192.168.1.4的Length大小不变
结果:192.168.1.2,192.168.1.4,24
第二问
题目二:通信包数据某些字段可能为确定的,请给出确定字节数值。
tshark -r a.pcap -T fields -e data.data -Y "data.len==12"
2024f7b039ae1f546c8e8b1b
2024b939b6fdd3a92dacee64
2024fd300d3fd17b85d1ae51
20249cf615176e00d3fde264
20247b5207a1d2b639fe1e55
202432b3b42ff36424a15d01
2024f2122ad847094be81d58
2024e866d7ec7b7d5ae618bf
20244057c7e66ca371b2c938
202433b4fba38bac7e29bc6a
2024796986cd9b1fc559ad61
20248c6b6efd392e9839a3eb
202462434670e7e76d766c58
20241cc66ab532ff8c8f1d2e
很明显就是前面的2024
第三问
一些网络通信业务在时间序列上有确定性规律,请提供涉及的IP地址及时间规律数值(小数点后两位)
看文末的流量分组
第五组 - 192.168.1.3 192.168.1.5, 这一组的时间间隔固定
结果:192.168.1.3,192.168.1.5,0.06
第四问
一些网络通信业务存在逻辑关联性,请提供涉及的IP地址
看文末的流量分组,就能看出这三个IP是有业务关联性的
192.168.1.3 --> 192.168.1.2 --> 192.168.1.6
结果:192.168.1.2,192.168.1.3,192.168.1.6
第五问
网络数据包往往会添加数据完整性校验值,请分析出数据校验算法名称及校验值在数据包的起始位和结束位(倒数位)
五个字符的校验算法,先假设是 CRC16 或者 CRC32 倒数位必为1
尝试CRC16 CRC32并尝试0-10为起始位
为CRC16,4,1时成功提交
所有的结果:
192.168.1.2,192.168.1.4,24
2024
192.168.1.3,192.168.1.5,0.06
192.168.1.2,192.168.1.3,192.168.1.6
CRC16,4,1
运行后得到flag
精装四合一
拿到图片后放入010editor发现每张图片的最下面都有一堆多余数据,那就把IEND及之前的数据全部删除,留下多余数据看看。
一堆乱码,可能是让我们进行异或,观察了一下每段数据都有较多的FF,就全选,异或ff试试。(四张都异或)
我们发现异或后的四个图片的文件头居然是50 4B 03 04,是我们熟悉的zip文件头,写脚本,将每段数据的字节按文件顺序进行拼接。
Exp:
tp1 = open("./left_foot_invert.png", "rb")
tp2 = open("./left_hand_invert.png", "rb")
tp3 = open("./right_foot_invert.png", "rb")
tp4 = open("./right_hand_invert.png", "rb")
fp5 = open("key.zip", "wb")
for i in range(3176):
fp5.write(tp1.read(1))
fp5.write(tp2.read(1))
fp5.write(tp3.read(1))
fp5.write(tp4.read(1))
fp5.write(tp1.read(1))
运行后得到key.zip,是加密的,爆破一下得到密钥为65537(rsa中常用的e,后续可能会用到rsa解密)
解压后得到一个word文档,里面有一个图片,将图片移开后,ctrl+a全选,换个主题即可得到一串数字:
16920251144570812336430166924811515273080382783829495988294341496740639931651
猜测其为rsa里面的n,factor分解后得到p,q
p=100882503720822822072470797230485840381
q=167722355418488286110758738271573756671
Exp:
import gmpy2
from Crypto.Util.number import *
n = 16920251144570812336430166924811515273080382783829495988294341496740639931651
#分解n在线网站:http://www.factordb.com/,得到p,q
p = 100882503720822822072470797230485840381
q = 167722355418488286110758738271573756671
e = 65537
phi_n = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi_n)
c = bytes_to_long(open("./true_flag.jpeg", "rb").read())
m = pow(c, d, n)
flag = long_to_bytes(m)
print(flag)
运行后即可得到flag:ISCC{NbJY499CcSrP198}
b'\x02\x18\t\xcb\x7f\x9dT\xcc\xe1\x00ISCC{NbJY499CcSrP198}'
时间刺客
题目给了流量包”给你也用不了.pcap”和一个加密的7z文件,首先我们先分析一下流量包发现很多键盘鼠标流量
结合题目描述,可以初步判断出为键盘流量
我们可以利用tshark提取出有效数据段
tshark -r 给你也用不了.pcap -T fields -e usb.capdata > usbdata.txt
得到以下数据:
0000090000000000
0000000000000000
00000f0000000000
0000000000000000
0000040000000000
0000000000000000
00000a0000000000
0000000000000000
2000000000000000
20002f0000000000
2000000000000000
0000000000000000
0000130000000000
0000000000000000
0000150000000000
0000000000000000
0000200000000000
0000000000000000
0000220000000000
0000000000000000
0000220000000000
0000000000000000
2000000000000000
20002d0000000000
2000000000000000
0000000000000000
0000270000000000
0000000000000000
0000110000000000
0000000000000000
00001a0000000000
0000000000000000
0000040000000000
0000000000000000
0000150000000000
0000000000000000
0000070000000000
0000000000000000
0000160000000000
0000000000000000
2000000000000000
20002d0000000000
2000000000000000
0000000000000000
0000040000000000
0000000000000000
00001f0000000000
0000000000000000
0000090000000000
0000000000000000
0000080000000000
0000000000000000
0000080000000000
0000000000000000
0000230000000000
0000000000000000
0000080000000000
0000000000000000
0000270000000000
0000000000000000
2000000000000000
2000300000000000
2000000000000000
0000000000000000
0100000000000000
0100060000000000
接下来使用脚本处理一下,得到
FLAGPR3550NWARDSA2FEE6E0
EXP:
#1.使用脚本删除空行
with open('usbdata.txt', 'r', encoding='utf-8') as f:
lines = f.readlines()
lines = filter(lambda x: x.strip(), lines)
with open('usbdata.txt', 'w', encoding='utf-8') as f:
f.writelines(lines)
#2.将上面的文件用脚本分隔,加上冒号;
f=open('usbdata.txt','r')
fi=open('out.txt','w')
while 1:
a=f.readline().strip()
if a:
if len(a)==16:#键盘流量的话len为16鼠标为8
out=''
for i in range(0,len(a),2):
if i+2 != len(a):
out+=a[i]+a[i+1]+":"
else:
out+=a[i]+a[i+1]
fi.write(out)
fi.write('\n')
else:
break
fi.close()
#3.最后用脚本提取
# print((line[6:8])) #输出6到8之间的值
#取出6到8之间的值
mappings = { 0x04:"A", 0x05:"B", 0x06:"C", 0x07:"D", 0x08:"E", 0x09:"F", 0x0A:"G", 0x0B:"H", 0x0C:"I", 0x0D:"J", 0x0E:"K", 0x0F:"L", 0x10:"M", 0x11:"N",0x12:"O", 0x13:"P", 0x14:"Q", 0x15:"R", 0x16:"S", 0x17:"T", 0x18:"U",0x19:"V", 0x1A:"W", 0x1B:"X", 0x1C:"Y", 0x1D:"Z", 0x1E:"1", 0x1F:"2", 0x20:"3", 0x21:"4", 0x22:"5", 0x23:"6", 0x24:"7", 0x25:"8", 0x26:"9", 0x27:"0", 0x28:"\n", 0x2a:"[DEL]", 0X2B:" ", 0x2C:" ", 0x2D:"-", 0x2E:"=", 0x2F:"[", 0x30:"]", 0x31:"\\", 0x32:"~", 0x33:";", 0x34:"'", 0x36:",", 0x37:"." }
nums = []
keys = open('out.txt')
for line in keys:
if line[0]!='0' or line[1]!='0' or line[3]!='0' or line[4]!='0' or line[9]!='0' or line[10]!='0' or line[12]!='0' or line[13]!='0' or line[15]!='0' or line[16]!='0' or line[18]!='0' or line[19]!='0' or line[21]!='0' or line[22]!='0':
continue
nums.append(int(line[6:8],16))
keys.close()
output = ""
for n in nums:
if n == 0 :
continue
if n in mappings:
output += mappings[n]
else:
output += '[unknown]'
print ('output :\n' + output)
得到的并不是flag,用pr3550nwardsa2fee6e0去解密7z文件,成功得到一个新的rar文件,但是也是加密的,猜测密钥为大写的刚才的“flag”:PR3550NWARDSA2FEE6E0,得到一堆空文件,仔细观察发现时间有问题
写个时间戳脚本,可以得到flag
Exp:
import time
import os
# 设置包含文件的文件夹路径
folder_path = r"G:\CTF\练习\ISCC2024\Misc\时间刺客\attachment-27\20" # 使用原始字符串以避免转义字符问题
# 初始化一个空字符串以保存结果字符
b = ""
# 循环处理从0到17(包括)的文件
for i in range(18):
# 构造当前文件的完整路径
file_path = os.path.join(folder_path, ".%s.txt" % i)
# 获取文件的最后修改时间并转换为time.struct_time对象
mtime = time.localtime(os.path.getmtime(file_path))
# 将time.struct_time转换为格式化字符串,然后解析回time.struct_time以确保格式正确
mtime = int(time.mktime(time.strptime(time.strftime('%Y-%m-%d %H:%M:%S', mtime), "%Y-%m-%d %H:%M:%S")))
# 通过减去特定的基准值并转换为字符来计算字符
b += chr(mtime - 1728864000)
# 打印结果
print("ISCC{%s}" % b)
有人让我给你带个话
题目给了一个图片和一个文件
首先使用foremost对tony.png进行分离得到新的图片,名称为:lyra.png
百度搜索后在github上发现项目工具lyra(1.3.2)
在kali上首先安装好bazel_5.3.2
(1)下载软件包
curl -O https://mirrors.huaweicloud.com/bazel/5.3.2/bazel_5.3.2-linux-x86_64.deb
(2)安装软件包
sudo dpkg -i bazel_5.3.2-linux-x86_64.deb
(3)检查是否安装成功(查看版本)
bazel --version
搭建好环境后将另外一个未命名文件修改后缀名为.lyra,这里我改名为key.lyra
运行得到一段音频
使用在线转换工具语音转文字|语音识别-在线录音转文字-录音转文字助手 将音频转化为文本
得到一串关于核心价值观的字符
平等平等自由友善自由自由友善爱国自由民主和谐平等平等平等自由平等自由民主和谐富强平等爱国自由自由自由友善法治。
解密后得到flag
ISCC{UJNA5UEA0XDM}