博主头像
Anna YanamiのBlog

先を見てください、世界は素晴らしい場所です

ISCTF 2024

Crypto

我和小蓝鲨的秘密

ISCTF{success!_bluesharkinfo_gogogo!}
from PIL import Image
from Crypto.Util.number import bytes_to_long, long_to_bytes
import numpy as np

n = 29869349657224745144762606999
e = 65537

original_image_path = "flag.jpg"
img = Image.open(original_image_path)
img = img.convert("RGB")

img_array = np.array(img)
h, w, _ = img_array.shape

encrypted_array = np.zeros((h, w, 3), dtype=object)
for i in range(h):
    for j in range(w):
        r, g, b = int(img_array[i, j, 0]), int(img_array[i, j, 1]), int(img_array[i, j, 2])

        encrypted_array[i, j, 0] = pow(r, e, n)
        encrypted_array[i, j, 1] = pow(g, e, n)
        encrypted_array[i, j, 2] = pow(b, e, n)

np.save("encrypted_image.npy", encrypted_array)
print("图片已加密并保存为 encrypted_image.npy")

分析源码就是将每个像素的rbg加密了,n直接在网站上分解就行,rsa正常的拿到d进行解密就行了

exp

from PIL import Image
from Crypto.Util.number import bytes_to_long, long_to_bytes
import numpy as np
import gmpy2

n = 29869349657224745144762606999
e = 65537

p = 160216064374859
q = 186431677583461
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)

original_image_path = "encrypted_image.npy"
encrypted_array = np.load(original_image_path,allow_pickle=True)
decrypted_array = np.zeros_like(encrypted_array,dtype=np.uint8)
for i in range(encrypted_array.shape[0]):
    for j in range(encrypted_array.shape[1]):
        r_encrypted, g_encrypted, b_encrypted = encrypted_array[i, j]

        r_decrypted = pow(r_encrypted,d,n)
        g_decrypted = pow(g_encrypted,d,n)
        b_decrypted = pow(b_encrypted,d,n)

        decrypted_array[i, j, 0] = r_decrypted
        decrypted_array[i, j, 1] = g_decrypted
        decrypted_array[i, j, 2] = b_decrypted
decrypted_img = Image.fromarray(decrypted_array)

decrypted_img.save("flag.jpg")
print("图片已解密并保存为 flag.jpg")

image-20241109215323052
image-20241109215323052

蓝鲨的费马

ISCTF{u_got_it}
import libnum
import gmpy2
from Crypto.Util.number import *

flag=b'ISCTF{********}'
m = bytes_to_long(flag)

p=libnum.generate_prime(1024)
q=libnum.generate_prime(1024)
n=p*q
e=0x10001
c=pow(m,e,n)
d=inverse(e,(p-1)*(q-1))
leak = (d+(pow(p,q,n)+pow(q,p,n)))%n

print("c=", c)
print("n=", n)
print("leak=", leak)
分析:leak = (d+(pow(p,q,n)+pow(q,p,n)))%n
=>pow(p,q,n) = p
=>pow(q,p,n) = q
=>leak = d + p + q
=>d = leak - (p + q)
=>m = pow(c,leak - (p + q),n)
=>m = c^leak * c^[-(p+q)]%n
=>phi = n + 1 - (p + q)
根据欧拉定理=>c^phi%n=1
=>c^[n + 1 - (p + q)]%n=1
=>c^(n + 1) * c^[-(p + q)]%n=1
=>c^(n + 1) * c^[-(p + q)]%n * c^(p + q)%n=1 * c^(p + q)%n
结论:c^(n + 1)%n=c^(p + q)%n
所以:m = c^leak * c^[-(p+q)]%n=>m = c^leak * c^[-(n + 1)]%n
=>m = pow(c,leak-(n+1),n)

exp

from Crypto.Util.number import *

c= 
n= 
leak= 
m = pow(c,leak-(n+1),n)
print(long_to_bytes(m))#b'ISCTF{u_got_it}'

ChaCha20-Poly1305

ISCTF{Blueshark_Swims_Through_ChaCha20_Poly1305}
from Crypto.Cipher import ChaCha20_Poly1305
import os

key = os.urandom(32)
nonce = os.urandom(12)

with open('flag.txt', 'rb') as f:
    plaintext = f.read()

cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)

ct, tag = cipher.encrypt_and_digest(plaintext)

print(f"Encrypted Flag: {ct.hex()}")
print(f"Tag: {tag.hex()}")
print(f"Nonce: {nonce.hex()}")

with open('key.txt', 'w') as key_file:
    key_file.write(key.hex())

附件给了密文,tag和nonce以及被修改过的key

将被修改过的key放在随波逐流解密,发现是base92编码

所以真key的hex是173974535637a5ef30a116b03d00bd2fe751951ca3eaa62daec2b8f5ca5b6135

