MRCTF My secret
My secret
知识点:wireshark基本操作,shadowsocks3.0源码利用,拼图(os脚本编写能力),
根据这里的信息可以知道,tcp所传输的源数据是在target address后面的数据。那么我们现在去寻找target address(即wireshark中的Destination)
那么我们已经找到了,即第一张图中的2f 5e ca a8。我们取走后面的数据存储为文件。
通过导出字节流文件可以得到一下两个文件


通过010拿走16进制编码数然后进行解密。
D1 DF BC 46 8E 33 B2 AE A4 E7 D7 4F 35 B2 0D 0A
CE EC 19 F7 2B FC B7 64 1B E8 55 12 5C 53 F1 08
C7 B9 FD EE B1 16 B5 79 C2 EE 6F F6 3D 74 8D 54
D6 4D DC 6B A2 50 C7 0C 32 5F 8E 38 9D 78 73 AA
88 1E 40 2C BF 32 54 E8 6C 6C 33 E2 B7 8E CA 89
9F 51 BB 36 87 8F AF CF EA 75 3A 10 CE 0D A7 C7
9F F7 84 91 AF 1D 53 81 87 97 33 5E 2D 7C DF
那么我的思路在这里就停滞了。经过师傅的提醒和帮助下,我下载了shadowsocks3.0版本的源码(python版),然后很容易找到一个显眼的cryptor.py文件。(这里有一个误区,如果你下载到的源码中没有题目所示的aes-256-gcm加密方法,后续是无法进行解密的。因此需要下载到相应的版本的shadowsocks3.0)

我们仔细看一下这个加密的算法。
加密算法如下。当设置了iv_sent时进行iv的设置,false时不设置iv

然后发现这里是自带decrypt函数的。那么数据包解密就简单多了。

这个函数对数据进行了iv的判断和提取。我们只需要传入完整的数据包进行解密就可以了。

with open('tcp.txt','rb') as f:
encrypted_data = f.read()
c = Cryptor('db6c73af3d8585c', 'aes-256-gcm')
data = (c.decrypt(encrypted_data))
with open('tcp2.txt', 'wb') as f:
f.write(data)
对数据进行解密,然后就可以在tcp2.txt中看到我们想要看到的数据包了!
那么数据该提取哪一部分呢?红色部分或者蓝色部分。也就是请求部分和响应部分。


