随便玩玩
猫星球
脑王题,做的大脑升级了
Konano/CatWatermark (github.com)
给了项目,水印写在图像内,原始图像下载
Desktop Wallpapers Earth planet Africa Space 11500×11500 (1zoom.me)
原图另一个链接:https://eoimages.gsfc.nasa.gov/images/imagerecords/77000/77085/marble_east_vir_2012023_lrg.jpg
(这两个图片相近)
两张图片xor后获得一个明显的猫脸变换的图片
审给的脚本,
可以发现
水印的位置是在变换后的中间部分,已知图像长宽为11500,那么图像中间也就是5700,5700的位置
并且他的dx,dy的范围是随机的,大概在1150-11500之间,非常之大
此时随机生成private后带入函数中。
加密脚本根据他写的其实iterations并没有实际使用,实际上只运行了一次(此处贴个常规猫脸变换,对比一下就知道问题所在了
def arnold(img, shuffle_times, a, b):
r, c, d = img.shape # 高,宽,通道个数
p = np.zeros(img.shape, np.uint8)
for times in range(shuffle_times):
for i in range(r):
for j in range(c):
x = (i + b * j) % r
y = (a * i + (a * b + 1) * j) % c
p[x, y, :] = img[i, j, :]
img = np.copy(p)
return p
综上所述,我们获得了三个信息,
第一,变换次数恒为1,
第二,数据较大,并且图片也很大,盲目爆破不现实
第三,思考一种办法能够提前获知dx或者dy,这样可以减少爆破数量和时间。
根据分析Arnold算法的关系,
当_x=0的时候。_y=_y
_x=1时,_y=_y+dx
也就是说,第0行元素不变,根据这个公式来编写即可计算我们所需要的dx值。
import sys
import numpy as np
from PIL import Image,ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
img = np.array(Image.open('1234.png').convert('L'))
width,height = img.shape
np.set_printoptions(threshold=np.inf)
def arnold_cat_map_rev_single_row(row, offset_x, width):
new_row = np.zeros(row.shape, dtype=np.uint8)
for y in range(width):
_y = (y - offset_x * (row.size - y)) % width
new_row[_y] = row[y]
return new_row
def compute_dx(first_row, second_row, width):
best_dx = None
best_diff = float('inf')
for dx in range(5700, width): #从图像中间开始
# Apply the Arnold's cat map reverse transformation to the second row
second_row_transformed = arnold_cat_map_rev_single_row(second_row, dx, width)
# Compute the difference between the first row and the transformed second row
diff = np.abs(first_row - second_row_transformed).sum()
# If the difference is smaller than the best difference found so far, update the best dx value
if diff < best_diff:
best_dx = dx -1
best_diff = diff
return best_dx
row0 = img[0,:]
row1 = img[1,:]
# Compute the width of the image (or the watermark)
width = len(row0)
# Calculate the dx value
dx = compute_dx(row0, row1, width)
print(dx)
可以计算出dx值为5809,此时拥有其中一个值我们无脑爆破最后一个dy就好了,体力活。
import os
import sys
import numpy as np
from PIL import Image, ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
def arnold_cat_map(image, key=(1, 2, 1)):
"""
Implements Arnold's cat map transformation on an image.
"""
height, width, *_ = image.shape
offset_x, offset_y, iterations = key
new_image = np.zeros(image.shape, dtype=np.uint8)
for x in range(height):
for y in range(width):
_x, _y = x, y
_y = (_y + offset_x * _x) % width
_x = (_x + offset_y * _y) % height
new_image[_x, _y] = image[x, y]
return new_image
def arnold_cat_map_rev(image, key=(1, 2, 1)):
"""
Implements Arnold's cat map transformation on an image (reverse).
"""
height, width, *_ = image.shape
offset_x, offset_y, iterations = key
new_image = np.zeros(image.shape, dtype=np.uint8)
for x in range(height):
for y in range(width):
_x, _y = x, y
_x = (_x - offset_y * _y) % height
_y = (_y - offset_x * _x) % width
new_image[_x, _y] = image[x, y]
return new_image
def extract_watermark(original_image_path, watermarked_image_path, output_image_path, private_key):
"""
Extracts a text watermark from a watermarked image using the Arnold's cat map transformation.
"""
# Open the original image
original_image = np.array(Image.open(original_image_path).convert("RGB"))
# Open the watermarked image
watermarked_image = np.array(Image.open(watermarked_image_path).convert("RGB"))
assert watermarked_image.shape == original_image.shape
# Extract the watermark from the watermarked image
original_image ^= watermarked_image
transformed_image = arnold_cat_map(original_image, private_key)
transformed_image[transformed_image > 0] = 255
transformed_image = 255 - transformed_image
# Save the extracted watermark
Image.fromarray(np.uint8(transformed_image)).save(output_image_path)
def try_arnold_dy(original_image_path, watermarked_image_path, output_image_path, arnold_dx, arnold_rd):
original_image = np.array(Image.open(original_image_path).convert("RGB"))
watermarked_image = np.array(Image.open(watermarked_image_path).convert("RGB"))
height, width, *_ = original_image.shape
for arnold_dy in range(2800, 3000):
private_key = (arnold_dx, arnold_dy, arnold_rd)
extracted_watermark = arnold_cat_map(original_image ^ watermarked_image, private_key)
extracted_watermark[extracted_watermark > 0] = 255
extracted_watermark = 255 - extracted_watermark
# 将尝试的结果保存为文件,文件名包含尝试的 arnold_dy 值
output_filename = f"{output_image_path}_arnold_dy_{arnold_dy}.png"
Image.fromarray(np.uint8(extracted_watermark)).save(output_filename)
print(f"Saved {output_filename} with arnold_dy = {arnold_dy}")
# 输入参数检查
if len(sys.argv) != 4:
print("Usage: brute_force_arnold_dy.py original_image watermarked_image output_image")
sys.exit(1)
original_image_path = sys.argv[1]
watermarked_image_path = sys.argv[2]
output_image_path = sys.argv[3]
arnold_dx = 5809
arnold_rd = 1
try_arnold_dy(original_image_path, watermarked_image_path, output_image_path, arnold_dx, arnold_rd)
最后找到最终值 5809 2901 1为最终flag
flag图
OOBdetection
邪道做法,先做第一层爆破
# -*- coding: utf-8 -*-
from pwn import *
import hashlib
import string
import itertools
from tqdm import tqdm
#开启日志
context.log_level = 'debug'
sh = remote("47.98.209.191", 1337)
def crack():
temp = sh.recvuntil(b"sha256(XXX +")
temp = sh.recvline()
target_hash = temp.split(b" == ")[1].strip()
suffix = temp[1:15]
print(temp, target_hash, suffix)
target_hash = target_hash.decode('utf-8')
suffix = suffix.decode('utf-8')
charset = "0123456789abcdef"
total_combinations = len(charset) ** 6
for combination in tqdm(itertools.product(charset, repeat=6), desc="Cracking progress", total=total_combinations):
prefix = ''.join(combination)
test_string = prefix + suffix
test_string_bytes = bytes.fromhex(test_string)
test_hash = hashlib.sha256(test_string_bytes).hexdigest()
if test_hash == target_hash:
print("XXX = " + prefix)
return prefix
passwd = crack()
assert passwd is not None
sh.sendline(passwd.encode())
sh.interactive()
然后内容是根据运算内容判断是否存在溢出和异常,常规做法是转lark然后跑
我又不懂编译原理,答案是GPT帮我判断
写好prompt多次调教后提高准确性
最后弄个脚本就行了,这里就不放了,省的我钱没了
懂得都懂带带弟弟
正挺好,非预期
import('../flag')
消失的声波
minimoden直接解
获得个oss桶,根据官网规则,直接拼接url访问
https://iot2023.oss-cn-hangzhou.aliyuncs.com/OpYdCuMtkQ8Yjhm2
下载文件是个macos的程序,不逆向直接strings怎么说
关键信息拿到了,直接连就完事了
import sys
from linkkit import linkkit
import threading
import traceback
import inspect
import time
import logging
# config log
__log_format = '%(asctime)s-%(process)d-%(thread)d - %(name)s:%(module)s:%(funcName)s - %(levelname)s - %(message)s'
# logging.basicConfig(format=__log_format)
lk = linkkit.LinkKit(
host_name="cn-shanghai",
product_key="a1eAwsBKddO",
device_name="ncApIY2XV9NUIY4VpbGk",
device_secret="04845e512ead208b2437d970a154d69e")
# lk.config_mqtt(endpoint="iot-cn-6ja******.mqtt.iothub.aliyuncs.com")
lk.enable_logger(logging.DEBUG)
def on_device_dynamic_register(rc, value, userdata):
if rc == 0:
print("dynamic register device success, value:" + value)
else:
print("dynamic register device fail, message:" + value)
def on_connect(session_flag, rc, userdata):
print("on_connect:%d,rc:%d" % (session_flag, rc))
pass
def on_disconnect(rc, userdata):
print("on_disconnect:rc:%d,userdata:" % rc)
def on_topic_message(topic, payload, qos, userdata):
print("on_topic_message:" + topic + " payload:" + str(payload) + " qos:" + str(qos))
pass
def on_subscribe_topic(mid, granted_qos, userdata):
print("on_subscribe_topic mid:%d, granted_qos:%s" %
(mid, str(','.join('%s' % it for it in granted_qos))))
pass
def on_unsubscribe_topic(mid, userdata):
print("on_unsubscribe_topic mid:%d" % mid)
pass
def on_publish_topic(mid, userdata):
print("on_publish_topic mid:%d" % mid)
lk.on_device_dynamic_register = on_device_dynamic_register
lk.on_connect = on_connect
lk.on_disconnect = on_disconnect
lk.on_topic_message = on_topic_message
lk.on_subscribe_topic = on_subscribe_topic
lk.on_unsubscribe_topic = on_unsubscribe_topic
lk.on_publish_topic = on_publish_topic
lk.config_device_info("Eth|03ACDEFF0032|Eth|03ACDEFF0031")
lk.config_mqtt(port=1883, protocol="MQTTv311", transport="TCP",secure="TLS")
lk.connect_async()
lk.start_worker_loop()
while True:
try:
msg = input()
except KeyboardInterrupt:
sys.exit()
else:
if msg == "1":
lk.disconnect()
elif msg == "2":
lk.connect_async()
elif msg == "3":
rc, mid = lk.subscribe_topic(lk.to_full_topic("user/get"))
if rc == 0:
print("subscribe topic success:%r, mid:%r" % (rc, mid))
else:
print("subscribe topic fail:%d" % rc)
elif msg == "4":
rc, mid = lk.unsubscribe_topic(lk.to_full_topic("user/get"))
if rc == 0:
print("unsubscribe topic success:%r, mid:%r" % (rc, mid))
else:
print("unsubscribe topic fail:%d" % rc)
elif msg == "5":
#发送{"id":"flag"}到/user/get
rc, mid = lk.publish_topic(lk.to_full_topic("user/update"), "{\"id\":\"flag\"}")
if rc == 0:
print("publish topic success:%r, mid:%r" % (rc, mid))
else:
print("publish topic fail:%d" % rc)
elif msg == "8":
ret = lk.dump_user_topics()
print("user topics:%s", str(ret))
elif msg == "9":
lk.destruct()
print("destructed")
else:
sys.exit()
最后获得flag
暂无评论内容