exp

key_hex = '173974535637a5ef30a116b03d00bd2fe751951ca3eaa62daec2b8f5ca5b6135'
key = bytes.fromhex(key_hex)

ct_hex = ""
tag_hex = ""
nonce_hex = ""

ct = bytes.fromhex(ct_hex)
tag = bytes.fromhex(tag_hex)
nonce = bytes.fromhex(nonce_hex)

# 创建解密对象
cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)

# 解密数据
plaintext = cipher.decrypt_and_verify(ct, tag)
print(f"Decrypted Flag: {plaintext.decode()}")
#Decrypted Flag: ISCTF{Blueshark_Swims_Through_ChaCha20_Poly1305}

小蓝鲨的数学题

ISCTF{5f95ca93-1594-762d-ed0b-a9139692cb4a}

题目说是log,附件给了base和c,猜测是离散对数,且c = pow(m,flag,n),一开始没给n,我猜是2**512

也是小小的拿了次一血,后面估计没人想到n是2**512,主办方也是给了hint,告诉了n的值

exp

#Base和Ciphertext
import gmpy2
import libnum
import sympy
m = 5321153468370294351697008906248782883193902636120413346203705810525086437271585682015110123362488732193020749380395419994982400888011862076022065339666193
c = 7383779796712259466884236308066760158536557371789388054326630574611014773044467468610300619865230550443643660647968413988480055366698747395046400909922513
n = 2 ** 512

flag=sympy.discrete_log(n,c,m)
print(flag)
print(libnum.n2s(int(flag)))
#ISCTF{5f95ca93-1594-762d-ed0b-a9139692cb4a}

Misc

小蓝鲨的签到01

ISCTF{Welcome_to_blueshark}

扫码关注公众号没啥好说的

小蓝鲨的签到02