拿到压缩包后就是一个2500个图片的拼图题。hint为gps。
我们在exiftool中可以找到图片的gps值。编写脚本进行提取并修改名字。(我写的脚本)
import os
import re
path = r"/root/Desktop/jigsaw on earch" # 文件夹目录
files = os.listdir(path) # 得到文件夹下的所有文件名称
for file in files: # 遍历文件夹
cmd=r"exiftool {0} | grep GPS\ Position".format(re.escape(file))
#print(cmd)
#print(file)
gpsTemp = os.popen(cmd).read()
for i in range(len(gpsTemp)):
if gpsTemp[i]==':':
num1 = int(gpsTemp[i+2:i+4].strip())
if gpsTemp[i] == ',':
num2 = int(gpsTemp[i+2:i+4].strip())
fileName = num1*50+num2
cmdNext = "mv {0} {1}\.png".format(re.escape(file),fileName)
#print(cmdNext)
os.system(cmdNext)
#print(num1*50+num2)
#print(gpsTemp)
后面拼图脚本不会写了。
师傅放了wp出来。看了一下,真复杂。看不懂。先进行rename
import os
import piexif
from PIL import Image
file = os.listdir('jigsaw')
def calc_file(x, y):
num = str(y * 50 + x).zfill(4)
return f'jigsaw/{num}.png'
for i in file:
img = Image.open(f'jigsaw/{i}')
exif_dict = piexif.load(img.info['exif'])
img.close()
latitude = exif_dict['GPS'][piexif.GPSIFD.GPSLatitude]
longtitude = exif_dict['GPS'][piexif.GPSIFD.GPSLongitude]
y = latitude[0][0]
x = longtitude[0][0]
file = calc_file(x, y)
os.rename(f'jigsaw/{i}', file)
然后利用拼图脚本进行拼图
from PIL import Image
from tqdm import tqdm
x_sum = 50
y_sum = 50
ori_width = 60
ori_height = 60
jigsaw_width = 20
width = ori_width + jigsaw_width * 2
height = ori_height + jigsaw_width * 2
def calc_file(x, y):
num = str(y * x_sum + x).zfill(4)
return f'jigsaw/{num}.png'
def check_info(file):
img_info = [0, 0, 0, 0]
img = Image.open(file)
pix_out1 = img.getpixel((width // 2, 0))[3]
pix_out2 = img.getpixel((width - 1, height // 2))[3]
pix_out3 = img.getpixel((width // 2, height - 1))[3]
pix_out4 = img.getpixel((0, height // 2))[3]
pix_out = [pix_out1, pix_out2, pix_out3, pix_out4]
pix_in1 = img.getpixel((width // 2, jigsaw_width))[3]
pix_in2 = img.getpixel((width - jigsaw_width - 1, height // 2))[3]
pix_in3 = img.getpixel((width // 2, height - jigsaw_width - 1))[3]
pix_in4 = img.getpixel((jigsaw_width, height // 2))[3]
pix_in = [pix_in1, pix_in2, pix_in3, pix_in4]
for i in range(4):
if pix_out[i] == 0 and pix_in[i] == 0:
img_info[i] = -1
elif pix_out[i] != 0 and pix_in[i] != 0:
img_info[i] = 1
elif pix_out[i] == 0 and pix_in[i] != 0:
img_info[i] = 0
else:
raise Exception("Invalid jigsaw!", file)
return img_info
def init_table():
info_table = []
for y in range(y_sum):
row_info = []
for x in range(x_sum):
file = calc_file(x, y)
img_info = check_info(file)
row_info.append(img_info)
info_table.append(row_info)
return info_table
def cut(direction, file):
if direction == 0:
left_top_x = (ori_width - jigsaw_width) // 2 + jigsaw_width
left_top_y = 0
elif direction == 1:
left_top_x = ori_width + jigsaw_width
left_top_y = (ori_height - jigsaw_width) // 2 + jigsaw_width
elif direction == 2:
left_top_x = (ori_width - jigsaw_width) // 2 + jigsaw_width
left_top_y = ori_height + jigsaw_width
elif direction == 3:
left_top_x = 0
left_top_y = (ori_height - jigsaw_width) // 2 + jigsaw_width
right_bottom_x = left_top_x + jigsaw_width
right_bottom_y = left_top_y + jigsaw_width
img = Image.open(file)
cut_img = img.crop((left_top_x, left_top_y, right_bottom_x, right_bottom_y))
blank_img = Image.new('RGBA', (jigsaw_width, jigsaw_width), (0, 0, 0, 0))
img.paste(blank_img, (left_top_x, left_top_y))
img.save(file)
return cut_img
def paste(direction, file, cut_img):
if direction == 0:
left_top_x = (ori_width - jigsaw_width) // 2 + jigsaw_width
left_top_y = jigsaw_width
elif direction == 1:
left_top_x = ori_width
left_top_y = (ori_height - jigsaw_width) // 2 + jigsaw_width
elif direction == 2:
left_top_x = (ori_width - jigsaw_width) // 2 + jigsaw_width
left_top_y = ori_height
elif direction == 3:
left_top_x = jigsaw_width
left_top_y = (ori_height - jigsaw_width) // 2 + jigsaw_width
img = Image.open(file)
img.paste(cut_img, (left_top_x, left_top_y))
img.save(file)
def recover_jigsaw(info_table):
for y in tqdm(range(y_sum)):
for x in range(x_sum):
img_info = info_table[y][x]
for direction in range(4):
if img_info[direction] != 'free':
file = calc_file(x, y)
if direction == 0:
x2 = x
y2 = y - 1
file2 = calc_file(x2, y2)
direction2 = 2
elif direction == 1:
x2 = x + 1
y2 = y
file2 = calc_file(x2, y2)
direction2 = 3
elif direction == 2:
x2 = x
y2 = y + 1
file2 = calc_file(x2, y2)
direction2 = 0
elif direction == 3:
x2 = x - 1
y2 = y
file2 = calc_file(x2, y2)
direction2 = 1
if img_info[direction] == 1:
cut_img = cut(direction, file)
paste(direction2, file2, cut_img)
elif img_info[direction] == -1:
cut_img = cut(direction2, file2)
paste(direction, file, cut_img)
info_table[y2][x2][direction2] = 'free'
img_info[direction] = 'free'
def remove_border(file):
img = Image.open(file)
new_img = img.crop((jigsaw_width, jigsaw_width, width - jigsaw_width, height - jigsaw_width))
new_img.save(file)
if __name__ == '__main__':
info_table = init_table()
recover_jigsaw(info_table)
for i in range(x_sum * y_sum):
file = 'jigsaw/' + str(i).zfill(4) + '.png'
remove_border(file)

扫描后得到flag
MRCTF{795c666e-6244-4768-981d-3b******2c}
MRCTF My secret的更多相关文章
- Android Secret Code
我们很多人应该都做过这样的操作,打开拨号键盘输入*#*#4636#*#*等字符就会弹出一个界面显示手机相关的一些信息,这个功能在Android中被称为android secret code,除了这些系 ...
- ASP.NET OAuth:access token的加密解密,client secret与refresh token的生成
在 ASP.NET OWIN OAuth(Microsoft.Owin.Security.OAuth)中,access token 的默认加密方法是: 1) System.Security.Crypt ...
- Lucky 2048 - The secret of being lucky
Lucky 2048 uses a normal distribution to create "lucky" start. Generally speaking, it prov ...
- Secret Codes
Secret Codes This is a list of codes that can be entered into the dialer to output the listed info ...
- 微信企业号开发之-如何获取secret 序列号
最近有项目基于微信企业号开发,简单记录下如何查看企业号secert 工具/原料 微信企业号 方法/步骤 用管理员的帐号登录后,选择[设置]-[权限管理]进入管理组设置界面 在左边点击[ ...
- hdu.1111.Secret Code(dfs + 秦九韶算法)
Secret Code Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...
- 2078 Problem H Secret Message 中石油-未提交-->已提交
题目描述 Jack and Jill developed a special encryption method, so they can enjoy conversations without wo ...
- Rails4 中 因为secret key 引起在production环境下无法运行
错误信息 Missing `secret_key_base` for 'production' environment, set this value in `config/secrets.yml` ...
- URAL 1932 The Secret of Identifier 题解
http://acm.timus.ru/problem.aspx?space=1&num=1932 B - The Secret of Identifier Time Limit:1000MS ...
随机推荐
- 运行Chrome浏览器如何添加Options
原文档 Options Windows: 退出Chrome的所有正在运行的实例. 右键单击"Chrome"快捷方式 选择属性 在"目标:"行的末尾添加命令行标志 ...
- 如何通过NGK数字增益平台实现兑换算力
最近币圈里有一个新项目NGK非常火热,很多朋友在经过了了解以后纷纷表示很看好这个项目,那么除了二级市场之外,是否还能有其他的方式可以更低成本地获得NGK代币呢? 答案是肯定的,NGK数字增益平台便是低 ...
- scrapy 运行逻辑
爬虫的步骤:发送请求获得响应→解析并提取数据→保存数据 我们沿用这个朴素的逻辑去理解scrapy 一.发送请求获得响应 1.爬虫发送请求request到引擎 2.引擎将请求request传递给调度器s ...
- 微信小程序:页面全局参数(注意不是小程序的全局变量globalData)
为什么要使用页面全局参数:方便使用数据. 由于总页数需要再另外的一个方法中使用,所以要把总页数变成一个页面全局参数.因为取数据使用this.xxx即可,中间不用加data,给页面全局参数赋值页方便,直 ...
- eclipse定制工具栏,修改工具栏
目前eclipse定制工具栏的入口就是window- customize perspective,在弹出的窗口中选择Tool Bar Visibility,选择要在工具栏中显示的快捷图标.注:在Too ...
- the import java.util cannot be resolve
重新配置一下build path 的jre,如果不行的话就重新设置jre(在add library中installed JREs)
- 零基础学Python:数据容器
1.常用操作 列表常用操作 在 ipython 中定义一个 列表,例如: l= list() 输入 l. 按下 TAB 键, ipython 会提示 字典 能够使用的函数如下: 可以到官方网址查询使用 ...
- .Net Core 3.1浏览器后端服务(四) 你眼中的依赖注入与我相同吗?
一.前言 DI-Dependency Injection 依赖注入 IoC-Inversion of Control 控制反转 近几年这依赖注入. 控制反转已成为软件开发中不可或缺的一部分,那么该怎么 ...
- 02.从0实现一个JVM语言之词法分析器-Lexer-03月02日更新
从0实现JVM语言之词法分析器-Lexer 本次有较大幅度更新, 老读者如果对前面的一些bug, 错误有疑问可以复盘或者留言. 源码github仓库, 如果这个系列文章对你有帮助, 希望获得你的一个s ...
- HDOJ-1043 Eight(八数码问题+双向bfs+高效记录路径+康拓展开)
bfs搜索加记录路径 HDOJ-1043 主要思路就是使用双向广度优先搜索,找最短路径.然后记录路径,找到结果是打印出来. 使用康拓序列来来实现状态的映射. 打印路径推荐使用vector最后需要使用a ...