ISCTF{blueshark!_@#2024$%^&*}

010打开拉到最下面

image-20241109235753387
image-20241109235753387

少女的秘密花园

ISCTF{C0me_0n_fr35hm3n}

image-20241110151206590
image-20241110151206590

010打开发现含有zip的标识,分离出来,解压获得base_misc,用010打开也是一个压缩包,改一下后缀

打开发现需要密码,暴力破解

image-20241110151312308
image-20241110151312308

用密码打开压缩包,获得:

image-20241110151354259
image-20241110151354259

一段base64编码,iVBOR开头怀疑是图片的base64编码,将其转为图片发现高度不对,修复获得:

result-修复高宽
result-修复高宽

这是盲文,从网上找到对照表

盲文字母, 标点符号和数字。为盲人读书。盲人或视力受损者使用的触觉书写系统。矢量插图.
盲文字母, 标点符号和数字。为盲人读书。盲人或视力受损者使用的触觉书写系统。矢量插图.

对照出来的字符:JFJUGVCGPNBTA3LFL4YG4X3GOIZTK2DNGNXH2===

厨子自动识别是base32

image-20241116202748582
image-20241116202748582

watermark

ISCTF{Watermark_is_used_2_protect%digital*assets}

image-20241116210920568
image-20241116210920568

零宽隐写,随便找个网站解密文本隐水印

image-20241116210955729
image-20241116210955729

key1:FAAqDPjpgKJiB6m

根据题目第二个的图片应该也是水印

image-20241116211222652
image-20241116211222652

key2:64oRvUfta9yJsBv

连接获得FAAqDPjpgKJiB6m64oRvUfta9yJsBv

打开文件是一大堆文本,直接搜索ISCTF

image-20241116211449366
image-20241116211449366

File_Format

ISCTF{WinACE_is_Easy_Subject_0v0}

image-20241110161856963
image-20241110161856963

用010查看文件,在最后发现了flag.txt和sfx标识,这是一种自解压程序的标识,将文件后缀改为exe

image-20241110162015414
image-20241110162015414

打开发现需要密码,暴力破解获得:

image-20241110162039103
image-20241110162039103

解压获得flag:ISCTF{WinACE_is_Easy_Subject_0v0}

老八奇怪自拍照

ISCTF{St4gs0lve_Rbg_S4eGh1de_H1de!!!}

用Stegsolve打开,在red 5,green2,blue1处发现异常

image-20241116210243428
image-20241116210243428

image-20241116210303322
image-20241116210303322

image-20241116210321090
image-20241116210321090

将数据提取出来,PK是个压缩包

image-20241116210439913
image-20241116210439913

解压获得一张图片,拖进随波逐流看看

image-20241116210555076
image-20241116210555076

猜测是密码,一开始以为是F5隐写,最后发现是steghide

image-20241116210648247
image-20241116210648247

Web

ezSSIT

ISCTF{65c30d4e-c71b-40cf-9bd0-e7c3c019a4a1}

工具秒了

image-20241111094753748
image-20241111094753748

1z_php

ISCTF{496a2960-b905-4c29-b5f5-0e0fe3b2d0a8}
<?php
highlight_file('index.php');
#一句话木马,神神又奇奇
if(isset($_POST['J'])){
    $call=$_POST['J'];
    $dangerous_commands = ['cat', 'tac', 'head', 'nl', 'more', 'less', 'tail', 'vi', 'sed', 'od'];
    foreach ($dangerous_commands as $command) {
        if (preg_match("/$command/i", $call)) {
            die("这些个危险函数可不兴使啊");
        }  
    }  system($call);}
?>

过滤了些常见查看函数,可以用\绕过,比如ca\t,尝试执行ca\t /flag,发现没有反应

执行ls /

image-20241114121523025
image-20241114121523025

文件名叫f14g,执行ca\t /f14g

image-20241114121618365
image-20241114121618365

小蓝鲨的冒险

ISCTF{300265bf-1f41-44aa-b2eb-7c1049e0ebe1}
<?php
error_reporting(0);
highlight_file(__FILE__);
$a = "isctf2024";
$b = $_GET["b"];
@parse_str($b);
echo "小蓝鲨开始闯关,你能帮助他拿到flag吗?<br>";
if ($a[0] != 'QNKCDZO' && md5($a[0]) == md5('QNKCDZO')) {
    $num = $_POST["num"];
    echo "第一关有惊无险!小蓝鲨壮着胆子接着继续往下走!<br>";
    if($num == 2024){
        die("QAQ小蓝鲨误入陷阱,不怕,再接再厉!");
    }
    if(preg_match("/[a-z]/i", $num)){
        die("陷阱太多QAQ");
    }
    if(intval($num,0) == 2024){
        echo "到这了难道还要放弃吗?<br>";
        if (isset($_GET['which'])){
            $which = $_GET['which'];
            echo "小蓝鲨貌似在哪里见过这个陷阱O.o?继续加油,还差最后一步了!";
            switch ($which){
                case 0:
                    print('QAQ');
                case 1:
                case 2:
                    require_once $which.'.php';
                    echo $flag;
                    break;
                default:
                    echo GWF_HTML::error('PHP-0817', 'Hacker NoNoNo!', false);
                    break;
            }
        }
    }
}

分析代码:

  • @parse_str($b); b传入a[0]=xx,那a[0]=xx
  • md5('QNKCDZO') = 0e开头,再找一个0e开头的就可以绕过
  • $num不能等于2024且不能有大小写字母
  • intval($num,0),自动匹配进制,0开头八进制,03750就是2024
  • case 0和case 1 都没加break,which传入flag就行了

image-20241114132336714
image-20241114132336714

exp

#GET传参
http://url?b=a[0]=240610708&which=flag
#POST传参
num=03750

Pwn

ez_game

ISCTF{178ffe78-088f-413d-adfa-bd812390488c}

image-20241114180029836
image-20241114180029836

分析伪代码,就是生成20001次随机数,你输入的值要和生成的随机数相同,要在15秒内完成

给了seed,seed固定那么每次生成的随机数都一样,生成20001个输出出来

#include <string.h>

int main(){
    int seed = 1,v7;
    srand(seed);
    printf("[");
    for(int i=0;i<=20000;++i){
        v7 = rand() % 7 + 1;
        printf("%d,",v7);
    }
    printf("]");
    return 0;
}

image-20241114180322477
image-20241114180322477

可以用在线环境生成,记得去掉最后的,

将生成的数据保存在txt里

image-20241114180541075
image-20241114180541075

exp

from pwn import *

rand_list = eval(open('rand.txt').read())
re = remote("27.25.151.12",32284)
re.recvuntil(b'Enter your username:')
re.sendline(b'yanami')
re.recvuntil(b'Please enter the number you want to guess:')
for i in range(20001):
    re.sendline(str(rand_list[i]))

re.interactive()

Reverse

你知道.elf文件嘛

ISCTF{0h!_Y0u_kn0w_th3_sTd64_t@bl3}

直接运行输入base64的码表就行

image-20241114220737186
image-20241114220737186

逃不出的黑墙

ISCTF{e920b34ba2ad1ac5e8f9edca57068ecc}

image-20241115132236860
image-20241115132236860

image-20241115132302806
image-20241115132302806

经典走迷宫,起点是P,终点是E,上下左右是love,把迷宫提取出来shift+E

image-20241115132533816
image-20241115132533816

用python编写脚本

exp

from collections import deque
unsigned_char_aP =[
  0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
  0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
  0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
  0x23, 0x50, 0x23, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
  0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x23, 0x2E,
  0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
  0x23, 0x2E, 0x23, 0x23, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x23,
  0x23, 0x2E, 0x23, 0x23, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E,
  0x23, 0x23, 0x23, 0x2E, 0x23, 0x23, 0x23, 0x23, 0x23, 0x2E,
  0x23, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E,
  0x23, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x23, 0x2E,
  0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E,
  0x23, 0x23, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x23,
  0x23, 0x2E, 0x23, 0x2E, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
  0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x23, 0x23, 0x2E,
  0x23, 0x43, 0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E,
  0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x2E, 0x2E,
  0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x23, 0x2E, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x23,
  0x23, 0x2E, 0x23, 0x23, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x23,
  0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x23,
  0x23, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E,
  0x23, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E,
  0x23, 0x2E, 0x23, 0x2E, 0x23, 0x23, 0x23, 0x23, 0x23, 0x2E,
  0x23, 0x23, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x23, 0x23, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x23, 0x23, 0x2E,
  0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E,
  0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E,
  0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x2E, 0x2E,
  0x23, 0x2E, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x23,
  0x23, 0x2E, 0x23, 0x2E, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
  0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E,
  0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x23,
  0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x23,
  0x23, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E,
  0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
  0x23, 0x2E, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
  0x23, 0x2E, 0x23, 0x23, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E,
  0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x23, 0x23, 0x2E,
  0x23, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x23, 0x2E,
  0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E,
  0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x23, 0x23, 0x23,
  0x23, 0x2E, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x2E, 0x2E,
  0x23, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E,
  0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E,
  0x23, 0x2E, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x23, 0x23, 0x2E,
  0x23, 0x2E, 0x23, 0x23, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E,
  0x23, 0x23, 0x23, 0x2E, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E,
  0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E,
  0x23, 0x23, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x23,
  0x23, 0x23, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x23,
  0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x23, 0x23, 0x2E,
  0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x2E, 0x2E,
  0x2E, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x2E, 0x2E,
  0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x2E, 0x45,
  0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x23,
  0x23, 0x23, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x23, 0x23, 0x2E,
  0x23, 0x2E, 0x23, 0x23, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E,
  0x23, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E,
  0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
  0x23, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x23, 0x2E, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
  0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x23,
  0x23, 0x23, 0x23, 0x23, 0x23, 0x2E, 0x23, 0x2E, 0x23, 0x2E,
  0x23, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
  0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E,
  0x2E, 0x2E, 0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x23, 0x2E,
  0x23, 0x2E, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x2E,
  0x23, 0x2E, 0x23, 0x2E, 0x23, 0x23, 0x23, 0x23, 0x23, 0x2E,
  0x23, 0x2E, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x2E,
  0x23, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x23, 0x2E,
  0x2E, 0x2E, 0x23, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
  0x23, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E]
maze = []
list1 = []
for i in range(0,len(unsigned_char_aP)):
  if i % 30 == 0 and i != 0:
    maze.append(list1)
    print(list1)
    list1 = []
  b = chr(unsigned_char_aP[i])
  if b == "C":
    b = "#"
  list1.append(b)

path_len = 0x7fffffff

def bfs(start, end, barrier):
    directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]  # 定义四个方向的移动
    for i in range(len(maze)):  # 获取起点和终点在列表中的索引
      for j in range(len(maze[i])):
        if (maze[i][j] == start):
          start = (i, j)
        if (maze[i][j] == end):
          end = (i, j)
    # 以下均是bfs算法套路
    queue = deque()
    queue.append((start, [start]))  # (当前位置, 路径)
    visited = set()
    visited.add(start)
    while queue:
      position, path = queue.popleft()
      if position == end:
        return path
      elif len(path) == path_len:
        return path
      for d in directions:
        next_position = (position[0] + d[0], position[1] + d[1])
        if 0 <= next_position[0] < len(maze) and 0 <= next_position[1] < len(maze[0]) and \
                maze[next_position[0]][next_position[1]] != barrier and next_position not in visited:
          queue.append((next_position, path + [next_position]))
          visited.add(next_position)
    return None

# 执行BFS搜索并打印结果
if __name__ == '__main__':

  path = bfs('P', 'E', "#")
  print("移动路径坐标:", path)
  for i in range(1, len(path)):
    x1, y1, x2, y2 = path[i - 1][0], path[i - 1][1], path[i][0], path[i][1]
    if (x1 > x2):  # 上
      print("l", end='')
    elif (x1 < x2):  # 下
      print("o", end='')
    elif (y1 > y2):  # 左
      print("v", end='')
    elif (y1 < y2):  # 右
      print("e", end='')

运行结果:将路径转为md5就是flag

image-20241115132751848
image-20241115132751848

ISCTF 2024
http://yanami.voin.ink/index.php/archives/14/
本文作者 YunLi
发布时间 2024-11-17
许可协议 CC BY-NC-SA 4.0
发表新评论